Skip to content

Port 5 router cookie tests from openshift-tests-private#31157

Open
dgoodwin wants to merge 3 commits into
openshift:mainfrom
dgoodwin:port-router-cookie-tests
Open

Port 5 router cookie tests from openshift-tests-private#31157
dgoodwin wants to merge 3 commits into
openshift:mainfrom
dgoodwin:port-router-cookie-tests

Conversation

@dgoodwin
Copy link
Copy Markdown
Contributor

@dgoodwin dgoodwin commented May 11, 2026

Testing a test porting agent, please be patient.

Agent will respond to coderabbit feedback, ensure the tests appear to be running and passing, then respond to human feedback.

Human feedback can request improvements or to skip porting a test entirely.

Summary

  • Ports 5 high-pass-rate router cookie tests from openshift-tests-private (OCP-11903, OCP-12566, OCP-15872, OCP-35547, OCP-35548)
  • Tests cover HAProxy sticky sessions, cookie naming conventions, and SameSite attribute behavior for edge/reencrypt routes
  • All tests have >98% pass rate over 760-790 runs in the last 60 days
  • Adds helper utilities in util_otp.go and 4 fixture YAML files

Test plan

  • Verify go build ./test/extended/router/ passes (verified locally)
  • Verify go vet ./test/extended/router/ passes (verified locally)
  • CI presubmit passes
  • Tests discoverable with [OTP] tag

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests
    • Added comprehensive tests for OTP cookie behavior: cookie-based sticky sessions, cookie naming, custom cookie names, and SameSite/Secure handling across route types.
  • Test Utilities
    • Added helper utilities to create/manage ingress controllers, routes, and to inspect router behavior for end-to-end testing.
  • Test Data
    • Added manifests and embedded test assets for web servers, signed HTTPS server, client pod, and a NodePort-configured ingress template.

Port high-pass-rate router cookie tests covering HAProxy sticky sessions,
cookie naming, and SameSite attribute behavior for edge and reencrypt routes.

Tests ported:
- OCP-11903: haproxy cookies based sticky session for unsecure routes (98.0%)
- OCP-12566: Cookie name should not use openshift prefix (98.9%)
- OCP-15872: can set cookie name for unsecure routes by annotation (98.9%)
- OCP-35547: cookie-same-site annotation for edge routes (99.2%)
- OCP-35548: cookie-same-site annotation for Reencrypt routes (98.7%)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@openshift-merge-bot
Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: automatic mode

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

Walkthrough

Adds end-to-end Ginkgo/Gomega tests for router OTP cookie behavior (sticky sessions, cookie naming, custom names, SameSite) plus helper utilities and test manifests to exercise HAProxy config, routes, and backend traffic.

Changes

Router OTP Cookie Testing

Layer / File(s) Summary
Test Fixtures / Infrastructure
test/extended/testdata/router/ingresscontroller-np.yaml, test/extended/testdata/router/test-client-pod.yaml, test/extended/testdata/router/web-server-deploy.yaml, test/extended/testdata/router/web-server-signed-deploy.yaml
New templates/manifests: an IngressController (NodePortService), a constrained test client pod, and web server deployments/services (HTTP and HTTPS with TLS ConfigMap/secret mounts) used by the tests.
Test Asset Embedding
test/extended/testdata/bindata.go
Registers and embeds the four new testdata YAML files into test assets (byte arrays and asset helpers).
Test Utilities
test/extended/router/util_otp.go
New helper functions: create/delete IngressController from templates, process templates via oc process, create routes with annotations, query router pods/nodes, detect router rolling updates and generation changes, inspect HAProxy config in router pods (string/regex assertions), run commands with polling, curl/backends and count responses, and small file edits (sed). Uses Ginkgo/Gomega and polling helpers.
Test Cases
test/extended/router/cookies_otp.go
Ginkgo tests covering: (1) unsecure HTTP route cookie-based sticky sessions and disabling cookies via annotation, (2) cookie name rules (no OPENSHIFT prefix, not IP-like), (3) custom cookie name annotation propagation to HAProxy and Set-Cookie header, (4) SameSite attribute checks for edge routes (None → Strict) and (5) reencrypt routes (None → Lax → Strict), verifying HAProxy config and successive Set-Cookie header values.

Sequence Diagram

sequenceDiagram
participant Test as Test Suite
participant API as Kubernetes API
participant Router as HAProxy Pod
participant Backend as Web Server Pod
participant Client as curl

Test->>API: create IngressController, Deployments, Services, Routes
API-->>Test: resource created / admitted
Test->>Router: exec into router pod, fetch haproxy config
Router-->>Test: haproxy config text
Test->>Client: curl route (no cookie) -> responses from Backend A/B
Client-->>Test: Set-Cookie header (OTP cookie)
Test->>Client: subsequent curls with cookie -> backend sticky selection
Test->>API: patch route annotations (disable cookies / set cookie name / set SameSite)
API-->>Router: rollout config changes
Test->>Router: wait for new replica/pod ready, fetch haproxy config
Router-->>Test: updated haproxy config
Test->>Client: curl route, validate Set-Cookie header and backend distribution
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 7 | ❌ 5

❌ Failed checks (5 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Structure And Quality ⚠️ Warning Tests lack setup/cleanup (no BeforeEach/AfterEach), assertions have no failure messages (14/14), missing pod/service cleanup. Inconsistent with dualstack.go and certs.go patterns. Add BeforeEach/AfterEach hooks. Add meaningful messages to all assertions. Explicitly clean up namespace-scoped resources. Follow existing router test patterns.
Microshift Test Compatibility ⚠️ Warning Test OCP-11903 uses IngressController (operator.openshift.io/v1) which is unavailable on MicroShift. Only tagged with [apigroup:route.openshift.io], missing operator.openshift.io protection. Add [apigroup:operator.openshift.io] tag to OCP-11903 test, or use [Skipped:MicroShift] or exutil.IsMicroShiftCluster() guard. Other 4 tests are properly protected.
Single Node Openshift (Sno) Test Compatibility ⚠️ Warning Tests lack SNO compatibility checks. No [Skipped:SingleReplicaTopology] labels or IsSingleNode() guards found, which are recommended for SNO validation. Add [Skipped:SingleReplicaTopology] label to all 5 test names or implement IsSingleNode() checks with g.Skip(). Tests should work on SNO but need explicit SNO handling per OpenShift test guidelines.
Ipv6 And Disconnected Network Test Compatibility ⚠️ Warning Test OCP-11903 uses IPv4-specific getPodv4Address() without IPv6 support. Tests pull images from external quay.io, failing in disconnected environments. Make getPodv4Address() IP-agnostic. Add [Skipped:Disconnected] tag to skip in disconnected environments. Support IPv6 with proper curl --resolve formatting.
✅ Passed checks (7 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main purpose of the changeset: porting five router cookie tests from openshift-tests-private. It is concise, specific, and clearly conveys what the PR accomplishes.
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 test names use static strings with no dynamic content, fmt.Sprintf, concatenation, variables, pod suffixes, IPs, UUIDs, or timestamps.
Topology-Aware Scheduling Compatibility ✅ Passed Test fixtures only. No production code. No topology-aware scheduling constraints in YAML files.
Ote Binary Stdout Contract ✅ Passed No OTE Binary Stdout Contract violations found. All code properly isolates stdout writes within test blocks or avoids stdout writes entirely. No unredirected klog or logging at process level.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 11, 2026
@openshift-ci openshift-ci Bot requested review from knobunc and rikatz May 11, 2026 14:06
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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 (6)
test/extended/router/util_otp.go (3)

69-77: 💤 Low value

Per-call random seeding is inefficient but acceptable for test code.

Creating a new rand.Source seeded with time.Now().UnixNano() on each call is inefficient and could theoretically produce duplicates if called rapidly. For test temp filenames this is acceptable, but a package-level seeded source would be cleaner.

🤖 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/extended/router/util_otp.go` around lines 69 - 77, getRandomString
currently creates a new rand.Source seeded with time.Now().UnixNano() on every
call which is inefficient and can collide under rapid calls; change this to use
a package-level seeded *rand.Rand or rand.Source (e.g. a var seeded in init or
at declaration) and have getRandomString reuse that global RNG instead of
calling rand.New(rand.NewSource(...)) each time to improve efficiency and
uniqueness while keeping the same logic.

39-46: ⚖️ Poor tradeoff

String-based node counting may miscount if node names contain status keywords.

The function counts occurrences of "Ready", "SchedulingDisabled", and "NotReady" in the raw output. If a node name happens to contain these substrings (e.g., node-NotReady-01), the count will be incorrect. Consider using kubectl get nodes -o jsonpath to extract status conditions more reliably.

🤖 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/extended/router/util_otp.go` around lines 39 - 46, The exactNodeDetails
function currently counts status keywords in the raw kubectl output which can be
miscounted if node names include those substrings; update exactNodeDetails to
call
oc.AsAdmin().WithoutNamespace().Run("get").Args("nodes","--selector=node-role.kubernetes.io/worker=,kubernetes.io/os=linux","-o","jsonpath={range
.items[*]}{.metadata.name}:{range
.status.conditions[*]}{.type}={.status};{end}\n{end}").Output() (or equivalent
json/jsonpath) and parse each node's status conditions to compute nodeCount from
actual Condition type/status pairs instead of string-counting
"Ready"/"NotReady"/"SchedulingDisabled", keeping the returned values nodeCount
and the raw or formatted node details for logging.

446-450: 💤 Low value

Sed command may fail if replacement strings contain the pipe delimiter.

The sed command uses | as a delimiter. If toBeReplaced or newContent contain |, the command will fail or produce unexpected results. While current callers use safe strings like "replicas: 1", this could be fragile for future use.

♻️ Safer alternative using Go's file manipulation
 func updateFilebySedCmd(file, toBeReplaced, newContent string) {
-	sedCmd := fmt.Sprintf(`sed -i'' -e 's|%s|%s|g' %s`, toBeReplaced, newContent, file)
-	_, err := exec.Command("bash", "-c", sedCmd).Output()
+	content, err := os.ReadFile(file)
+	o.Expect(err).NotTo(o.HaveOccurred())
+	newData := strings.ReplaceAll(string(content), toBeReplaced, newContent)
+	err = os.WriteFile(file, []byte(newData), 0644)
 	o.Expect(err).NotTo(o.HaveOccurred())
 }
🤖 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/extended/router/util_otp.go` around lines 446 - 450, The helper
updateFilebySedCmd is brittle because it shells out to sed with '|' delimiters;
replace it with pure-Go file manipulation: read the file (os.ReadFile), perform
a safe replacement (strings.ReplaceAll on the file content using the provided
toBeReplaced and newContent values, or use regexp.QuoteMeta+ReplaceAllString for
regex needs), then write the updated content back (os.WriteFile) preserving
original file permissions (os.Stat to get FileMode); return or fail on any IO
errors instead of invoking bash/exec.Command. Ensure the function name
updateFilebySedCmd is updated to use this approach and that error assertions
(o.Expect) still validate the operation.
test/extended/router/cookies_otp.go (1)

130-135: ⚡ Quick win

Prefer os.ReadFile over shell command for reading local files.

Using exec.Command("bash", "-c", "cat ...") to read a file is unnecessary when Go's os.ReadFile is available. This also addresses the static analysis hint about shell command injection.

♻️ Suggested fix
-		cmd := fmt.Sprintf(`cat %s`, cookie)
-		cookiesOutput, err := exec.Command("bash", "-c", cmd).Output()
+		cookiesOutput, err := os.ReadFile(cookie)
 		o.Expect(err).NotTo(o.HaveOccurred())
🤖 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/extended/router/cookies_otp.go` around lines 130 - 135, Replace the
shell cat invocation using exec.Command("bash", "-c", cmd) with a direct file
read via os.ReadFile(cookie): call data, err := os.ReadFile(cookie) and check
err with o.Expect(err).NotTo(o.HaveOccurred()), then use string(data) in place
of string(cookiesOutput) for the subsequent assertions
(o.Expect(string(data)).NotTo(o.ContainSubstring("OPENSHIFT")) and
o.Expect(string(data)).NotTo(o.MatchRegexp(...))). Remove cmd and cookiesOutput
variables and import "os" if not already imported.
test/extended/testdata/router/web-server-signed-deploy.yaml (1)

34-64: 💤 Low value

Consider adding security context for consistency.

Same as web-server-deploy.yaml, this deployment lacks pod and container securityContext settings. For consistency with test-client-pod.yaml, consider adding security context settings.

🤖 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/extended/testdata/router/web-server-signed-deploy.yaml` around lines 34
- 64, The Deployment "web-server-deploy" is missing pod- and container-level
securityContext entries; add a pod securityContext under spec.template.spec
(e.g., runAsNonRoot: true, runAsUser: <non-root uid>, fsGroup: <gid>) and add a
container securityContext on the "nginx" container (e.g.,
allowPrivilegeEscalation: false, readOnlyRootFilesystem: true, runAsUser
matching pod UID) to match the settings used in test-client-pod.yaml for
consistency and stricter security.
test/extended/testdata/router/web-server-deploy.yaml (1)

19-29: 💤 Low value

Consider adding security context for consistency with other test fixtures.

The deployment lacks pod and container securityContext settings. The test-client-pod.yaml in this PR properly sets runAsNonRoot, seccompProfile, and allowPrivilegeEscalation: false. Adding similar settings here would align with security best practices and ensure consistency across test fixtures.

♻️ Suggested security context addition
     spec:
+      securityContext:
+        runAsNonRoot: true
+        seccompProfile:
+          type: RuntimeDefault
       containers:
       - name: nginx
         image: quay.io/openshifttest/nginx-alpine@sha256:cee6930776b92dc1e93b73f9e5965925d49cff3d2e91e1d071c2f0ff72cbca29
+        securityContext:
+          allowPrivilegeEscalation: false
+          capabilities:
+            drop:
+            - ALL
         ports:
🤖 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/extended/testdata/router/web-server-deploy.yaml` around lines 19 - 29,
Add consistent pod- and container-level securityContext entries to the
Deployment spec: under the Pod spec (same level as containers) add
securityContext with runAsNonRoot: true and a seccompProfile (type:
RuntimeDefault), and for the nginx container (name: "nginx") add a
container-level securityContext with allowPrivilegeEscalation: false and
runAsNonRoot: true; ensure field names match the existing test-client-pod.yaml
pattern so the fixture aligns with other tests.
🤖 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/extended/router/cookies_otp.go`:
- Line 49: The test mutates a shared fixture by calling updateFilebySedCmd on
testPodSvc which can cause flakiness; instead create a temp copy of the fixture
or avoid in-place edits (e.g., use oc process with parameter overrides).
Implement by reading the file referenced by testPodSvc, writing a modified copy
to a temporary file (os.CreateTemp / os.WriteFile), replace "replicas: 1" →
"replicas: 2" in that temp content, use the temp file path for subsequent calls
instead of testPodSvc, and ensure the temp file is removed in a defer;
alternatively refactor the apply step to call oc process with parameter
overrides rather than mutating the file.

---

Nitpick comments:
In `@test/extended/router/cookies_otp.go`:
- Around line 130-135: Replace the shell cat invocation using
exec.Command("bash", "-c", cmd) with a direct file read via os.ReadFile(cookie):
call data, err := os.ReadFile(cookie) and check err with
o.Expect(err).NotTo(o.HaveOccurred()), then use string(data) in place of
string(cookiesOutput) for the subsequent assertions
(o.Expect(string(data)).NotTo(o.ContainSubstring("OPENSHIFT")) and
o.Expect(string(data)).NotTo(o.MatchRegexp(...))). Remove cmd and cookiesOutput
variables and import "os" if not already imported.

In `@test/extended/router/util_otp.go`:
- Around line 69-77: getRandomString currently creates a new rand.Source seeded
with time.Now().UnixNano() on every call which is inefficient and can collide
under rapid calls; change this to use a package-level seeded *rand.Rand or
rand.Source (e.g. a var seeded in init or at declaration) and have
getRandomString reuse that global RNG instead of calling
rand.New(rand.NewSource(...)) each time to improve efficiency and uniqueness
while keeping the same logic.
- Around line 39-46: The exactNodeDetails function currently counts status
keywords in the raw kubectl output which can be miscounted if node names include
those substrings; update exactNodeDetails to call
oc.AsAdmin().WithoutNamespace().Run("get").Args("nodes","--selector=node-role.kubernetes.io/worker=,kubernetes.io/os=linux","-o","jsonpath={range
.items[*]}{.metadata.name}:{range
.status.conditions[*]}{.type}={.status};{end}\n{end}").Output() (or equivalent
json/jsonpath) and parse each node's status conditions to compute nodeCount from
actual Condition type/status pairs instead of string-counting
"Ready"/"NotReady"/"SchedulingDisabled", keeping the returned values nodeCount
and the raw or formatted node details for logging.
- Around line 446-450: The helper updateFilebySedCmd is brittle because it
shells out to sed with '|' delimiters; replace it with pure-Go file
manipulation: read the file (os.ReadFile), perform a safe replacement
(strings.ReplaceAll on the file content using the provided toBeReplaced and
newContent values, or use regexp.QuoteMeta+ReplaceAllString for regex needs),
then write the updated content back (os.WriteFile) preserving original file
permissions (os.Stat to get FileMode); return or fail on any IO errors instead
of invoking bash/exec.Command. Ensure the function name updateFilebySedCmd is
updated to use this approach and that error assertions (o.Expect) still validate
the operation.

In `@test/extended/testdata/router/web-server-deploy.yaml`:
- Around line 19-29: Add consistent pod- and container-level securityContext
entries to the Deployment spec: under the Pod spec (same level as containers)
add securityContext with runAsNonRoot: true and a seccompProfile (type:
RuntimeDefault), and for the nginx container (name: "nginx") add a
container-level securityContext with allowPrivilegeEscalation: false and
runAsNonRoot: true; ensure field names match the existing test-client-pod.yaml
pattern so the fixture aligns with other tests.

In `@test/extended/testdata/router/web-server-signed-deploy.yaml`:
- Around line 34-64: The Deployment "web-server-deploy" is missing pod- and
container-level securityContext entries; add a pod securityContext under
spec.template.spec (e.g., runAsNonRoot: true, runAsUser: <non-root uid>,
fsGroup: <gid>) and add a container securityContext on the "nginx" container
(e.g., allowPrivilegeEscalation: false, readOnlyRootFilesystem: true, runAsUser
matching pod UID) to match the settings used in test-client-pod.yaml for
consistency and stricter security.
🪄 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 YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: db47178e-63d2-4739-901c-bf3babc8eb71

📥 Commits

Reviewing files that changed from the base of the PR and between 5ab531b and 6166637.

📒 Files selected for processing (6)
  • test/extended/router/cookies_otp.go
  • test/extended/router/util_otp.go
  • test/extended/testdata/router/ingresscontroller-np.yaml
  • test/extended/testdata/router/test-client-pod.yaml
  • test/extended/testdata/router/web-server-deploy.yaml
  • test/extended/testdata/router/web-server-signed-deploy.yaml

ensureRouterDeployGenerationIs(oc, ingctrl.name, "1")

g.By("2.0: Prepare file for testing")
updateFilebySedCmd(testPodSvc, "replicas: 1", "replicas: 2")
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 | ⚡ Quick win

Mutating shared fixture files can cause test flakiness or pollution.

updateFilebySedCmd modifies web-server-deploy.yaml on disk. Multiple tests (OCP-11903, OCP-12566, OCP-15872) call this on the same file. If tests run in parallel or the file is already modified from a previous run, the sed replacement becomes a no-op (the pattern won't match). Consider either:

  1. Creating a temporary copy of the fixture per test, or
  2. Using oc process with parameter overrides instead of file mutation
🛠️ Suggested approach: copy fixture to temp file
// Create a temp copy of the fixture
tmpFile, err := os.CreateTemp("", "web-server-deploy-*.yaml")
o.Expect(err).NotTo(o.HaveOccurred())
defer os.Remove(tmpFile.Name())

content, err := os.ReadFile(testPodSvc)
o.Expect(err).NotTo(o.HaveOccurred())

modifiedContent := strings.ReplaceAll(string(content), "replicas: 1", "replicas: 2")
err = os.WriteFile(tmpFile.Name(), []byte(modifiedContent), 0644)
o.Expect(err).NotTo(o.HaveOccurred())

// Use tmpFile.Name() instead of testPodSvc
🤖 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/extended/router/cookies_otp.go` at line 49, The test mutates a shared
fixture by calling updateFilebySedCmd on testPodSvc which can cause flakiness;
instead create a temp copy of the fixture or avoid in-place edits (e.g., use oc
process with parameter overrides). Implement by reading the file referenced by
testPodSvc, writing a modified copy to a temporary file (os.CreateTemp /
os.WriteFile), replace "replicas: 1" → "replicas: 2" in that temp content, use
the temp file path for subsequent calls instead of testPodSvc, and ensure the
temp file is removed in a defer; alternatively refactor the apply step to call
oc process with parameter overrides rather than mutating the file.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 11, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: dgoodwin

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

The pull request process is described 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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
test/extended/router/cookies_otp.go (1)

49-49: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid mutating shared fixture files in-place across specs.

Line 49, Line 117, and Line 151 mutate test/extended/testdata/router/web-server-deploy.yaml directly. This can leak state between specs/retries and cause flaky behavior when runs overlap. Please use a per-spec temp copy (or parameterized processing) instead of editing the shared fixture.

Suggested fix pattern (temp copy per spec)
+content, err := os.ReadFile(testPodSvc)
+o.Expect(err).NotTo(o.HaveOccurred())
+
+tmp, err := os.CreateTemp("", "web-server-deploy-*.yaml")
+o.Expect(err).NotTo(o.HaveOccurred())
+defer os.Remove(tmp.Name())
+
+patched := strings.ReplaceAll(string(content), "replicas: 1", "replicas: 2")
+err = os.WriteFile(tmp.Name(), []byte(patched), 0644)
+o.Expect(err).NotTo(o.HaveOccurred())
+
- updateFilebySedCmd(testPodSvc, "replicas: 1", "replicas: 2")
- srvPodList := createResourceFromWebServer(oc, ns, testPodSvc, srvrcInfo)
+ srvPodList := createResourceFromWebServer(oc, ns, tmp.Name(), srvrcInfo)

Also applies to: 117-117, 151-151

🤖 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/extended/router/cookies_otp.go` at line 49, The test is mutating a
shared fixture in-place via updateFilebySedCmd in cookies_otp.go; instead, copy
the fixture to a per-spec temp file and run updateFilebySedCmd against that temp
copy (createTempFile + io.Copy or os.ReadFile/os.WriteFile), pass the temp file
path into any Deploy/Apply helper used in the spec, and remove the temp file in
a defer cleanup so each spec operates on an isolated copy (update references to
updateFilebySedCmd calls at lines around where it's used and ensure any helpers
that load the fixture accept the temp path).
🤖 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/extended/router/cookies_otp.go`:
- Around line 131-133: Replace the shell-backed cat call that builds cmd and
runs exec.Command("bash", "-c", cmd) with a direct file read using
os.ReadFile(cookie); assign the returned []byte to cookiesOutput and handle the
error the same way (o.Expect(err).NotTo(o.HaveOccurred())). Update the
references to cmd and exec.Command to use os.ReadFile(cookie) so file contents
are read safely without spawning a shell.

---

Duplicate comments:
In `@test/extended/router/cookies_otp.go`:
- Line 49: The test is mutating a shared fixture in-place via updateFilebySedCmd
in cookies_otp.go; instead, copy the fixture to a per-spec temp file and run
updateFilebySedCmd against that temp copy (createTempFile + io.Copy or
os.ReadFile/os.WriteFile), pass the temp file path into any Deploy/Apply helper
used in the spec, and remove the temp file in a defer cleanup so each spec
operates on an isolated copy (update references to updateFilebySedCmd calls at
lines around where it's used and ensure any helpers that load the fixture accept
the temp path).
🪄 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 YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 0afd1ffe-a225-47bb-b998-9443ba5cb0cf

📥 Commits

Reviewing files that changed from the base of the PR and between 6166637 and be507ab.

📒 Files selected for processing (2)
  • test/extended/router/cookies_otp.go
  • test/extended/testdata/bindata.go
✅ Files skipped from review due to trivial changes (1)
  • test/extended/testdata/bindata.go

Comment on lines +131 to +133
cmd := fmt.Sprintf(`cat %s`, cookie)
cookiesOutput, err := exec.Command("bash", "-c", cmd).Output()
o.Expect(err).NotTo(o.HaveOccurred())
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 | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify there are no remaining shell-wrapped exec.Command usages in router extended tests
rg -nP 'exec\.Command\("bash",\s*"-c"' --type go test/extended/router

Repository: openshift/origin

Length of output: 362


🏁 Script executed:

#!/bin/bash
# Get the context around lines 131-133 in cookies_otp.go
sed -n '125,140p' test/extended/router/cookies_otp.go | cat -n

Repository: openshift/origin

Length of output: 1059


🏁 Script executed:

#!/bin/bash
# Check the util_otp.go instances to see what they're doing
echo "=== util_otp.go:391 ===" 
sed -n '385,395p' test/extended/router/util_otp.go | cat -n
echo ""
echo "=== util_otp.go:448 ===" 
sed -n '442,452p' test/extended/router/util_otp.go | cat -n

Repository: openshift/origin

Length of output: 907


🏁 Script executed:

#!/bin/bash
# Verify what imports are available in cookies_otp.go
head -30 test/extended/router/cookies_otp.go | cat -n

Repository: openshift/origin

Length of output: 1332


Replace shell-wrapped cat with os.ReadFile() for cleaner, safer file reading.

Line 132 uses exec.Command("bash", "-c", cmd) to read a file with cat. Use os.ReadFile(cookie) instead, which returns []byte and error matching the existing error handling pattern.

Safer direct read
- cmd := fmt.Sprintf(`cat %s`, cookie)
- cookiesOutput, err := exec.Command("bash", "-c", cmd).Output()
+ cookiesOutput, err := os.ReadFile(cookie)
  o.Expect(err).NotTo(o.HaveOccurred())
🧰 Tools
🪛 OpenGrep (1.20.0)

[ERROR] 132-132: Dynamic command passed to exec.Command with a shell invocation. Pass arguments directly to exec.Command without a shell wrapper.

(coderabbit.command-injection.go-exec-command)

🤖 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/extended/router/cookies_otp.go` around lines 131 - 133, Replace the
shell-backed cat call that builds cmd and runs exec.Command("bash", "-c", cmd)
with a direct file read using os.ReadFile(cookie); assign the returned []byte to
cookiesOutput and handle the error the same way
(o.Expect(err).NotTo(o.HaveOccurred())). Update the references to cmd and
exec.Command to use os.ReadFile(cookie) so file contents are read safely without
spawning a shell.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 12, 2026

@dgoodwin: The following test 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 be507ab link true /test verify

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

approved Indicates a PR has been approved by an approver from all required OWNERS files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant