From 2b1178313efb6488986e00ed2ea2fc34a068720c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20m=C3=A5s=C3=A9n?= Date: Sat, 24 Apr 2021 18:22:02 +0200 Subject: [PATCH 1/4] test: use httptest instead of host port binding --- pkg/api/metrics/metrics_test.go | 68 ++++++++++++++++----------------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/pkg/api/metrics/metrics_test.go b/pkg/api/metrics/metrics_test.go index 44379eed0..03cfe0787 100644 --- a/pkg/api/metrics/metrics_test.go +++ b/pkg/api/metrics/metrics_test.go @@ -2,44 +2,54 @@ package metrics_test import ( "fmt" - "github.com/containrrr/watchtower/pkg/metrics" "io/ioutil" + stdlog "log" "net/http" + "net/http/httptest" "testing" "github.com/containrrr/watchtower/pkg/api" metricsAPI "github.com/containrrr/watchtower/pkg/api/metrics" + "github.com/containrrr/watchtower/pkg/metrics" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) -const Token = "123123123" +const ( + token = "123123123" + getUrl = "http://localhost:8080/v1/metrics" +) + +var log = stdlog.New(GinkgoWriter, "", 0) func TestContainer(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "Metrics Suite") } -func runTestServer(m *metricsAPI.Handler) { - http.Handle(m.Path, m.Handle) - go func() { - http.ListenAndServe(":8080", nil) - }() -} +func getWithToken(handler http.Handler) string { + respWriter := httptest.NewRecorder() -func getWithToken(c http.Client, url string) (*http.Response, error) { - req, _ := http.NewRequest("GET", url, nil) - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", Token)) - return c.Do(req) + req := httptest.NewRequest("GET", getUrl, nil) + req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token)) + + handler.ServeHTTP(respWriter, req) + + res := respWriter.Result() + body, err := ioutil.ReadAll(res.Body) + if err != nil { + log.Println("reading body failed: ", err) + return "" + } + return string(body) } -var _ = Describe("the metrics", func() { - httpAPI := api.New(Token) +var _ = Describe("the metrics API", func() { + httpAPI := api.New(token) m := metricsAPI.New() - httpAPI.RegisterHandler(m.Path, m.Handle) - httpAPI.Start(false) + handleReq := httpAPI.RequireToken(m.Handle) It("should serve metrics", func() { metric := &metrics.Metric{ @@ -50,30 +60,18 @@ var _ = Describe("the metrics", func() { metrics.RegisterScan(metric) Eventually(metrics.Default().QueueIsEmpty).Should(BeTrue()) - c := http.Client{} - - res, err := getWithToken(c, "http://localhost:8080/v1/metrics") - Expect(err).ToNot(HaveOccurred()) - - contents, err := ioutil.ReadAll(res.Body) - Expect(err).ToNot(HaveOccurred()) - Expect(string(contents)).To(ContainSubstring("watchtower_containers_updated 3")) - Expect(string(contents)).To(ContainSubstring("watchtower_containers_failed 1")) - Expect(string(contents)).To(ContainSubstring("watchtower_containers_scanned 4")) - Expect(string(contents)).To(ContainSubstring("watchtower_scans_total 1")) - Expect(string(contents)).To(ContainSubstring("watchtower_scans_skipped 0")) + Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_containers_updated 3")) + Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_containers_failed 1")) + Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_containers_scanned 4")) + Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_scans_total 1")) + Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_scans_skipped 0")) for i := 0; i < 3; i++ { metrics.RegisterScan(nil) } Eventually(metrics.Default().QueueIsEmpty).Should(BeTrue()) - res, err = getWithToken(c, "http://localhost:8080/v1/metrics") - Expect(err).ToNot(HaveOccurred()) - - contents, err = ioutil.ReadAll(res.Body) - Expect(err).ToNot(HaveOccurred()) - Expect(string(contents)).To(ContainSubstring("watchtower_scans_total 4")) - Expect(string(contents)).To(ContainSubstring("watchtower_scans_skipped 3")) + Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_scans_total 4")) + Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_scans_skipped 3")) }) }) From 89c8c9495a14e1c9f33f80d37fbe2eec12bcc3e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20m=C3=A5s=C3=A9n?= Date: Sat, 24 Apr 2021 19:27:38 +0200 Subject: [PATCH 2/4] increase timeout for windows (?) --- pkg/api/metrics/metrics_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/api/metrics/metrics_test.go b/pkg/api/metrics/metrics_test.go index 03cfe0787..49d152a7c 100644 --- a/pkg/api/metrics/metrics_test.go +++ b/pkg/api/metrics/metrics_test.go @@ -7,6 +7,7 @@ import ( "net/http" "net/http/httptest" "testing" + "time" "github.com/containrrr/watchtower/pkg/api" metricsAPI "github.com/containrrr/watchtower/pkg/api/metrics" @@ -57,10 +58,11 @@ var _ = Describe("the metrics API", func() { Updated: 3, Failed: 1, } + metrics.RegisterScan(metric) Eventually(metrics.Default().QueueIsEmpty).Should(BeTrue()) - Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_containers_updated 3")) + Eventually(getWithToken(handleReq), time.Second * 5, time.Second).Should(ContainSubstring("watchtower_containers_updated 3")) Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_containers_failed 1")) Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_containers_scanned 4")) Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_scans_total 1")) @@ -71,7 +73,7 @@ var _ = Describe("the metrics API", func() { } Eventually(metrics.Default().QueueIsEmpty).Should(BeTrue()) - Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_scans_total 4")) + Eventually(getWithToken(handleReq), time.Second * 5, time.Second).Should(ContainSubstring("watchtower_scans_total 4")) Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_scans_skipped 3")) }) }) From 927f8a59a89772f44d311618aa24ab60652c8a8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20m=C3=A5s=C3=A9n?= Date: Sun, 25 Apr 2021 00:38:48 +0200 Subject: [PATCH 3/4] test: restore matrix and remove artificial delay --- .github/workflows/pull-request.yml | 21 +-------------------- pkg/api/metrics/metrics_test.go | 8 +++++--- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 24bfe13fd..80eb3e310 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -35,6 +35,7 @@ jobs: platform: - macos-latest - windows-latest + - ubuntu-latest runs-on: ${{ matrix.platform }} steps: - name: Checkout @@ -52,26 +53,6 @@ jobs: uses: codecov/codecov-action@v1 with: token: ${{ secrets.CODECOV_TOKEN }} - test-ubuntu: - name: Test (Ubuntu) - runs-on: ubuntu-latest - needs: test - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Set up Go - uses: actions/setup-go@v2 - with: - go-version: 1.15.x - - name: Run tests - run: | - go test -v -coverprofile coverage.out -covermode atomic ./... - - name: Publish coverage - uses: codecov/codecov-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} build: name: Build runs-on: ubuntu-latest diff --git a/pkg/api/metrics/metrics_test.go b/pkg/api/metrics/metrics_test.go index 49d152a7c..1f6c6c5aa 100644 --- a/pkg/api/metrics/metrics_test.go +++ b/pkg/api/metrics/metrics_test.go @@ -7,7 +7,6 @@ import ( "net/http" "net/http/httptest" "testing" - "time" "github.com/containrrr/watchtower/pkg/api" metricsAPI "github.com/containrrr/watchtower/pkg/api/metrics" @@ -53,6 +52,9 @@ var _ = Describe("the metrics API", func() { handleReq := httpAPI.RequireToken(m.Handle) It("should serve metrics", func() { + + Expect(getWithToken(handleReq)).To(ContainSubstring("watchtower_containers_updated 0")) + metric := &metrics.Metric{ Scanned: 4, Updated: 3, @@ -62,7 +64,7 @@ var _ = Describe("the metrics API", func() { metrics.RegisterScan(metric) Eventually(metrics.Default().QueueIsEmpty).Should(BeTrue()) - Eventually(getWithToken(handleReq), time.Second * 5, time.Second).Should(ContainSubstring("watchtower_containers_updated 3")) + Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_containers_updated 3")) Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_containers_failed 1")) Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_containers_scanned 4")) Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_scans_total 1")) @@ -73,7 +75,7 @@ var _ = Describe("the metrics API", func() { } Eventually(metrics.Default().QueueIsEmpty).Should(BeTrue()) - Eventually(getWithToken(handleReq), time.Second * 5, time.Second).Should(ContainSubstring("watchtower_scans_total 4")) + Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_scans_total 4")) Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_scans_skipped 3")) }) }) From c4a338f83da88542284e3b093f8d15e5a97228b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20m=C3=A5s=C3=A9n?= Date: Fri, 21 May 2021 15:14:46 +0200 Subject: [PATCH 4/4] fix metrics api test expect calls --- pkg/api/metrics/metrics_test.go | 49 +++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/pkg/api/metrics/metrics_test.go b/pkg/api/metrics/metrics_test.go index 1f6c6c5aa..5120f8df7 100644 --- a/pkg/api/metrics/metrics_test.go +++ b/pkg/api/metrics/metrics_test.go @@ -3,9 +3,9 @@ package metrics_test import ( "fmt" "io/ioutil" - stdlog "log" "net/http" "net/http/httptest" + "strings" "testing" "github.com/containrrr/watchtower/pkg/api" @@ -18,31 +18,35 @@ import ( const ( token = "123123123" - getUrl = "http://localhost:8080/v1/metrics" + getURL = "http://localhost:8080/v1/metrics" ) -var log = stdlog.New(GinkgoWriter, "", 0) - -func TestContainer(t *testing.T) { +func TestMetrics(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "Metrics Suite") } -func getWithToken(handler http.Handler) string { +func getWithToken(handler http.Handler) map[string]string { + metricMap := map[string]string{} respWriter := httptest.NewRecorder() - req := httptest.NewRequest("GET", getUrl, nil) + req := httptest.NewRequest("GET", getURL, nil) req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token)) handler.ServeHTTP(respWriter, req) res := respWriter.Result() - body, err := ioutil.ReadAll(res.Body) - if err != nil { - log.Println("reading body failed: ", err) - return "" + body, _ := ioutil.ReadAll(res.Body) + + for _, line := range strings.Split(string(body), "\n") { + if len(line) < 1 || line[0] == '#' { + continue + } + parts := strings.Split(line, " ") + metricMap[parts[0]] = parts[1] } - return string(body) + + return metricMap } var _ = Describe("the metrics API", func() { @@ -50,10 +54,11 @@ var _ = Describe("the metrics API", func() { m := metricsAPI.New() handleReq := httpAPI.RequireToken(m.Handle) + tryGetMetrics := func() map[string]string { return getWithToken(handleReq) } It("should serve metrics", func() { - Expect(getWithToken(handleReq)).To(ContainSubstring("watchtower_containers_updated 0")) + Expect(tryGetMetrics()).To(HaveKeyWithValue("watchtower_containers_updated", "0")) metric := &metrics.Metric{ Scanned: 4, @@ -64,18 +69,22 @@ var _ = Describe("the metrics API", func() { metrics.RegisterScan(metric) Eventually(metrics.Default().QueueIsEmpty).Should(BeTrue()) - Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_containers_updated 3")) - Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_containers_failed 1")) - Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_containers_scanned 4")) - Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_scans_total 1")) - Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_scans_skipped 0")) + Eventually(tryGetMetrics).Should(SatisfyAll( + HaveKeyWithValue("watchtower_containers_updated", "3"), + HaveKeyWithValue("watchtower_containers_failed", "1"), + HaveKeyWithValue("watchtower_containers_scanned", "4"), + HaveKeyWithValue("watchtower_scans_total", "1"), + HaveKeyWithValue("watchtower_scans_skipped", "0"), + )) for i := 0; i < 3; i++ { metrics.RegisterScan(nil) } Eventually(metrics.Default().QueueIsEmpty).Should(BeTrue()) - Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_scans_total 4")) - Eventually(getWithToken(handleReq)).Should(ContainSubstring("watchtower_scans_skipped 3")) + Eventually(tryGetMetrics).Should(SatisfyAll( + HaveKeyWithValue("watchtower_scans_total", "4"), + HaveKeyWithValue("watchtower_scans_skipped", "3"), + )) }) })