From 2aab2ebde5644ba1ea5ba6126e9f2000a9307ee8 Mon Sep 17 00:00:00 2001 From: AlinsRan Date: Mon, 15 Sep 2025 15:40:29 +0800 Subject: [PATCH 1/3] chore: add more conformance-test report for gateway-api (#2557) --- .github/workflows/apisix-conformance-test.yml | 20 ++++-- .github/workflows/conformance-test.yml | 17 +++-- Makefile | 30 ++++++--- .../{apisix => api7ee}/conformance_test.go | 30 +++------ .../{apisix => api7ee}/suite_test.go | 64 ++++++++----------- test/conformance/conformance_test.go | 32 +++------- test/conformance/suite_test.go | 62 ++++++++++-------- 7 files changed, 128 insertions(+), 127 deletions(-) rename test/conformance/{apisix => api7ee}/conformance_test.go (76%) rename test/conformance/{apisix => api7ee}/suite_test.go (83%) diff --git a/.github/workflows/apisix-conformance-test.yml b/.github/workflows/apisix-conformance-test.yml index 13562a071..1fe34fdc7 100644 --- a/.github/workflows/apisix-conformance-test.yml +++ b/.github/workflows/apisix-conformance-test.yml @@ -34,6 +34,8 @@ permissions: jobs: conformance-test: + env: + CONFORMANCE_TEST_REPORT_OUTPUT: /tmp/apisix-ingress-controller-conformance-report.yaml timeout-minutes: 60 strategy: matrix: @@ -62,6 +64,10 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} + - name: Install kind + run: | + go install sigs.k8s.io/kind@v0.23.0 + - name: Build images env: TAG: dev @@ -97,27 +103,31 @@ jobs: env: PROVIDER_TYPE: ${{ matrix.provider_type }} run: | - make conformance-test-standalone + make conformance-test - - name: Get Logs from api7-ingress-controller + - name: Show Conformance Report + shell: bash + run: | + cat ${CONFORMANCE_TEST_REPORT_OUTPUT} + + - name: Get Logs from apisix-ingress-controller shell: bash run: | export KUBECONFIG=/tmp/apisix-ingress-cluster.kubeconfig kubectl logs -n apisix-conformance-test -l app=apisix-ingress-controller - name: Upload Gateway API Conformance Report - if: ${{ github.event_name == 'push' }} uses: actions/upload-artifact@v4 with: name: apisix-ingress-controller-conformance-report-${{ matrix.provider_type }}.yaml - path: apisix-ingress-controller-conformance-report.yaml + path: ${{ env.CONFORMANCE_TEST_REPORT_OUTPUT }} - name: Format Conformance Test Report if: ${{ github.event_name == 'pull_request' }} run: | echo '# conformance test report - ${{ matrix.provider_type }} mode' > report.md echo '```yaml' >> report.md - cat apisix-ingress-controller-conformance-report.yaml >> report.md + cat ${CONFORMANCE_TEST_REPORT_OUTPUT} >> report.md echo '```' >> report.md - name: Report Conformance Test Result to PR Comment diff --git a/.github/workflows/conformance-test.yml b/.github/workflows/conformance-test.yml index 7e6c1b67b..514204835 100644 --- a/.github/workflows/conformance-test.yml +++ b/.github/workflows/conformance-test.yml @@ -31,6 +31,8 @@ concurrency: jobs: conformance-test: + env: + CONFORMANCE_TEST_REPORT_OUTPUT: /tmp/api7-ingress-controller-conformance-report.yaml timeout-minutes: 60 runs-on: ubuntu-latest steps: @@ -105,8 +107,13 @@ jobs: API7_EE_LICENSE: ${{ secrets.API7_EE_LICENSE }} continue-on-error: true run: | - make conformance-test + make conformance-test-api7ee + - name: Show Conformance Report + shell: bash + run: | + cat ${CONFORMANCE_TEST_REPORT_OUTPUT} + - name: Get Logs from api7-ingress-controller shell: bash run: | @@ -117,20 +124,20 @@ jobs: if: ${{ github.event_name == 'push' }} uses: actions/upload-artifact@v4 with: - name: apisix-ingress-controller-conformance-report.yaml - path: apisix-ingress-controller-conformance-report.yaml + name: api7-ingress-controller-conformance-report.yaml + path: ${{ env.CONFORMANCE_TEST_REPORT_OUTPUT }} - name: Format Conformance Test Report if: ${{ github.event_name == 'pull_request' }} run: | echo '# conformance test report' > report.md echo '```yaml' >> report.md - cat apisix-ingress-controller-conformance-report.yaml >> report.md + cat ${CONFORMANCE_TEST_REPORT_OUTPUT} >> report.md echo '```' >> report.md - name: Report Conformance Test Result to PR Comment if: ${{ github.event_name == 'pull_request' }} - uses: mshick/add-pr-comment@v2 + uses: ./.github/actions/add-pr-comment with: message-id: 'conformance-test-report' message-path: | diff --git a/Makefile b/Makefile index 83a91fd6c..edcf2fbe3 100644 --- a/Makefile +++ b/Makefile @@ -29,10 +29,10 @@ ENVTEST_K8S_VERSION = 1.30.0 KIND_NAME ?= apisix-ingress-cluster KIND_NODE_IMAGE ?= kindest/node:v1.30.0@sha256:047357ac0cfea04663786a612ba1eaba9702bef25227a794b52890dd8bcd692e -GATEAY_API_VERSION ?= v1.3.0 -DASHBOARD_VERSION ?= dev ADC_VERSION ?= 0.21.0 +DIR := $(shell pwd) + GINKGO_VERSION ?= 2.20.0 TEST_TIMEOUT ?= 80m TEST_DIR ?= ./test/e2e/ @@ -55,6 +55,14 @@ GITSHASYM="github.com/apache/apisix-ingress-controller/internal/version._buildGi BUILDOSSYM="github.com/apache/apisix-ingress-controller/internal/version._buildOS" GO_LDFLAGS ?= "-X=$(VERSYM)=$(VERSION) -X=$(GITSHASYM)=$(GITSHA) -X=$(BUILDOSSYM)=$(OSNAME)/$(OSARCH)" +# gateway-api +GATEAY_API_VERSION ?= v1.3.0 +## https://github.com/kubernetes-sigs/gateway-api/blob/v1.3.0/pkg/features/httproute.go +SUPPORTED_EXTENDED_FEATURES = "HTTPRouteDestinationPortMatching,HTTPRouteMethodMatching,HTTPRoutePortRedirect,HTTPRouteRequestMirror,HTTPRouteSchemeRedirect,GatewayAddressEmpty,HTTPRouteResponseHeaderModification,GatewayPort8080" +CONFORMANCE_TEST_REPORT_OUTPUT ?= $(DIR)/apisix-ingress-controller-conformance-report.yaml +## https://github.com/kubernetes-sigs/gateway-api/blob/v1.3.0/conformance/utils/suite/profiles.go +CONFORMANCE_PROFILES ?= GATEWAY-HTTP + # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) ifeq (,$(shell go env GOBIN)) GOBIN=$(shell go env GOPATH)/bin @@ -154,12 +162,18 @@ install-ginkgo: .PHONY: conformance-test conformance-test: - DASHBOARD_VERSION=$(DASHBOARD_VERSION) go test -v ./test/conformance -tags=conformance -timeout 60m - -.PHONY: conformance-test-standalone -conformance-test-standalone: - @kind get kubeconfig --name $(KIND_NAME) > $$KUBECONFIG - go test -v ./test/conformance/apisix -tags=conformance -timeout 60m + go test -v ./test/conformance -tags conformance,experimental -timeout 60m \ + --supported-features=$(SUPPORTED_EXTENDED_FEATURES) \ + --conformance-profiles=$(CONFORMANCE_PROFILES) \ + --report-output=$(CONFORMANCE_TEST_REPORT_OUTPUT) + + +.PHONY: conformance-test-api7ee +conformance-test-api7ee: + go test -v ./test/conformance/api7ee -tags conformance,experimental -timeout 60m \ + --supported-features=$(SUPPORTED_EXTENDED_FEATURES) \ + --conformance-profiles=$(CONFORMANCE_PROFILES) \ + --report-output=$(CONFORMANCE_TEST_REPORT_OUTPUT) .PHONY: lint lint: sort-import golangci-lint ## Run golangci-lint linter diff --git a/test/conformance/apisix/conformance_test.go b/test/conformance/api7ee/conformance_test.go similarity index 76% rename from test/conformance/apisix/conformance_test.go rename to test/conformance/api7ee/conformance_test.go index f5630329e..6ae824752 100644 --- a/test/conformance/apisix/conformance_test.go +++ b/test/conformance/api7ee/conformance_test.go @@ -15,13 +15,9 @@ // specific language governing permissions and limitations // under the License. -//go:build conformance -// +build conformance - -package conformance +package api7ee import ( - "flag" "os" "testing" @@ -30,8 +26,8 @@ import ( "sigs.k8s.io/gateway-api/conformance" conformancev1 "sigs.k8s.io/gateway-api/conformance/apis/v1" "sigs.k8s.io/gateway-api/conformance/tests" + "sigs.k8s.io/gateway-api/conformance/utils/flags" "sigs.k8s.io/gateway-api/conformance/utils/suite" - "sigs.k8s.io/gateway-api/pkg/features" "sigs.k8s.io/yaml" ) @@ -43,24 +39,11 @@ var skippedTestsForSSL = []string{ // TODO: HTTPRoute hostname intersection and listener hostname matching -var gatewaySupportedFeatures = []features.FeatureName{ - features.SupportGateway, - features.SupportHTTPRoute, - // features.SupportHTTPRouteMethodMatching, - // features.SupportHTTPRouteResponseHeaderModification, - // features.SupportHTTPRouteRequestMirror, - // features.SupportHTTPRouteBackendRequestHeaderModification, - // features.SupportHTTPRouteHostRewrite, -} - func TestGatewayAPIConformance(t *testing.T) { - flag.Parse() - opts := conformance.DefaultOptions(t) opts.Debug = true opts.CleanupBaseResources = true opts.GatewayClassName = gatewayClassName - opts.SupportedFeatures = sets.New(gatewaySupportedFeatures...) opts.SkipTests = skippedTestsForSSL opts.Implementation = conformancev1.Implementation{ Organization: "APISIX", @@ -80,7 +63,6 @@ func TestGatewayAPIConformance(t *testing.T) { t.Fatalf("failed to run the gateway conformance test suite: %v", err) } - const reportFileName = "apisix-ingress-controller-conformance-report.yaml" report, err := cSuite.Report() if err != nil { t.Fatalf("failed to get the gateway conformance test report: %v", err) @@ -90,6 +72,10 @@ func TestGatewayAPIConformance(t *testing.T) { if err != nil { t.Fatalf("failed to marshal the gateway conformance test report: %v", err) } - // Save report in the root of the repository, file name is in .gitignore. - require.NoError(t, os.WriteFile("../../../"+reportFileName, rawReport, 0o600)) + f, err := os.Create(*flags.ReportOutput) + require.NoError(t, err) + defer func() { _ = f.Close() }() + + _, err = f.Write(rawReport) + require.NoError(t, err) } diff --git a/test/conformance/apisix/suite_test.go b/test/conformance/api7ee/suite_test.go similarity index 83% rename from test/conformance/apisix/suite_test.go rename to test/conformance/api7ee/suite_test.go index 75b45cad1..2812d1af4 100644 --- a/test/conformance/apisix/suite_test.go +++ b/test/conformance/api7ee/suite_test.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package conformance +package api7ee import ( "context" @@ -32,7 +32,6 @@ import ( gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" "github.com/apache/apisix-ingress-controller/test/e2e/framework" - "github.com/apache/apisix-ingress-controller/test/e2e/scaffold" ) var gatewayClassName = "apisix" @@ -124,8 +123,7 @@ func TestMain(m *testing.M) { RegisterFailHandler(Fail) f := framework.NewFramework() - // init newDeployer function - scaffold.NewDeployer = scaffold.NewAPISIXDeployer + f.BeforeSuite() // Check and delete specific namespaces if they exist kubectl := k8s.NewKubectlOptions("", "", "default") @@ -138,24 +136,23 @@ func TestMain(m *testing.M) { k8s.CreateNamespace(GinkgoT(), kubectl, namespace) defer k8s.DeleteNamespace(GinkgoT(), kubectl, namespace) - adminkey := getEnvOrDefault("APISIX_ADMIN_KEY", "edd1c9f034335f136f87ad84b625c8f1") - controllerName := "apisix.apache.org/apisix-ingress-controller" - s := scaffold.NewScaffold(scaffold.Options{ - ControllerName: controllerName, - SkipHooks: true, - APISIXAdminAPIKey: adminkey, + gatewayGroupId := f.CreateNewGatewayGroupWithIngress() + adminKey := f.GetAdminKey(gatewayGroupId) + + svc := f.DeployGateway(&framework.API7DeployOptions{ + Namespace: namespace, + GatewayGroupID: gatewayGroupId, + DPManagerEndpoint: framework.DPManagerTLSEndpoint, + SetEnv: true, + SSLKey: framework.TestKey, + SSLCert: framework.TestCert, + TLSEnabled: true, + ForIngressGatewayGroup: true, + ServiceType: "LoadBalancer", + ServiceHTTPPort: 80, + ServiceHTTPSPort: 443, }) - s.Deployer.DeployDataplane(scaffold.DeployDataplaneOptions{ - AdminKey: adminkey, - Namespace: namespace, - SkipCreateTunnels: true, - ServiceType: "LoadBalancer", - ServiceHTTPPort: 80, - ServiceHTTPSPort: 443, - }) - svc := s.GetDataplaneService() - if len(svc.Status.LoadBalancer.Ingress) == 0 { Fail("No LoadBalancer found for the service") } @@ -163,26 +160,25 @@ func TestMain(m *testing.M) { address := svc.Status.LoadBalancer.Ingress[0].IP f.DeployIngress(framework.IngressDeployOpts{ - ControllerName: controllerName, - Namespace: namespace, - StatusAddress: address, - InitSyncDelay: 20 * time.Minute, - ProviderType: framework.ProviderType, - ProviderSyncPeriod: 1 * time.Hour, + ControllerName: "apisix.apache.org/apisix-ingress-controller", + Namespace: namespace, + StatusAddress: address, + InitSyncDelay: 1 * time.Minute, + ProviderType: "api7ee", }) - adminEndpoint := fmt.Sprintf("http://%s.%s:9180", svc.Name, namespace) - defaultGatewayProxyOpts = GatewayProxyOpts{ StatusAddress: address, - AdminKey: adminkey, - AdminEndpoint: adminEndpoint, + AdminKey: adminKey, + AdminEndpoint: framework.DashboardTLSEndpoint, } patchGatewaysForConformanceTest(context.Background(), f.K8sClient) code := m.Run() + f.AfterSuite() + os.Exit(code) } @@ -262,11 +258,3 @@ func patchGatewaysForConformanceTest(ctx context.Context, k8sClient client.Clien } }() } - -// getEnvOrDefault returns environment variable value or default -func getEnvOrDefault(key, defaultValue string) string { - if value := os.Getenv(key); value != "" { - return value - } - return defaultValue -} diff --git a/test/conformance/conformance_test.go b/test/conformance/conformance_test.go index f9582f614..42161ad5e 100644 --- a/test/conformance/conformance_test.go +++ b/test/conformance/conformance_test.go @@ -15,52 +15,34 @@ // specific language governing permissions and limitations // under the License. -//go:build conformance -// +build conformance - package conformance import ( - "flag" "os" "testing" "github.com/stretchr/testify/require" - "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/gateway-api/conformance" conformancev1 "sigs.k8s.io/gateway-api/conformance/apis/v1" "sigs.k8s.io/gateway-api/conformance/tests" + "sigs.k8s.io/gateway-api/conformance/utils/flags" "sigs.k8s.io/gateway-api/conformance/utils/suite" - "sigs.k8s.io/gateway-api/pkg/features" "sigs.k8s.io/yaml" ) +// https://github.com/kubernetes-sigs/gateway-api/blob/5c5fc388829d24e8071071b01e8313ada8f15d9f/conformance/utils/suite/suite.go#L358. SAN includes '*' var skippedTestsForSSL = []string{ - // Reason: https://github.com/kubernetes-sigs/gateway-api/blob/5c5fc388829d24e8071071b01e8313ada8f15d9f/conformance/utils/suite/suite.go#L358. SAN includes '*' tests.HTTPRouteHTTPSListener.ShortName, tests.HTTPRouteRedirectPortAndScheme.ShortName, } // TODO: HTTPRoute hostname intersection and listener hostname matching -var gatewaySupportedFeatures = []features.FeatureName{ - features.SupportGateway, - features.SupportHTTPRoute, - // features.SupportHTTPRouteMethodMatching, - // features.SupportHTTPRouteResponseHeaderModification, - // features.SupportHTTPRouteRequestMirror, - // features.SupportHTTPRouteBackendRequestHeaderModification, - // features.SupportHTTPRouteHostRewrite, -} - func TestGatewayAPIConformance(t *testing.T) { - flag.Parse() - opts := conformance.DefaultOptions(t) opts.Debug = true opts.CleanupBaseResources = true opts.GatewayClassName = gatewayClassName - opts.SupportedFeatures = sets.New(gatewaySupportedFeatures...) opts.SkipTests = skippedTestsForSSL opts.Implementation = conformancev1.Implementation{ Organization: "APISIX", @@ -68,7 +50,6 @@ func TestGatewayAPIConformance(t *testing.T) { URL: "https://github.com/apache/apisix-ingress-controller.git", Version: "v2.0.0", } - opts.ConformanceProfiles = sets.New(suite.GatewayHTTPConformanceProfileName) cSuite, err := suite.NewConformanceTestSuite(opts) require.NoError(t, err) @@ -80,7 +61,6 @@ func TestGatewayAPIConformance(t *testing.T) { t.Fatalf("failed to run the gateway conformance test suite: %v", err) } - const reportFileName = "apisix-ingress-controller-conformance-report.yaml" report, err := cSuite.Report() if err != nil { t.Fatalf("failed to get the gateway conformance test report: %v", err) @@ -90,6 +70,10 @@ func TestGatewayAPIConformance(t *testing.T) { if err != nil { t.Fatalf("failed to marshal the gateway conformance test report: %v", err) } - // Save report in the root of the repository, file name is in .gitignore. - require.NoError(t, os.WriteFile("../../"+reportFileName, rawReport, 0o600)) + f, err := os.Create(*flags.ReportOutput) + require.NoError(t, err) + defer func() { _ = f.Close() }() + + _, err = f.Write(rawReport) + require.NoError(t, err) } diff --git a/test/conformance/suite_test.go b/test/conformance/suite_test.go index 89c87c236..75b45cad1 100644 --- a/test/conformance/suite_test.go +++ b/test/conformance/suite_test.go @@ -32,6 +32,7 @@ import ( gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" "github.com/apache/apisix-ingress-controller/test/e2e/framework" + "github.com/apache/apisix-ingress-controller/test/e2e/scaffold" ) var gatewayClassName = "apisix" @@ -123,7 +124,8 @@ func TestMain(m *testing.M) { RegisterFailHandler(Fail) f := framework.NewFramework() - f.BeforeSuite() + // init newDeployer function + scaffold.NewDeployer = scaffold.NewAPISIXDeployer // Check and delete specific namespaces if they exist kubectl := k8s.NewKubectlOptions("", "", "default") @@ -136,23 +138,24 @@ func TestMain(m *testing.M) { k8s.CreateNamespace(GinkgoT(), kubectl, namespace) defer k8s.DeleteNamespace(GinkgoT(), kubectl, namespace) - gatewayGroupId := f.CreateNewGatewayGroupWithIngress() - adminKey := f.GetAdminKey(gatewayGroupId) - - svc := f.DeployGateway(&framework.API7DeployOptions{ - Namespace: namespace, - GatewayGroupID: gatewayGroupId, - DPManagerEndpoint: framework.DPManagerTLSEndpoint, - SetEnv: true, - SSLKey: framework.TestKey, - SSLCert: framework.TestCert, - TLSEnabled: true, - ForIngressGatewayGroup: true, - ServiceType: "LoadBalancer", - ServiceHTTPPort: 80, - ServiceHTTPSPort: 443, + adminkey := getEnvOrDefault("APISIX_ADMIN_KEY", "edd1c9f034335f136f87ad84b625c8f1") + controllerName := "apisix.apache.org/apisix-ingress-controller" + s := scaffold.NewScaffold(scaffold.Options{ + ControllerName: controllerName, + SkipHooks: true, + APISIXAdminAPIKey: adminkey, }) + s.Deployer.DeployDataplane(scaffold.DeployDataplaneOptions{ + AdminKey: adminkey, + Namespace: namespace, + SkipCreateTunnels: true, + ServiceType: "LoadBalancer", + ServiceHTTPPort: 80, + ServiceHTTPSPort: 443, + }) + svc := s.GetDataplaneService() + if len(svc.Status.LoadBalancer.Ingress) == 0 { Fail("No LoadBalancer found for the service") } @@ -160,25 +163,26 @@ func TestMain(m *testing.M) { address := svc.Status.LoadBalancer.Ingress[0].IP f.DeployIngress(framework.IngressDeployOpts{ - ControllerName: "apisix.apache.org/apisix-ingress-controller", - Namespace: namespace, - StatusAddress: address, - InitSyncDelay: 1 * time.Minute, - ProviderType: "api7ee", + ControllerName: controllerName, + Namespace: namespace, + StatusAddress: address, + InitSyncDelay: 20 * time.Minute, + ProviderType: framework.ProviderType, + ProviderSyncPeriod: 1 * time.Hour, }) + adminEndpoint := fmt.Sprintf("http://%s.%s:9180", svc.Name, namespace) + defaultGatewayProxyOpts = GatewayProxyOpts{ StatusAddress: address, - AdminKey: adminKey, - AdminEndpoint: framework.DashboardTLSEndpoint, + AdminKey: adminkey, + AdminEndpoint: adminEndpoint, } patchGatewaysForConformanceTest(context.Background(), f.K8sClient) code := m.Run() - f.AfterSuite() - os.Exit(code) } @@ -258,3 +262,11 @@ func patchGatewaysForConformanceTest(ctx context.Context, k8sClient client.Clien } }() } + +// getEnvOrDefault returns environment variable value or default +func getEnvOrDefault(key, defaultValue string) string { + if value := os.Getenv(key); value != "" { + return value + } + return defaultValue +} From 0ad55ae89e725dfeb486fba6320b0b8503ad3827 Mon Sep 17 00:00:00 2001 From: rongxin Date: Thu, 18 Sep 2025 01:49:02 +0800 Subject: [PATCH 2/3] f --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index edcf2fbe3..c78d20275 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,7 @@ ENVTEST_K8S_VERSION = 1.30.0 KIND_NAME ?= apisix-ingress-cluster KIND_NODE_IMAGE ?= kindest/node:v1.30.0@sha256:047357ac0cfea04663786a612ba1eaba9702bef25227a794b52890dd8bcd692e +DASHBOARD_VERSION ?= dev ADC_VERSION ?= 0.21.0 DIR := $(shell pwd) From cd14a2807550e50c611de1482da865192621a642 Mon Sep 17 00:00:00 2001 From: rongxin Date: Thu, 18 Sep 2025 09:41:53 +0800 Subject: [PATCH 3/3] add var --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c78d20275..ccaed1542 100644 --- a/Makefile +++ b/Makefile @@ -171,7 +171,7 @@ conformance-test: .PHONY: conformance-test-api7ee conformance-test-api7ee: - go test -v ./test/conformance/api7ee -tags conformance,experimental -timeout 60m \ + DASHBOARD_VERSION=$(DASHBOARD_VERSION) go test -v ./test/conformance/api7ee -tags conformance,experimental -timeout 60m \ --supported-features=$(SUPPORTED_EXTENDED_FEATURES) \ --conformance-profiles=$(CONFORMANCE_PROFILES) \ --report-output=$(CONFORMANCE_TEST_REPORT_OUTPUT)