Skip to content

CORENET-6822: OTE framework for Ingress Node Firewall with LEVEL0 test case#694

Open
anuragthehatter wants to merge 2 commits into
openshift:masterfrom
anuragthehatter:infw_ote
Open

CORENET-6822: OTE framework for Ingress Node Firewall with LEVEL0 test case#694
anuragthehatter wants to merge 2 commits into
openshift:masterfrom
anuragthehatter:infw_ote

Conversation

@anuragthehatter

@anuragthehatter anuragthehatter commented Jan 25, 2026

Copy link
Copy Markdown

Summary

  • Add OpenShift Tests Extension (OTE) framework for ingress-node-firewall
  • Migrate LEVEL0 test case (61481 - Operator Installation) with [OTP][LEVEL0] tag and LifecycleBlocking
  • Registration of binary in origin (per origin PR #31245)
  • Build test binary in Dockerfile.openshift (gzipped to /usr/bin/ingress-node-firewall-tests.gz)
  • No vendor files included — go mod vendor runs in Dockerfile before test binary build

Files Changed

  • test/cmd/main.go — OTE entry point with 4 suites (parallel, serial, slow, all), LifecycleBlocking for all specs
  • test/e2e/operator/operator.go — LEVEL0 test: validates operator namespace, CRDs, and deployment readiness
  • test/e2e/cli.go / test/e2e/util.go — OC client helper and utilities
  • test/Makefile — Builds ingress-node-firewall-tests binary
  • Makefile — Adds build-e2e-tests target delegating to test/Makefile
  • Dockerfile.openshift — Builds and gzips test binary into the operator image
  • manifests/stable/image-references — Adds testextension.redhat.io/component and testextension.redhat.io/binary annotations for non-payload OTE discovery
  • go.mod / go.sum — OTE and ginkgo dependencies

Next Steps

  • Create ImageStream to define the location of the binary
  • CI workflow that wants to test the operator should add a step to deploy the operator in day2
  • When the operator is set up, the ImageStream is created and discovered via non-payload extension mechanism

Test Plan

  • Build test binary locally and run against cluster with operator installed
  • Verify non-payload discovery picks up the annotated ImageStreamTag
  • CI e2e job passes with operator deployed

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added extended end-to-end test suite for the ingress-node-firewall operator to validate deployment and CRD availability
  • Tests

    • Implemented operator verification tests and test artifact integration into runtime image
    • Added test build and cleanup infrastructure

@openshift-ci openshift-ci Bot requested review from abhat and jcaamano January 25, 2026 02:47
@openshift-ci

openshift-ci Bot commented Jan 25, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: anuragthehatter
Once this PR has been reviewed and has the lgtm label, please assign tssurya for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@anuragthehatter

Copy link
Copy Markdown
Author

cc @zhaozhanqi @asood-rh

@coderabbitai

coderabbitai Bot commented Jan 25, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds OpenShift extended e2e tests: dependency pins in go.mod, a test build system and Makefile targets, Dockerfile packaging of the gzipped test binary, a Cobra-based OTE test entrypoint, OCClient and kubeconfig utilities, and an initial Ginkgo operator installation test.

Changes

Extended tests (OTE) integration

Layer / File(s) Summary
Go module dependency pins
go.mod
Adds direct OTE/testing deps and wide indirect deps; introduces replace block rewriting ginkgo to an OpenShift fork and pins k8s.io/* modules to v0.32.3.
Test build Makefile & targets
test/Makefile, Makefile
New test/Makefile with version ldflags and build-e2e-tests/clean/help targets; top-level Makefile adds .PHONY build-e2e-tests and clean-e2e-tests that delegate to test/.
Dockerfile: build and package test binary
Dockerfile.openshift
Builder stage copies test/, runs go mod vendor, runs make -C test build-e2e-tests, gzips ingress-node-firewall-tests, and final image copies ingress-node-firewall-tests.gz into /usr/bin/.
OTE test registry entrypoint
test/cmd/main.go
Cobra root ingress-node-firewall-tests registers an OTE extension and builds/attaches Ginkgo suites and specs to the registry.
E2E utilities and OC client
test/e2e/util.go, test/e2e/cli.go
Adds GetKubeconfig() and OCClient with NewOCClient, Run, and Get for invoking oc with kubeconfig handling.
Operator installation e2e test
test/e2e/operator/operator.go
Ginkgo test that checks operator namespace, validates three CRDs, lists deployments, and waits for ingress-node-firewall-controller-manager to become Available.
ImageStream annotations
manifests/stable/image-references
Adds testextension.redhat.io/component and testextension.redhat.io/binary annotations pointing to the packaged test binary path.

Sequence Diagram

sequenceDiagram
  participant DockerBuilder
  participant MakeTest
  participant GoCompiler
  participant gzip
  participant RuntimeImage
  DockerBuilder->>MakeTest: build e2e tests
  MakeTest->>GoCompiler: compile main.go
  GoCompiler->>gzip: gzip binary
  DockerBuilder->>RuntimeImage: copy gzipped binary to /usr/bin/
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error test/e2e/cli.go includes raw stderr in error messages via fmt.Errorf (line 37), which could expose sensitive Kubernetes API errors or internal configuration details. Sanitize or omit stderr output in error messages. Only include essential error summaries without raw command output.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (13 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding an OpenShift Tests Extension (OTE) framework for Ingress Node Firewall with a LEVEL0 test case, which aligns with all the significant files changed (test entrypoint, e2e tests, Makefile, Dockerfile updates, and image references).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed All Ginkgo test titles are stable and deterministic. The Describe and It blocks use static strings with no dynamic content, fmt.Sprintf, concatenation, or variable substitution.
Test Structure And Quality ✅ Passed Test code meets quality requirements: single responsibility, proper setup/cleanup, appropriate timeouts (10m context + 5m wait), and meaningful assertion messages. Follows existing patterns.
Microshift Test Compatibility ✅ Passed New test uses only Kubernetes native APIs (namespace, crd, deployment) and operator's custom API group. No restricted OpenShift APIs or MicroShift-incompatible patterns detected.
Single Node Openshift (Sno) Test Compatibility ✅ Passed Test checks operator namespace existence, CRDs, and deployment readiness—no multi-node, anti-affinity, or node-scaling assumptions that would break SNO compatibility.
Topology-Aware Scheduling Compatibility ✅ Passed PR adds test infrastructure only; does not modify operator deployments or introduce scheduling constraints that affect topology compatibility.
Ote Binary Stdout Contract ✅ Passed Main binary writes errors to os.Stderr via fmt.Fprintf(os.Stderr,...). The fmt.Println in test code is inside an It() block, which is exempted. No klog or process-level stdout writes.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed New test (test/e2e/operator/operator.go) has no IPv4 assumptions or external connectivity; uses only cluster-internal API queries and string matching.
No-Weak-Crypto ✅ Passed No weak cryptography detected. Added code does not use MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB mode, custom crypto implementations, or non-constant-time secret comparisons.
Container-Privileges ✅ Passed PR adds test framework files without introducing container privilege escalations: no privileged: true, hostPID, hostNetwork, hostIPC, SYS_ADMIN, or allowPrivilegeEscalation: true settings.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@test/e2e/operator/operator.go`:
- Around line 15-16: The defer g.GinkgoRecover() call is misplaced inside the
g.Describe callback; remove it from the Describe block and either delete it
entirely or relocate it to the setup of any goroutine-starting tests (e.g.,
inside BeforeEach/It where goroutines are spawned) so that GinkgoRecover() is
deferred in the same function that starts those goroutines; search for
g.Describe and GinkgoRecover to find and update the placement accordingly.

In `@test/e2e/util.go`:
- Around line 91-92: Check for nil before dereferencing
deployment.Spec.Replicas: compute an int32 desiredReplicas := int32(1) and if
deployment.Spec.Replicas != nil set desiredReplicas = *deployment.Spec.Replicas,
then compare deployment.Status.ReadyReplicas == desiredReplicas &&
deployment.Status.UpdatedReplicas == desiredReplicas instead of directly
dereferencing deployment.Spec.Replicas; update the conditional that currently
uses deployment.Spec.Replicas to use this safe desiredReplicas value.
- Around line 52-59: CreateNamespace currently fails if the namespace already
exists; update CreateNamespace to call client.CoreV1().Namespaces().Create and,
if it returns an error, check kubernetes API error using
apierrors.IsAlreadyExists(err) and in that case return the existing namespace
via client.CoreV1().Namespaces().Get(ctx, name, metav1.GetOptions{}) with a nil
error; otherwise propagate the original error. Use the apierrors.IsAlreadyExists
helper and the CreateNamespace function name to locate where to add this
handling.
🧹 Nitpick comments (4)
test/e2e/util.go (1)

70-72: Consider tolerating transient errors during polling.

Returning false, err on Get failure stops polling immediately. For NotFound errors (pod not yet created), this may be premature. Consider returning false, nil for transient/expected errors to allow polling to continue.

Proposed approach
 		pod, err := client.CoreV1().Pods(namespace).Get(ctx, podName, metav1.GetOptions{})
 		if err != nil {
+			if k8serrors.IsNotFound(err) {
+				return false, nil // Pod not yet created, keep polling
+			}
 			return false, err
 		}
test/e2e/operator/operator.go (1)

55-58: Use ContainSubstring matcher directly for cleaner assertions.

More idiomatic Gomega
 		for _, crd := range expectedCRDs {
-			o.Expect(strings.Contains(crdOutput, crd)).To(o.BeTrue(),
-				"CRD %s should be installed", crd)
+			o.Expect(crdOutput).To(o.ContainSubstring(crd),
+				"CRD %s should be installed", crd)
 		}
test/extension/registry.go (1)

9-14: Consider if mutex is necessary for the current usage pattern.

The RWMutex provides thread-safety, but based on the usage in test/cmd/main.go, the registry is created and populated once during startup before any concurrent access. If concurrent registration isn't a requirement, the mutex adds unnecessary complexity. However, this is fine to keep if you anticipate future concurrent usage.

test/extension/cmd/commands.go (1)

43-50: Hardcoded test list will become stale.

The test names are hardcoded, which means this list must be manually updated whenever tests are added or removed. Consider generating this dynamically from Ginkgo's spec tree, or documenting that this list requires manual maintenance.

Comment thread test/e2e/operator/operator.go Outdated
Comment thread test/e2e/util.go Outdated
Comment on lines +52 to +59
func CreateNamespace(ctx context.Context, client kubernetes.Interface, name string) (*corev1.Namespace, error) {
ns := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
}
return client.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{})
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

CreateNamespace should handle AlreadyExists for idempotency.

Unlike the existing namespaces.Create in test/e2e/namespaces/namespaces.go (lines 32-42), this function returns an error if the namespace already exists. This will cause test failures on reruns or when the namespace pre-exists.

Proposed fix
+import k8serrors "k8s.io/apimachinery/pkg/api/errors"
+
 // CreateNamespace creates a namespace with the given name
 func CreateNamespace(ctx context.Context, client kubernetes.Interface, name string) (*corev1.Namespace, error) {
 	ns := &corev1.Namespace{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: name,
 		},
 	}
-	return client.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{})
+	created, err := client.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{})
+	if k8serrors.IsAlreadyExists(err) {
+		return client.CoreV1().Namespaces().Get(ctx, name, metav1.GetOptions{})
+	}
+	return created, err
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func CreateNamespace(ctx context.Context, client kubernetes.Interface, name string) (*corev1.Namespace, error) {
ns := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
}
return client.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{})
}
func CreateNamespace(ctx context.Context, client kubernetes.Interface, name string) (*corev1.Namespace, error) {
ns := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
}
created, err := client.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{})
if k8serrors.IsAlreadyExists(err) {
return client.CoreV1().Namespaces().Get(ctx, name, metav1.GetOptions{})
}
return created, err
}
🤖 Prompt for AI Agents
In `@test/e2e/util.go` around lines 52 - 59, CreateNamespace currently fails if
the namespace already exists; update CreateNamespace to call
client.CoreV1().Namespaces().Create and, if it returns an error, check
kubernetes API error using apierrors.IsAlreadyExists(err) and in that case
return the existing namespace via client.CoreV1().Namespaces().Get(ctx, name,
metav1.GetOptions{}) with a nil error; otherwise propagate the original error.
Use the apierrors.IsAlreadyExists helper and the CreateNamespace function name
to locate where to add this handling.

Comment thread test/e2e/util.go Outdated
Comment on lines +91 to +92
if deployment.Status.ReadyReplicas == *deployment.Spec.Replicas &&
deployment.Status.UpdatedReplicas == *deployment.Spec.Replicas {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Potential nil pointer dereference on Spec.Replicas.

deployment.Spec.Replicas can be nil (defaults to 1 when unset). Dereferencing without a nil check will panic.

Proposed fix
+func int32PtrDerefOr(ptr *int32, def int32) int32 {
+	if ptr != nil {
+		return *ptr
+	}
+	return def
+}
+
 // WaitForDeploymentReady waits for a deployment to be ready
 func WaitForDeploymentReady(ctx context.Context, client kubernetes.Interface, namespace, deploymentName string) error {
 	return wait.PollUntilContextTimeout(ctx, DefaultInterval, DefaultTimeout, true, func(ctx context.Context) (bool, error) {
 		deployment, err := client.AppsV1().Deployments(namespace).Get(ctx, deploymentName, metav1.GetOptions{})
 		if err != nil {
 			return false, err
 		}
 
-		if deployment.Status.ReadyReplicas == *deployment.Spec.Replicas &&
-			deployment.Status.UpdatedReplicas == *deployment.Spec.Replicas {
+		replicas := int32PtrDerefOr(deployment.Spec.Replicas, 1)
+		if deployment.Status.ReadyReplicas == replicas &&
+			deployment.Status.UpdatedReplicas == replicas {
 			return true, nil
 		}
 		return false, nil
 	})
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if deployment.Status.ReadyReplicas == *deployment.Spec.Replicas &&
deployment.Status.UpdatedReplicas == *deployment.Spec.Replicas {
func int32PtrDerefOr(ptr *int32, def int32) int32 {
if ptr != nil {
return *ptr
}
return def
}
// WaitForDeploymentReady waits for a deployment to be ready
func WaitForDeploymentReady(ctx context.Context, client kubernetes.Interface, namespace, deploymentName string) error {
return wait.PollUntilContextTimeout(ctx, DefaultInterval, DefaultTimeout, true, func(ctx context.Context) (bool, error) {
deployment, err := client.AppsV1().Deployments(namespace).Get(ctx, deploymentName, metav1.GetOptions{})
if err != nil {
return false, err
}
replicas := int32PtrDerefOr(deployment.Spec.Replicas, 1)
if deployment.Status.ReadyReplicas == replicas &&
deployment.Status.UpdatedReplicas == replicas {
return true, nil
}
return false, nil
})
}
🤖 Prompt for AI Agents
In `@test/e2e/util.go` around lines 91 - 92, Check for nil before dereferencing
deployment.Spec.Replicas: compute an int32 desiredReplicas := int32(1) and if
deployment.Spec.Replicas != nil set desiredReplicas = *deployment.Spec.Replicas,
then compare deployment.Status.ReadyReplicas == desiredReplicas &&
deployment.Status.UpdatedReplicas == desiredReplicas instead of directly
dereferencing deployment.Spec.Replicas; update the conditional that currently
uses deployment.Spec.Replicas to use this safe desiredReplicas value.

@zhaozhanqi

Copy link
Copy Markdown

You are not using OTE framework ? but title named 'OTE' . and you are building the binary with owned options.

@zhaozhanqi

Copy link
Copy Markdown

Could you make the go vendor and go.sum .etc in one separate commit thus we can review others changes easily? thanks

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@go.mod`:
- Line 94: Upgrade the indirect dependency golang.org/x/oauth2 in go.mod from
v0.25.0 to v0.27.0 (or newer) to remediate CVE-2025-22868; update the version
string for golang.org/x/oauth2, run go mod tidy to refresh go.sum, and re-run
your build/tests to ensure no dependency breakage (look for the
golang.org/x/oauth2 entry in go.mod and the resulting changes in go.sum).
🧹 Nitpick comments (2)
test/e2e/cli.go (1)

49-57: Consider adding --ignore-not-found flag for cleanup resilience.

The Delete method may fail if the resource doesn't exist, which can cause issues during test cleanup or idempotent operations.

♻️ Proposed enhancement
 // Delete deletes a resource
-func (c *OCClient) Delete(ctx context.Context, resourceType, name, namespace string) error {
-	args := []string{"delete", resourceType, name}
+func (c *OCClient) Delete(ctx context.Context, resourceType, name, namespace string, ignoreNotFound bool) error {
+	args := []string{"delete", resourceType, name}
+	if ignoreNotFound {
+		args = append(args, "--ignore-not-found")
+	}
 	if namespace != "" {
 		args = append(args, "-n", namespace)
 	}
test/e2e/operator/operator.go (1)

71-72: Use g.By() or GinkgoWriter instead of fmt.Println.

fmt.Println output may not be captured properly by Ginkgo's test output handling. For consistency with the rest of the test, use g.By() for step logging.

♻️ Proposed fix
 		g.By("SUCCESS - Ingress Node Firewall operator and CRDs installed")
-		fmt.Println("Operator install and CRDs check successful!")

The g.By() call on line 71 already logs the success message, making the fmt.Println redundant.

Comment thread go.mod Outdated
@anuragthehatter

anuragthehatter commented Jan 26, 2026

Copy link
Copy Markdown
Author

You are not using OTE framework ? but title named 'OTE' . and you are building the binary with owned options.

You're right. This is fixed. Thanks for reviewing that. Re-ran the usecase. It was an experiment and seems like real cimmit was missed :(

$ ./test/bin/ingress-node-firewall-tests run-test -n "[sig-network] INFW Author:anusaxen-High-61481-[LEVEL0][OTP]-StagerunBoth-Ingress Node Firewall Operator Installation [apigroup:ingressnodefirewall.openshift.io]"                                                                           
 
  Running Suite:  - /home/anusaxen/git/ingress-node-firewall
  ==========================================================
  Random Seed: 1769462563 - will randomize all specs

  Will run 1 of 1 specs
  ------------------------------
  [sig-network] INFW Author:anusaxen-High-61481-[LEVEL0][OTP]-StagerunBoth-Ingress Node Firewall Operator Installation [apigroup:ingressnodefirewall.openshift.io]
  /home/anusaxen/git/ingress-node-firewall/test/e2e/operator/operator.go:37
    STEP: Checking Ingress Node Firewall operator installation @ 01/26/26 16:22:43.688
    STEP: Verifying CRDs are installed @ 01/26/26 16:22:44.008
    STEP: Verifying operator deployment is running @ 01/26/26 16:22:44.341
    STEP: SUCCESS - Ingress Node Firewall operator and CRDs installed @ 01/26/26 16:22:44.977
Operator install and CRDs check successful!
  • [1.290 seconds]
  ------------------------------

  Ran 1 of 1 Specs in 1.290 seconds
  SUCCESS! -- 1 Passed | 0 Failed | 0 Pending | 0 Skipped
[

Comment thread test/e2e/operator/operator.go Outdated
Comment thread test/e2e/cli.go Outdated
Comment thread test/e2e/cli.go Outdated
Comment thread test/e2e/util.go Outdated
Comment thread test/e2e/util.go Outdated
Comment thread test/e2e/util.go Outdated
Comment thread test/e2e/util.go Outdated
Comment thread test/e2e/util.go Outdated
Comment thread test/e2e/util.go Outdated
Comment thread test/e2e/util.go Outdated
Comment thread test/e2e/util.go Outdated
Comment thread test/e2e/util.go Outdated
@anuragthehatter anuragthehatter changed the title OTE framework for Ingress Node Firewall and migrating a LEVEL0 usecase WIP: OTE framework for Ingress Node Firewall and migrating a LEVEL0 usecase Jan 29, 2026
@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jan 29, 2026
@openshift-bot

Copy link
Copy Markdown

Issues go stale after 90d of inactivity.

Mark the issue as fresh by commenting /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.
Exclude this issue from closing by commenting /lifecycle frozen.

If this issue is safe to close now please do so with /close.

/lifecycle stale

@openshift-ci openshift-ci Bot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label May 5, 2026
@anuragthehatter

Copy link
Copy Markdown
Author

/remove-lifecycle stale

@openshift-ci openshift-ci Bot removed the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Jun 1, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/Makefile (1)

34-37: 💤 Low value

Consider building the package (./cmd) instead of a single file.

go build ... ./cmd/main.go only compiles that one file; if a second file is later added to cmd, the build breaks confusingly. Building the package is more robust.

♻️ Proposed change
 	CGO_ENABLED=0 GO_COMPLIANCE_POLICY="exempt_all" $(GO) build \
 		-a -mod=mod \
 		-ldflags "$(LDFLAGS)" \
-		-o $(BINARY_PATH) ./cmd/main.go
+		-o $(BINARY_PATH) ./cmd
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/Makefile` around lines 34 - 37, The Makefile currently invokes go build
on the single file "./cmd/main.go" which will break if additional files are
added; change the build invocation in the target that sets
CGO_ENABLED/GO_COMPLIANCE_POLICY/$(GO) to build the package path "./cmd" instead
of the single file. Locate the rule containing the variables CGO_ENABLED,
GO_COMPLIANCE_POLICY, $(GO) build and the -o $(BINARY_PATH) invocation and
replace "./cmd/main.go" with "./cmd" so the package is compiled as a whole.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/Makefile`:
- Around line 23-37: The Makefile is injecting linker -X values for
github.com/openshift/ingress-node-firewall/test/version.{Version,GitCommit,BuildDate}
but there is no package test/version with exported Version/GitCommit/BuildDate
variables to receive them; add a new package "test/version" that declares
exported string vars Version, GitCommit, BuildDate (or update the LDFLAGS to
point at an existing package) so the values passed by the LDFLAGS in the
build-e2e-tests target actually get embedded into the binary; ensure the package
path and symbol names exactly match the -X flags used in LDFLAGS.

---

Nitpick comments:
In `@test/Makefile`:
- Around line 34-37: The Makefile currently invokes go build on the single file
"./cmd/main.go" which will break if additional files are added; change the build
invocation in the target that sets CGO_ENABLED/GO_COMPLIANCE_POLICY/$(GO) to
build the package path "./cmd" instead of the single file. Locate the rule
containing the variables CGO_ENABLED, GO_COMPLIANCE_POLICY, $(GO) build and the
-o $(BINARY_PATH) invocation and replace "./cmd/main.go" with "./cmd" so the
package is compiled as a whole.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 9a7431ad-96b9-492f-a937-9ff2c3ae623a

📥 Commits

Reviewing files that changed from the base of the PR and between 50de070 and 725dcc3.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (8)
  • Dockerfile.openshift
  • Makefile
  • go.mod
  • test/Makefile
  • test/cmd/main.go
  • test/e2e/cli.go
  • test/e2e/operator/operator.go
  • test/e2e/util.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • test/e2e/operator/operator.go
  • Dockerfile.openshift
  • go.mod

Comment thread test/Makefile
Comment on lines +23 to +37
LDFLAGS += -X github.com/openshift/ingress-node-firewall/test/version.Version=$(VERSION)
LDFLAGS += -X github.com/openshift/ingress-node-firewall/test/version.GitCommit=$(GIT_COMMIT)
LDFLAGS += -X github.com/openshift/ingress-node-firewall/test/version.BuildDate=$(BUILD_DATE)

.PHONY: all
all: build-e2e-tests

.PHONY: build-e2e-tests
build-e2e-tests: ## Build the extended e2e test binary (static, ART compliant)
@echo "Building $(BINARY_NAME)..."
@mkdir -p $(BUILD_DIR)
CGO_ENABLED=0 GO_COMPLIANCE_POLICY="exempt_all" $(GO) build \
-a -mod=mod \
-ldflags "$(LDFLAGS)" \
-o $(BINARY_PATH) ./cmd/main.go

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Locate the version package and confirm the three exported vars exist.
fd -t f -e go . test/version 2>/dev/null
rg -nP '\b(Version|GitCommit|BuildDate)\b\s*(=|string)' -g '*.go' test/version 2>/dev/null || \
  echo "test/version package or vars not found"

Repository: openshift/ingress-node-firewall

Length of output: 114


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== test/version directory listing (if present) =="
ls -la test/version 2>/dev/null || echo "test/version directory not found"

echo
echo "== Go files under test/version =="
fd -t f -e go test/version 2>/dev/null || true

echo
echo "== Find package version declarations under test/ =="
rg -n --hidden --no-ignore '^\s*package\s+version\s*$' -g '*.go' test 2>/dev/null || echo "No 'package version' found under test/"

echo
echo "== Find exported vars/constants for Version/GitCommit/BuildDate =="
rg -n --hidden --no-ignore '^(export\s+)?(var|const)\s+(Version|GitCommit|BuildDate)\b' -g '*.go' test 2>/dev/null || echo "No exported Version/GitCommit/BuildDate declarations found under test/"

echo
echo "== Locate references to github.com/openshift/ingress-node-firewall/test/version =="
rg -n 'github\.com/openshift/ingress-node-firewall/test/version' -S -g '*.go' . 2>/dev/null || echo "No references found"

Repository: openshift/ingress-node-firewall

Length of output: 528


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Search for -X injections (LDFLAGS) =="

rg -n --hidden --no-ignore 'LDFLAGS\s*\+?=' -g 'Makefile' . || true
rg -n --hidden --no-ignore '-X\s+github\.com/openshift/ingress-node-firewall/[^ ]+' -g 'Makefile' . || true
rg -n --hidden --no-ignore '-X\s+github\.com/openshift/ingress-node-firewall/test/version' -S -g 'Makefile' . || true

echo
echo "== Search for exported identifiers =="

rg -n --hidden --no-ignore '\b(GitCommit|BuildDate|Version)\b' -S -g '*.go' . || true

echo
echo "== Find any version packages under test/ =="

fd -t d test -a 2>/dev/null | rg '(^|/)version$' || true
fd -t d -a . 2>/dev/null | rg '(^|/)test/version$|(^|/)version$' || true

echo
echo "== Search for package name 'version' anywhere =="

rg -n --hidden --no-ignore '^\s*package\s+version\s*$' -g '*.go' . || true

Repository: openshift/ingress-node-firewall

Length of output: 51216


Fix linker -X version injection: test/version package is missing

  • test/version (and any package version under test/) doesn’t exist, and there are no exported Version, GitCommit, or BuildDate vars to receive the linker values.
  • The -X github.com/openshift/ingress-node-firewall/test/version.{Version,GitCommit,BuildDate}=... flags in test/Makefile will therefore be silently ignored, so the e2e test binary won’t embed version info.
🧰 Tools
🪛 checkmake (0.3.2)

[warning] 31-31: Target body for "build-e2e-tests" exceeds allowed length of 5 lines (7).

(maxbodylength)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/Makefile` around lines 23 - 37, The Makefile is injecting linker -X
values for
github.com/openshift/ingress-node-firewall/test/version.{Version,GitCommit,BuildDate}
but there is no package test/version with exported Version/GitCommit/BuildDate
variables to receive them; add a new package "test/version" that declares
exported string vars Version, GitCommit, BuildDate (or update the LDFLAGS to
point at an existing package) so the values passed by the LDFLAGS in the
build-e2e-tests target actually get embedded into the binary; ensure the package
path and symbol names exactly match the -X flags used in LDFLAGS.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
test/e2e/operator/operator.go (2)

52-55: ⚡ Quick win

Prefer o.ContainSubstring over strings.Contains + BeTrue for better failure output.

BeTrue() produces an uninformative message (Expected <bool>: false to be true) on failure, hiding which CRD was missing and the actual output. Asserting the substring directly surfaces the diff.

♻️ Proposed refactor
 	for _, crd := range expectedCRDs {
-		o.Expect(strings.Contains(crdOutput, crd)).To(o.BeTrue(),
-			"CRD %s should be installed", crd)
+		o.Expect(crdOutput).To(o.ContainSubstring(crd),
+			"CRD %s should be installed", crd)
 	}

Note: if this is the only remaining use of strings, drop the now-unused "strings" import on Line 6.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/e2e/operator/operator.go` around lines 52 - 55, Replace the boolean
substring assertion using strings.Contains with a direct substring matcher for
clearer failure output: change the loop that uses
o.Expect(strings.Contains(crdOutput, crd)).To(o.BeTrue(), ...) to assert on
crdOutput with o.ContainSubstring(crd) (e.g.,
o.Expect(crdOutput).To(o.ContainSubstring(crd), "CRD %s should be installed",
crd)); also remove the "strings" import if it becomes unused after this change.

68-69: 💤 Low value

Drop fmt.Println in favor of Ginkgo output.

fmt.Println writes to os.Stdout instead of GinkgoWriter, so the line isn't tied to the spec in parallel/CI runs. The preceding g.By already records the success step, making this redundant.

♻️ Proposed change
 	g.By("SUCCESS - Ingress Node Firewall operator and CRDs installed")
-	fmt.Println("Operator install and CRDs check successful!")

If you remove it, also drop the now-unused "fmt" import on Line 5.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/e2e/operator/operator.go` around lines 68 - 69, Remove the redundant
fmt.Println("Operator install and CRDs check successful!") call in the test
where g.By("SUCCESS - Ingress Node Firewall operator and CRDs installed")
already records the step; this also requires removing the unused "fmt" import at
the top of the file so the build won’t complain. Locate the g.By call in
operator.go and delete the subsequent fmt.Println line, then remove the "fmt"
entry from the import block.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@go.mod`:
- Line 16: The go.mod currently requires github.com/onsi/ginkgo/v2 v2.23.3 but
then replaces it with github.com/openshift/onsi-ginkgo/v2
v2.6.1-0.20241205171354-8006f302fd12; update the module comment near the
require/replace entries to explain why the declared require differs from the
effective replace (e.g., compatibility, forked bugfixes) and ensure the replace
target is intentional, then run go mod vendor to regenerate vendor/modules.txt
so the vendored dependency graph includes the effective module
(github.com/onsi/ginkgo/v2 / github.com/openshift/onsi-ginkgo/v2) and commit the
updated vendor directory.

---

Nitpick comments:
In `@test/e2e/operator/operator.go`:
- Around line 52-55: Replace the boolean substring assertion using
strings.Contains with a direct substring matcher for clearer failure output:
change the loop that uses o.Expect(strings.Contains(crdOutput,
crd)).To(o.BeTrue(), ...) to assert on crdOutput with o.ContainSubstring(crd)
(e.g., o.Expect(crdOutput).To(o.ContainSubstring(crd), "CRD %s should be
installed", crd)); also remove the "strings" import if it becomes unused after
this change.
- Around line 68-69: Remove the redundant fmt.Println("Operator install and CRDs
check successful!") call in the test where g.By("SUCCESS - Ingress Node Firewall
operator and CRDs installed") already records the step; this also requires
removing the unused "fmt" import at the top of the file so the build won’t
complain. Locate the g.By call in operator.go and delete the subsequent
fmt.Println line, then remove the "fmt" entry from the import block.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 1c49da77-9ccf-4fb7-8442-0b0a4b906173

📥 Commits

Reviewing files that changed from the base of the PR and between 725dcc3 and 00c445d.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (9)
  • Dockerfile.openshift
  • Makefile
  • go.mod
  • manifests/stable/image-references
  • test/Makefile
  • test/cmd/main.go
  • test/e2e/cli.go
  • test/e2e/operator/operator.go
  • test/e2e/util.go
✅ Files skipped from review due to trivial changes (1)
  • manifests/stable/image-references
🚧 Files skipped from review as they are similar to previous changes (4)
  • test/e2e/util.go
  • Dockerfile.openshift
  • test/e2e/cli.go
  • test/cmd/main.go

Comment thread go.mod
@anuragthehatter anuragthehatter changed the title WIP: OTE framework for Ingress Node Firewall and migrating a LEVEL0 usecase CORENET-7206: OTE framework for Ingress Node Firewall with LEVEL0 test case Jun 1, 2026
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 1, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jun 1, 2026
@openshift-ci-robot

openshift-ci-robot commented Jun 1, 2026

Copy link
Copy Markdown

@anuragthehatter: This pull request references CORENET-7206 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Add OpenShift Tests Extension (OTE) framework for ingress-node-firewall
  • Migrate LEVEL0 test case (61481 - Operator Installation) with [OTP][LEVEL0] tag and LifecycleBlocking
  • Add non-payload extension annotations to image-references for runtime discovery via testextension.redhat.io annotations (per origin PR #30863)
  • Build test binary in Dockerfile.openshift (gzipped to /usr/bin/ingress-node-firewall-tests.gz)
  • No vendor files included — go mod vendor runs in Dockerfile before test binary build

Files Changed

  • test/cmd/main.go — OTE entry point with 4 suites (parallel, serial, slow, all), LifecycleBlocking for all specs
  • test/e2e/operator/operator.go — LEVEL0 test: validates operator namespace, CRDs, and deployment readiness
  • test/e2e/cli.go / test/e2e/util.go — OC client helper and utilities
  • test/Makefile — Builds ingress-node-firewall-tests binary
  • Makefile — Adds build-e2e-tests target delegating to test/Makefile
  • Dockerfile.openshift — Builds and gzips test binary into the operator image
  • manifests/stable/image-references — Adds testextension.redhat.io/component and testextension.redhat.io/binary annotations for non-payload OTE discovery
  • go.mod / go.sum — OTE and ginkgo dependencies

Next Steps

  • Create ImageStream to define the location of the binary
  • CI workflow that wants to test the operator should add a step to deploy the operator in day2
  • When the operator is set up, the ImageStream is created and discovered via non-payload extension mechanism

Test Plan

  • Build test binary locally and run against cluster with operator installed
  • Verify non-payload discovery picks up the annotated ImageStreamTag
  • CI e2e job passes with operator deployed

🤖 Generated with Claude Code

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@anuragthehatter anuragthehatter changed the title CORENET-7206: OTE framework for Ingress Node Firewall with LEVEL0 test case CORENET-6822: OTE framework for Ingress Node Firewall with LEVEL0 test case Jun 1, 2026
@openshift-ci-robot

openshift-ci-robot commented Jun 1, 2026

Copy link
Copy Markdown

@anuragthehatter: This pull request references CORENET-6822 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Add OpenShift Tests Extension (OTE) framework for ingress-node-firewall
  • Migrate LEVEL0 test case (61481 - Operator Installation) with [OTP][LEVEL0] tag and LifecycleBlocking
  • Add non-payload extension annotations to image-references for runtime discovery via testextension.redhat.io annotations (per origin PR #30863)
  • Build test binary in Dockerfile.openshift (gzipped to /usr/bin/ingress-node-firewall-tests.gz)
  • No vendor files included — go mod vendor runs in Dockerfile before test binary build

Files Changed

  • test/cmd/main.go — OTE entry point with 4 suites (parallel, serial, slow, all), LifecycleBlocking for all specs
  • test/e2e/operator/operator.go — LEVEL0 test: validates operator namespace, CRDs, and deployment readiness
  • test/e2e/cli.go / test/e2e/util.go — OC client helper and utilities
  • test/Makefile — Builds ingress-node-firewall-tests binary
  • Makefile — Adds build-e2e-tests target delegating to test/Makefile
  • Dockerfile.openshift — Builds and gzips test binary into the operator image
  • manifests/stable/image-references — Adds testextension.redhat.io/component and testextension.redhat.io/binary annotations for non-payload OTE discovery
  • go.mod / go.sum — OTE and ginkgo dependencies

Next Steps

  • Create ImageStream to define the location of the binary
  • CI workflow that wants to test the operator should add a step to deploy the operator in day2
  • When the operator is set up, the ImageStream is created and discovered via non-payload extension mechanism

Test Plan

  • Build test binary locally and run against cluster with operator installed
  • Verify non-payload discovery picks up the annotated ImageStreamTag
  • CI e2e job passes with operator deployed

🤖 Generated with Claude Code

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

…ss-node-firewall

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add 7 new test cases migrated from openshift-tests-private into the OTE
(OpenShift Tests Extension) framework, alongside the existing LEVEL0 test:

- 54714: TCP NodePort Allow/Deny (Baremetal, Disruptive)
- 54992: UDP NodePort Allow/Deny (Baremetal)
- 55411: ICMP Allow/Deny (single-stack only)
- 55410: SCTP Allow/Deny
- 54973: Daemon metrics verification
- 55414: Multiple CIDRs with multiple rules (single-stack only)
- 73844: SSH traffic blocking (single-stack only)

Updates suite definitions to use valid CEL qualifier syntax and adds an
AWS suite that excludes Baremetal-labeled tests. LEVEL0 tests are
LifecycleBlocking; all others are LifecycleInforming.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@openshift-ci

openshift-ci Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

@anuragthehatter: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/verify-deps e248522 link true /test verify-deps
ci/prow/ingress-node-firewall-e2e-metal-ipi e248522 link true /test ingress-node-firewall-e2e-metal-ipi
ci/prow/images e248522 link true /test images
ci/prow/ci-index e248522 link true /test ci-index
ci/prow/unit-test e248522 link true /test unit-test
ci/prow/test-fmt e248522 link true /test test-fmt

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants