You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by zh...@apache.org on 2022/04/07 04:48:55 UTC

[apisix-ingress-controller] branch master updated: Split e2e test cases (#949)

This is an automated email from the ASF dual-hosted git repository.

zhangjintao 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 4bdc9471 Split e2e test cases (#949)
4bdc9471 is described below

commit 4bdc9471172a8b1574c61ba5ad5b8fbc4160fc22
Author: Hoshea Jiang <fg...@gmail.com>
AuthorDate: Thu Apr 7 12:48:51 2022 +0800

    Split e2e test cases (#949)
---
 .github/actions/e2e/action.yaml                    | 68 ++++++++++++++++++++++
 .github/workflows/e2e-test-ci.yml                  | 48 +++++++--------
 Makefile                                           |  2 +-
 test/e2e/README.md                                 | 13 ++++-
 test/e2e/e2e.go                                    | 14 ++---
 .../e2e/{annotations => suite-annotations}/cors.go | 22 +++----
 .../iprestriction.go                               |  2 +-
 .../{annotations => suite-annotations}/redirect.go |  2 +-
 .../{annotations => suite-annotations}/rewrite.go  |  2 +-
 test/e2e/{chaos => suite-chaos}/chaos.go           |  2 +-
 test/e2e/{config => suite-config}/config.go        |  2 +-
 test/e2e/{config => suite-config}/manifests.go     |  0
 .../{endpoints => suite-endpoints}/endpoints.go    |  2 +-
 test/e2e/{features => suite-features}/consumer.go  |  2 +-
 .../{features => suite-features}/global_rule.go    |  4 +-
 .../{features => suite-features}/healthcheck.go    |  2 +-
 .../remote_addrs_match.go                          |  2 +-
 test/e2e/{features => suite-features}/retries.go   |  2 +-
 .../route_match_exprs.go                           |  2 +-
 test/e2e/{features => suite-features}/scheme.go    | 34 +++++------
 test/e2e/{features => suite-features}/subset.go    |  2 +-
 .../{features => suite-features}/traffic_split.go  |  2 +-
 test/e2e/{features => suite-features}/websocket.go |  2 +-
 test/e2e/{ingress => suite-ingress}/compare.go     |  2 +-
 test/e2e/{ingress => suite-ingress}/ingress.go     |  4 +-
 test/e2e/{ingress => suite-ingress}/namespace.go   |  2 +-
 .../{ingress => suite-ingress}/resourcepushing.go  |  2 +-
 test/e2e/{ingress => suite-ingress}/sanity.go      |  2 +-
 test/e2e/{ingress => suite-ingress}/secret.go      |  2 +-
 test/e2e/{ingress => suite-ingress}/ssl.go         |  2 +-
 test/e2e/{ingress => suite-ingress}/status.go      |  2 +-
 test/e2e/{ingress => suite-ingress}/stream.go      |  2 +-
 .../e2e/{ingress => suite-ingress}/upstream_tls.go |  8 +--
 test/e2e/{ingress => suite-ingress}/webhook.go     |  2 +-
 test/e2e/{plugins => suite-plugins}/api_breaker.go |  2 +-
 test/e2e/{plugins => suite-plugins}/cors.go        | 10 ++--
 test/e2e/{plugins => suite-plugins}/echo.go        |  2 +-
 .../{plugins => suite-plugins}/fault_injection.go  |  2 +-
 .../{plugins => suite-plugins}/ip-restriction.go   |  2 +-
 test/e2e/{plugins => suite-plugins}/limit_count.go |  2 +-
 .../{plugins => suite-plugins}/plugin_config.go    |  8 +--
 .../{plugins => suite-plugins}/proxy_rewrite.go    |  2 +-
 test/e2e/{plugins => suite-plugins}/redirect.go    |  2 +-
 .../referer-restriction.go                         |  2 +-
 .../request-validation.go                          |  2 +-
 test/e2e/{plugins => suite-plugins}/request_id.go  |  2 +-
 .../{plugins => suite-plugins}/response_rewrite.go |  2 +-
 test/e2e/{plugins => suite-plugins}/server-info.go |  2 +-
 test/e2e/{plugins => suite-plugins}/uri_blocker.go |  2 +-
 49 files changed, 191 insertions(+), 116 deletions(-)

diff --git a/.github/actions/e2e/action.yaml b/.github/actions/e2e/action.yaml
new file mode 100644
index 00000000..fd83cb29
--- /dev/null
+++ b/.github/actions/e2e/action.yaml
@@ -0,0 +1,68 @@
+#
+# 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.
+
+name: Run E2E tests
+description: "Run an E2E test suite"
+
+inputs:
+  testsuite_name:
+    description: "Name of the test suite to run"
+    required: true
+  concurrency:
+    description: "Number of concurrent test runs"
+    required: false
+    default: '2'
+
+runs:
+  using: "composite"
+  steps:
+    - uses: actions/checkout@v2
+      with:
+        submodules: recursive
+
+    - name: Install kind
+      shell: bash
+      run: |
+        curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.11.1/kind-linux-amd64
+        chmod +x ./kind
+        sudo mv kind /usr/local/bin
+
+    - name: Setup Go Env
+      uses: actions/setup-go@v2
+      with:
+        go-version: "1.16"
+
+    - name: Install ginkgo
+      shell: bash
+      run: |
+        go install github.com/onsi/ginkgo/ginkgo@v1.16.4
+        sudo cp ~/go/bin/ginkgo /usr/local/bin
+
+    - name: Create K8s cluster
+      shell: bash
+      run: |
+        make kind-up
+        kubectl wait --for=condition=Ready nodes --all
+
+    - name: Run E2E test suite
+      shell: bash
+      env:
+        E2E_FOCUS: "${{ inputs.testsuite_name }}*"
+        E2E_CONCURRENCY: "${{ inputs.concurrency }}"
+      run: |
+        make e2e-test
diff --git a/.github/workflows/e2e-test-ci.yml b/.github/workflows/e2e-test-ci.yml
index 82e5c2e3..e734fa77 100644
--- a/.github/workflows/e2e-test-ci.yml
+++ b/.github/workflows/e2e-test-ci.yml
@@ -62,37 +62,33 @@ jobs:
               - 'conf/**'
               - 'utils/**'
 
-  e2e-test:
+  prepare-matrix:
     needs: changes
-    if: |
-      (needs.changes.outputs.go == 'true')
+    if: needs.changes.outputs.go == 'true'
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v2
         with:
           submodules: recursive
-      - name: Install kind
+
+      - name: List test suites and set the matrix
+        id: set-matrix
         run: |
-          curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.11.1/kind-linux-amd64
-          chmod +x ./kind
-          sudo mv kind /usr/local/bin
-      - name: Setup Go Env
-        uses: actions/setup-go@v2
+          SUITES=($(find test/e2e -type d -iname 'suite-*' | grep -E -o '(\w|\-)*' | grep -v 'test' | grep -v 'e2e'))
+          echo $SUITES
+          echo "::set-output name=matrix::$(jq --compact-output --null-input '$ARGS.positional' --args "${SUITES[@]}")"
+    outputs:
+      matrix: ${{ steps.set-matrix.outputs.matrix }}
+
+  e2e-test:
+    needs: prepare-matrix
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        suite: ${{ fromJson(needs.prepare-matrix.outputs.matrix) }}
+    steps:
+      - uses: actions/checkout@v2
+
+      - uses: ./.github/actions/e2e
         with:
-          go-version: "1.16"
-      - name: Install ginkgo
-        run: |
-          go install github.com/onsi/ginkgo/ginkgo@v1.16.4
-          sudo cp ~/go/bin/ginkgo /usr/local/bin
-      - name: Create K8s cluster
-        run: |
-          make kind-up
-          kubectl wait --for=condition=Ready nodes --all
-      - name: Run e2e test cases
-        working-directory: ./
-        run: |
-          make e2e-test E2E_CONCURRENCY=2
-      - name: upload coverage profile
-        working-directory: ./test/e2e
-        run: |
-          bash <(curl -s https://codecov.io/bash)
+          testsuite_name: ${{ matrix.suite }}
diff --git a/Makefile b/Makefile
index dc00715b..e482a18f 100644
--- a/Makefile
+++ b/Makefile
@@ -70,7 +70,7 @@ e2e-test: ginkgo-check push-images
 	cd test/e2e \
 		&& go mod download \
 		&& export REGISTRY=$(REGISTRY) \
-		&& ACK_GINKGO_RC=true ginkgo -cover -coverprofile=coverage.txt -r --randomizeSuites --randomizeAllSpecs --trace --nodes=$(E2E_CONCURRENCY)
+		&& ACK_GINKGO_RC=true ginkgo -cover -coverprofile=coverage.txt -r --randomizeSuites --randomizeAllSpecs --trace --nodes=$(E2E_CONCURRENCY) --focus=$(E2E_FOCUS)
 
 ### e2e-test-local:        Run e2e test cases (kind is required)
 .PHONY: e2e-test-local
diff --git a/test/e2e/README.md b/test/e2e/README.md
index be5ddd79..a175e746 100644
--- a/test/e2e/README.md
+++ b/test/e2e/README.md
@@ -41,7 +41,7 @@ Test cases inside `plugins` directory test the availability about APISIX plugins
 Features
 --------
 
-Test caes inside `features` directory test some features about APISIX, such as traffic-split, health check and so on.
+Test case inside `features` directory test some features about APISIX, such as traffic-split, health check and so on.
 
 Quick Start
 -----------
@@ -57,4 +57,15 @@ Run `make e2e-test` to run the e2e test suites in an existing cluster, you can s
 Step `1` and `2` can be skipped by passing `E2E_SKIP_BUILD=1` to this directive, also, you can customize the
 running concurrency of e2e test suites by passing `E2E_CONCURRENCY=X` where `X` is the desired number of cases running in parallel.
 
+You can run specific test cases by passing the environment variable `E2E_FOCUS=suite-<suite name>`, where `<suite name>` can be found under `test/e2e` directory.
+For example, `E2E_FOCUS=suite-plugins* make e2e-test` will only run test cases in `test/e2e/suite-plugins` directory.
+
 Run `make kind-reset` to delete the cluster that created by `make e2e-test`.
+
+How to name test cases
+-----------
+
+Because we use `ginkgo --focus` option and the prefix `suite-<suite name>` to split test cases and make them run in parallel in CI, test cases should be named in the following way:
+
+- All test cases are grouped by directories, and **their names should have `suite-` prefix**
+- All top level specs (i.e. `ginkgo.Describe`) under the suite directory should have corresponding `suite-<suite-name>: ` prefix.
diff --git a/test/e2e/e2e.go b/test/e2e/e2e.go
index 651a1c69..28f8ae47 100644
--- a/test/e2e/e2e.go
+++ b/test/e2e/e2e.go
@@ -15,13 +15,13 @@
 package e2e
 
 import (
-	_ "github.com/apache/apisix-ingress-controller/test/e2e/annotations"
-	_ "github.com/apache/apisix-ingress-controller/test/e2e/chaos"
-	_ "github.com/apache/apisix-ingress-controller/test/e2e/config"
-	_ "github.com/apache/apisix-ingress-controller/test/e2e/endpoints"
-	_ "github.com/apache/apisix-ingress-controller/test/e2e/features"
-	_ "github.com/apache/apisix-ingress-controller/test/e2e/ingress"
-	_ "github.com/apache/apisix-ingress-controller/test/e2e/plugins"
+	_ "github.com/apache/apisix-ingress-controller/test/e2e/suite-annotations"
+	_ "github.com/apache/apisix-ingress-controller/test/e2e/suite-chaos"
+	_ "github.com/apache/apisix-ingress-controller/test/e2e/suite-config"
+	_ "github.com/apache/apisix-ingress-controller/test/e2e/suite-endpoints"
+	_ "github.com/apache/apisix-ingress-controller/test/e2e/suite-features"
+	_ "github.com/apache/apisix-ingress-controller/test/e2e/suite-ingress"
+	_ "github.com/apache/apisix-ingress-controller/test/e2e/suite-plugins"
 )
 
 func runE2E() {}
diff --git a/test/e2e/annotations/cors.go b/test/e2e/suite-annotations/cors.go
similarity index 94%
rename from test/e2e/annotations/cors.go
rename to test/e2e/suite-annotations/cors.go
index 3c09eb2e..5d1f9d37 100644
--- a/test/e2e/annotations/cors.go
+++ b/test/e2e/suite-annotations/cors.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("cors annotations", func() {
+var _ = ginkgo.Describe("suite-annotations: cors annotations", func() {
 	s := scaffold.NewDefaultScaffold()
 
 	ginkgo.It("enable in ingress networking/v1", func() {
@@ -61,14 +61,14 @@ spec:
 		resp := s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").Expect()
 		resp.Status(http.StatusOK)
 		// As httpbin itself adds this header, we don't check it here.
-		//resp.Header("Access-Control-Allow-Origin").Empty()
+		// resp.Header("Access-Control-Allow-Origin").Empty()
 		resp.Header("Access-Control-Allow-Methods").Empty()
 		resp.Header("Access-Control-Allow-Headers").Empty()
 
 		resp = s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").WithHeader("Origin", "https://baz.com").Expect()
 		resp.Status(http.StatusOK)
 		// As httpbin itself adds this header, we don't check it here.
-		//resp.Header("Access-Control-Allow-Origin").Empty()
+		// resp.Header("Access-Control-Allow-Origin").Empty()
 		resp.Header("Access-Control-Allow-Methods").Empty()
 		resp.Header("Access-Control-Allow-Headers").Empty()
 
@@ -112,7 +112,7 @@ spec:
 		resp := s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").WithHeader("Origin", "https://foo.com").Expect()
 		resp.Status(http.StatusOK)
 		// As httpbin itself adds this header, we don't check it here.
-		//resp.Header("Access-Control-Allow-Origin").Empty()
+		// resp.Header("Access-Control-Allow-Origin").Empty()
 		resp.Header("Access-Control-Allow-Methods").Empty()
 		resp.Header("Access-Control-Allow-Headers").Empty()
 	})
@@ -148,14 +148,14 @@ spec:
 		resp := s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").Expect()
 		resp.Status(http.StatusOK)
 		// As httpbin itself adds this header, we don't check it here.
-		//resp.Header("Access-Control-Allow-Origin").Empty()
+		// resp.Header("Access-Control-Allow-Origin").Empty()
 		resp.Header("Access-Control-Allow-Methods").Empty()
 		resp.Header("Access-Control-Allow-Headers").Empty()
 
 		resp = s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").WithHeader("Origin", "https://baz.com").Expect()
 		resp.Status(http.StatusOK)
 		// As httpbin itself adds this header, we don't check it here.
-		//resp.Header("Access-Control-Allow-Origin").Empty()
+		// resp.Header("Access-Control-Allow-Origin").Empty()
 		resp.Header("Access-Control-Allow-Methods").Empty()
 		resp.Header("Access-Control-Allow-Headers").Empty()
 
@@ -197,14 +197,14 @@ spec:
 		resp := s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").Expect()
 		resp.Status(http.StatusOK)
 		// As httpbin itself adds this header, we don't check it here.
-		//resp.Header("Access-Control-Allow-Origin").Empty()
+		// resp.Header("Access-Control-Allow-Origin").Empty()
 		resp.Header("Access-Control-Allow-Methods").Empty()
 		resp.Header("Access-Control-Allow-Headers").Empty()
 
 		resp = s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").WithHeader("Origin", "https://foo.com").Expect()
 		resp.Status(http.StatusOK)
 		// As httpbin itself adds this header, we don't check it here.
-		//resp.Header("Access-Control-Allow-Origin").Empty()
+		// resp.Header("Access-Control-Allow-Origin").Empty()
 		resp.Header("Access-Control-Allow-Methods").Empty()
 		resp.Header("Access-Control-Allow-Headers").Empty()
 	})
@@ -240,14 +240,14 @@ spec:
 		resp := s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").Expect()
 		resp.Status(http.StatusOK)
 		// As httpbin itself adds this header, we don't check it here.
-		//resp.Header("Access-Control-Allow-Origin").Empty()
+		// resp.Header("Access-Control-Allow-Origin").Empty()
 		resp.Header("Access-Control-Allow-Methods").Empty()
 		resp.Header("Access-Control-Allow-Headers").Empty()
 
 		resp = s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").WithHeader("Origin", "https://baz.com").Expect()
 		resp.Status(http.StatusOK)
 		// As httpbin itself adds this header, we don't check it here.
-		//resp.Header("Access-Control-Allow-Origin").Empty()
+		// resp.Header("Access-Control-Allow-Origin").Empty()
 		resp.Header("Access-Control-Allow-Methods").Empty()
 		resp.Header("Access-Control-Allow-Headers").Empty()
 
@@ -289,7 +289,7 @@ spec:
 		resp := s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").WithHeader("Origin", "https://foo.com").Expect()
 		resp.Status(http.StatusOK)
 		// As httpbin itself adds this header, we don't check it here.
-		//resp.Header("Access-Control-Allow-Origin").Empty()
+		// resp.Header("Access-Control-Allow-Origin").Empty()
 		resp.Header("Access-Control-Allow-Methods").Empty()
 		resp.Header("Access-Control-Allow-Headers").Empty()
 	})
diff --git a/test/e2e/annotations/iprestriction.go b/test/e2e/suite-annotations/iprestriction.go
similarity index 98%
rename from test/e2e/annotations/iprestriction.go
rename to test/e2e/suite-annotations/iprestriction.go
index feb1e4f0..e5b594fe 100644
--- a/test/e2e/annotations/iprestriction.go
+++ b/test/e2e/suite-annotations/iprestriction.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("allowlist-source-range annotations", func() {
+var _ = ginkgo.Describe("suite-annotations: allowlist-source-range annotations", func() {
 	s := scaffold.NewDefaultScaffold()
 
 	ginkgo.It("enable in ingress networking/v1", func() {
diff --git a/test/e2e/annotations/redirect.go b/test/e2e/suite-annotations/redirect.go
similarity index 97%
rename from test/e2e/annotations/redirect.go
rename to test/e2e/suite-annotations/redirect.go
index 0dd41003..02275117 100644
--- a/test/e2e/annotations/redirect.go
+++ b/test/e2e/suite-annotations/redirect.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("redirect annotations", func() {
+var _ = ginkgo.Describe("suite-annotations: redirect annotations", func() {
 	s := scaffold.NewDefaultScaffold()
 
 	ginkgo.It("redirect http-to-https in ingress networking/v1", func() {
diff --git a/test/e2e/annotations/rewrite.go b/test/e2e/suite-annotations/rewrite.go
similarity index 98%
rename from test/e2e/annotations/rewrite.go
rename to test/e2e/suite-annotations/rewrite.go
index 581f4a97..ce9d3caa 100644
--- a/test/e2e/annotations/rewrite.go
+++ b/test/e2e/suite-annotations/rewrite.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("rewrite annotations", func() {
+var _ = ginkgo.Describe("suite-annotations: rewrite annotations", func() {
 	s := scaffold.NewDefaultScaffold()
 
 	ginkgo.It("enable in ingress networking/v1", func() {
diff --git a/test/e2e/chaos/chaos.go b/test/e2e/suite-chaos/chaos.go
similarity index 97%
rename from test/e2e/chaos/chaos.go
rename to test/e2e/suite-chaos/chaos.go
index 4b152e49..49681c1f 100644
--- a/test/e2e/chaos/chaos.go
+++ b/test/e2e/suite-chaos/chaos.go
@@ -24,7 +24,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("Chaos Testing", func() {
+var _ = ginkgo.Describe("suite-chaos: Chaos Testing", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/config/config.go b/test/e2e/suite-config/config.go
similarity index 97%
rename from test/e2e/config/config.go
rename to test/e2e/suite-config/config.go
index 7139bda6..aa9cde27 100644
--- a/test/e2e/config/config.go
+++ b/test/e2e/suite-config/config.go
@@ -27,7 +27,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("deploy ingress controller with config", func() {
+var _ = ginkgo.Describe("suite-config: deploy ingress controller with config", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/config/manifests.go b/test/e2e/suite-config/manifests.go
similarity index 100%
rename from test/e2e/config/manifests.go
rename to test/e2e/suite-config/manifests.go
diff --git a/test/e2e/endpoints/endpoints.go b/test/e2e/suite-endpoints/endpoints.go
similarity index 98%
rename from test/e2e/endpoints/endpoints.go
rename to test/e2e/suite-endpoints/endpoints.go
index 3b07da95..1da6a13a 100644
--- a/test/e2e/endpoints/endpoints.go
+++ b/test/e2e/suite-endpoints/endpoints.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("endpoints", func() {
+var _ = ginkgo.Describe("suite-endpoints: endpoints", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/features/consumer.go b/test/e2e/suite-features/consumer.go
similarity index 99%
rename from test/e2e/features/consumer.go
rename to test/e2e/suite-features/consumer.go
index 353c853d..785981ab 100644
--- a/test/e2e/features/consumer.go
+++ b/test/e2e/suite-features/consumer.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("ApisixConsumer", func() {
+var _ = ginkgo.Describe("suite-features: ApisixConsumer", func() {
 	s := scaffold.NewDefaultV2Scaffold()
 
 	ginkgo.It("ApisixRoute with basicAuth consumer", func() {
diff --git a/test/e2e/features/global_rule.go b/test/e2e/suite-features/global_rule.go
similarity index 97%
rename from test/e2e/features/global_rule.go
rename to test/e2e/suite-features/global_rule.go
index aade03d8..773e19b8 100644
--- a/test/e2e/features/global_rule.go
+++ b/test/e2e/suite-features/global_rule.go
@@ -19,14 +19,14 @@ import (
 	"net/http"
 	"time"
 
-	"github.com/apache/apisix-ingress-controller/pkg/id"
 	"github.com/onsi/ginkgo"
 	"github.com/stretchr/testify/assert"
 
+	"github.com/apache/apisix-ingress-controller/pkg/id"
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("ApisixClusterConfig", func() {
+var _ = ginkgo.Describe("suite-features: ApisixClusterConfig", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/features/healthcheck.go b/test/e2e/suite-features/healthcheck.go
similarity index 98%
rename from test/e2e/features/healthcheck.go
rename to test/e2e/suite-features/healthcheck.go
index b1a250d8..7d2d56a4 100644
--- a/test/e2e/features/healthcheck.go
+++ b/test/e2e/suite-features/healthcheck.go
@@ -24,7 +24,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("health check", func() {
+var _ = ginkgo.Describe("suite-features: health check", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/features/remote_addrs_match.go b/test/e2e/suite-features/remote_addrs_match.go
similarity index 97%
rename from test/e2e/features/remote_addrs_match.go
rename to test/e2e/suite-features/remote_addrs_match.go
index 90c5cc4d..55fcf568 100644
--- a/test/e2e/features/remote_addrs_match.go
+++ b/test/e2e/suite-features/remote_addrs_match.go
@@ -24,7 +24,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("traffic split", func() {
+var _ = ginkgo.Describe("suite-features: traffic split", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/features/retries.go b/test/e2e/suite-features/retries.go
similarity index 98%
rename from test/e2e/features/retries.go
rename to test/e2e/suite-features/retries.go
index 91f5c908..0e311d32 100644
--- a/test/e2e/features/retries.go
+++ b/test/e2e/suite-features/retries.go
@@ -24,7 +24,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("retries", func() {
+var _ = ginkgo.Describe("suite-features: retries", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/features/route_match_exprs.go b/test/e2e/suite-features/route_match_exprs.go
similarity index 99%
rename from test/e2e/features/route_match_exprs.go
rename to test/e2e/suite-features/route_match_exprs.go
index 14a8a5d3..eeba9bdb 100644
--- a/test/e2e/features/route_match_exprs.go
+++ b/test/e2e/suite-features/route_match_exprs.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("route match exprs", func() {
+var _ = ginkgo.Describe("suite-features: route match exprs", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/features/scheme.go b/test/e2e/suite-features/scheme.go
similarity index 87%
rename from test/e2e/features/scheme.go
rename to test/e2e/suite-features/scheme.go
index d4557cd3..d580ab14 100644
--- a/test/e2e/features/scheme.go
+++ b/test/e2e/suite-features/scheme.go
@@ -27,7 +27,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/testbackend/client"
 )
 
-var _ = ginkgo.Describe("choose scheme", func() {
+var _ = ginkgo.Describe("suite-features: choose scheme", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
@@ -99,28 +99,28 @@ spec:
 		assert.Equal(ginkgo.GinkgoT(), ups[0].Scheme, "grpc")
 
 		// TODO enable the following test cases once APISIX supports HTTP/2 in plain.
-		//ep, err := s.GetAPISIXEndpoint()
-		//assert.Nil(ginkgo.GinkgoT(), err)
-		//ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-		//defer cancel()
-		//dialFunc := func(ctx context.Context, addr string) (net.Conn, error) {
+		// ep, err := s.GetAPISIXEndpoint()
+		// assert.Nil(ginkgo.GinkgoT(), err)
+		// ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+		// defer cancel()
+		// dialFunc := func(ctx context.Context, addr string) (net.Conn, error) {
 		//	return (&net.Dialer{}).DialContext(ctx, "tcp", addr)
-		//}
+		// }
 		//
-		//grpcConn, err := grpc.DialContext(ctx, ep,
+		// grpcConn, err := grpc.DialContext(ctx, ep,
 		//	grpc.WithBlock(),
 		//	grpc.WithInsecure(),
 		//	grpc.WithContextDialer(dialFunc),
-		//)
-		//assert.Nil(ginkgo.GinkgoT(), err)
-		//defer grpcConn.Close()
-		//cli := helloworld.NewGreeterClient(grpcConn)
-		//hr := &helloworld.HelloRequest{
+		// )
+		// assert.Nil(ginkgo.GinkgoT(), err)
+		// defer grpcConn.Close()
+		// cli := helloworld.NewGreeterClient(grpcConn)
+		// hr := &helloworld.HelloRequest{
 		//	Name: "Alex",
-		//}
-		//resp, err := cli.SayHello(context.TODO(), hr)
-		//assert.Nil(ginkgo.GinkgoT(), err)
-		//assert.Equal(ginkgo.GinkgoT(), resp.Message, "Alex")
+		// }
+		// resp, err := cli.SayHello(context.TODO(), hr)
+		// assert.Nil(ginkgo.GinkgoT(), err)
+		// assert.Equal(ginkgo.GinkgoT(), resp.Message, "Alex")
 	})
 
 	ginkgo.It("grpcs", func() {
diff --git a/test/e2e/features/subset.go b/test/e2e/suite-features/subset.go
similarity index 98%
rename from test/e2e/features/subset.go
rename to test/e2e/suite-features/subset.go
index e705ccdf..681c730f 100644
--- a/test/e2e/features/subset.go
+++ b/test/e2e/suite-features/subset.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("service subset", func() {
+var _ = ginkgo.Describe("suite-features: service subset", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/features/traffic_split.go b/test/e2e/suite-features/traffic_split.go
similarity index 98%
rename from test/e2e/features/traffic_split.go
rename to test/e2e/suite-features/traffic_split.go
index 2becfa7d..ef37fa86 100644
--- a/test/e2e/features/traffic_split.go
+++ b/test/e2e/suite-features/traffic_split.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("traffic split", func() {
+var _ = ginkgo.Describe("suite-features: traffic split", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/features/websocket.go b/test/e2e/suite-features/websocket.go
similarity index 98%
rename from test/e2e/features/websocket.go
rename to test/e2e/suite-features/websocket.go
index d35a27b1..a64fc80f 100644
--- a/test/e2e/features/websocket.go
+++ b/test/e2e/suite-features/websocket.go
@@ -26,7 +26,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("websocket", func() {
+var _ = ginkgo.Describe("suite-features: websocket", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/ingress/compare.go b/test/e2e/suite-ingress/compare.go
similarity index 97%
rename from test/e2e/ingress/compare.go
rename to test/e2e/suite-ingress/compare.go
index 9a935255..4fd046a4 100644
--- a/test/e2e/ingress/compare.go
+++ b/test/e2e/suite-ingress/compare.go
@@ -24,7 +24,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("Testing compare resources", func() {
+var _ = ginkgo.Describe("suite-ingress: Testing compare resources", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/ingress/ingress.go b/test/e2e/suite-ingress/ingress.go
similarity index 99%
rename from test/e2e/ingress/ingress.go
rename to test/e2e/suite-ingress/ingress.go
index 92dd07f8..01d018f1 100644
--- a/test/e2e/ingress/ingress.go
+++ b/test/e2e/suite-ingress/ingress.go
@@ -21,15 +21,15 @@ import (
 	"net/http"
 	"time"
 
-	"github.com/apache/apisix-ingress-controller/pkg/id"
 	"github.com/onsi/ginkgo"
 	"github.com/stretchr/testify/assert"
 	corev1 "k8s.io/api/core/v1"
 
+	"github.com/apache/apisix-ingress-controller/pkg/id"
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("support ingress https", func() {
+var _ = ginkgo.Describe("suite-ingress: support ingress https", func() {
 	s := scaffold.NewDefaultV2Scaffold()
 
 	rootCA := `-----BEGIN CERTIFICATE-----
diff --git a/test/e2e/ingress/namespace.go b/test/e2e/suite-ingress/namespace.go
similarity index 98%
rename from test/e2e/ingress/namespace.go
rename to test/e2e/suite-ingress/namespace.go
index 649d49ee..083d0f25 100644
--- a/test/e2e/ingress/namespace.go
+++ b/test/e2e/suite-ingress/namespace.go
@@ -36,7 +36,7 @@ type headers struct {
 	} `json:"headers"`
 }
 
-var _ = ginkgo.Describe("namespacing filtering", func() {
+var _ = ginkgo.Describe("suite-ingress: namespacing filtering", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/ingress/resourcepushing.go b/test/e2e/suite-ingress/resourcepushing.go
similarity index 99%
rename from test/e2e/ingress/resourcepushing.go
rename to test/e2e/suite-ingress/resourcepushing.go
index 9a1fd6ba..618435b8 100644
--- a/test/e2e/ingress/resourcepushing.go
+++ b/test/e2e/suite-ingress/resourcepushing.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("ApisixRoute Testing", func() {
+var _ = ginkgo.Describe("suite-ingress: ApisixRoute Testing", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/ingress/sanity.go b/test/e2e/suite-ingress/sanity.go
similarity index 99%
rename from test/e2e/ingress/sanity.go
rename to test/e2e/suite-ingress/sanity.go
index 05bef74b..06340bab 100644
--- a/test/e2e/ingress/sanity.go
+++ b/test/e2e/suite-ingress/sanity.go
@@ -30,7 +30,7 @@ type ip struct {
 	IP string `json:"origin"`
 }
 
-var _ = ginkgo.Describe("single-route", func() {
+var _ = ginkgo.Describe("suite-ingress: single-route", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/ingress/secret.go b/test/e2e/suite-ingress/secret.go
similarity index 99%
rename from test/e2e/ingress/secret.go
rename to test/e2e/suite-ingress/secret.go
index cbea8122..41ad8428 100644
--- a/test/e2e/ingress/secret.go
+++ b/test/e2e/suite-ingress/secret.go
@@ -27,7 +27,7 @@ import (
 )
 
 // TODO: FIXME
-var _ = ginkgo.Describe("secret Testing", func() {
+var _ = ginkgo.Describe("suite-ingress: secret Testing", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/ingress/ssl.go b/test/e2e/suite-ingress/ssl.go
similarity index 99%
rename from test/e2e/ingress/ssl.go
rename to test/e2e/suite-ingress/ssl.go
index e3f8d4f1..52fe57c4 100644
--- a/test/e2e/ingress/ssl.go
+++ b/test/e2e/suite-ingress/ssl.go
@@ -28,7 +28,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("SSL Testing", func() {
+var _ = ginkgo.Describe("suite-ingress: SSL Testing", func() {
 	s := scaffold.NewDefaultScaffold()
 	ginkgo.It("create a SSL from ApisixTls ", func() {
 		secretName := "test-apisix-tls"
diff --git a/test/e2e/ingress/status.go b/test/e2e/suite-ingress/status.go
similarity index 98%
rename from test/e2e/ingress/status.go
rename to test/e2e/suite-ingress/status.go
index 75513470..c9c81f0f 100644
--- a/test/e2e/ingress/status.go
+++ b/test/e2e/suite-ingress/status.go
@@ -27,7 +27,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("Status subresource Testing", func() {
+var _ = ginkgo.Describe("suite-ingress: Status subresource Testing", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/ingress/stream.go b/test/e2e/suite-ingress/stream.go
similarity index 97%
rename from test/e2e/ingress/stream.go
rename to test/e2e/suite-ingress/stream.go
index b4e330ba..9d6d0020 100644
--- a/test/e2e/ingress/stream.go
+++ b/test/e2e/suite-ingress/stream.go
@@ -26,7 +26,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("ApisixRoute stream Testing with v2beta2", func() {
+var _ = ginkgo.Describe("suite-ingress: ApisixRoute stream Testing with v2beta2", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/ingress/upstream_tls.go b/test/e2e/suite-ingress/upstream_tls.go
similarity index 96%
rename from test/e2e/ingress/upstream_tls.go
rename to test/e2e/suite-ingress/upstream_tls.go
index e54c79ce..b0fa97b2 100644
--- a/test/e2e/ingress/upstream_tls.go
+++ b/test/e2e/suite-ingress/upstream_tls.go
@@ -28,7 +28,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/testbackend/client"
 )
 
-var _ = ginkgo.Describe("ApisixUpstreams mTLS test", func() {
+var _ = ginkgo.Describe("suite-ingress: ApisixUpstreams mTLS test", func() {
 	clientSecret := `client-secret`
 
 	f, err := ioutil.ReadFile("testbackend/tls/client.pem")
@@ -41,7 +41,7 @@ var _ = ginkgo.Describe("ApisixUpstreams mTLS test", func() {
 
 	s := scaffold.NewDefaultV2Scaffold()
 	ginkgo.It("create ApisixUpstreams with http mTLS", func() {
-		//create client secret
+		// create client secret
 		err := s.NewSecret(clientSecret, clientCert, clientKey)
 		assert.NoError(ginkgo.GinkgoT(), err, "create client cert secret")
 
@@ -79,7 +79,7 @@ spec:
 	})
 
 	ginkgo.It("create ApisixUpstreams with grpc mTLS", func() {
-		//create grpc secret for apisix grpc route
+		// create grpc secret for apisix grpc route
 		grpcSecret := `grpc-secret`
 		f, err := ioutil.ReadFile("testbackend/tls/server.pem")
 		assert.NoError(ginkgo.GinkgoT(), err, "read server cert")
@@ -92,7 +92,7 @@ spec:
 		err = s.NewSecret(grpcSecret, serverCert, serverKey)
 		assert.NoError(ginkgo.GinkgoT(), err, "create server cert secret")
 
-		//create client secret
+		// create client secret
 		err = s.NewSecret(clientSecret, clientCert, clientKey)
 		assert.NoError(ginkgo.GinkgoT(), err, "create client cert secret")
 
diff --git a/test/e2e/ingress/webhook.go b/test/e2e/suite-ingress/webhook.go
similarity index 97%
rename from test/e2e/ingress/webhook.go
rename to test/e2e/suite-ingress/webhook.go
index 23acc58b..fd92b991 100644
--- a/test/e2e/ingress/webhook.go
+++ b/test/e2e/suite-ingress/webhook.go
@@ -24,7 +24,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("Enable webhooks", func() {
+var _ = ginkgo.Describe("suite-ingress: Enable webhooks", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/plugins/api_breaker.go b/test/e2e/suite-plugins/api_breaker.go
similarity index 98%
rename from test/e2e/plugins/api_breaker.go
rename to test/e2e/suite-plugins/api_breaker.go
index d0efa5ee..03a305e1 100644
--- a/test/e2e/plugins/api_breaker.go
+++ b/test/e2e/suite-plugins/api_breaker.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("api-breaker plugin", func() {
+var _ = ginkgo.Describe("suite-plugins: api-breaker plugin", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/plugins/cors.go b/test/e2e/suite-plugins/cors.go
similarity index 97%
rename from test/e2e/plugins/cors.go
rename to test/e2e/suite-plugins/cors.go
index f40ea602..4a35bcb9 100644
--- a/test/e2e/plugins/cors.go
+++ b/test/e2e/suite-plugins/cors.go
@@ -24,7 +24,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("fault-injection plugin", func() {
+var _ = ginkgo.Describe("suite-plugins: fault-injection plugin", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
@@ -132,7 +132,7 @@ spec:
 		resp.Header("Access-Control-Expose-Headers").Empty()
 		resp.Header("Access-Control-Max-Age").Empty()
 		// httpbin set it by itself.
-		//resp.Header("Access-Control-Allow-Credentials").Empty()
+		// resp.Header("Access-Control-Allow-Credentials").Empty()
 		resp.Body().Contains("origin")
 	})
 	ginkgo.It("allow_origins_by_regex", func() {
@@ -208,7 +208,7 @@ spec:
 		resp.Header("Access-Control-Expose-Headers").Empty()
 		resp.Header("Access-Control-Max-Age").Empty()
 		// httpbin set it by itself.
-		//resp.Header("Access-Control-Allow-Credentials").Empty()
+		// resp.Header("Access-Control-Allow-Credentials").Empty()
 		resp.Body().Contains("origin")
 	})
 	ginkgo.It("disable plugin", func() {
@@ -244,7 +244,7 @@ spec:
 		resp := s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").Expect()
 		resp.Status(http.StatusOK)
 		// httpbin sets this header by itself.
-		//resp.Header("Access-Control-Allow-Origin").Empty()
+		// resp.Header("Access-Control-Allow-Origin").Empty()
 		resp.Header("Access-Control-Allow-Methods").Empty()
 		resp.Header("Access-Control-Allow-Headers").Empty()
 		resp.Header("Access-Control-Expose-Headers").Empty()
@@ -320,7 +320,7 @@ spec:
 		resp.Status(http.StatusOK)
 
 		// httpbin sets this header by itself.
-		//resp.Header("Access-Control-Allow-Origin").Empty()
+		// resp.Header("Access-Control-Allow-Origin").Empty()
 		resp.Header("Access-Control-Allow-Methods").Empty()
 		resp.Header("Access-Control-Allow-Headers").Empty()
 		resp.Header("Access-Control-Expose-Headers").Empty()
diff --git a/test/e2e/plugins/echo.go b/test/e2e/suite-plugins/echo.go
similarity index 98%
rename from test/e2e/plugins/echo.go
rename to test/e2e/suite-plugins/echo.go
index 3f795256..b20fc832 100644
--- a/test/e2e/plugins/echo.go
+++ b/test/e2e/suite-plugins/echo.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("echo plugin", func() {
+var _ = ginkgo.Describe("suite-plugins: echo plugin", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/plugins/fault_injection.go b/test/e2e/suite-plugins/fault_injection.go
similarity index 98%
rename from test/e2e/plugins/fault_injection.go
rename to test/e2e/suite-plugins/fault_injection.go
index fbaa306e..d601aa80 100644
--- a/test/e2e/plugins/fault_injection.go
+++ b/test/e2e/suite-plugins/fault_injection.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("fault-injection plugin", func() {
+var _ = ginkgo.Describe("suite-plugins: fault-injection plugin", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/plugins/ip-restriction.go b/test/e2e/suite-plugins/ip-restriction.go
similarity index 98%
rename from test/e2e/plugins/ip-restriction.go
rename to test/e2e/suite-plugins/ip-restriction.go
index 982b2fd1..9794b347 100644
--- a/test/e2e/plugins/ip-restriction.go
+++ b/test/e2e/suite-plugins/ip-restriction.go
@@ -23,7 +23,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("ip-restriction plugin", func() {
+var _ = ginkgo.Describe("suite-plugins: ip-restriction plugin", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/plugins/limit_count.go b/test/e2e/suite-plugins/limit_count.go
similarity index 98%
rename from test/e2e/plugins/limit_count.go
rename to test/e2e/suite-plugins/limit_count.go
index e9cec362..2594cd27 100644
--- a/test/e2e/plugins/limit_count.go
+++ b/test/e2e/suite-plugins/limit_count.go
@@ -24,7 +24,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("limit-count plugin", func() {
+var _ = ginkgo.Describe("suite-plugins: limit-count plugin", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/plugins/plugin_config.go b/test/e2e/suite-plugins/plugin_config.go
similarity index 98%
rename from test/e2e/plugins/plugin_config.go
rename to test/e2e/suite-plugins/plugin_config.go
index 9b4ae47a..c54b7fa8 100644
--- a/test/e2e/plugins/plugin_config.go
+++ b/test/e2e/suite-plugins/plugin_config.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("ApisixPluginConfig", func() {
+var _ = ginkgo.Describe("suite-plugins: ApisixPluginConfig", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
@@ -405,7 +405,7 @@ spec:
 		resp.Header("Access-Control-Expose-Headers").Empty()
 		resp.Header("Access-Control-Max-Age").Empty()
 		// httpbin set it by itself.
-		//resp.Header("Access-Control-Allow-Credentials").Empty()
+		// resp.Header("Access-Control-Allow-Credentials").Empty()
 		resp.Body().Contains("origin")
 	})
 
@@ -453,7 +453,7 @@ spec:
 		resp := s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").Expect()
 		resp.Status(http.StatusOK)
 		// httpbin sets this header by itself.
-		//resp.Header("Access-Control-Allow-Origin").Empty()
+		// resp.Header("Access-Control-Allow-Origin").Empty()
 		resp.Header("Access-Control-Allow-Methods").Empty()
 		resp.Header("Access-Control-Allow-Headers").Empty()
 		resp.Header("Access-Control-Expose-Headers").Empty()
@@ -536,7 +536,7 @@ spec:
 		resp.Status(http.StatusOK)
 
 		// httpbin sets this header by itself.
-		//resp.Header("Access-Control-Allow-Origin").Empty()
+		// resp.Header("Access-Control-Allow-Origin").Empty()
 		resp.Header("Access-Control-Allow-Methods").Empty()
 		resp.Header("Access-Control-Allow-Headers").Empty()
 		resp.Header("Access-Control-Expose-Headers").Empty()
diff --git a/test/e2e/plugins/proxy_rewrite.go b/test/e2e/suite-plugins/proxy_rewrite.go
similarity index 98%
rename from test/e2e/plugins/proxy_rewrite.go
rename to test/e2e/suite-plugins/proxy_rewrite.go
index 44135945..16380ae3 100644
--- a/test/e2e/plugins/proxy_rewrite.go
+++ b/test/e2e/suite-plugins/proxy_rewrite.go
@@ -24,7 +24,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("proxy-rewrite plugin", func() {
+var _ = ginkgo.Describe("suite-plugins: proxy-rewrite plugin", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/plugins/redirect.go b/test/e2e/suite-plugins/redirect.go
similarity index 98%
rename from test/e2e/plugins/redirect.go
rename to test/e2e/suite-plugins/redirect.go
index cc3de096..028fa14b 100644
--- a/test/e2e/plugins/redirect.go
+++ b/test/e2e/suite-plugins/redirect.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("redirect plugin", func() {
+var _ = ginkgo.Describe("suite-plugins: redirect plugin", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/plugins/referer-restriction.go b/test/e2e/suite-plugins/referer-restriction.go
similarity index 98%
rename from test/e2e/plugins/referer-restriction.go
rename to test/e2e/suite-plugins/referer-restriction.go
index 932b1c6f..91297973 100644
--- a/test/e2e/plugins/referer-restriction.go
+++ b/test/e2e/suite-plugins/referer-restriction.go
@@ -24,7 +24,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("referer-restriction plugin", func() {
+var _ = ginkgo.Describe("suite-plugins: referer-restriction plugin", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/plugins/request-validation.go b/test/e2e/suite-plugins/request-validation.go
similarity index 98%
rename from test/e2e/plugins/request-validation.go
rename to test/e2e/suite-plugins/request-validation.go
index 7a27b2e1..bc37eadf 100644
--- a/test/e2e/plugins/request-validation.go
+++ b/test/e2e/suite-plugins/request-validation.go
@@ -23,7 +23,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("redirect plugin", func() {
+var _ = ginkgo.Describe("suite-plugins: redirect plugin", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/plugins/request_id.go b/test/e2e/suite-plugins/request_id.go
similarity index 98%
rename from test/e2e/plugins/request_id.go
rename to test/e2e/suite-plugins/request_id.go
index e8d82b27..6ecff96d 100644
--- a/test/e2e/plugins/request_id.go
+++ b/test/e2e/suite-plugins/request_id.go
@@ -24,7 +24,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("request-id plugin", func() {
+var _ = ginkgo.Describe("suite-plugins: request-id plugin", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/plugins/response_rewrite.go b/test/e2e/suite-plugins/response_rewrite.go
similarity index 98%
rename from test/e2e/plugins/response_rewrite.go
rename to test/e2e/suite-plugins/response_rewrite.go
index 240d0200..8ea68359 100644
--- a/test/e2e/plugins/response_rewrite.go
+++ b/test/e2e/suite-plugins/response_rewrite.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("response rewrite plugin", func() {
+var _ = ginkgo.Describe("suite-plugins: response rewrite plugin", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/plugins/server-info.go b/test/e2e/suite-plugins/server-info.go
similarity index 96%
rename from test/e2e/plugins/server-info.go
rename to test/e2e/suite-plugins/server-info.go
index 218f03b3..ffc0ee98 100644
--- a/test/e2e/plugins/server-info.go
+++ b/test/e2e/suite-plugins/server-info.go
@@ -21,7 +21,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("server-info plugin", func() {
+var _ = ginkgo.Describe("suite-plugins: server-info plugin", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),
diff --git a/test/e2e/plugins/uri_blocker.go b/test/e2e/suite-plugins/uri_blocker.go
similarity index 98%
rename from test/e2e/plugins/uri_blocker.go
rename to test/e2e/suite-plugins/uri_blocker.go
index d7955009..71542b9e 100644
--- a/test/e2e/plugins/uri_blocker.go
+++ b/test/e2e/suite-plugins/uri_blocker.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
 )
 
-var _ = ginkgo.Describe("uri-blocker plugin", func() {
+var _ = ginkgo.Describe("suite-plugins: uri-blocker plugin", func() {
 	opts := &scaffold.Options{
 		Name:                  "default",
 		Kubeconfig:            scaffold.GetKubeconfig(),