-
Notifications
You must be signed in to change notification settings - Fork 366
refactor: E2E tests to support parallel tests #2501
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Another way of doing this is to create a random name generator like in this PR If this method looks better, then reviewers can suggest. |
|
Each job ran all the use cases. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors E2E tests to support parallel execution by eliminating shared resources that cause conflicts when tests run simultaneously. The changes replace static names with unique identifiers (primarily using s.Namespace()) for resources like GatewayProxy, IngressClass, Gateway, and other Kubernetes objects to ensure test isolation.
Key Changes
- Replace static resource names with unique names based on test namespace
- Update timeout values to be more resilient for parallel execution
- Mark certain tests requiring shared resources (like default IngressClass) as Serial
- Replace direct request calls with Eventually() blocks for better retry handling
Reviewed Changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| test/e2e/scaffold/assertion.go | Increase timeout and interval values for better parallel test stability |
| test/e2e/scaffold/apisix_deployer.go | Add conditional logic to skip tunnels and pod waiting when replicas is 0 |
| test/e2e/ingress/ingress.go | Convert static resource names to namespace-based unique names, mark Serial tests |
| test/e2e/gatewayapi/*.go | Update all Gateway API tests with unique resource naming and increased timeouts |
| test/e2e/crds/v2/*.go | Refactor CRD v2 tests with unique naming and improved timeout handling |
| test/e2e/crds/v1alpha1/*.go | Update CRD v1alpha1 tests for parallel execution compatibility |
| test/e2e/framework/assertion.go | Increase polling intervals and timeouts for more reliable assertions |
| Makefile | Increase E2E_NODES from 2 to 4 and add label filtering support |
| Check: scaffold.WithExpectedStatus(http.StatusOK), | ||
| Interval: time.Second * 10, | ||
| Timeout: 3 * time.Minute, | ||
| }) |
Copilot
AI
Aug 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sleep duration of 10 minutes is excessively long and will significantly slow down test execution. Consider reducing this to a more reasonable duration like 30 seconds or use Eventually() blocks instead.
| }) | |
| Eventually(func(g Gomega) { | |
| s.RequestAssert(&scaffold.RequestAssert{ | |
| Method: "GET", | |
| Path: "/get", | |
| Host: "httpbin.external", | |
| Check: scaffold.WithExpectedStatus(http.StatusOK), | |
| Interval: time.Second * 10, | |
| Timeout: 3 * time.Minute, | |
| }) | |
| }, 3*time.Minute, 10*time.Second).Should(Succeed()) |
test/e2e/ingress/ingress.go
Outdated
| Expect(). | ||
| Status(200) | ||
|
|
||
| time.Sleep(10 * time.Minute) |
Copilot
AI
Aug 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another 10-minute sleep that will make tests unnecessarily slow. This should be reduced to a reasonable duration or replaced with proper wait conditions.
| time.Sleep(10 * time.Minute) | |
| // Removed unnecessary 10-minute sleep; rely on RequestAssert for readiness |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wow I really forgot to remove this😂
test/e2e/gatewayapi/httproute.go
Outdated
| Timeout: 30 * time.Second, | ||
| }) | ||
|
|
||
| time.Sleep((8 * time.Second)) |
Copilot
AI
Aug 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary parentheses around the sleep duration expression. This should be simplified to time.Sleep(8 * time.Second).
| time.Sleep((8 * time.Second)) | |
| time.Sleep(8 * time.Second) |
test/e2e/scaffold/apisix_deployer.go
Outdated
| LabelSelector: "app.kubernetes.io/name=apisix", | ||
| }) | ||
| Expect(err).ToNot(HaveOccurred(), "waiting for gateway pod ready") | ||
| if opts.Replicas == nil || (opts.Replicas != nil && *opts.Replicas > 0) { |
Copilot
AI
Aug 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition can be simplified. Since opts.Replicas != nil is redundant when already checked with ||, this can be written as if opts.Replicas == nil || *opts.Replicas > 0 {.
| if opts.Replicas == nil || (opts.Replicas != nil && *opts.Replicas > 0) { | |
| if opts.Replicas == nil || *opts.Replicas > 0 { |
test/e2e/crds/v2/route.go
Outdated
| } | ||
|
|
||
| By("wait for route to be ready") | ||
|
|
Copilot
AI
Aug 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an empty line followed by a comment without any actual waiting logic. This appears to be incomplete - either add the waiting logic or remove the misleading comment.
| - name: Install ginkgo | ||
| run: | | ||
| GINKGO_VERSION=$(cd test/e2e && go list -m -mod=readonly -f {{.Version}} github.com/onsi/ginkgo/v2) | ||
| go install github.com/onsi/ginkgo/v2/ginkgo@$GINKGO_VERSION |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use make install-ginkgo?
| s := scaffold.NewDefaultScaffold() | ||
| var ( | ||
| s = scaffold.NewScaffold(&scaffold.Options{ | ||
| ControllerName: fmt.Sprintf("apisix.apache.org/apisix-ingress-controller-%d", time.Now().Unix()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be used as the default behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It already has default behavior:
https://github.com/apache/apisix-ingress-controller/blob/master/test/e2e/scaffold/apisix_deployer.go#L69
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
revered to defaultscaffold
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have reverted back to this behavior. I see a lot of tests fail when defaultScaffold is used. I am looking into the reason but for now I have reverted to this.
| time.Sleep(time.Second) | ||
|
|
||
| By("create Gateway") | ||
| err = s.CreateResourceFromStringWithNamespace(fmt.Sprintf(defaultGateway, gatewayName, gatewayClassName, gatewayProxyName), s.Namespace()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CreateResourceFromString uses the namespace of the current test, so there's no need to explicitly specify it for namespace-scoped resources.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only cluster level resources will use CreateResourceFromStringWithnamespace, or a fixed namespace.
test/e2e/crds/v2/config.go
Outdated
| func getGatewayProxyYaml(namespace, endpoint, adminKey string) string { | ||
| return fmt.Sprintf(gatewayProxyYaml, namespace, namespace, endpoint, adminKey) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function can be encapsulated in the Scaffold, so we don't need to manually pass many parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay
ronething
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
What this PR does / why we need it:
Currently running tests in parallel doesn't work due to conflict of Shared resources. For instance, the tests in crds/v2 share GatewayProxy and IngressClass configuration causing issues while running tests in parallel.
Goal of this PR is to eliminate the use of shared resources and use unique resources for tests.
Eventually from here and now, we need unique resource <name/namespace> for GatewayProxy, IngressClass, Gateway, GatewayClass, Ingress(similarly HTTPRoute, etc) so that parallel tests don't override each other's configuration.
In this PR, I have replaced all static names with
s.Namespace()as it already provides a unique string.Things to note before review:
Serial.Pre-submission checklist: