From a3e08e3ddf442ada78a302592dd3d90846a63733 Mon Sep 17 00:00:00 2001 From: Fernando Cainelli Date: Tue, 21 Jan 2025 09:03:30 -0300 Subject: [PATCH] ref: tests and setup ci (#11) --- .github/workflows/build-and-test.yaml | 25 ++++++++++ .golangci.yml | 14 ++++++ CODEOWNERS.md | 1 + examples/filters/setcookie_test.go | 55 +++++++++++++++++++++- filter/request.go | 1 - filter/request_test.go | 16 +++---- go.mod | 13 +++--- go.sum | 39 +++++++++------- server/server.go | 66 ++++++++++++++------------- server/server_test.go | 11 +++-- service/service_test.go | 65 ++++++++++++++++---------- test/filter/filter.go | 1 - test/testcases_test.go | 47 ++++++++++++++++++- 13 files changed, 256 insertions(+), 98 deletions(-) create mode 100644 .github/workflows/build-and-test.yaml create mode 100644 .golangci.yml create mode 100644 CODEOWNERS.md diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml new file mode 100644 index 0000000..dc28db0 --- /dev/null +++ b/.github/workflows/build-and-test.yaml @@ -0,0 +1,25 @@ +name: build +on: + push: + branches: + - main + pull_request: {} +concurrency: ${{ github.ref }} +permissions: + contents: read + pull-requests: read + id-token: write + +jobs: + test: + runs-on: [ubuntu-latest] + steps: + - name: checkout code + uses: actions/checkout@v4 + + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + + - name: tests + run: | + go test -vet=off -timeout 10m ./... -count=1 -race -v -p 1 diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..a3b6be6 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,14 @@ +run: + timeout: 10m +linters: + disable-all: true + enable: + - errcheck + - gofumpt + - gosimple + - govet + - ineffassign + - staticcheck + - stylecheck + - typecheck + - unused diff --git a/CODEOWNERS.md b/CODEOWNERS.md new file mode 100644 index 0000000..66bb5bc --- /dev/null +++ b/CODEOWNERS.md @@ -0,0 +1 @@ +* @getyourguide/sre @gygrobot diff --git a/examples/filters/setcookie_test.go b/examples/filters/setcookie_test.go index 4ae2c3d..9cf5540 100644 --- a/examples/filters/setcookie_test.go +++ b/examples/filters/setcookie_test.go @@ -1,12 +1,63 @@ package filters_test import ( + "context" + "log" "testing" + "time" + "github.com/getyourguide/extproc-go/examples/filters" + "github.com/getyourguide/extproc-go/server" extproctest "github.com/getyourguide/extproc-go/test" + "github.com/getyourguide/extproc-go/test/containers/envoy" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" ) -func TestSameSiteLax(t *testing.T) { +func TestFilters(t *testing.T) { + suite.Run(t, &FiltersTestSuite{}) +} + +type FiltersTestSuite struct { + suite.Suite + container *envoy.TestContainer + url string + ctx context.Context +} + +func (suite *FiltersTestSuite) SetupSuite() { + suite.ctx = context.Background() + suite.container = envoy.NewTestContainer() + if err := suite.container.Run(suite.ctx, "istio/proxyv2:1.24.2"); err != nil { + log.Fatal(err) + } + suite.url = suite.container.URL.String() +} + +func (suite *FiltersTestSuite) TearDownSuite() { + if err := suite.container.Terminate(suite.ctx); err != nil { + log.Fatalf("error terminating postgres container: %s", err) + } +} + +func (suite *FiltersTestSuite) TestSameSiteLaxMode() { + t := suite.T() + srv := server.New(context.Background(), + server.WithEcho(), + server.WithFilters(&filters.SameSiteLaxMode{}), + ) + + errCh := make(chan error, 1) + go func() { + errCh <- srv.Serve() + }() + err := server.WaitReady(srv, 10*time.Second) + require.NoError(t, err) + tc := extproctest.Load(t, "testdata/setcookie.yml") - tc.Run(t) + tc.Run(t, extproctest.WithURL(suite.url)) + + require.NoError(t, srv.Stop()) + err = <-errCh + require.NoError(t, err) } diff --git a/filter/request.go b/filter/request.go index f322df0..b0edd06 100644 --- a/filter/request.go +++ b/filter/request.go @@ -199,5 +199,4 @@ func NewRequestContext() *RequestContext { } return req - } diff --git a/filter/request_test.go b/filter/request_test.go index 100b180..9d6bf20 100644 --- a/filter/request_test.go +++ b/filter/request_test.go @@ -12,15 +12,13 @@ const ( requestID = "30149a57-c842-9e40-968d-bf9bdbed55b1" ) -var ( - envoyHeadersValue = http.Header{ - ":scheme": []string{"https"}, - ":authority": []string{"example.com"}, - ":method": []string{"GET"}, - ":path": []string{"/?q=a"}, - "X-Request-Id": []string{requestID}, - } -) +var envoyHeadersValue = http.Header{ + ":scheme": []string{"https"}, + ":authority": []string{"example.com"}, + ":method": []string{"GET"}, + ":path": []string{"/?q=a"}, + "X-Request-Id": []string{requestID}, +} func TestMutatedRequestHeaders(t *testing.T) { for _, tt := range []struct { diff --git a/go.mod b/go.mod index 4543b1e..e0fa7b2 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/testcontainers/testcontainers-go v0.34.0 go.opentelemetry.io/otel v1.32.0 go.opentelemetry.io/otel/trace v1.32.0 - google.golang.org/grpc v1.68.0 + google.golang.org/grpc v1.69.0 sigs.k8s.io/yaml v1.4.0 ) @@ -35,9 +35,9 @@ require ( github.com/go-ole/go-ole v1.2.6 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/klauspost/compress v1.17.4 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/kr/text v0.2.0 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/patternmatcher v0.6.0 // indirect @@ -50,20 +50,21 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect - github.com/shirou/gopsutil/v3 v3.23.12 // indirect + github.com/shirou/gopsutil/v3 v3.24.4 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect - github.com/yusufpapurcu/wmi v1.2.3 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel/metric v1.32.0 // indirect golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect + golang.org/x/time v0.7.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 // indirect google.golang.org/protobuf v1.35.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 05892c2..3dc36ab 100644 --- a/go.sum +++ b/go.sum @@ -60,14 +60,15 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rH github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= -github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY= +github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= @@ -93,12 +94,13 @@ github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c h1:NRoLoZvkBTKvR5gQLgA3e0hqjkY9u1wm+iOL45VN/qI= +github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4= -github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= +github.com/shirou/gopsutil/v3 v3.24.4 h1:dEHgzZXt4LMNm+oYELpzl9YCqV65Yr/6SfrvgRBtXeU= +github.com/shirou/gopsutil/v3 v3.24.4/go.mod h1:lTd2mdiOspcqLgAnr9/nGi71NkeMpWKdmhuxm9GusH8= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= @@ -114,6 +116,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/testcontainers/testcontainers-go v0.34.0 h1:5fbgF0vIN5u+nD3IWabQwRybuB4GY8G2HHgCkbMzMHo= @@ -124,8 +127,8 @@ github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+F github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= -github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= @@ -136,8 +139,10 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMey go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= -go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= -go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= +go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= @@ -167,7 +172,7 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= @@ -176,8 +181,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= +golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -187,12 +192,12 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto v0.0.0-20230920204549-e6e6cdab5c13 h1:vlzZttNJGVqTsRFU9AmdnrcO1Znh8Ew9kCD//yjigk0= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= +google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 h1:fVoAXEKA4+yufmbdVYv+SE73+cPZbbbe8paLsHfkK+U= +google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4= google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 h1:LWZqQOEjDyONlF1H6afSWpAL/znlREo2tHfLoe+8LMA= google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= -google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= -google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= +google.golang.org/grpc v1.69.0 h1:quSiOM1GJPmPH5XtU+BCoVXcDVJJAzNcoyfC2cCjGkI= +google.golang.org/grpc v1.69.0/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/server/server.go b/server/server.go index 2d6224d..bce867a 100644 --- a/server/server.go +++ b/server/server.go @@ -50,6 +50,32 @@ func New(ctx context.Context, opts ...Option) *Server { opt(srv) } + if srv.grpcNetwork == "" { + srv.grpcNetwork = defaultGrpcNetwork + } + if srv.grpcAddress == "" { + srv.grpcAddress = defaultGrpcAddress + } + if srv.grpcServer == nil { + srv.grpcServer = grpc.NewServer() + } + + if srv.echoConfig.enabled { + if srv.echoConfig.mux == nil { + srv.echoConfig.mux = http.NewServeMux() + } + if srv.echoConfig.bindAddress == "" { + srv.echoConfig.bindAddress = defaultHTTPBindAddr + } + + srv.echoConfig.mux.HandleFunc("/headers", echo.RequestHeaders) + srv.echoConfig.mux.HandleFunc("/response-headers", echo.ResponseHeaders) + srv.echoConfig.httpsrv = &http.Server{ + Addr: srv.echoConfig.bindAddress, + } + srv.echoConfig.httpsrv.Handler = srv.echoConfig.mux + + } return srv } @@ -96,32 +122,13 @@ func (s *Server) Serve() error { errCh := make(chan error, 1) if s.echoConfig.enabled { - if s.echoConfig.mux == nil { - s.echoConfig.mux = http.NewServeMux() - } - if s.echoConfig.bindAddress == "" { - s.echoConfig.bindAddress = defaultHTTPBindAddr - } - - s.echoConfig.mux.HandleFunc("/headers", echo.RequestHeaders) - s.echoConfig.mux.HandleFunc("/response-headers", echo.ResponseHeaders) go func() { - s.echoConfig.httpsrv = &http.Server{ - Addr: s.echoConfig.bindAddress, - } - s.echoConfig.httpsrv.Handler = s.echoConfig.mux slog.Info("starting http server", "address", s.echoConfig.bindAddress) errCh <- s.echoConfig.httpsrv.ListenAndServe() }() } go func() { - if s.grpcAddress == "" { - s.grpcAddress = defaultGrpcAddress - } - if s.grpcNetwork == "" { - s.grpcNetwork = defaultGrpcNetwork - } if s.grpcNetwork == "unix" { os.RemoveAll(s.grpcAddress) // nolint:errcheck } @@ -130,9 +137,6 @@ func (s *Server) Serve() error { errCh <- fmt.Errorf("cannot listen: %w", err) return } - if s.grpcServer == nil { - s.grpcServer = grpc.NewServer() - } extprocService := service.New(s.serviceOpts...) extproc.RegisterExternalProcessorServer(s.grpcServer, extprocService) slog.Info("starting grpc server", "address", s.grpcAddress) @@ -148,6 +152,9 @@ func (s *Server) Serve() error { } func (s *Server) Stop() error { + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + if s.grpcServer != nil { slog.Info("stopping grpc server") s.grpcServer.GracefulStop() @@ -155,13 +162,13 @@ func (s *Server) Stop() error { if s.grpcNetwork == "unix" { os.RemoveAll(s.grpcAddress) // nolint:errcheck } - if s.echoConfig.httpsrv == nil { - return nil - } - slog.Info("stopping http server") - if err := s.echoConfig.httpsrv.Shutdown(context.Background()); err != nil { - return fmt.Errorf("http server shutdown error: %w", err) + if s.echoConfig.httpsrv != nil { + slog.Info("stopping http server") + if err := s.echoConfig.httpsrv.Shutdown(ctx); err != nil { + return fmt.Errorf("http server shutdown error: %w", err) + } } + time.Sleep(defaultShutdownWait) return nil } @@ -182,9 +189,6 @@ func IsReady(s *Server) bool { return false } } - if s.grpcServer == nil { - return false - } return true } diff --git a/server/server_test.go b/server/server_test.go index a0ae361..ea8717a 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -21,7 +21,7 @@ func TestServer(t *testing.T) { go func() { errCh <- srv.Serve() }() - err := server.WaitReady(srv, 5*time.Second) + err := server.WaitReady(srv, 10*time.Second) require.NoError(t, err) shutdown() @@ -34,11 +34,11 @@ func TestServer(t *testing.T) { server.WithEcho(), server.WithFilters(&filter.NoOpFilter{}), ) + errCh := make(chan error, 1) go func() { - require.NoError(t, srv.Serve()) + errCh <- srv.Serve() }() - defer require.NoError(t, srv.Stop()) - err := server.WaitReady(srv, 5*time.Second) + err := server.WaitReady(srv, 10*time.Second) require.NoError(t, err) httpClient := http.Client{ @@ -51,7 +51,6 @@ func TestServer(t *testing.T) { res, err := httpClient.Do(req) require.NoError(t, err) - require.Equal(t, http.StatusOK, res.StatusCode) var resp echo.RequestHeaderResponse @@ -64,6 +63,8 @@ func TestServer(t *testing.T) { for key, expectedValue := range expectedHeaders { require.Equal(t, expectedValue, resp.Headers[key], "mismatch for header %s", key) } + require.NoError(t, srv.Stop()) + err = <-errCh require.NoError(t, err) }) } diff --git a/service/service_test.go b/service/service_test.go index b474484..f49062c 100644 --- a/service/service_test.go +++ b/service/service_test.go @@ -2,48 +2,57 @@ package service_test import ( "context" + "log" "os" "testing" "time" "github.com/getyourguide/extproc-go/filter" "github.com/getyourguide/extproc-go/server" - "github.com/getyourguide/extproc-go/test" + extproctest "github.com/getyourguide/extproc-go/test" "github.com/getyourguide/extproc-go/test/containers/envoy" filtertest "github.com/getyourguide/extproc-go/test/filter" "github.com/stretchr/testify/require" - "github.com/testcontainers/testcontainers-go" + "github.com/stretchr/testify/suite" "sigs.k8s.io/yaml" ) -var envoyProxy *envoy.TestContainer +func TestService(t *testing.T) { + suite.Run(t, &ServiceTestSuite{}) +} -func TestMain(m *testing.M) { - ctx := context.Background() - envoyProxy = envoy.NewTestContainer() - if err := envoyProxy.Run(ctx, "istio/proxyv2:1.24.2"); err != nil { - panic(err) - } - m.Run() - if err := testcontainers.TerminateContainer(envoyProxy); err != nil { - panic(err) +type ServiceTestSuite struct { + suite.Suite + container *envoy.TestContainer + url string + ctx context.Context +} + +func (suite *ServiceTestSuite) SetupSuite() { + suite.ctx = context.Background() + suite.container = envoy.NewTestContainer() + if err := suite.container.Run(suite.ctx, "istio/proxyv2:1.24.2"); err != nil { + log.Fatal(err) } + suite.url = suite.container.URL.String() } -func TestRequestHeaders(t *testing.T) { - runServiceTest(t, "testdata/request_header_order.yml") +func (suite *ServiceTestSuite) TearDownSuite() { + if err := suite.container.Terminate(suite.ctx); err != nil { + log.Fatalf("error terminating postgres container: %s", err) + } } -func TestResponseHeaders(t *testing.T) { - runServiceTest(t, "testdata/response_header_order.yml") +func (suite *ServiceTestSuite) TestRequestHeaders() { + suite.Run("testdata/request_header_order.yml") } -type serviceTest struct { - Filters []filtertest.Configuration `json:"filters"` - TestCases test.TestCases `json:"tests"` +func (suite *ServiceTestSuite) TestResponseHeaders() { + suite.Run("testdata/response_header_order.yml") } -func runServiceTest(t *testing.T, fileName string) { +func (suite *ServiceTestSuite) Run(fileName string) { + t := suite.T() f, err := os.ReadFile(fileName) require.NoError(t, err) @@ -62,16 +71,24 @@ func runServiceTest(t *testing.T, fileName string) { server.WithEcho(), server.WithFilters(filters...), ) + + errCh := make(chan error, 1) go func() { - require.NoError(t, srv.Serve()) + errCh <- srv.Serve() }() - waitTimeout := 5 * time.Second - err = server.WaitReady(srv, waitTimeout) + err = server.WaitReady(srv, 15*time.Second) require.NoError(t, err) tt.TestCases.Run(t, - test.WithURL(envoyProxy.URL.String()), + extproctest.WithURL(suite.url), ) require.NoError(t, srv.Stop()) + err = <-errCh + require.NoError(t, err) +} + +type serviceTest struct { + Filters []filtertest.Configuration `json:"filters"` + TestCases extproctest.TestCases `json:"tests"` } diff --git a/test/filter/filter.go b/test/filter/filter.go index 76615eb..f90963a 100644 --- a/test/filter/filter.go +++ b/test/filter/filter.go @@ -47,7 +47,6 @@ func (f *Filter) RequestHeaders(ctx context.Context, crw *filter.CommonResponseW crw.RemoveHeaders(f.Configuration.RequestHeaders.HeaderMutation.RemoveHeader...) for k, v := range f.Configuration.RequestHeaders.HeaderMutation.SetHeader { crw.SetHeader(k, v) - } for k, v := range f.Configuration.RequestHeaders.HeaderMutation.AppendHeader { crw.AppendHeader(k, v) diff --git a/test/testcases_test.go b/test/testcases_test.go index 6888ccf..0f5b44a 100644 --- a/test/testcases_test.go +++ b/test/testcases_test.go @@ -1,13 +1,54 @@ package test_test import ( + "context" + "log" "testing" + "time" + "github.com/getyourguide/extproc-go/server" extproctest "github.com/getyourguide/extproc-go/test" + "github.com/getyourguide/extproc-go/test/containers/envoy" "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" ) -func TestIntegrationTest(t *testing.T) { +func TestIntegration(t *testing.T) { + suite.Run(t, &IntegrationTestSuite{}) +} + +type IntegrationTestSuite struct { + suite.Suite + container *envoy.TestContainer + url string + ctx context.Context +} + +func (suite *IntegrationTestSuite) SetupSuite() { + suite.ctx = context.Background() + suite.container = envoy.NewTestContainer() + if err := suite.container.Run(suite.ctx, "istio/proxyv2:1.24.2"); err != nil { + log.Fatal(err) + } + suite.url = suite.container.URL.String() +} + +func (suite *IntegrationTestSuite) TearDownSuite() { + if err := suite.container.Terminate(suite.ctx); err != nil { + log.Fatalf("error terminating postgres container: %s", err) + } +} + +func (suite *IntegrationTestSuite) TestIntegrationTest() { + t := suite.T() + srv := server.New(context.Background(), server.WithEcho()) + errCh := make(chan error, 1) + go func() { + errCh <- srv.Serve() + }() + err := server.WaitReady(srv, 10*time.Second) + require.NoError(t, err) + templateData := struct { HeaderName string HeaderValue string @@ -17,5 +58,7 @@ func TestIntegrationTest(t *testing.T) { } testcases := extproctest.LoadTemplate(t, "testdata/httptest.yml", templateData) require.NotEmpty(t, testcases) - testcases.Run(t) + testcases.Run(t, extproctest.WithURL(suite.url)) + + require.NoError(t, srv.Stop()) }