This is an automated email from the ASF dual-hosted git repository.
alinsran pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git
The following commit(s) were added to refs/heads/master by this push:
new f536c26c chore: refactor e2e-test (#2467)
f536c26c is described below
commit f536c26c918e42b4de416eda1c4ffa95e9937a55
Author: AlinsRan <[email protected]>
AuthorDate: Thu Jul 17 09:00:11 2025 +0800
chore: refactor e2e-test (#2467)
---
Makefile | 10 +
go.mod | 76 +-
go.sum | 157 +++-
test/e2e/apisix/e2e_test.go | 4 +-
test/e2e/apisix/status.go | 161 ++---
test/e2e/crds/backendtrafficpolicy.go | 110 +--
test/e2e/crds/consumer.go | 357 ++++++----
test/e2e/framework/manifests/apisix.yaml | 7 +
test/e2e/framework/manifests/ingress.yaml | 21 +-
test/e2e/gatewayapi/gatewayproxy.go | 93 +--
test/e2e/gatewayapi/httproute.go | 1106 ++++++++++++++++-------------
test/e2e/ingress/ingress.go | 8 +-
test/e2e/scaffold/apisix_deployer.go | 12 +-
test/e2e/scaffold/assertion.go | 252 +++++++
test/e2e/scaffold/k8s.go | 18 +-
15 files changed, 1447 insertions(+), 945 deletions(-)
diff --git a/Makefile b/Makefile
index 15b7ecf1..35c593d1 100644
--- a/Makefile
+++ b/Makefile
@@ -30,8 +30,10 @@ KIND_NAME ?= apisix-ingress-cluster
GATEAY_API_VERSION ?= v1.2.0
ADC_VERSION ?= 0.20.0
+GINKGO_VERSION ?= 2.20.0
TEST_TIMEOUT ?= 80m
TEST_DIR ?= ./test/e2e/apisix/
+E2E_NODES ?= 2
# CRD Reference Documentation
CRD_REF_DOCS_VERSION ?= v0.1.0
@@ -127,6 +129,14 @@ kind-e2e-test: kind-up build-image kind-load-images
e2e-test
e2e-test:
go test $(TEST_DIR) -test.timeout=$(TEST_TIMEOUT) -v -ginkgo.v
-ginkgo.focus="$(TEST_FOCUS)" -ginkgo.label-filter="$(TEST_LABEL)"
+.PHONY: ginkgo-e2e-test
+ginkgo-e2e-test:
+ @ginkgo -cover -coverprofile=coverage.txt -r --randomize-all
--randomize-suites --trace --focus=$(E2E_FOCUS) --nodes=$(E2E_NODES) $(TEST_DIR)
+
+.PHONY: install-ginkgo
+install-ginkgo:
+ @go install github.com/onsi/ginkgo/v2/ginkgo@v$(GINKGO_VERSION)
+
.PHONY: conformance-test
conformance-test:
go test -v ./test/conformance -tags=conformance -timeout 60m
diff --git a/go.mod b/go.mod
index 068e83a9..3e5cf556 100644
--- a/go.mod
+++ b/go.mod
@@ -11,7 +11,7 @@ require (
github.com/go-logr/logr v1.4.2
github.com/go-logr/zapr v1.3.0
github.com/google/uuid v1.6.0
- github.com/gruntwork-io/terratest v0.47.0
+ github.com/gruntwork-io/terratest v0.50.0
github.com/hashicorp/go-memdb v1.3.4
github.com/incubator4/go-resty-expr v0.1.1
github.com/onsi/ginkgo/v2 v2.20.0
@@ -19,7 +19,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/samber/lo v1.47.0
github.com/spf13/cobra v1.8.1
- github.com/stretchr/testify v1.9.0
+ github.com/stretchr/testify v1.10.0
go.uber.org/zap v1.27.0
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
gopkg.in/yaml.v3 v3.0.1
@@ -35,6 +35,7 @@ require (
)
require (
+ filippo.io/edwards25519 v1.1.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.1 // indirect
github.com/TylerBrock/colorjson v0.0.0-20200706003622-8a50f05110d2 //
indirect
@@ -42,13 +43,48 @@ require (
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 //
indirect
- github.com/aws/aws-sdk-go v1.44.245 // indirect
+ github.com/aws/aws-sdk-go-v2 v1.32.5 // indirect
+ github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect
+ github.com/aws/aws-sdk-go-v2/config v1.28.5 // indirect
+ github.com/aws/aws-sdk-go-v2/credentials v1.17.46 // indirect
+ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20 // indirect
+ github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.41 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24 // indirect
+ github.com/aws/aws-sdk-go-v2/service/acm v1.30.6 // indirect
+ github.com/aws/aws-sdk-go-v2/service/autoscaling v1.51.0 // indirect
+ github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.44.0 // indirect
+ github.com/aws/aws-sdk-go-v2/service/dynamodb v1.37.1 // indirect
+ github.com/aws/aws-sdk-go-v2/service/ec2 v1.193.0 // indirect
+ github.com/aws/aws-sdk-go-v2/service/ecr v1.36.6 // indirect
+ github.com/aws/aws-sdk-go-v2/service/ecs v1.52.0 // indirect
+ github.com/aws/aws-sdk-go-v2/service/iam v1.38.1 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1
// indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5 //
indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery
v1.10.5 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5 //
indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5 //
indirect
+ github.com/aws/aws-sdk-go-v2/service/kms v1.37.6 // indirect
+ github.com/aws/aws-sdk-go-v2/service/lambda v1.69.0 // indirect
+ github.com/aws/aws-sdk-go-v2/service/rds v1.91.0 // indirect
+ github.com/aws/aws-sdk-go-v2/service/route53 v1.46.2 // indirect
+ github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0 // indirect
+ github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.6 // indirect
+ github.com/aws/aws-sdk-go-v2/service/sns v1.33.6 // indirect
+ github.com/aws/aws-sdk-go-v2/service/sqs v1.37.1 // indirect
+ github.com/aws/aws-sdk-go-v2/service/ssm v1.56.0 // indirect
+ github.com/aws/aws-sdk-go-v2/service/sso v1.24.6 // indirect
+ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5 // indirect
+ github.com/aws/aws-sdk-go-v2/service/sts v1.33.1 // indirect
+ github.com/aws/smithy-go v1.22.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc //
indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
- github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
+ github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc //
indirect
github.com/emicklei/go-restful/v3 v3.12.0 // indirect
github.com/evanphx/json-patch v5.9.0+incompatible // indirect
@@ -63,7 +99,7 @@ require (
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
- github.com/go-sql-driver/mysql v1.7.1 // indirect
+ github.com/go-sql-driver/mysql v1.8.1 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
@@ -88,6 +124,10 @@ require (
github.com/imdario/mergo v0.3.16 // indirect
github.com/imkira/go-interpol v1.1.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
+ github.com/jackc/pgpassfile v1.0.0 // indirect
+ github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 //
indirect
+ github.com/jackc/pgx/v5 v5.7.1 // indirect
+ github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
@@ -107,7 +147,7 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 //
indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f //
indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 //
indirect
- github.com/pquerna/otp v1.2.0 // indirect
+ github.com/pquerna/otp v1.4.0 // indirect
github.com/prometheus/client_golang v1.19.1 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
@@ -119,7 +159,7 @@ require (
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
- github.com/urfave/cli v1.22.14 // indirect
+ github.com/urfave/cli v1.22.16 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.34.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
@@ -129,31 +169,31 @@ require (
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect
github.com/yudai/gojsondiff v1.0.0 // indirect
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0
// indirect
- go.opentelemetry.io/otel v1.28.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0
// indirect
+ go.opentelemetry.io/otel v1.29.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0
// indirect
- go.opentelemetry.io/otel/metric v1.28.0 // indirect
- go.opentelemetry.io/otel/sdk v1.28.0 // indirect
- go.opentelemetry.io/otel/trace v1.28.0 // indirect
+ go.opentelemetry.io/otel/metric v1.29.0 // indirect
+ go.opentelemetry.io/otel/sdk v1.29.0 // indirect
+ go.opentelemetry.io/otel/trace v1.29.0 // indirect
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/arch v0.6.0 // indirect
golang.org/x/crypto v0.36.0 // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/net v0.38.0 // indirect
- golang.org/x/oauth2 v0.21.0 // indirect
+ golang.org/x/oauth2 v0.24.0 // indirect
golang.org/x/sync v0.12.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/term v0.30.0 // indirect
golang.org/x/text v0.23.0 // indirect
- golang.org/x/time v0.5.0 // indirect
+ golang.org/x/time v0.8.0 // indirect
golang.org/x/tools v0.24.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
- google.golang.org/genproto/googleapis/api
v0.0.0-20240604185151-ef581f913117 // indirect
- google.golang.org/genproto/googleapis/rpc
v0.0.0-20240701130421-f6361c86f094 // indirect
- google.golang.org/grpc v1.66.2 // indirect
- google.golang.org/protobuf v1.34.2 // indirect
+ google.golang.org/genproto/googleapis/api
v0.0.0-20241104194629-dd2ea8efbc28 // indirect
+ google.golang.org/genproto/googleapis/rpc
v0.0.0-20241104194629-dd2ea8efbc28 // indirect
+ google.golang.org/grpc v1.67.1 // indirect
+ google.golang.org/protobuf v1.35.1 // indirect
gopkg.in/fsnotify.v1 v1.4.7 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
diff --git a/go.sum b/go.sum
index 2be83ffa..9ba03274 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,7 @@
+filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
+filippo.io/edwards25519 v1.1.0/go.mod
h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/BurntSushi/toml v0.3.1/go.mod
h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/toml v1.3.2/go.mod
h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/BurntSushi/toml v1.4.0/go.mod
h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/Masterminds/goutils v1.1.1
h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod
h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.2.0/go.mod
h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
@@ -22,8 +24,78 @@ github.com/armon/go-socks5
v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod
h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod
h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
-github.com/aws/aws-sdk-go v1.44.245
h1:KtY2s4q31/kn33AdV63R5t77mdxsI7rq3YT7Mgo805M=
-github.com/aws/aws-sdk-go v1.44.245/go.mod
h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
+github.com/aws/aws-sdk-go-v2 v1.32.5
h1:U8vdWJuY7ruAkzaOdD7guwJjD06YSKmnKCJs7s3IkIo=
+github.com/aws/aws-sdk-go-v2 v1.32.5/go.mod
h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7
h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod
h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc=
+github.com/aws/aws-sdk-go-v2/config v1.28.5
h1:Za41twdCXbuyyWv9LndXxZZv3QhTG1DinqlFsSuvtI0=
+github.com/aws/aws-sdk-go-v2/config v1.28.5/go.mod
h1:4VsPbHP8JdcdUDmbTVgNL/8w9SqOkM5jyY8ljIxLO3o=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.46
h1:AU7RcriIo2lXjUfHFnFKYsLCwgbz1E7Mm95ieIRDNUg=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.46/go.mod
h1:1FmYyLGL08KQXQ6mcTlifyFXfJVCNJTVGuQP4m0d/UA=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20
h1:sDSXIrlsFSFJtWKLQS4PUWRvrT580rrnuLydJrCQ/yA=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20/go.mod
h1:WZ/c+w0ofps+/OUqMwWgnfrgzZH1DZO1RIkktICsqnY=
+github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.41
h1:hqcxMc2g/MwwnRMod9n6Bd+t+9Nf7d5qRg7RaXKPd6o=
+github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.41/go.mod
h1:d1eH0VrttvPmrCraU68LOyNdu26zFxQFjrVSb5vdhog=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24
h1:4usbeaes3yJnCFC7kfeyhkdkPtoRYPa/hTmCqMpKpLI=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24/go.mod
h1:5CI1JemjVwde8m2WG3cz23qHKPOxbpkq0HaoreEgLIY=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24
h1:N1zsICrQglfzaBnrfM0Ys00860C+QFwu6u/5+LomP+o=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24/go.mod
h1:dCn9HbJ8+K31i8IQ8EWmWj0EiIk0+vKiHNMxTTYveAg=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1
h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod
h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24
h1:JX70yGKLj25+lMC5Yyh8wBtvB01GDilyRuJvXJ4piD0=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24/go.mod
h1:+Ln60j9SUTD0LEwnhEB0Xhg61DHqplBrbZpLgyjoEHg=
+github.com/aws/aws-sdk-go-v2/service/acm v1.30.6
h1:fDg0RlN30Xf/yYzEUL/WXqhmgFsjVb/I3230oCfyI5w=
+github.com/aws/aws-sdk-go-v2/service/acm v1.30.6/go.mod
h1:zRR6jE3v/TcbfO8C2P+H0Z+kShiKKVaVyoIl8NQRjyg=
+github.com/aws/aws-sdk-go-v2/service/autoscaling v1.51.0
h1:1KzQVZi7OTixxaVJ8fWaJAUBjme+iQ3zBOCZhE4RgxQ=
+github.com/aws/aws-sdk-go-v2/service/autoscaling v1.51.0/go.mod
h1:I1+/2m+IhnK5qEbhS3CrzjeiVloo9sItE/2K+so0fkU=
+github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.44.0
h1:OREVd94+oXW5a+3SSUAo4K0L5ci8cucCLu+PSiek8OU=
+github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.44.0/go.mod
h1:Qbr4yfpNqVNl69l/GEDK+8wxLf/vHi0ChoiSDzD7thU=
+github.com/aws/aws-sdk-go-v2/service/dynamodb v1.37.1
h1:vucMirlM6D+RDU8ncKaSZ/5dGrXNajozVwpmWNPn2gQ=
+github.com/aws/aws-sdk-go-v2/service/dynamodb v1.37.1/go.mod
h1:fceORfs010mNxZbQhfqUjUeHlTwANmIT4mvHamuUaUg=
+github.com/aws/aws-sdk-go-v2/service/ec2 v1.193.0
h1:RhSoBFT5/8tTmIseJUXM6INTXTQDF8+0oyxWBnozIms=
+github.com/aws/aws-sdk-go-v2/service/ec2 v1.193.0/go.mod
h1:mzj8EEjIHSN2oZRXiw1Dd+uB4HZTl7hC8nBzX9IZMWw=
+github.com/aws/aws-sdk-go-v2/service/ecr v1.36.6
h1:zg+3FGHA0PBs0KM25qE/rOf2o5zsjNa1g/Qq83+SDI0=
+github.com/aws/aws-sdk-go-v2/service/ecr v1.36.6/go.mod
h1:ZSq54Z9SIsOTf1Efwgw1msilSs4XVEfVQiP9nYVnKpM=
+github.com/aws/aws-sdk-go-v2/service/ecs v1.52.0
h1:7/vgFWplkusJN/m+3QOa+W9FNRqa8ujMPNmdufRaJpg=
+github.com/aws/aws-sdk-go-v2/service/ecs v1.52.0/go.mod
h1:dPTOvmjJQ1T7Q+2+Xs2KSPrMvx+p0rpyV+HsQVnUK4o=
+github.com/aws/aws-sdk-go-v2/service/iam v1.38.1
h1:hfkzDZHBp9jAT4zcd5mtqckpU4E3Ax0LQaEWWk1VgN8=
+github.com/aws/aws-sdk-go-v2/service/iam v1.38.1/go.mod
h1:u36ahDtZcQHGmVm/r+0L1sfKX4fzLEMdCqiKRKkUMVM=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1
h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod
h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5
h1:gvZOjQKPxFXy1ft3QnEyXmT+IqneM9QAUWlM3r0mfqw=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5/go.mod
h1:DLWnfvIcm9IET/mmjdxeXbBKmTCm0ZB8p1za9BVteM8=
+github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.5
h1:3Y457U2eGukmjYjeHG6kanZpDzJADa2m0ADqnuePYVQ=
+github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery
v1.10.5/go.mod h1:CfwEHGkTjYZpkQ/5PvcbEtT7AJlG68KkEvmtwU8z3/U=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5
h1:wtpJ4zcwrSbwhECWQoI/g6WM9zqCcSpHDJIWSbMLOu4=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5/go.mod
h1:qu/W9HXQbbQ4+1+JcZp0ZNPV31ym537ZJN+fiS7Ti8E=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5
h1:P1doBzv5VEg1ONxnJss1Kh5ZG/ewoIE4MQtKKc6Crgg=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5/go.mod
h1:NOP+euMW7W3Ukt28tAxPuoWao4rhhqJD3QEBk7oCg7w=
+github.com/aws/aws-sdk-go-v2/service/kms v1.37.6
h1:CZImQdb1QbU9sGgJ9IswhVkxAcjkkD1eQTMA1KHWk+E=
+github.com/aws/aws-sdk-go-v2/service/kms v1.37.6/go.mod
h1:YJDdlK0zsyxVBxGU48AR/Mi8DMrGdc1E3Yij4fNrONA=
+github.com/aws/aws-sdk-go-v2/service/lambda v1.69.0
h1:BXt75frE/FYtAmEDBJRBa2HexOw+oAZWZl6QknZEFgg=
+github.com/aws/aws-sdk-go-v2/service/lambda v1.69.0/go.mod
h1:guz2K3x4FKSdDaoeB+TPVgJNU9oj2gftbp5cR8ela1A=
+github.com/aws/aws-sdk-go-v2/service/rds v1.91.0
h1:eqHz3Uih+gb0vLE5Cc4Xf733vOxsxDp6GFUUVQU4d7w=
+github.com/aws/aws-sdk-go-v2/service/rds v1.91.0/go.mod
h1:h2jc7IleH3xHY7y+h8FH7WAZcz3IVLOB6/jXotIQ/qU=
+github.com/aws/aws-sdk-go-v2/service/route53 v1.46.2
h1:wmt05tPp/CaRZpPV5B4SaJ5TwkHKom07/BzHoLdkY1o=
+github.com/aws/aws-sdk-go-v2/service/route53 v1.46.2/go.mod
h1:d+K9HESMpGb1EU9/UmmpInbGIUcAkwmcY6ZO/A3zZsw=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0
h1:Q2ax8S21clKOnHhhr933xm3JxdJebql+R7aNo7p7GBQ=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0/go.mod
h1:ralv4XawHjEMaHOWnTFushl0WRqim/gQWesAMF6hTow=
+github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.6
h1:1KDMKvOKNrpD667ORbZ/+4OgvUoaok1gg/MLzrHF9fw=
+github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.6/go.mod
h1:DmtyfCfONhOyVAJ6ZMTrDSFIeyCBlEO93Qkfhxwbxu0=
+github.com/aws/aws-sdk-go-v2/service/sns v1.33.6
h1:lEUtRHICiXsd7VRwRjXaY7MApT2X4Ue0Mrwe6XbyBro=
+github.com/aws/aws-sdk-go-v2/service/sns v1.33.6/go.mod
h1:SODr0Lu3lFdT0SGsGX1TzFTapwveBrT5wztVoYtppm8=
+github.com/aws/aws-sdk-go-v2/service/sqs v1.37.1
h1:39WvSrVq9DD6UHkD+fx5x19P5KpRQfNdtgReDVNbelc=
+github.com/aws/aws-sdk-go-v2/service/sqs v1.37.1/go.mod
h1:3gwPzC9LER/BTQdQZ3r6dUktb1rSjABF1D3Sr6nS7VU=
+github.com/aws/aws-sdk-go-v2/service/ssm v1.56.0
h1:mADKqoZaodipGgiZfuAjtlcr4IVBtXPZKVjkzUZCCYM=
+github.com/aws/aws-sdk-go-v2/service/ssm v1.56.0/go.mod
h1:l9qF25TzH95FhcIak6e4vt79KE4I7M2Nf59eMUVjj6c=
+github.com/aws/aws-sdk-go-v2/service/sso v1.24.6
h1:3zu537oLmsPfDMyjnUS2g+F2vITgy5pB74tHI+JBNoM=
+github.com/aws/aws-sdk-go-v2/service/sso v1.24.6/go.mod
h1:WJSZH2ZvepM6t6jwu4w/Z45Eoi75lPN7DcydSRtJg6Y=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5
h1:K0OQAsDywb0ltlFrZm0JHPY3yZp/S9OaoLU33S7vPS8=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5/go.mod
h1:ORITg+fyuMoeiQFiVGoqB3OydVTLkClw/ljbblMq6Cc=
+github.com/aws/aws-sdk-go-v2/service/sts v1.33.1
h1:6SZUVRQNvExYlMLbHdlKB48x0fLbc2iVROyaNEwBHbU=
+github.com/aws/aws-sdk-go-v2/service/sts v1.33.1/go.mod
h1:GqWyYCwLXnlUB1lOAXQyNSPqPLQJvmo8J0DWBzp9mtg=
+github.com/aws/smithy-go v1.22.1
h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro=
+github.com/aws/smithy-go v1.22.1/go.mod
h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod
h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod
h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
@@ -38,9 +110,9 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod
h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY
github.com/cespare/xxhash/v2 v2.3.0
h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod
h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod
h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
-github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod
h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
-github.com/cpuguy83/go-md2man/v2 v2.0.4
h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod
h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.5
h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
+github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod
h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod
h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -90,8 +162,8 @@ github.com/go-playground/assert/v2 v2.0.1/go.mod
h1:VDjEfimB/XKnb+ZQfWdccd7VUvSc
github.com/go-playground/locales v0.14.0/go.mod
h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/universal-translator v0.18.0/go.mod
h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/validator/v10 v10.10.0/go.mod
h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
-github.com/go-sql-driver/mysql v1.7.1
h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
-github.com/go-sql-driver/mysql v1.7.1/go.mod
h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/go-sql-driver/mysql v1.8.1
h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
+github.com/go-sql-driver/mysql v1.8.1/go.mod
h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/go-task/slim-sprig/v3 v3.0.0
h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod
h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
@@ -130,8 +202,8 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0
h1:bkypFPDjIYGfCYD5mRBvpqxfYX1
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod
h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
github.com/gruntwork-io/go-commons v0.8.0
h1:k/yypwrPqSeYHevLlEDmvmgQzcyTwrlZGRaxEM6G0ro=
github.com/gruntwork-io/go-commons v0.8.0/go.mod
h1:gtp0yTtIBExIZp7vyIV9I0XQkVwiQZze678hvDXof78=
-github.com/gruntwork-io/terratest v0.47.0
h1:xIy1pT7NbGVlMLDZEHl3+3iSnvffh8tN2pL6idn448c=
-github.com/gruntwork-io/terratest v0.47.0/go.mod
h1:oywHw1cFKXSYvKPm27U7quZVzDUlA22H2xUrKCe26xM=
+github.com/gruntwork-io/terratest v0.50.0
h1:AbBJ7IRCpLZ9H4HBrjeoWESITv8nLjN6/f1riMNcAsw=
+github.com/gruntwork-io/terratest v0.50.0/go.mod
h1:see0lbKvAqz6rvzvN2wyfuFQQG4PWcAb2yHulF6B2q4=
github.com/hashicorp/errwrap v1.0.0/go.mod
h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0
h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod
h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -165,6 +237,14 @@ github.com/inconshreveable/mousetrap v1.1.0
h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
github.com/inconshreveable/mousetrap v1.1.0/go.mod
h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/incubator4/go-resty-expr v0.1.1
h1:9ur1M+p0wDzL1bprdGzHugGkfK0Yd3Ba/ijcgvL+a1k=
github.com/incubator4/go-resty-expr v0.1.1/go.mod
h1:w9YQkQLUs1cArOb4O7SGJwJL/L8kuAo6y5CVS2o9eag=
+github.com/jackc/pgpassfile v1.0.0
h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
+github.com/jackc/pgpassfile v1.0.0/go.mod
h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761
h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
+github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod
h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
+github.com/jackc/pgx/v5 v5.7.1/go.mod
h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
+github.com/jackc/puddle/v2 v2.2.2
h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
+github.com/jackc/puddle/v2 v2.2.2/go.mod
h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jmespath/go-jmespath v0.4.0
h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
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=
@@ -243,8 +323,8 @@ github.com/pmezard/go-difflib
v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77
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/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok=
-github.com/pquerna/otp v1.2.0/go.mod
h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
+github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
+github.com/pquerna/otp v1.4.0/go.mod
h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
github.com/prometheus/client_golang v1.19.1
h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
github.com/prometheus/client_golang v1.19.1/go.mod
h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.6.1
h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
@@ -288,6 +368,7 @@ github.com/stretchr/objx v0.1.0/go.mod
h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod
h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod
h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod
h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2/go.mod
h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod
h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod
h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod
h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -298,14 +379,15 @@ 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
h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
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/tailscale/depaware v0.0.0-20210622194025-720c4b409502/go.mod
h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8=
github.com/ugorji/go v1.2.7/go.mod
h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
github.com/ugorji/go/codec v1.2.7/go.mod
h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
github.com/urfave/cli v1.22.2/go.mod
h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
-github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk=
-github.com/urfave/cli v1.22.14/go.mod
h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA=
+github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ=
+github.com/urfave/cli v1.22.16/go.mod
h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po=
github.com/valyala/bytebufferpool v1.0.0
h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod
h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.34.0
h1:d3AAQJ2DRcxJYHm7OXNXtXt2as1vMDfxeIcFvhmGGm4=
@@ -331,20 +413,20 @@ github.com/yudai/pp v2.0.1+incompatible/go.mod
h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZ
github.com/yuin/goldmark v1.1.27/go.mod
h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod
h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod
h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0
h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod
h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
-go.opentelemetry.io/otel v1.28.0
h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
-go.opentelemetry.io/otel v1.28.0/go.mod
h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0
h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod
h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
+go.opentelemetry.io/otel v1.29.0
h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=
+go.opentelemetry.io/otel v1.29.0/go.mod
h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0
h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod
h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0
h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod
h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ=
-go.opentelemetry.io/otel/metric v1.28.0
h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
-go.opentelemetry.io/otel/metric v1.28.0/go.mod
h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
-go.opentelemetry.io/otel/sdk v1.28.0
h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
-go.opentelemetry.io/otel/sdk v1.28.0/go.mod
h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
-go.opentelemetry.io/otel/trace v1.28.0
h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
-go.opentelemetry.io/otel/trace v1.28.0/go.mod
h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
+go.opentelemetry.io/otel/metric v1.29.0
h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc=
+go.opentelemetry.io/otel/metric v1.29.0/go.mod
h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8=
+go.opentelemetry.io/otel/sdk v1.29.0
h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo=
+go.opentelemetry.io/otel/sdk v1.29.0/go.mod
h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok=
+go.opentelemetry.io/otel/trace v1.29.0
h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4=
+go.opentelemetry.io/otel/trace v1.29.0/go.mod
h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
go.opentelemetry.io/proto/otlp v1.3.1
h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
go.opentelemetry.io/proto/otlp v1.3.1/go.mod
h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
go.uber.org/atomic v1.7.0/go.mod
h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
@@ -385,12 +467,11 @@ golang.org/x/net
v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod
h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod
h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
-golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
-golang.org/x/oauth2 v0.21.0/go.mod
h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
+golang.org/x/oauth2 v0.24.0/go.mod
h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -413,14 +494,12 @@ golang.org/x/sys
v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod
h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod
h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
golang.org/x/term v0.30.0/go.mod
h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
@@ -431,8 +510,8 @@ golang.org/x/text v0.3.7/go.mod
h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod
h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
-golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
-golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
+golang.org/x/time v0.8.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-20190328211700-ab21143f2384/go.mod
h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod
h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -448,16 +527,16 @@ golang.org/x/xerrors
v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gomodules.xyz/jsonpatch/v2 v2.4.0
h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod
h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
-google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117
h1:+rdxYoE3E5htTEWIe15GlN6IfvbURM//Jt0mmkmm6ZU=
-google.golang.org/genproto/googleapis/api
v0.0.0-20240604185151-ef581f913117/go.mod
h1:OimBR/bc1wPO9iV4NC2bpyjy3VnAwZh5EBPQdtaE5oo=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094
h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
-google.golang.org/genproto/googleapis/rpc
v0.0.0-20240701130421-f6361c86f094/go.mod
h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
-google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo=
-google.golang.org/grpc v1.66.2/go.mod
h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
+google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28
h1:M0KvPgPmDZHPlbRbaNU1APr28TvwvvdUPlSv7PUvy8g=
+google.golang.org/genproto/googleapis/api
v0.0.0-20241104194629-dd2ea8efbc28/go.mod
h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28
h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE=
+google.golang.org/genproto/googleapis/rpc
v0.0.0-20241104194629-dd2ea8efbc28/go.mod
h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
+google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
+google.golang.org/grpc v1.67.1/go.mod
h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/protobuf v1.26.0-rc.1/go.mod
h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.28.0/go.mod
h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-google.golang.org/protobuf v1.34.2
h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
-google.golang.org/protobuf v1.34.2/go.mod
h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
+google.golang.org/protobuf v1.35.1
h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
+google.golang.org/protobuf v1.35.1/go.mod
h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod
h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod
h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod
h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/test/e2e/apisix/e2e_test.go b/test/e2e/apisix/e2e_test.go
index da357c5d..ea814157 100644
--- a/test/e2e/apisix/e2e_test.go
+++ b/test/e2e/apisix/e2e_test.go
@@ -38,9 +38,7 @@ func TestAPISIXE2E(t *testing.T) {
_ = framework.NewFramework()
// init newDeployer function
- scaffold.NewDeployer = func(s *scaffold.Scaffold) scaffold.Deployer {
- return scaffold.NewAPISIXDeployer(s)
- }
+ scaffold.NewDeployer = scaffold.NewAPISIXDeployer
_, _ = fmt.Fprintf(GinkgoWriter, "Starting APISIX standalone e2e
suite\n")
RunSpecs(t, "apisix standalone e2e suite")
diff --git a/test/e2e/apisix/status.go b/test/e2e/apisix/status.go
index 1c72e412..7bc0b6a5 100644
--- a/test/e2e/apisix/status.go
+++ b/test/e2e/apisix/status.go
@@ -39,10 +39,6 @@ var _ = Describe("Test CRD Status",
Label("apisix.apache.org", "v2", "apisixrout
applier = framework.NewApplier(s.GinkgoT, s.K8sClient,
s.CreateResourceFromString)
)
- assertion := func(actualOrCtx any, args ...any) AsyncAssertion {
- return
Eventually(actualOrCtx).WithArguments(args...).WithTimeout(30 *
time.Second).ProbeEvery(time.Second)
- }
-
Context("Test ApisixRoute Sync Status", func() {
BeforeEach(func() {
By("create GatewayProxy")
@@ -95,22 +91,16 @@ spec:
- name: non-existent-plugin
enable: true
`
-
- getRequest := func(path string) func() int {
- return func() int {
- return
s.NewAPISIXClient().GET(path).WithHost("httpbin").Expect().Raw().StatusCode
- }
- }
-
It("unknown plugin", func() {
if os.Getenv("PROVIDER_TYPE") == "apisix-standalone" {
Skip("apisix standalone does not validate
unknown plugins")
}
By("apply ApisixRoute with valid plugin")
- applier.MustApplyAPIv2(types.NamespacedName{Namespace:
s.Namespace(), Name: "default"}, &apiv2.ApisixRoute{}, arWithInvalidPlugin)
+ err := s.CreateResourceFromString(arWithInvalidPlugin)
+ Expect(err).NotTo(HaveOccurred(), "creating ApisixRoute
with valid plugin")
By("check ApisixRoute status")
- assertion(func() string {
+ s.RetryAssertion(func() string {
output, _ := s.GetOutputFromString("ar",
"default", "-o", "yaml")
return output
}).Should(
@@ -124,67 +114,62 @@ spec:
By("Update ApisixRoute")
applier.MustApplyAPIv2(types.NamespacedName{Namespace:
s.Namespace(), Name: "default"}, &apiv2.ApisixRoute{}, ar)
- By("check ApisixRoute status")
- assertion(func() string {
- output, _ := s.GetOutputFromString("ar",
"default", "-o", "yaml")
- return output
- }).Should(
- And(
- ContainSubstring(`status: "True"`),
- ContainSubstring(`reason: Accepted`),
- ),
- )
-
By("check route in APISIX")
- assertion(getRequest("/get")).Should(Equal(200),
"should be able to access the route")
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin",
+ Check: scaffold.WithExpectedStatus(200),
+ })
})
It("dataplane unavailable", func() {
By("apply ApisixRoute")
applier.MustApplyAPIv2(types.NamespacedName{Namespace:
s.Namespace(), Name: "default"}, &apiv2.ApisixRoute{}, ar)
- By("check ApisixRoute status")
- assertion(func() string {
- output, _ := s.GetOutputFromString("ar",
"default", "-o", "yaml")
- return output
- }).Should(
- And(
- ContainSubstring(`status: "True"`),
- ContainSubstring(`reason: Accepted`),
- ),
- )
-
By("check route in APISIX")
- assertion(getRequest("/get")).Should(Equal(200),
"should be able to access the route")
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Headers: map[string]string{"Host": "httpbin"},
+ Check: scaffold.WithExpectedStatus(200),
+ })
s.Deployer.ScaleDataplane(0)
By("check ApisixRoute status")
- assertion(func() string {
+ s.RetryAssertion(func() string {
output, _ := s.GetOutputFromString("ar",
"default", "-o", "yaml")
return output
- }).Should(
- And(
- ContainSubstring(`status: "False"`),
- ContainSubstring(`reason: SyncFailed`),
- ),
- )
+ }).WithTimeout(80 * time.Second).
+ Should(
+ And(
+ ContainSubstring(`status:
"False"`),
+ ContainSubstring(`reason:
SyncFailed`),
+ ),
+ )
s.Deployer.ScaleDataplane(1)
By("check ApisixRoute status after scaling up")
- assertion(func() string {
+ s.RetryAssertion(func() string {
output, _ := s.GetOutputFromString("ar",
"default", "-o", "yaml")
return output
- }).Should(
- And(
- ContainSubstring(`status: "True"`),
- ContainSubstring(`reason: Accepted`),
- ),
- )
+ }).WithTimeout(80 * time.Second).
+ Should(
+ And(
+ ContainSubstring(`status:
"True"`),
+ ContainSubstring(`reason:
Accepted`),
+ ),
+ )
By("check route in APISIX")
- assertion(getRequest("/get")).Should(Equal(200),
"should be able to access the route")
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin",
+ Check: scaffold.WithExpectedStatus(200),
+ })
})
})
@@ -276,67 +261,55 @@ spec:
AfterEach(func() {
_ = s.DeleteResource("Gateway", "apisix")
})
- getRequest := func(path string) func() int {
- return func() int {
- return
s.NewAPISIXClient().GET(path).WithHost("httpbin").Expect().Raw().StatusCode
- }
- }
- var resourceApplied = func(resourType, resourceName,
resourceRaw string, observedGeneration int) {
- Expect(s.CreateResourceFromString(resourceRaw)).
- NotTo(HaveOccurred(), fmt.Sprintf("creating
%s", resourType))
-
- Eventually(func() string {
- hryaml, err := s.GetResourceYaml(resourType,
resourceName)
- Expect(err).NotTo(HaveOccurred(),
fmt.Sprintf("getting %s yaml", resourType))
- return hryaml
- }, "8s", "2s").
- Should(
- SatisfyAll(
- ContainSubstring(`status:
"True"`),
-
ContainSubstring(fmt.Sprintf("observedGeneration: %d", observedGeneration)),
- ),
- fmt.Sprintf("checking %s condition
status", resourType),
- )
- time.Sleep(5 * time.Second)
- }
It("dataplane unavailable", func() {
By("Create HTTPRoute")
- resourceApplied("HTTPRoute", "httpbin", httproute, 1)
+ err := s.CreateResourceFromString(httproute)
+ Expect(err).NotTo(HaveOccurred(), "creating HTTPRoute")
By("check route in APISIX")
- assertion(getRequest("/get")).Should(Equal(200),
"should be able to access the route")
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin",
+ Check: scaffold.WithExpectedStatus(200),
+ })
s.Deployer.ScaleDataplane(0)
- time.Sleep(10 * time.Second)
By("check ApisixRoute status")
- assertion(func() string {
+ s.RetryAssertion(func() string {
output, _ := s.GetOutputFromString("httproute",
"httpbin", "-o", "yaml")
return output
- }).Should(
- And(
- ContainSubstring(`status: "False"`),
- ContainSubstring(`reason: SyncFailed`),
- ),
- )
+ }).WithTimeout(80 * time.Second).
+ Should(
+ And(
+ ContainSubstring(`status:
"False"`),
+ ContainSubstring(`reason:
SyncFailed`),
+ ),
+ )
s.Deployer.ScaleDataplane(1)
- time.Sleep(10 * time.Second)
By("check ApisixRoute status after scaling up")
- assertion(func() string {
+ s.RetryAssertion(func() string {
output, _ := s.GetOutputFromString("httproute",
"httpbin", "-o", "yaml")
return output
- }).Should(
- And(
- ContainSubstring(`status: "True"`),
- ContainSubstring(`reason: Accepted`),
- ),
- )
+ }).WithTimeout(80 * time.Second).
+ Should(
+ And(
+ ContainSubstring(`status:
"True"`),
+ ContainSubstring(`reason:
Accepted`),
+ ),
+ )
By("check route in APISIX")
- assertion(getRequest("/get")).Should(Equal(200),
"should be able to access the route")
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin",
+ Check: scaffold.WithExpectedStatus(200),
+ })
})
})
})
diff --git a/test/e2e/crds/backendtrafficpolicy.go
b/test/e2e/crds/backendtrafficpolicy.go
index 4dc2ca92..82b88a20 100644
--- a/test/e2e/crds/backendtrafficpolicy.go
+++ b/test/e2e/crds/backendtrafficpolicy.go
@@ -19,7 +19,6 @@ package gatewayapi
import (
"fmt"
- "time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
@@ -130,33 +129,55 @@ spec:
})
It("should rewrite upstream host", func() {
s.ResourceApplied("BackendTrafficPolicy", "httpbin",
createUpstreamHost, 1)
- s.NewAPISIXClient().
- GET("/headers").
- WithHost("httpbin.org").
- Expect().
- Status(200).
- Body().Contains("httpbin.example.com")
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/headers",
+ Host: "httpbin.org",
+ Headers: map[string]string{
+ "Host": "httpbin.org",
+ },
+ Checks: []scaffold.ResponseCheckFunc{
+ scaffold.WithExpectedStatus(200),
+ scaffold.WithExpectedBodyContains(
+ "httpbin.example.com",
+ ),
+ },
+ })
s.ResourceApplied("BackendTrafficPolicy", "httpbin",
updateUpstreamHost, 2)
- s.NewAPISIXClient().
- GET("/headers").
- WithHost("httpbin.org").
- Expect().
- Status(200).
- Body().Contains("httpbin.update.example.com")
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/headers",
+ Host: "httpbin.org",
+ Headers: map[string]string{
+ "Host": "httpbin.org",
+ },
+ Checks: []scaffold.ResponseCheckFunc{
+ scaffold.WithExpectedStatus(200),
+ scaffold.WithExpectedBodyContains(
+ "httpbin.update.example.com",
+ ),
+ },
+ })
err := s.DeleteResourceFromString(createUpstreamHost)
Expect(err).NotTo(HaveOccurred(), "deleting
BackendTrafficPolicy")
- time.Sleep(5 * time.Second)
- s.NewAPISIXClient().
- GET("/headers").
- WithHost("httpbin.org").
- Expect().
- Status(200).
- Body().
- NotContains("httpbin.update.example.com").
- NotContains("httpbin.example.com")
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/headers",
+ Host: "httpbin.org",
+ Headers: map[string]string{
+ "Host": "httpbin.org",
+ },
+ Checks: []scaffold.ResponseCheckFunc{
+ scaffold.WithExpectedStatus(200),
+ scaffold.WithExpectedBodyNotContains(
+ "httpbin.update.example.com",
+ "httpbin.example.com",
+ ),
+ },
+ })
})
})
})
@@ -231,7 +252,6 @@ spec:
By("create Ingress with GatewayProxy IngressClass")
err = s.CreateResourceFromString(defaultIngress)
Expect(err).NotTo(HaveOccurred(), "creating Ingress with
GatewayProxy IngressClass")
- time.Sleep(5 * time.Second)
}
Context("Rewrite Upstream Host", func() {
@@ -265,34 +285,36 @@ spec:
BeforeEach(beforeEach)
It("should rewrite upstream host", func() {
+ reqAssert := &scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/headers",
+ Host: "httpbin.org",
+ Headers: map[string]string{
+ "Host": "httpbin.org",
+ },
+ }
s.ResourceApplied("BackendTrafficPolicy", "httpbin",
createUpstreamHost, 1)
- s.NewAPISIXClient().
- GET("/headers").
- WithHost("httpbin.org").
- Expect().
- Status(200).
- Body().Contains("httpbin.example.com")
+ s.RequestAssert(reqAssert.SetChecks(
+ scaffold.WithExpectedStatus(200),
+
scaffold.WithExpectedBodyContains("httpbin.example.com"),
+ ))
s.ResourceApplied("BackendTrafficPolicy", "httpbin",
updateUpstreamHost, 2)
- s.NewAPISIXClient().
- GET("/headers").
- WithHost("httpbin.org").
- Expect().
- Status(200).
- Body().Contains("httpbin.update.example.com")
+ s.RequestAssert(reqAssert.SetChecks(
+ scaffold.WithExpectedStatus(200),
+
scaffold.WithExpectedBodyContains("httpbin.update.example.com"),
+ ))
err := s.DeleteResourceFromString(createUpstreamHost)
Expect(err).NotTo(HaveOccurred(), "deleting
BackendTrafficPolicy")
- time.Sleep(5 * time.Second)
- s.NewAPISIXClient().
- GET("/headers").
- WithHost("httpbin.org").
- Expect().
- Status(200).
- Body().
- NotContains("httpbin.update.example.com").
- NotContains("httpbin.example.com")
+ s.RequestAssert(reqAssert.SetChecks(
+ scaffold.WithExpectedStatus(200),
+ scaffold.WithExpectedBodyNotContains(
+ "httpbin.update.example.com",
+ "httpbin.example.com",
+ ),
+ ))
})
})
})
diff --git a/test/e2e/crds/consumer.go b/test/e2e/crds/consumer.go
index 879d6048..26b8554f 100644
--- a/test/e2e/crds/consumer.go
+++ b/test/e2e/crds/consumer.go
@@ -19,8 +19,6 @@ package gatewayapi
import (
"fmt"
- "net/http"
- "time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
@@ -161,35 +159,47 @@ spec:
s.ResourceApplied("Consumer", "consumer-sample",
limitCountConsumer, 1)
s.ResourceApplied("Consumer", "consumer-sample2",
unlimitConsumer, 1)
- s.NewAPISIXClient().
- GET("/get").
- WithHeader("apikey", "sample-key").
- WithHost("httpbin.org").
- Expect().
- Status(200)
-
- s.NewAPISIXClient().
- GET("/get").
- WithHeader("apikey", "sample-key").
- WithHost("httpbin.org").
- Expect().
- Status(200)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ Headers: map[string]string{
+ "apikey": "sample-key",
+ },
+ Check: scaffold.WithExpectedStatus(200),
+ })
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ Headers: map[string]string{
+ "apikey": "sample-key",
+ },
+ Check: scaffold.WithExpectedStatus(200),
+ })
By("trigger limit-count")
- s.NewAPISIXClient().
- GET("/get").
- WithHeader("apikey", "sample-key").
- WithHost("httpbin.org").
- Expect().
- Status(503)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ Headers: map[string]string{
+ "apikey": "sample-key",
+ },
+ Check: scaffold.WithExpectedStatus(503),
+ })
for i := 0; i < 10; i++ {
- s.NewAPISIXClient().
- GET("/get").
- WithHeader("apikey", "sample-key2").
- WithHost("httpbin.org").
- Expect().
- Status(200)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ Headers: map[string]string{
+ "apikey": "sample-key2",
+ },
+ Check: scaffold.WithExpectedStatus(200),
+ })
}
})
})
@@ -244,72 +254,98 @@ spec:
It("Create/Update/Delete", func() {
s.ResourceApplied("Consumer", "consumer-sample",
defaultCredential, 1)
- s.NewAPISIXClient().
- GET("/get").
- WithHeader("apikey", "sample-key").
- WithHost("httpbin.org").
- Expect().
- Status(200)
-
- s.NewAPISIXClient().
- GET("/get").
- WithHeader("apikey", "sample-key2").
- WithHost("httpbin.org").
- Expect().
- Status(200)
-
- s.NewAPISIXClient().
- GET("/get").
- WithBasicAuth("sample-user", "sample-password").
- WithHost("httpbin.org").
- Expect().
- Status(200)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ Headers: map[string]string{
+ "apikey": "sample-key",
+ },
+ Check: scaffold.WithExpectedStatus(200),
+ })
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ Headers: map[string]string{
+ "apikey": "sample-key2",
+ },
+ Check: scaffold.WithExpectedStatus(200),
+ })
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ BasicAuth: &scaffold.BasicAuth{
+ Username: "sample-user",
+ Password: "sample-password",
+ },
+ Check: scaffold.WithExpectedStatus(200),
+ })
By("update Consumer")
s.ResourceApplied("Consumer", "consumer-sample",
updateCredential, 2)
- s.NewAPISIXClient().
- GET("/get").
- WithHeader("apikey", "sample-key").
- WithHost("httpbin.org").
- Expect().
- Status(401)
-
- s.NewAPISIXClient().
- GET("/get").
- WithHeader("apikey", "sample-key2").
- WithHost("httpbin.org").
- Expect().
- Status(401)
-
- s.NewAPISIXClient().
- GET("/get").
- WithHeader("apikey", "consumer-key").
- WithHost("httpbin.org").
- Expect().
- Status(200)
-
- s.NewAPISIXClient().
- GET("/get").
- WithBasicAuth("sample-user", "sample-password").
- WithHost("httpbin.org").
- Expect().
- Status(200)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ Headers: map[string]string{
+ "apikey": "sample-key",
+ },
+ Check: scaffold.WithExpectedStatus(401),
+ })
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ Headers: map[string]string{
+ "apikey": "sample-key2",
+ },
+ Check: scaffold.WithExpectedStatus(401),
+ })
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ Headers: map[string]string{
+ "apikey": "consumer-key",
+ },
+ Check: scaffold.WithExpectedStatus(200),
+ })
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ BasicAuth: &scaffold.BasicAuth{
+ Username: "sample-user",
+ Password: "sample-password",
+ },
+ Check: scaffold.WithExpectedStatus(200),
+ })
By("delete Consumer")
err := s.DeleteResourceFromString(updateCredential)
Expect(err).NotTo(HaveOccurred(), "deleting Consumer")
- time.Sleep(5 * time.Second)
-
- s.NewAPISIXClient().
- GET("/get").
- WithBasicAuth("sample-user", "sample-password").
- WithHost("httpbin.org").
- Expect().
- Status(401)
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ BasicAuth: &scaffold.BasicAuth{
+ Username: "sample-user",
+ Password: "sample-password",
+ },
+ Check: scaffold.WithExpectedStatus(401),
+ })
})
- })
+ })
Context("SecretRef", func() {
var keyAuthSecret = `
apiVersion: v1
@@ -370,61 +406,79 @@ spec:
Expect(err).NotTo(HaveOccurred(), "creating basic-auth
secret")
s.ResourceApplied("Consumer", "consumer-sample",
defaultConsumer, 1)
- s.NewAPISIXClient().
- GET("/get").
- WithHeader("apikey", "sample-key").
- WithHost("httpbin.org").
- Expect().
- Status(200)
-
- s.NewAPISIXClient().
- GET("/get").
- WithBasicAuth("sample-user", "sample-password").
- WithHost("httpbin.org").
- Expect().
- Status(200)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ Headers: map[string]string{
+ "apikey": "sample-key",
+ },
+ Check: scaffold.WithExpectedStatus(200),
+ })
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ BasicAuth: &scaffold.BasicAuth{
+ Username: "sample-user",
+ Password: "sample-password",
+ },
+ Check: scaffold.WithExpectedStatus(200),
+ })
// update basic-auth password
err = s.CreateResourceFromString(basicAuthSecret2)
Expect(err).NotTo(HaveOccurred(), "creating basic-auth
secret")
// use the old password will get 401
- Eventually(func() int {
- return s.NewAPISIXClient().
- GET("/get").
- WithBasicAuth("sample-user",
"sample-password").
- WithHost("httpbin.org").
- Expect().
- Raw().StatusCode
- }).WithTimeout(8 * time.Second).ProbeEvery(time.Second).
- Should(Equal(http.StatusUnauthorized))
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ BasicAuth: &scaffold.BasicAuth{
+ Username: "sample-user",
+ Password: "sample-password",
+ },
+ Check: scaffold.WithExpectedStatus(401),
+ })
// use the new password will get 200
- s.NewAPISIXClient().
- GET("/get").
- WithBasicAuth("sample-user",
"sample-password-new").
- WithHost("httpbin.org").
- Expect().
- Status(http.StatusOK)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ BasicAuth: &scaffold.BasicAuth{
+ Username: "sample-user",
+ Password: "sample-password-new",
+ },
+ Check: scaffold.WithExpectedStatus(200),
+ })
By("delete consumer")
err = s.DeleteResourceFromString(defaultConsumer)
Expect(err).NotTo(HaveOccurred(), "deleting consumer")
- time.Sleep(5 * time.Second)
-
- s.NewAPISIXClient().
- GET("/get").
- WithHeader("apikey", "sample-key").
- WithHost("httpbin.org").
- Expect().
- Status(401)
-
- s.NewAPISIXClient().
- GET("/get").
- WithBasicAuth("sample-user", "sample-password").
- WithHost("httpbin.org").
- Expect().
- Status(401)
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ Headers: map[string]string{
+ "apikey": "sample-key",
+ },
+ Check: scaffold.WithExpectedStatus(401),
+ })
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ BasicAuth: &scaffold.BasicAuth{
+ Username: "sample-user",
+ Password: "sample-password",
+ },
+ Check: scaffold.WithExpectedStatus(401),
+ })
})
})
@@ -471,12 +525,16 @@ spec:
s.ResourceApplied("Consumer", "consumer-sample",
defaultCredential, 1)
// verify basic-auth works
- s.NewAPISIXClient().
- GET("/get").
- WithBasicAuth("sample-user", "sample-password").
- WithHost("httpbin.org").
- Expect().
- Status(200)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ BasicAuth: &scaffold.BasicAuth{
+ Username: "sample-user",
+ Password: "sample-password",
+ },
+ Check: scaffold.WithExpectedStatus(200),
+ })
By("create additional gateway group to get new admin
key")
var err error
@@ -490,26 +548,35 @@ spec:
Expect(err).NotTo(HaveOccurred(), "creating APISIX
client for additional gateway group")
By("Consumer not found for additional gateway group")
- client.
- GET("/get").
- WithBasicAuth("sample-user", "sample-password").
- WithHost("httpbin.org").
- Expect().
- Status(404)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Client: client,
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ BasicAuth: &scaffold.BasicAuth{
+ Username: "sample-user",
+ Password: "sample-password",
+ },
+ Check: scaffold.WithExpectedStatus(404),
+ })
By("update GatewayProxy with new admin key")
updatedProxy := fmt.Sprintf(updatedGatewayProxy,
s.Deployer.GetAdminEndpoint(resources.DataplaneService), resources.AdminAPIKey)
err = s.CreateResourceFromString(updatedProxy)
Expect(err).NotTo(HaveOccurred(), "updating
GatewayProxy")
- time.Sleep(5 * time.Second)
By("verify Consumer works for additional gateway group")
- client.
- GET("/get").
- WithBasicAuth("sample-user", "sample-password").
- WithHost("httpbin.org").
- Expect().
- Status(200)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Client: client,
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.org",
+ BasicAuth: &scaffold.BasicAuth{
+ Username: "sample-user",
+ Password: "sample-password",
+ },
+ Check: scaffold.WithExpectedStatus(200),
+ })
})
})
})
diff --git a/test/e2e/framework/manifests/apisix.yaml
b/test/e2e/framework/manifests/apisix.yaml
index affa4bfb..6b4adbbc 100644
--- a/test/e2e/framework/manifests/apisix.yaml
+++ b/test/e2e/framework/manifests/apisix.yaml
@@ -93,6 +93,13 @@ spec:
volumeMounts:
- name: config-writable
mountPath: /usr/local/apisix/conf
+ readinessProbe:
+ failureThreshold: 6
+ initialDelaySeconds: 10
+ periodSeconds: 10
+ successThreshold: 1
+ tcpSocket:
+ port: 9080
volumes:
- name: config-source
configMap:
diff --git a/test/e2e/framework/manifests/ingress.yaml
b/test/e2e/framework/manifests/ingress.yaml
index c4bb1014..addb9552 100644
--- a/test/e2e/framework/manifests/ingress.yaml
+++ b/test/e2e/framework/manifests/ingress.yaml
@@ -68,7 +68,7 @@ rules:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
- name: apisix-ingress-manager-role
+ name: {{ .Namespace }}-apisix-ingress-manager-role
rules:
- apiGroups:
- ""
@@ -244,7 +244,7 @@ rules:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
- name: apisix-ingress-metrics-auth-role
+ name: {{ .Namespace }}-apisix-ingress-metrics-auth-role
rules:
- apiGroups:
- authentication.k8s.io
@@ -262,7 +262,7 @@ rules:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
- name: apisix-ingress-metrics-reader
+ name: {{ .Namespace }}-apisix-ingress-metrics-reader
rules:
- nonResourceURLs:
- /metrics
@@ -280,7 +280,7 @@ metadata:
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
- name: apisix-ingress-leader-election-role
+ name: {{ .Namespace }}-apisix-ingress-leader-election-role
subjects:
- kind: ServiceAccount
name: apisix-ingress-controller-manager
@@ -292,11 +292,11 @@ metadata:
labels:
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: apisix-ingress
- name: apisix-ingress-manager-rolebinding
+ name: {{ .Namespace }}-apisix-ingress-manager-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
- name: apisix-ingress-manager-role
+ name: {{ .Namespace }}-apisix-ingress-manager-role
subjects:
- kind: ServiceAccount
name: apisix-ingress-controller-manager
@@ -305,11 +305,11 @@ subjects:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
- name: apisix-ingress-metrics-auth-rolebinding
+ name: {{ .Namespace }}-apisix-ingress-metrics-auth-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
- name: apisix-ingress-metrics-auth-role
+ name: {{ .Namespace }}-apisix-ingress-metrics-auth-role
subjects:
- kind: ServiceAccount
name: apisix-ingress-controller-manager
@@ -320,14 +320,13 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: ingress-config
+ namespace: {{ .Namespace }}
data:
config.yaml: |
log_level: "debug"
-
controller_name: {{ .ControllerName | default
"apisix.apache.org/apisix-ingress-controller" }}
-
leader_election_id: "apisix-ingress-controller-leader"
-
+ exec_adc_timeout: 5s
provider:
type: {{ .ProviderType | default "apisix" }}
sync_period: {{ .ProviderSyncPeriod | default "0s" }}
diff --git a/test/e2e/gatewayapi/gatewayproxy.go
b/test/e2e/gatewayapi/gatewayproxy.go
index dfcbba9b..f8fc56f7 100644
--- a/test/e2e/gatewayapi/gatewayproxy.go
+++ b/test/e2e/gatewayapi/gatewayproxy.go
@@ -123,25 +123,6 @@ spec:
port: 80
`
- var resourceApplied = func(resourceType, resourceName, resourceRaw
string, observedGeneration int) {
- Expect(s.CreateResourceFromString(resourceRaw)).
- NotTo(HaveOccurred(), fmt.Sprintf("creating %s",
resourceType))
-
- Eventually(func() string {
- hryaml, err := s.GetResourceYaml(resourceType,
resourceName)
- Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("getting
%s yaml", resourceType))
- return hryaml
- }).WithTimeout(8*time.Second).ProbeEvery(2*time.Second).
- Should(
- SatisfyAll(
- ContainSubstring(`status: "True"`),
-
ContainSubstring(fmt.Sprintf("observedGeneration: %d", observedGeneration)),
- ),
- fmt.Sprintf("checking %s condition status",
resourceType),
- )
- time.Sleep(3 * time.Second)
- }
-
var (
gatewayClassName string
)
@@ -176,43 +157,40 @@ spec:
Expect(gwyaml).To(ContainSubstring("message: the gateway has
been accepted by the apisix-ingress-controller"), "checking Gateway condition
message")
})
- AfterEach(func() {
- By("Clean up resources")
- _ = s.DeleteResourceFromString(fmt.Sprintf(httpRouteForTest,
"apisix"))
- _ = s.DeleteResourceFromString(fmt.Sprintf(gatewayWithProxy,
gatewayClassName))
- _ =
s.DeleteResourceFromString(fmt.Sprintf(gatewayProxyWithEnabledPlugin,
s.Deployer.GetAdminEndpoint(), s.AdminKey()))
- })
-
Context("Test Gateway with enabled GatewayProxy plugin", func() {
It("Should apply plugin configuration when enabled", func() {
By("Create HTTPRoute for Gateway with GatewayProxy")
- resourceApplied("HTTPRoute", "test-route",
fmt.Sprintf(httpRouteForTest, "apisix"), 1)
+ s.ResourceApplied("HTTPRoute", "test-route",
fmt.Sprintf(httpRouteForTest, "apisix"), 1)
By("Check if the plugin is applied")
- resp := s.NewAPISIXClient().
- GET("/get").
- WithHost("example.com").
- Expect().
- Status(200)
-
- resp.Header("X-Proxy-Test").IsEqual("enabled")
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "example.com",
+ Checks: []scaffold.ResponseCheckFunc{
+ scaffold.WithExpectedStatus(200),
+
scaffold.WithExpectedHeader("X-Proxy-Test", "enabled"),
+ },
+ })
By("Update GatewayProxy with disabled plugin")
err :=
s.CreateResourceFromString(fmt.Sprintf(gatewayProxyWithDisabledPlugin,
s.Deployer.GetAdminEndpoint(), s.AdminKey()))
Expect(err).NotTo(HaveOccurred(), "updating
GatewayProxy with disabled plugin")
- time.Sleep(5 * time.Second)
By("Create HTTPRoute for Gateway with GatewayProxy")
- resourceApplied("HTTPRoute", "test-route",
fmt.Sprintf(httpRouteForTest, "apisix"), 1)
+ s.ResourceApplied("HTTPRoute", "test-route",
fmt.Sprintf(httpRouteForTest, "apisix"), 1)
By("Check if the plugin is not applied")
- resp = s.NewAPISIXClient().
- GET("/get").
- WithHost("example.com").
- Expect().
- Status(200)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "example.com",
+ Checks: []scaffold.ResponseCheckFunc{
+ scaffold.WithExpectedStatus(200),
+
scaffold.WithExpectedHeader("X-Proxy-Test", ""),
+ },
+ })
- resp.Header("X-Proxy-Test").IsEmpty()
})
})
@@ -238,20 +216,19 @@ spec:
By("Update GatewayProxy with invalid endpoint")
err :=
s.CreateResourceFromString(fmt.Sprintf(gatewayProxyWithInvalidEndpoint,
s.Deployer.GetAdminEndpoint(), s.AdminKey()))
Expect(err).NotTo(HaveOccurred(), "creating
GatewayProxy with enabled plugin")
- time.Sleep(5 * time.Second)
By("Create HTTPRoute")
- resourceApplied("HTTPRoute", "test-route",
fmt.Sprintf(httpRouteForTest, "apisix"), 1)
-
- expectRequest := func() bool {
- resp := s.NewAPISIXClient().
- GET("/get").
- WithHost("example.com").
- Expect().Raw()
- return resp.StatusCode == 200 &&
resp.Header.Get("X-Proxy-Test") == ""
- }
-
- Eventually(expectRequest).WithTimeout(8 *
time.Second).ProbeEvery(time.Second).Should(BeTrue())
+ s.ResourceApplied("HTTPRoute", "test-route",
fmt.Sprintf(httpRouteForTest, "apisix"), 1)
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "example.com",
+ Checks: []scaffold.ResponseCheckFunc{
+ scaffold.WithExpectedStatus(200),
+
scaffold.WithExpectedHeader("X-Proxy-Test", ""),
+ },
+ })
})
})
@@ -311,12 +288,10 @@ spec:
err :=
s.CreateResourceFromString(gatewayProxyWithValidProvider)
Expect(err).NotTo(HaveOccurred(), "creating
GatewayProxy with valid provider")
- Eventually(func() string {
- gpYaml, err :=
s.GetResourceYaml("GatewayProxy", "apisix-proxy-config")
- Expect(err).NotTo(HaveOccurred(), "getting
GatewayProxy yaml")
+ s.RetryAssertion(func() string {
+ gpYaml, _ := s.GetResourceYaml("GatewayProxy",
"apisix-proxy-config")
return gpYaml
- }).WithTimeout(8*time.Second).ProbeEvery(2*time.Second).
-
Should(ContainSubstring(`"type":"ControlPlane"`), "checking GatewayProxy is
applied")
+ }).Should(ContainSubstring(`"type":"ControlPlane"`),
"checking GatewayProxy is applied")
})
})
})
diff --git a/test/e2e/gatewayapi/httproute.go b/test/e2e/gatewayapi/httproute.go
index a634447e..daba664e 100644
--- a/test/e2e/gatewayapi/httproute.go
+++ b/test/e2e/gatewayapi/httproute.go
@@ -24,7 +24,6 @@ import (
"strings"
"time"
- "github.com/gruntwork-io/terratest/modules/retry"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/pkg/errors"
@@ -112,86 +111,80 @@ spec:
name: apisix-proxy-config
`
- var ResourceApplied = func(resourType, resourceName, resourceRaw
string, observedGeneration int) {
- Expect(s.CreateResourceFromString(resourceRaw)).
- NotTo(HaveOccurred(), fmt.Sprintf("creating %s",
resourType))
-
- Eventually(func() string {
- hryaml, err := s.GetResourceYaml(resourType,
resourceName)
- Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("getting
%s yaml", resourType))
- return hryaml
- }, "8s", "2s").
- Should(
- SatisfyAll(
- ContainSubstring(`status: "True"`),
-
ContainSubstring(fmt.Sprintf("observedGeneration: %d", observedGeneration)),
- ),
- fmt.Sprintf("checking %s condition status",
resourType),
- )
- time.Sleep(5 * time.Second)
- }
-
var beforeEachHTTP = func() {
- By("create GatewayProxy")
- err := s.CreateResourceFromString(getGatewayProxySpec())
- Expect(err).NotTo(HaveOccurred(), "creating GatewayProxy")
- time.Sleep(5 * time.Second)
-
- By("create GatewayClass")
- gatewayClassName := fmt.Sprintf("apisix-%d", time.Now().Unix())
- err =
s.CreateResourceFromStringWithNamespace(fmt.Sprintf(gatewayClassYaml,
gatewayClassName, s.GetControllerName()), "")
- Expect(err).NotTo(HaveOccurred(), "creating GatewayClass")
- time.Sleep(5 * time.Second)
-
- By("check GatewayClass condition")
- gcyaml, err := s.GetResourceYaml("GatewayClass",
gatewayClassName)
- Expect(err).NotTo(HaveOccurred(), "getting GatewayClass yaml")
- Expect(gcyaml).To(ContainSubstring(`status: "True"`), "checking
GatewayClass condition status")
- Expect(gcyaml).To(ContainSubstring("message: the gatewayclass
has been accepted by the apisix-ingress-controller"), "checking GatewayClass
condition message")
-
- By("create Gateway")
- err =
s.CreateResourceFromStringWithNamespace(fmt.Sprintf(defaultGateway,
gatewayClassName), s.Namespace())
- Expect(err).NotTo(HaveOccurred(), "creating Gateway")
- time.Sleep(5 * time.Second)
-
- By("check Gateway condition")
- gwyaml, err := s.GetResourceYaml("Gateway", "apisix")
- Expect(err).NotTo(HaveOccurred(), "getting Gateway yaml")
- Expect(gwyaml).To(ContainSubstring(`status: "True"`), "checking
Gateway condition status")
- Expect(gwyaml).To(ContainSubstring("message: the gateway has
been accepted by the apisix-ingress-controller"), "checking Gateway condition
message")
+ Expect(s.CreateResourceFromString(getGatewayProxySpec())).
+ NotTo(HaveOccurred(), "creating GatewayProxy")
+
+ gatewayClassName := fmt.Sprintf("apisix-%d",
time.Now().Nanosecond())
+
Expect(s.CreateResourceFromStringWithNamespace(fmt.Sprintf(gatewayClassYaml,
gatewayClassName, s.GetControllerName()), "")).
+ NotTo(HaveOccurred(), "creating GatewayClass")
+
+ s.RetryAssertion(func() string {
+ gcyaml, _ := s.GetResourceYaml("GatewayClass",
gatewayClassName)
+ return gcyaml
+ }).Should(
+ And(
+ ContainSubstring(`status: "True"`),
+ ContainSubstring("message: the gatewayclass has
been accepted by the apisix-ingress-controller"),
+ ),
+ "check GatewayClass condition",
+ )
+
+
Expect(s.CreateResourceFromStringWithNamespace(fmt.Sprintf(defaultGateway,
gatewayClassName), s.Namespace())).
+ NotTo(HaveOccurred(), "creating Gateway")
+
+ s.RetryAssertion(func() string {
+ gcyaml, _ := s.GetResourceYaml("Gateway", "apisix")
+ return gcyaml
+ }).Should(
+ And(
+ ContainSubstring(`status: "True"`),
+ ContainSubstring("message: the gateway has been
accepted by the apisix-ingress-controlle"),
+ ),
+ "check Gateway condition status",
+ )
}
var beforeEachHTTPS = func() {
By("create GatewayProxy")
err := s.CreateResourceFromString(getGatewayProxySpec())
Expect(err).NotTo(HaveOccurred(), "creating GatewayProxy")
- time.Sleep(5 * time.Second)
secretName := _secretName
createSecret(s, secretName)
- By("create GatewayClass")
- gatewayClassName := fmt.Sprintf("apisix-%d", time.Now().Unix())
- err =
s.CreateResourceFromStringWithNamespace(fmt.Sprintf(gatewayClassYaml,
gatewayClassName, s.GetControllerName()), "")
- Expect(err).NotTo(HaveOccurred(), "creating GatewayClass")
- time.Sleep(5 * time.Second)
- By("check GatewayClass condition")
- gcyaml, err := s.GetResourceYaml("GatewayClass",
gatewayClassName)
- Expect(err).NotTo(HaveOccurred(), "getting GatewayClass yaml")
- Expect(gcyaml).To(ContainSubstring(`status: "True"`), "checking
GatewayClass condition status")
- Expect(gcyaml).To(ContainSubstring("message: the gatewayclass
has been accepted by the apisix-ingress-controller"), "checking GatewayClass
condition message")
+ By("create GatewayClass")
+ gatewayClassName := fmt.Sprintf("apisix-%d",
time.Now().Nanosecond())
+
Expect(s.CreateResourceFromStringWithNamespace(fmt.Sprintf(gatewayClassYaml,
gatewayClassName, s.GetControllerName()), "")).
+ NotTo(HaveOccurred(), "creating GatewayClass")
+
+ s.RetryAssertion(func() string {
+ gcyaml, _ := s.GetResourceYaml("GatewayClass",
gatewayClassName)
+ return gcyaml
+ }).Should(
+ And(
+ ContainSubstring(`status: "True"`),
+ ContainSubstring("message: the gatewayclass has
been accepted by the apisix-ingress-controller"),
+ ),
+ "check GatewayClass condition",
+ )
By("create Gateway")
err =
s.CreateResourceFromStringWithNamespace(fmt.Sprintf(defaultGatewayHTTPS,
gatewayClassName), s.Namespace())
Expect(err).NotTo(HaveOccurred(), "creating Gateway")
- time.Sleep(5 * time.Second)
- By("check Gateway condition")
- gwyaml, err := s.GetResourceYaml("Gateway", "apisix")
- Expect(err).NotTo(HaveOccurred(), "getting Gateway yaml")
- Expect(gwyaml).To(ContainSubstring(`status: "True"`), "checking
Gateway condition status")
- Expect(gwyaml).To(ContainSubstring("message: the gateway has
been accepted by the apisix-ingress-controller"), "checking Gateway condition
message")
+ s.RetryAssertion(func() string {
+ gcyaml, _ := s.GetResourceYaml("Gateway", "apisix")
+ return gcyaml
+ }).Should(
+ And(
+ ContainSubstring(`status: "True"`),
+ ContainSubstring("message: the gateway has been
accepted by the apisix-ingress-controlle"),
+ ),
+ "check Gateway condition status",
+ )
}
+
Context("HTTPRoute with HTTPS Gateway", func() {
var exactRouteByGet = `
apiVersion: gateway.networking.k8s.io/v1
@@ -217,24 +210,26 @@ spec:
It("Create/Updtea/Delete HTTPRoute", func() {
By("create HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin",
exactRouteByGet, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin",
exactRouteByGet, 1)
By("access dataplane to check the HTTPRoute")
- s.NewAPISIXHttpsClient("api6.com").
- GET("/get").
- WithHost("api6.com").
- Expect().
- Status(200)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "api6.com",
+ Check: scaffold.WithExpectedStatus(200),
+ })
+
By("delete HTTPRoute")
err := s.DeleteResourceFromString(exactRouteByGet)
Expect(err).NotTo(HaveOccurred(), "deleting HTTPRoute")
- time.Sleep(5 * time.Second)
- s.NewAPISIXHttpsClient("api6.com").
- GET("/get").
- WithHost("api6.com").
- Expect().
- Status(404)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "api6.com",
+ Check: scaffold.WithExpectedStatus(404),
+ })
})
})
@@ -323,12 +318,17 @@ spec:
additionalGatewayClassName = fmt.Sprintf("apisix-%d",
time.Now().Unix())
err =
s.CreateResourceFromStringWithNamespace(fmt.Sprintf(gatewayClassYaml,
additionalGatewayClassName, s.GetControllerName()), "")
Expect(err).NotTo(HaveOccurred(), "creating additional
GatewayClass")
- time.Sleep(5 * time.Second)
+
By("Check additional GatewayClass condition")
- gcyaml, err := s.GetResourceYaml("GatewayClass",
additionalGatewayClassName)
- Expect(err).NotTo(HaveOccurred(), "getting additional
GatewayClass yaml")
- Expect(gcyaml).To(ContainSubstring(`status: "True"`),
"checking additional GatewayClass condition status")
- Expect(gcyaml).To(ContainSubstring("message: the
gatewayclass has been accepted by the apisix-ingress-controller"), "checking
additional GatewayClass condition message")
+ s.RetryAssertion(func() string {
+ gcyaml, _ := s.GetResourceYaml("GatewayClass",
additionalGatewayClassName)
+ return gcyaml
+ }).Should(
+ And(
+ ContainSubstring(`status: "True"`),
+ ContainSubstring("message: the
gatewayclass has been accepted by the apisix-ingress-controller"),
+ ),
+ )
additionalGatewayProxy :=
fmt.Sprintf(additionalGatewayProxyYaml,
s.Deployer.GetAdminEndpoint(resources.DataplaneService), resources.AdminAPIKey)
err =
s.CreateResourceFromStringWithNamespace(additionalGatewayProxy,
resources.DataplaneService.Namespace)
@@ -340,52 +340,56 @@ spec:
additionalSvc.Namespace,
)
Expect(err).NotTo(HaveOccurred(), "creating additional
Gateway")
- time.Sleep(5 * time.Second)
})
It("HTTPRoute should be accessible through both gateways",
func() {
By("Create HTTPRoute referencing both gateways")
multiGatewayRoute := fmt.Sprintf(multiGatewayHTTPRoute,
s.Namespace(), additionalSvc.Namespace)
- ResourceApplied("HTTPRoute", "multi-gateway-route",
multiGatewayRoute, 1)
+ s.ResourceApplied("HTTPRoute", "multi-gateway-route",
multiGatewayRoute, 1)
By("Access through default gateway")
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- Expect().
- Status(http.StatusOK)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
By("Access through additional gateway")
client, err :=
s.NewAPISIXClientForGateway(additionalGatewayGroupID)
Expect(err).NotTo(HaveOccurred(), "creating client for
additional gateway")
- client.
- GET("/get").
- WithHost("httpbin-additional.example").
- Expect().
- Status(http.StatusOK)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Client: client,
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin-additional.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
By("Delete Additional Gateway")
err =
s.DeleteResourceFromStringWithNamespace(fmt.Sprintf(additionalGateway,
additionalGatewayClassName), additionalSvc.Namespace)
Expect(err).NotTo(HaveOccurred(), "deleting additional
Gateway")
- time.Sleep(5 * time.Second)
By("HTTPRoute should still be accessible through
default gateway")
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- Expect().
- Status(http.StatusOK)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
By("HTTPRoute should not be accessible through
additional gateway")
client, err =
s.NewAPISIXClientForGateway(additionalGatewayGroupID)
Expect(err).NotTo(HaveOccurred(), "creating client for
additional gateway")
- client.
- GET("/get").
- WithHost("httpbin-additional.example").
- Expect().
- Status(http.StatusNotFound)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Client: client,
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin-additional.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
+ })
})
})
@@ -397,7 +401,7 @@ metadata:
name: httpbin-external-domain
spec:
type: ExternalName
- externalName: postman-echo.com
+ externalName: httpbin-service-e2e-test
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
@@ -501,121 +505,136 @@ spec:
It("Create/Update/Delete HTTPRoute", func() {
By("create HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin",
exactRouteByGet, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin",
exactRouteByGet, 1)
By("access dataplane to check the HTTPRoute")
- s.NewAPISIXClient().
- GET("/get").
- Expect().
- Status(404)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
+ })
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- Expect().
- Status(200)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
- By("delete HTTPRoute")
- err := s.DeleteResourceFromString(exactRouteByGet)
- Expect(err).NotTo(HaveOccurred(), "deleting HTTPRoute")
- time.Sleep(5 * time.Second)
+ Expect(s.DeleteResourceFromString(exactRouteByGet)).
+ NotTo(HaveOccurred(), "deleting HTTPRoute")
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- Expect().
- Status(404)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
+ })
})
It("Delete Gateway after apply HTTPRoute", func() {
By("create HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin",
exactRouteByGet, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin",
exactRouteByGet, 1)
By("access dataplane to check the HTTPRoute")
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- Expect().
- Status(200)
-
- By("delete Gateway")
- err := s.DeleteResource("Gateway", "apisix")
- Expect(err).NotTo(HaveOccurred(), "deleting Gateway")
-
- Eventually(func() int {
- return s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- Expect().
- Raw().StatusCode
- }).WithTimeout(5 *
time.Second).ProbeEvery(time.Second).Should(Equal(http.StatusNotFound))
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
+
+ Expect(s.DeleteResource("Gateway", "apisix")).
+ NotTo(HaveOccurred(), "deleting Gateway")
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
+ })
})
It("Proxy External Service", func() {
By("create HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin",
httprouteWithExternalName, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin",
httprouteWithExternalName, 1)
By("checking the external service response")
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.external").
- Expect().
- Status(http.StatusMovedPermanently)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.external",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
})
It("Match Port", func() {
By("create HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin",
invalidBackendPort, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin",
invalidBackendPort, 1)
- serviceResources, err :=
s.DefaultDataplaneResource().Service().List(context.Background())
- Expect(err).NotTo(HaveOccurred(), "listing services")
- Expect(serviceResources).To(HaveLen(1), "checking
service length")
+ s.RetryAssertion(func() error {
+ serviceResources, err :=
s.DefaultDataplaneResource().Service().List(context.Background())
+ if err != nil {
+ return errors.Wrap(err, "listing
services")
+ }
+ if len(serviceResources) != 1 {
+ return fmt.Errorf("expected 1 service,
got %d", len(serviceResources))
+ }
- serviceResource := serviceResources[0]
- nodes := serviceResource.Upstream.Nodes
- Expect(nodes).To(HaveLen(1), "checking nodes length")
- Expect(nodes[0].Port).To(Equal(80))
+ serviceResource := serviceResources[0]
+ nodes := serviceResource.Upstream.Nodes
+ if len(nodes) != 1 {
+ return fmt.Errorf("expected 1 node, got
%d", len(nodes))
+ }
+ if nodes[0].Port != 80 {
+ return fmt.Errorf("expected node port
80, got %d", nodes[0].Port)
+ }
+ return nil
+ }).Should(Succeed(), "checking service port")
})
It("Delete HTTPRoute during restart", func() {
By("create HTTPRoute httpbin")
- ResourceApplied("HTTPRoute", "httpbin",
exactRouteByGet, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin",
exactRouteByGet, 1)
By("create HTTPRoute httpbin2")
- ResourceApplied("HTTPRoute", "httpbin2",
exactRouteByGet2, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin2",
exactRouteByGet2, 1)
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- Expect().
- Status(200)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin2.example").
- Expect().
- Status(200)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin2.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
s.Deployer.ScaleIngress(0)
- By("delete HTTPRoute httpbin2")
- err := s.DeleteResource("HTTPRoute", "httpbin2")
- Expect(err).NotTo(HaveOccurred(), "deleting HTTPRoute
httpbin2")
+ Expect(s.DeleteResource("HTTPRoute", "httpbin2")).
+ NotTo(HaveOccurred(), "deleting HTTPRoute
httpbin2")
s.Deployer.ScaleIngress(1)
- time.Sleep(1 * time.Minute)
-
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- Expect().
- Status(200)
-
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin2.example").
- Expect().
- Status(404)
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Timeout: 1 * time.Minute,
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin2.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
+ })
})
})
@@ -736,92 +755,106 @@ spec:
It("HTTPRoute Exact Match", func() {
By("create HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin",
exactRouteByGet, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin",
exactRouteByGet, 1)
By("access daataplane to check the HTTPRoute")
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- Expect().
- Status(200)
-
- s.NewAPISIXClient().
- GET("/get/xxx").
- WithHost("httpbin.example").
- Expect().
- Status(404)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get/xxx",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
+ })
})
It("HTTPRoute Prefix Match", func() {
By("create HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin",
prefixRouteByStatus, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin",
prefixRouteByStatus, 1)
By("access daataplane to check the HTTPRoute")
- s.NewAPISIXClient().
- GET("/status/200").
- WithHost("httpbin.example").
- Expect().
- Status(200)
-
- s.NewAPISIXClient().
- GET("/status/201").
- WithHost("httpbin.example").
- Expect().
- Status(201)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/status/200",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/status/201",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusCreated),
+ })
})
It("HTTPRoute Method Match", func() {
By("create HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin",
methodRouteGETAndDELETEByAnything, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin",
methodRouteGETAndDELETEByAnything, 1)
By("access daataplane to check the HTTPRoute")
- s.NewAPISIXClient().
- GET("/anything").
- WithHost("httpbin.example").
- Expect().
- Status(200)
-
- s.NewAPISIXClient().
- DELETE("/anything").
- WithHost("httpbin.example").
- Expect().
- Status(200)
-
- s.NewAPISIXClient().
- POST("/anything").
- WithHost("httpbin.example").
- Expect().
- Status(404)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/anything",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "DELETE",
+ Path: "/anything",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "POST",
+ Path: "/anything",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
+ })
})
It("HTTPRoute Vars Match", func() {
By("create HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin", varsRoute, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin", varsRoute, 1)
By("access dataplane to check the HTTPRoute")
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- Expect().
- Status(http.StatusNotFound)
-
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- WithHeader("X-Route-Name", "httpbin").
- Expect().
- Status(http.StatusOK)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
+ })
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Headers: map[string]string{
+ "X-Route-Name": "httpbin",
+ },
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
})
It("HTTPRoutePolicy in effect", func() {
By("create HTTPRoute")
s.ApplyHTTPRoute(types.NamespacedName{Namespace:
s.Namespace(), Name: "httpbin"}, varsRoute)
- request := func() int {
- return s.NewAPISIXClient().GET("/get").
-
WithHost("httpbin.example").WithHeader("X-Route-Name", "httpbin").
- Expect().Raw().StatusCode
- }
- Eventually(request).WithTimeout(5 *
time.Second).ProbeEvery(time.Second).Should(Equal(http.StatusOK))
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Headers: map[string]string{
+ "X-Route-Name": "httpbin",
+ },
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
By("create HTTPRoutePolicy")
s.ApplyHTTPRoutePolicy(
@@ -831,16 +864,29 @@ spec:
)
By("access dataplane to check the HTTPRoutePolicy")
- Eventually(request).WithTimeout(5 *
time.Second).ProbeEvery(time.Second).Should(Equal(http.StatusNotFound))
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Headers: map[string]string{
+ "X-Route-Name": "httpbin",
+ },
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
+ })
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- WithHeader("X-Route-Name", "httpbin").
- WithHeader("X-HRP-Name", "http-route-policy-0").
- WithQuery("hrp_name", "http-route-policy-0").
- Expect().
- Status(http.StatusOK)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Query: map[string]any{
+ "hrp_name": "http-route-policy-0",
+ },
+ Headers: map[string]string{
+ "X-Route-Name": "httpbin",
+ "X-HRP-Name": "http-route-policy-0",
+ },
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
By("update HTTPRoutePolicy")
const changedHTTPRoutePolicy = `
@@ -867,24 +913,31 @@ spec:
)
// use the old vars cannot match any route
- Eventually(func() int {
- return s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- WithHeader("X-Route-Name", "httpbin").
- WithHeader("X-HRP-Name",
"http-route-policy-0").
- WithQuery("hrp_name",
"http-route-policy-0").
- Expect().Raw().StatusCode
- }).WithTimeout(8 *
time.Second).ProbeEvery(time.Second).Should(Equal(http.StatusNotFound))
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Query: map[string]any{
+ "hrp_name": "http-route-policy-0",
+ },
+ Headers: map[string]string{
+ "X-Route-Name": "httpbin",
+ "X-HRP-Name": "http-route-policy-0",
+ },
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
+ })
// use the new vars can match the route
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- WithHeader("X-Route-Name", "httpbin").
- WithHeader("X-HRP-Name", "new-hrp-name").
- Expect().
- Status(http.StatusOK)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Headers: map[string]string{
+ "X-Route-Name": "httpbin",
+ "X-HRP-Name": "new-hrp-name",
+ },
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
By("delete the HTTPRoutePolicy")
err := s.DeleteResource("HTTPRoutePolicy",
"http-route-policy-0")
@@ -894,18 +947,15 @@ spec:
return err.Error()
}).WithTimeout(8 *
time.Second).ProbeEvery(time.Second).Should(ContainSubstring(`httproutepolicies.apisix.apache.org
"http-route-policy-0" not found`))
// access the route without additional vars should be OK
- message := retry.DoWithRetry(s.GinkgoT, "", 10,
time.Second, func() (string, error) {
- statusCode := s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- WithHeader("X-Route-Name", "httpbin").
- Expect().Raw().StatusCode
- if statusCode != http.StatusOK {
- return "", errors.Errorf("unexpected
status code: %v", statusCode)
- }
- return "request OK", nil
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Headers: map[string]string{
+ "X-Route-Name": "httpbin",
+ },
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
})
- s.Logf(message)
})
It("HTTPRoutePolicy conflicts", func() {
@@ -1007,13 +1057,15 @@ spec:
}
// assert that conflict policies are not in effect
- Eventually(func() int {
- return s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- WithHeader("X-Route-Name", "httpbin").
- Expect().Raw().StatusCode
- }).WithTimeout(8 *
time.Second).ProbeEvery(time.Second).Should(Equal(http.StatusOK))
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Headers: map[string]string{
+ "X-Route-Name": "httpbin",
+ },
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
By("delete HTTPRoutePolicies")
err := s.DeleteResource("HTTPRoutePolicy",
"http-route-policy-2")
@@ -1029,13 +1081,15 @@ spec:
},
)
}
- Eventually(func() int {
- return s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- WithHeader("X-Route-Name", "httpbin").
- Expect().Raw().StatusCode
- }).WithTimeout(8 *
time.Second).ProbeEvery(time.Second).Should(Equal(http.StatusNotFound))
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Headers: map[string]string{
+ "X-Route-Name": "httpbin",
+ },
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
+ })
By("update HTTPRoutePolicy")
err =
s.CreateResourceFromString(httpRoutePolicy1Priority20)
@@ -1058,13 +1112,16 @@ spec:
},
)
}
- Eventually(func() int {
- return s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- WithHeader("X-Route-Name", "httpbin").
- Expect().Raw().StatusCode
- }).WithTimeout(8 *
time.Second).ProbeEvery(time.Second).Should(Equal(http.StatusOK))
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Headers: map[string]string{
+ "X-Route-Name": "httpbin",
+ },
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
})
It("HTTPRoutePolicy status changes on HTTPRoute deleting",
func() {
@@ -1079,42 +1136,49 @@ spec:
)
By("access dataplane to check the HTTPRoutePolicy")
- Eventually(func() int {
- return s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- WithHeader("X-Route-Name", "httpbin").
- Expect().Raw().StatusCode
- }).WithTimeout(8 *
time.Second).ProbeEvery(time.Second).Should(Equal(http.StatusNotFound))
-
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- WithHeader("X-Route-Name", "httpbin").
- WithHeader("X-HRP-Name", "http-route-policy-0").
- WithQuery("hrp_name", "http-route-policy-0").
- Expect().
- Status(http.StatusOK)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Headers: map[string]string{
+ "X-Route-Name": "httpbin",
+ },
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
+ })
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Query: map[string]any{
+ "hrp_name": "http-route-policy-0",
+ },
+ Headers: map[string]string{
+ "X-Route-Name": "httpbin",
+ "X-HRP-Name": "http-route-policy-0",
+ },
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
By("delete the HTTPRoute, assert the HTTPRoutePolicy's
status will be changed")
- err := s.DeleteResource("HTTPRoute", "httpbin")
- Expect(err).NotTo(HaveOccurred(), "deleting HTTPRoute")
- message := retry.DoWithRetry(s.GinkgoT, "request the
deleted route", 10, time.Second, func() (string, error) {
- statusCode := s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- WithHeader("X-Route-Name", "httpbin").
- WithHeader("X-HRP-Name",
"http-route-policy-0").
- WithQuery("hrp_name",
"http-route-policy-0").
- Expect().Raw().StatusCode
- if statusCode != http.StatusNotFound {
- return "", errors.Errorf("unexpected
status code: %v", statusCode)
- }
- return "the route is deleted", nil
+ Expect(s.DeleteResource("HTTPRoute", "httpbin")).
+ NotTo(HaveOccurred(), "deleting HTTPRoute")
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Query: map[string]any{
+ "hrp_name": "http-route-policy-0",
+ },
+ Headers: map[string]string{
+ "X-Route-Name": "httpbin",
+ "X-HRP-Name": "http-route-policy-0",
+ },
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
})
- s.Logf(message)
- err =
framework.PollUntilHTTPRoutePolicyHaveStatus(s.K8sClient, 8*time.Second,
types.NamespacedName{Namespace: s.Namespace(), Name: "http-route-policy-0"},
+ err :=
framework.PollUntilHTTPRoutePolicyHaveStatus(s.K8sClient, 8*time.Second,
types.NamespacedName{Namespace: s.Namespace(), Name: "http-route-policy-0"},
func(hrp *v1alpha1.HTTPRoutePolicy) bool {
return len(hrp.Status.Ancestors) == 0
},
@@ -1335,63 +1399,73 @@ spec:
It("HTTPRoute RequestHeaderModifier", func() {
By("create HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin",
reqHeaderModifyByHeaders, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin",
reqHeaderModifyByHeaders, 1)
By("access daataplane to check the HTTPRoute")
- respExp := s.NewAPISIXClient().
- GET("/headers").
- WithHost("httpbin.example").
- WithHeader("X-Req-Add", "test").
- WithHeader("X-Req-Removed", "test").
- WithHeader("X-Req-Set", "test").
- Expect()
-
- respExp.Status(200)
- respExp.Body().
- Contains(`"X-Req-Add": "test,add"`).
- Contains(`"X-Req-Set": "set"`).
- NotContains(`"X-Req-Removed": "remove"`)
-
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/headers",
+ Host: "httpbin.example",
+ Headers: map[string]string{
+ "X-Req-Add": "test",
+ "X-Req-Removed": "test",
+ "X-Req-Set": "test",
+ },
+ Checks: []scaffold.ResponseCheckFunc{
+
scaffold.WithExpectedStatus(http.StatusOK),
+
scaffold.WithExpectedBodyContains(`"X-Req-Add": "test,add"`, `"X-Req-Set":
"set"`),
+
scaffold.WithExpectedBodyNotContains(`"X-Req-Removed": "remove"`),
+ },
+ })
})
It("HTTPRoute ResponseHeaderModifier", func() {
By("create HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin",
respHeaderModifyByHeaders, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin",
respHeaderModifyByHeaders, 1)
By("access daataplane to check the HTTPRoute")
- respExp := s.NewAPISIXClient().
- GET("/headers").
- WithHost("httpbin.example").
- Expect()
-
- respExp.Status(200)
- respExp.Header("X-Resp-Add").IsEqual("add")
- respExp.Header("X-Resp-Set").IsEqual("set")
- respExp.Header("Server").IsEmpty()
- respExp.Body().
- NotContains(`"X-Resp-Add": "add"`).
- NotContains(`"X-Resp-Set": "set"`).
- NotContains(`"Server"`)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/headers",
+ Host: "httpbin.example",
+ Checks: []scaffold.ResponseCheckFunc{
+
scaffold.WithExpectedStatus(http.StatusOK),
+
scaffold.WithExpectedHeaders(map[string]string{
+ "X-Resp-Add": "add",
+ "X-Resp-Set": "set",
+ "Server": "",
+ }),
+
scaffold.WithExpectedBodyNotContains(`"X-Resp-Add": "add"`, `"X-Resp-Set":
"set"`, `"Server"`),
+ },
+ })
})
It("HTTPRoute RequestRedirect", func() {
By("create HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin",
httpsRedirectByHeaders, 1)
-
- s.NewAPISIXClient().GET("/headers").
- WithHeader("Host", "httpbin.example").
- Expect().
- Status(http.StatusFound).
-
Header("Location").IsEqual("https://httpbin.example:9443/headers")
+ s.ResourceApplied("HTTPRoute", "httpbin",
httpsRedirectByHeaders, 1)
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/headers",
+ Host: "httpbin.example",
+ Checks: []scaffold.ResponseCheckFunc{
+
scaffold.WithExpectedStatus(http.StatusFound),
+ scaffold.WithExpectedHeader("Location",
"https://httpbin.example:9443/headers"),
+ },
+ })
By("update HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin",
hostnameRedirectByHeaders, 2)
-
- s.NewAPISIXClient().GET("/headers").
- WithHeader("Host", "httpbin.example").
- Expect().
- Status(http.StatusMovedPermanently).
-
Header("Location").IsEqual("http://httpbin.org/headers")
+ s.ResourceApplied("HTTPRoute", "httpbin",
hostnameRedirectByHeaders, 2)
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/headers",
+ Host: "httpbin.example",
+ Checks: []scaffold.ResponseCheckFunc{
+
scaffold.WithExpectedStatus(http.StatusMovedPermanently),
+ scaffold.WithExpectedHeader("Location",
"http://httpbin.org/headers"),
+ },
+ })
})
It("HTTPRoute RequestMirror", func() {
@@ -1453,78 +1527,89 @@ spec:
- name: httpbin-service-e2e-test
port: 80
`
- ResourceApplied("HTTPRoute", "httpbin", echoRoute, 1)
-
- time.Sleep(time.Second * 6)
-
- _ = s.NewAPISIXClient().GET("/headers").
- WithHeader("Host", "httpbin.example").
- Expect().
- Status(http.StatusOK)
+ s.ResourceApplied("HTTPRoute", "httpbin", echoRoute, 1)
- echoLogs := s.GetDeploymentLogs("echo")
- Expect(echoLogs).To(ContainSubstring("GET /headers"))
+ s.RetryAssertion(func() string {
+ resp :=
s.NewAPISIXClient().GET("/headers").WithHost("httpbin.example").Expect().Raw()
+ if resp.StatusCode != http.StatusOK {
+ return fmt.Sprintf("expected status OK,
got %d", resp.StatusCode)
+ }
+ return s.GetDeploymentLogs("echo")
+ }).WithTimeout(2 *
time.Minute).Should(ContainSubstring("GET /headers"))
})
It("HTTPRoute URLRewrite with ReplaceFullPath And Hostname",
func() {
By("create HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin",
replaceFullPathAndHost, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin",
replaceFullPathAndHost, 1)
By("/replace/201 should be rewritten to /headers")
- s.NewAPISIXClient().GET("/replace/201").
- WithHeader("Host", "httpbin.example").
- Expect().
- Status(http.StatusOK).
- Body().
- Contains("replace.example.org")
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/replace/201",
+ Host: "httpbin.example",
+ Checks: []scaffold.ResponseCheckFunc{
+
scaffold.WithExpectedStatus(http.StatusOK),
+
scaffold.WithExpectedBodyContains("replace.example.org"),
+ },
+ })
By("/replace/500 should be rewritten to /headers")
- s.NewAPISIXClient().GET("/replace/500").
- WithHeader("Host", "httpbin.example").
- Expect().
- Status(http.StatusOK).
- Body().
- Contains("replace.example.org")
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/replace/500",
+ Host: "httpbin.example",
+ Checks: []scaffold.ResponseCheckFunc{
+
scaffold.WithExpectedStatus(http.StatusOK),
+
scaffold.WithExpectedBodyContains("replace.example.org"),
+ },
+ })
})
It("HTTPRoute URLRewrite with ReplacePrefixMatch", func() {
By("create HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin",
replacePrefixMatch, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin",
replacePrefixMatch, 1)
By("/replace/201 should be rewritten to /status/201")
- s.NewAPISIXClient().GET("/replace/201").
- WithHeader("Host", "httpbin.example").
- Expect().
- Status(http.StatusCreated)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/replace/201",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusCreated),
+ })
By("/replace/500 should be rewritten to /status/500")
- s.NewAPISIXClient().GET("/replace/500").
- WithHeader("Host", "httpbin.example").
- Expect().
- Status(http.StatusInternalServerError)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/replace/500",
+ Host: "httpbin.example",
+ Checks: []scaffold.ResponseCheckFunc{
+
scaffold.WithExpectedStatus(http.StatusInternalServerError),
+ },
+ })
})
It("HTTPRoute ExtensionRef", func() {
By("create HTTPRoute")
- err := s.CreateResourceFromString(echoPlugin)
- Expect(err).NotTo(HaveOccurred(), "creating
PluginConfig")
- ResourceApplied("HTTPRoute", "httpbin",
extensionRefEchoPlugin, 1)
-
- s.NewAPISIXClient().GET("/get").
- WithHeader("Host", "httpbin.example").
- Expect().
- Body().
- Contains("Hello, World!!")
-
- err = s.CreateResourceFromString(echoPluginUpdated)
- Expect(err).NotTo(HaveOccurred(), "updating
PluginConfig")
- time.Sleep(5 * time.Second)
+ Expect(s.CreateResourceFromString(echoPlugin)).
+ NotTo(HaveOccurred(), "creating PluginConfig")
+ s.ResourceApplied("HTTPRoute", "httpbin",
extensionRefEchoPlugin, 1)
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedBodyContains("Hello, World!!"),
+ })
- s.NewAPISIXClient().GET("/get").
- WithHeader("Host", "httpbin.example").
- Expect().
- Body().
- Contains("Updated")
+ Expect(s.CreateResourceFromString(echoPluginUpdated)).
+ NotTo(HaveOccurred(), "updating PluginConfig")
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedBodyContains("Updated"),
+ })
})
})
@@ -1583,45 +1668,58 @@ spec:
})
})
It("HTTPRoute Canary", func() {
- ResourceApplied("HTTPRoute", "httpbin", sameWeiht, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin", sameWeiht, 1)
+ time.Sleep(5 * time.Second)
- var (
- hitNginxCnt = 0
- hitHttpbinCnt = 0
- )
- for i := 0; i < 100; i++ {
- body := s.NewAPISIXClient().GET("/get").
- WithHeader("Host", "httpbin.example").
- Expect().
- Status(http.StatusOK).
- Body().Raw()
-
- if strings.Contains(body, "Hello") {
- hitNginxCnt++
- } else {
- hitHttpbinCnt++
+ s.RetryAssertion(func() int {
+ var (
+ hitNginxCnt = 0
+ hitHttpbinCnt = 0
+ )
+ for i := 0; i < 20; i++ {
+ resp := s.NewAPISIXClient().GET("/get").
+ WithHeader("Host",
"httpbin.example").
+ Expect()
+ body := resp.Body().Raw()
+ status := resp.Raw().StatusCode
+ if status != http.StatusOK {
+ return -100
+ }
+
+ if strings.Contains(body, "Hello") {
+ hitNginxCnt++
+ } else {
+ hitHttpbinCnt++
+ }
}
- }
- Expect(hitNginxCnt -
hitHttpbinCnt).To(BeNumerically("~", 0, 2))
-
- ResourceApplied("HTTPRoute", "httpbin", oneWeiht, 2)
-
- hitNginxCnt = 0
- hitHttpbinCnt = 0
- for i := 0; i < 100; i++ {
- body := s.NewAPISIXClient().GET("/get").
- WithHeader("Host", "httpbin.example").
- Expect().
- Status(http.StatusOK).
- Body().Raw()
-
- if strings.Contains(body, "Hello") {
- hitNginxCnt++
- } else {
- hitHttpbinCnt++
+ return hitNginxCnt - hitHttpbinCnt
+ }).WithTimeout(2 *
time.Minute).Should(BeNumerically("~", 0, 2))
+
+ s.ResourceApplied("HTTPRoute", "httpbin", oneWeiht, 2)
+
+ s.RetryAssertion(func() int {
+ var (
+ hitNginxCnt = 0
+ hitHttpbinCnt = 0
+ )
+ for i := 0; i < 20; i++ {
+ resp := s.NewAPISIXClient().GET("/get").
+ WithHeader("Host",
"httpbin.example").
+ Expect()
+ body := resp.Body().Raw()
+ status := resp.Raw().StatusCode
+ if status != http.StatusOK {
+ return -100
+ }
+
+ if strings.Contains(body, "Hello") {
+ hitNginxCnt++
+ } else {
+ hitHttpbinCnt++
+ }
}
- }
- Expect(hitHttpbinCnt - hitNginxCnt).To(Equal(100))
+ return hitHttpbinCnt - hitNginxCnt
+ }).WithTimeout(2 * time.Minute).Should(Equal(20))
})
})
@@ -1669,14 +1767,15 @@ spec:
It("Should sync HTTPRoute when GatewayProxy is updated", func()
{
By("create HTTPRoute")
- ResourceApplied("HTTPRoute", "httpbin",
exactRouteByGet, 1)
+ s.ResourceApplied("HTTPRoute", "httpbin",
exactRouteByGet, 1)
By("verify HTTPRoute works")
- s.NewAPISIXClient().
- GET("/get").
- WithHost("httpbin.example").
- Expect().
- Status(200)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
By("create additional gateway group to get new admin
key")
var err error
@@ -1690,24 +1789,27 @@ spec:
Expect(err).NotTo(HaveOccurred(), "creating APISIX
client for additional gateway group")
By("HTTPRoute not found for additional gateway group")
- client.
- GET("/get").
- WithHost("httpbin.example").
- Expect().
- Status(404)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Client: client,
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
+ })
By("update GatewayProxy with new admin key")
updatedProxy := fmt.Sprintf(updatedGatewayProxy,
s.Deployer.GetAdminEndpoint(resources.DataplaneService), resources.AdminAPIKey)
err = s.CreateResourceFromString(updatedProxy)
Expect(err).NotTo(HaveOccurred(), "updating
GatewayProxy")
- time.Sleep(5 * time.Second)
By("verify HTTPRoute works for additional gateway
group")
- client.
- GET("/get").
- WithHost("httpbin.example").
- Expect().
- Status(200)
+ s.RequestAssert(&scaffold.RequestAssert{
+ Client: client,
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin.example",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
})
})
@@ -1721,7 +1823,7 @@ metadata:
name: httpbin-external-domain
spec:
type: ExternalName
- externalName: httpbin.org
+ externalName: httpbin-service-e2e-test
---
apiVersion: v1
kind: Service
@@ -1744,7 +1846,7 @@ spec:
kind: Service
group: ""
passHost: node
- scheme: https
+ scheme: http
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
@@ -1760,10 +1862,10 @@ spec:
value: /headers
backendRefs:
- name: httpbin-external-domain
- port: 443
+ port: 80
weight: 1
- name: mockapi7-external-domain
- port: 443
+ port: 80
weight: 1
`
@@ -1778,22 +1880,14 @@ spec:
totalRequests := 20
for i := 0; i < totalRequests; i++ {
- resp :=
s.NewAPISIXClient().GET("/headers").Expect().Status(http.StatusOK)
-
- // Parse JSON response to get the Host header
- var responseBody map[string]any
- resp.JSON().Decode(&responseBody)
-
- if headers, ok :=
responseBody["headers"].(map[string]any); ok {
- var host string
- if host, ok = headers["Host"].(string);
!ok {
- host, ok =
headers["host"].(string)
- }
- if ok && host != "" {
- upstreamHosts[host]++
- }
- Expect(ok).To(BeTrue(), "Host header
should be present")
-
Expect(host).Should(Or(Equal("httpbin.org"), Equal("mock.api7.ai")))
+ statusCode :=
s.NewAPISIXClient().GET("/headers").Expect().Raw().StatusCode
+ Expect(statusCode).To(Or(Equal(http.StatusOK),
Equal(http.StatusMovedPermanently)))
+
+ switch statusCode {
+ case http.StatusOK:
+
upstreamHosts["httpbin-service-e2e-test"]++
+ case http.StatusMovedPermanently:
+ upstreamHosts["mock.api7.ai"]++
}
time.Sleep(100 * time.Millisecond) // Small
delay between requests
}
@@ -1806,16 +1900,4 @@ spec:
}
})
})
-
- /*
- Context("HTTPRoute Status Updated", func() {
- })
-
- Context("HTTPRoute ParentRefs With Multiple Gateway", func() {
- })
-
-
- Context("HTTPRoute BackendRefs Discovery", func() {
- })
- */
})
diff --git a/test/e2e/ingress/ingress.go b/test/e2e/ingress/ingress.go
index 0c85c532..6b537b98 100644
--- a/test/e2e/ingress/ingress.go
+++ b/test/e2e/ingress/ingress.go
@@ -186,7 +186,7 @@ metadata:
name: httpbin-external-domain
spec:
type: ExternalName
- externalName: postman-echo.com
+ externalName: httpbin-service-e2e-test
---
apiVersion: networking.k8s.io/v1
kind: Ingress
@@ -253,7 +253,7 @@ spec:
GET("/get").
WithHost("httpbin.external").
Expect().
- Status(http.StatusMovedPermanently)
+ Status(http.StatusOK)
})
It("Delete Ingress during restart", func() {
@@ -283,7 +283,7 @@ spec:
GET("/get").
WithHost("httpbin.external").
Expect().
- Status(http.StatusMovedPermanently)
+ Status(http.StatusOK)
s.NewAPISIXClient().
GET("/get").
@@ -304,7 +304,7 @@ spec:
GET("/get").
WithHost("httpbin.external").
Expect().
- Status(http.StatusMovedPermanently)
+ Status(http.StatusOK)
s.NewAPISIXClient().
GET("/get").
diff --git a/test/e2e/scaffold/apisix_deployer.go
b/test/e2e/scaffold/apisix_deployer.go
index b6fe7feb..e3e8b90a 100644
--- a/test/e2e/scaffold/apisix_deployer.go
+++ b/test/e2e/scaffold/apisix_deployer.go
@@ -53,7 +53,7 @@ type APISIXDeployer struct {
adminTunnel *k8s.Tunnel
}
-func NewAPISIXDeployer(s *Scaffold) *APISIXDeployer {
+func NewAPISIXDeployer(s *Scaffold) Deployer {
return &APISIXDeployer{
Scaffold: s,
}
@@ -66,7 +66,7 @@ func (s *APISIXDeployer) BeforeEach() {
Namespace: s.namespace,
}
if s.opts.ControllerName == "" {
- s.opts.ControllerName = fmt.Sprintf("%s/%d",
DefaultControllerName, time.Now().Nanosecond())
+ s.opts.ControllerName = fmt.Sprintf("%s/%s",
DefaultControllerName, s.namespace)
}
s.finalizers = nil
if s.label == nil {
@@ -130,14 +130,14 @@ func (s *APISIXDeployer) AfterEach() {
Expect(err).NotTo(HaveOccurred(), "cleaning up additional
gateway")
}
- // if the test case is successful, just delete namespace
- err := k8s.DeleteNamespaceE(s.t, s.kubectlOptions, s.namespace)
- Expect(err).NotTo(HaveOccurred(), "deleting namespace "+s.namespace)
-
for i := len(s.finalizers) - 1; i >= 0; i-- {
runWithRecover(s.finalizers[i])
}
+ // if the test case is successful, just delete namespace
+ err := k8s.DeleteNamespaceE(s.t, s.kubectlOptions, s.namespace)
+ Expect(err).NotTo(HaveOccurred(), "deleting namespace "+s.namespace)
+
// Wait for a while to prevent the worker node being overwhelming
// (new cases will be run).
time.Sleep(3 * time.Second)
diff --git a/test/e2e/scaffold/assertion.go b/test/e2e/scaffold/assertion.go
new file mode 100644
index 00000000..c8946f2f
--- /dev/null
+++ b/test/e2e/scaffold/assertion.go
@@ -0,0 +1,252 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package scaffold
+
+import (
+ "fmt"
+ "net/http"
+ "strings"
+ "time"
+
+ "github.com/gavv/httpexpect/v2"
+ . "github.com/onsi/gomega" //nolint:staticcheck
+ "github.com/onsi/gomega/types"
+)
+
+const (
+ DefaultTimeout = 12 * time.Second
+ DefaultInterval = 1 * time.Second
+)
+
+type ResponseCheckFunc func(*HTTPResponse) error
+
+type HTTPResponse struct {
+ *http.Response
+
+ Body string
+}
+
+type BasicAuth struct {
+ Username string
+ Password string
+}
+
+type RequestAssert struct {
+ Client *httpexpect.Expect
+ Method string
+ Path string
+ Host string
+ Query map[string]any
+ Headers map[string]string
+ Body []byte
+ BasicAuth *BasicAuth
+
+ Timeout time.Duration
+ Interval time.Duration
+
+ Check ResponseCheckFunc
+ Checks []ResponseCheckFunc
+}
+
+func (c *RequestAssert) request(method, path string, body []byte)
*httpexpect.Request {
+ switch strings.ToUpper(method) {
+ case "GET":
+ return c.Client.GET(path)
+ case "POST":
+ return c.Client.POST(path).WithBytes(body)
+ case "PUT":
+ return c.Client.PUT(path).WithBytes(body)
+ case "DELETE":
+ return c.Client.DELETE(path)
+ case "PATCH":
+ return c.Client.PATCH(path).WithBytes(body)
+ default:
+ panic("unsupported method: " + method)
+ }
+}
+
+func (c *RequestAssert) WithCheck(check ResponseCheckFunc) *RequestAssert {
+ c.Checks = append(c.Checks, check)
+ return c
+}
+
+func (c *RequestAssert) WithChecks(checks ...ResponseCheckFunc) *RequestAssert
{
+ c.Checks = append(c.Checks, checks...)
+ return c
+}
+
+func (c *RequestAssert) SetChecks(checks ...ResponseCheckFunc) *RequestAssert {
+ c.Checks = checks
+ return c
+}
+
+func WithExpectedStatus(status int) ResponseCheckFunc {
+ return func(resp *HTTPResponse) error {
+ if resp.StatusCode != status {
+ return fmt.Errorf("expected %d, but got %d", status,
resp.StatusCode)
+ }
+ return nil
+ }
+}
+
+func WithExpectedBodyContains(expectedBodyList ...string) ResponseCheckFunc {
+ return func(resp *HTTPResponse) error {
+ for _, body := range expectedBodyList {
+ if !strings.Contains(resp.Body, body) {
+ return fmt.Errorf("expected body to contain %q,
but got %q", body, resp.Body)
+ }
+ }
+ return nil
+ }
+}
+
+func WithExpectedBodyNotContains(unexpectedBodyList ...string)
ResponseCheckFunc {
+ return func(resp *HTTPResponse) error {
+ for _, unexpectedBody := range unexpectedBodyList {
+ if strings.Contains(resp.Body, unexpectedBody) {
+ return fmt.Errorf("expected body not to contain
%q, but got %q", unexpectedBody, resp.Body)
+ }
+ }
+ return nil
+ }
+}
+
+func WithExpectedHeader(key, value string) ResponseCheckFunc {
+ return func(resp *HTTPResponse) error {
+ if resp.Header.Get(key) != value {
+ return fmt.Errorf("expected header %q to be %q, but got
%q",
+ key, value, resp.Header.Get(key))
+ }
+ return nil
+ }
+}
+
+func WithExpectedHeaders(expectedHeaders map[string]string) ResponseCheckFunc {
+ return func(resp *HTTPResponse) error {
+ for key, expectedValue := range expectedHeaders {
+ actualValue := resp.Header.Get(key)
+ if actualValue != expectedValue {
+ return fmt.Errorf("expected header %q to be %q,
but got %q",
+ key, expectedValue, actualValue)
+ }
+ }
+ return nil
+ }
+}
+
+func (s *Scaffold) RequestAssert(r *RequestAssert) bool {
+ if r.Client == nil {
+ r.Client = s.NewAPISIXClient()
+ }
+ if r.Method == "" {
+ if len(r.Body) > 0 {
+ r.Method = "POST"
+ } else {
+ r.Method = "GET"
+ }
+ }
+ if r.Timeout == 0 {
+ r.Timeout = DefaultTimeout
+ }
+ if r.Interval == 0 {
+ r.Interval = DefaultInterval
+ }
+ if r.Check == nil && len(r.Checks) == 0 {
+ r.Check = WithExpectedStatus(http.StatusOK)
+ } else if r.Check != nil {
+ r.Checks = append(r.Checks, r.Check)
+ }
+
+ return EventuallyWithOffset(1, func() error {
+ req := r.request(r.Method, r.Path, r.Body)
+ if len(r.Headers) > 0 {
+ req = req.WithHeaders(r.Headers)
+ }
+ if r.Host != "" {
+ req = req.WithHost(r.Host)
+ }
+ if len(r.Query) > 0 {
+ for key, value := range r.Query {
+ req = req.WithQuery(key, value)
+ }
+ }
+ if r.BasicAuth != nil {
+ req = req.WithBasicAuth(r.BasicAuth.Username,
r.BasicAuth.Password)
+ }
+ expResp := req.Expect()
+
+ resp := &HTTPResponse{
+ Response: expResp.Raw(),
+ Body: expResp.Body().Raw(),
+ }
+
+ for _, check := range r.Checks {
+ if err := check(resp); err != nil {
+ return fmt.Errorf("response check failed: %w",
err)
+ }
+ }
+ return nil
+ }).WithTimeout(r.Timeout).ProbeEvery(r.Interval).Should(Succeed())
+}
+
+// RetryAssertion provides a reusable Eventually-based assertion
+type RetryAssertion struct {
+ timeout time.Duration
+ interval time.Duration
+
+ args []any
+ actualOrCtx any
+}
+
+// NewRetryAssertion creates a RetryAssertion with defaults
+func (s *Scaffold) RetryAssertion(actualOrCtx any, args ...any)
*RetryAssertion {
+ return &RetryAssertion{
+ timeout: DefaultTimeout,
+ interval: DefaultInterval,
+ args: args,
+ actualOrCtx: actualOrCtx,
+ }
+}
+
+// WithTimeout sets the timeout
+func (r *RetryAssertion) WithTimeout(timeout time.Duration) *RetryAssertion {
+ r.timeout = timeout
+ return r
+}
+
+// WithInterval sets the polling interval
+func (r *RetryAssertion) WithInterval(interval time.Duration) *RetryAssertion {
+ r.interval = interval
+ return r
+}
+
+// Should runs the Eventually assertion with the given matcher
+func (r *RetryAssertion) Should(matcher types.GomegaMatcher,
optionalDescription ...any) bool {
+ return EventuallyWithOffset(1, r.actualOrCtx, r.args...).
+ WithTimeout(r.timeout).
+ ProbeEvery(r.interval).
+ Should(matcher, optionalDescription...)
+}
+
+// ShouldNot runs the Eventually assertion with the given matcher
+func (r *RetryAssertion) ShouldNot(matcher types.GomegaMatcher,
optionalDescription ...any) bool {
+ return EventuallyWithOffset(1, r.actualOrCtx, r.args...).
+ WithTimeout(r.timeout).
+ ProbeEvery(r.interval).
+ ShouldNot(matcher, optionalDescription...)
+}
diff --git a/test/e2e/scaffold/k8s.go b/test/e2e/scaffold/k8s.go
index 890552c7..0612d4c0 100644
--- a/test/e2e/scaffold/k8s.go
+++ b/test/e2e/scaffold/k8s.go
@@ -184,19 +184,17 @@ func (s *Scaffold) ResourceApplied(resourType,
resourceName, resourceRaw string,
Expect(s.CreateResourceFromString(resourceRaw)).
NotTo(HaveOccurred(), fmt.Sprintf("creating %s", resourType))
- Eventually(func() string {
+ s.RetryAssertion(func() string {
hryaml, err := s.GetResourceYaml(resourType, resourceName)
Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("getting %s
yaml", resourType))
return hryaml
- }).WithTimeout(8*time.Second).ProbeEvery(2*time.Second).
- Should(
- SatisfyAll(
- ContainSubstring(`status: "True"`),
-
ContainSubstring(fmt.Sprintf("observedGeneration: %d", observedGeneration)),
- ),
- fmt.Sprintf("checking %s condition status", resourType),
- )
- time.Sleep(3 * time.Second)
+ }).Should(
+ SatisfyAll(
+ ContainSubstring(`status: "True"`),
+ ContainSubstring(fmt.Sprintf("observedGeneration: %d",
observedGeneration)),
+ ),
+ fmt.Sprintf("checking %s condition status", resourType),
+ )
}
func (s *Scaffold) ApplyDefaultGatewayResource(