From 35b35c5d67c83da87b6f4eeac5e6bd6242f2d807 Mon Sep 17 00:00:00 2001 From: 6543 <6543@noreply.codeberg.org> Date: Sat, 11 Jun 2022 23:17:43 +0200 Subject: [PATCH] Add integration tests (#86) close #82 close #32 make sure we dont get regressions again ... as we currently have in **main** followups: - create a DNS subdomayn specific to redirect to mock url ... Co-authored-by: 6543 <6543@obermui.de> Reviewed-on: https://codeberg.org/Codeberg/pages-server/pulls/86 Reviewed-by: crapStone --- .woodpecker.yml | 17 ++++++++-- Justfile | 2 +- go.mod | 1 + go.sum | 2 ++ integration/get_test.go | 69 ++++++++++++++++++++++++++++++++++++++++ integration/main_test.go | 62 ++++++++++++++++++++++++++++++++++++ main.go | 1 + 7 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 integration/get_test.go create mode 100644 integration/main_test.go diff --git a/.woodpecker.yml b/.woodpecker.yml index 271aaca..e7fa66a 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -8,19 +8,30 @@ pipeline: - go mod vendor lint: - image: golangci/golangci-lint:v1.45.2 + image: golangci/golangci-lint:latest + pull: true commands: - go version - go install mvdan.cc/gofumpt@latest - "[ $(gofumpt -extra -l . | wc -l) != 0 ] && { echo 'code not formated'; exit 1; }" - - golangci-lint run --timeout 5m + - golangci-lint run --timeout 5m --build-tags integration test: image: golang:1.18 commands: - - go test ./... + - go test -race codeberg.org/codeberg/pages/server/... build: image: golang:1.18 commands: - go build + + integration-tests: + image: golang:1.18 + commands: + - go test -race -tags integration codeberg.org/codeberg/pages/integration/... + environment: + - ACME_API=https://acme.mock.directory + - PAGES_DOMAIN=localhost.mock.directory + - RAW_DOMAIN=raw.localhost.mock.directory + - PORT=4430 \ No newline at end of file diff --git a/Justfile b/Justfile index bab0a1e..c5c5a08 100644 --- a/Justfile +++ b/Justfile @@ -13,7 +13,7 @@ build: lint: tool-golangci tool-gofumpt [ $(gofumpt -extra -l . | wc -l) != 0 ] && { echo 'code not formated'; exit 1; }; \ - golangci-lint run --timeout 5m + golangci-lint run --timeout 5m --build-tags integration fmt: tool-gofumpt gofumpt -w --extra . diff --git a/go.mod b/go.mod index 38a289a..13df431 100644 --- a/go.mod +++ b/go.mod @@ -60,6 +60,7 @@ require ( github.com/infobloxopen/infoblox-go-client v1.1.1 // indirect github.com/jarcoal/httpmock v1.0.6 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/joho/godotenv v1.4.0 // indirect github.com/json-iterator/go v1.1.7 // indirect github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 // indirect github.com/klauspost/compress v1.13.4 // indirect diff --git a/go.sum b/go.sum index a443641..f009f5e 100644 --- a/go.sum +++ b/go.sum @@ -266,6 +266,8 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= +github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= diff --git a/integration/get_test.go b/integration/get_test.go new file mode 100644 index 0000000..3f2048e --- /dev/null +++ b/integration/get_test.go @@ -0,0 +1,69 @@ +//go:build integration +// +build integration + +package integration + +import ( + "bytes" + "crypto/tls" + "io" + "net/http" + "net/http/cookiejar" + "testing" + + "github.com/rs/zerolog/log" + "github.com/stretchr/testify/assert" +) + +func TestGetRedirect(t *testing.T) { + log.Printf("== TestGetRedirect ==\n") + // test custom domain redirect + resp, err := getTestHTTPSClient().Get("https://calciumdibromid.localhost.mock.directory:4430") + assert.NoError(t, err) + if !assert.EqualValues(t, http.StatusTemporaryRedirect, resp.StatusCode) { + t.FailNow() + } + assert.EqualValues(t, "https://www.cabr2.de/", resp.Header["Location"][0]) + assert.EqualValues(t, 0, getSize(resp.Body)) +} + +func TestGetContent(t *testing.T) { + log.Printf("== TestGetContent ==\n") + // test get image + resp, err := getTestHTTPSClient().Get("https://magiclike.localhost.mock.directory:4430/images/827679288a.jpg") + assert.NoError(t, err) + if !assert.EqualValues(t, http.StatusOK, resp.StatusCode) { + t.FailNow() + } + assert.EqualValues(t, "image/jpeg", resp.Header["Content-Type"][0]) + assert.EqualValues(t, "124635", resp.Header["Content-Length"][0]) + assert.EqualValues(t, 124635, getSize(resp.Body)) + + // specify branch + resp, err = getTestHTTPSClient().Get("https://momar.localhost.mock.directory:4430/pag/@master/") + assert.NoError(t, err) + if !assert.EqualValues(t, http.StatusOK, resp.StatusCode) { + t.FailNow() + } + assert.EqualValues(t, "text/html; charset=utf-8", resp.Header["Content-Type"][0]) + assert.True(t, getSize(resp.Body) > 1000) +} + +func getTestHTTPSClient() *http.Client { + cookieJar, _ := cookiejar.New(nil) + return &http.Client{ + Jar: cookieJar, + CheckRedirect: func(_ *http.Request, _ []*http.Request) error { + return http.ErrUseLastResponse + }, + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } +} + +func getSize(stream io.Reader) int { + buf := new(bytes.Buffer) + _, _ = buf.ReadFrom(stream) + return buf.Len() +} diff --git a/integration/main_test.go b/integration/main_test.go new file mode 100644 index 0000000..43f6792 --- /dev/null +++ b/integration/main_test.go @@ -0,0 +1,62 @@ +//go:build integration +// +build integration + +package integration + +import ( + "context" + "os" + "testing" + "time" + + "codeberg.org/codeberg/pages/cmd" + + "github.com/rs/zerolog/log" + "github.com/urfave/cli/v2" +) + +func TestMain(m *testing.M) { + log.Printf("=== TestMain: START Server ==\n") + serverCtx, serverCancel := context.WithCancel(context.Background()) + if err := startServer(serverCtx); err != nil { + log.Fatal().Msgf("could not start server: %v", err) + } + defer func() { + serverCancel() + log.Printf("=== TestMain: Server STOPED ==\n") + }() + + time.Sleep(20 * time.Second) + + os.Exit(m.Run()) +} + +func startServer(ctx context.Context) error { + args := []string{ + "--verbose", + "--acme-accept-terms", "true", + } + setEnvIfNotSet("ACME_API", "https://acme.mock.directory") + setEnvIfNotSet("PAGES_DOMAIN", "localhost.mock.directory") + setEnvIfNotSet("RAW_DOMAIN", "raw.localhost.mock.directory") + setEnvIfNotSet("PORT", "4430") + + app := cli.NewApp() + app.Name = "pages-server" + app.Action = cmd.Serve + app.Flags = cmd.ServeFlags + + go func() { + if err := app.RunContext(ctx, args); err != nil { + log.Fatal().Msgf("run server error: %v", err) + } + }() + + return nil +} + +func setEnvIfNotSet(key, value string) { + if _, set := os.LookupEnv(key); !set { + os.Setenv(key, value) + } +} diff --git a/main.go b/main.go index 205ec93..2836b86 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "fmt" "os" + _ "github.com/joho/godotenv/autoload" "github.com/urfave/cli/v2" "codeberg.org/codeberg/pages/cmd"