Skip to content

Conversation

@gangwgr
Copy link
Contributor

@gangwgr gangwgr commented Jan 15, 2026

This PR adds comprehensive CLI test infrastructure for the oc command, implementing a self-contained testing framework that avoids external test dependencies

  • Added cli.go (2,512 lines) - 30+ comprehensive CLI test cases covering:
    • Image operations (mirror, extract, info, prune)
    • IDMS/ICSP configuration
    • Deployment and pod management
    • Network policies
    • Build operations
    • Custom Resource Definitions (CRDs)
    • Version and event handling
  • Added util.go (1,397 lines) - Test utilities including:
    • CLI wrapper for oc command execution with fluent API
    • e2e compatibility layer (avoids k8s.io/kubernetes/test/e2e/framework)
    • Platform detection (AWS, Azure, GCP, VSphere, etc.)
    • Architecture helpers (Multi, ARM64, x86_64, PPC64LE, S390X)
    • Test helper functions for pods, deployments, nodes
    • Minimal stub implementations for unused code paths
  • Removed e2e.go (15 lines) - replaced by cli.go

New dependencies added:

  • github.com/tidwall/gjson - JSON parsing for test validation
  • golang.org/x/crypto/ssh - SSH support for node operations
  • github.com/google/goexpect - Terminal interaction testing
  • github.com/google/goterm - Terminal utilities
  • google.golang.org/grpc - gRPC support (transitive)

Vendor updates:

  • Added ~100+ new vendor packages for test dependencies
  • Updated existing vendor packages for compatibility

@coderabbitai
Copy link

coderabbitai bot commented Jan 15, 2026

Walkthrough

Deletes a trivial e2e test and adds a large Ginkgo-based e2e test suite, a comprehensive CLI/test utilities library, embedded fixture extraction, and many Kubernetes/OpenShift YAML test fixtures.

Changes

Cohort / File(s) Summary
Removed test file
test/e2e/e2e.go
Deleted a minimal Ginkgo/Gomega test file containing two trivial tests.
E2E test suite
test/e2e/cli.go
Added a large Ginkgo-based end-to-end test suite with numerous oc CLI scenarios, workload tests, image/import/mirroring checks, init-container/debug flows, quota and platform-gated behaviors; introduces ClientVersion, ServerVersion, and VersionInfo types.
Test utilities / CLI library
test/e2e/util.go
Added a CLI orchestration and command-builder API (CLI, CLICommand), execution/output/background helpers, cluster inspection/debugging utilities, platform/architecture helpers, fixture helpers, and many exported helper functions and types.
Fixture extraction utilities
test/testdata/fixtures.go
Added embedded fixture extraction using embed.FS with public helpers: FixturePath, GetFixtureDir, CleanupFixtures, ListFixtures.
CRD & CR fixtures (case72217)
test/testdata/oc_cli/case72217/crd-cattoy-72217.yaml, test/testdata/oc_cli/case72217/crd-crontab-72217.yaml, test/testdata/oc_cli/case72217/crd-customtask-72217.yaml, test/testdata/oc_cli/case72217/cr-cat-72217.yaml, test/testdata/oc_cli/case72217/cr-cron-72217.yaml, test/testdata/oc_cli/case72217/cr-custom-72217.yaml
Added three CustomResourceDefinition manifests and three corresponding custom resource instances for test case 72217.
Additional YAML test fixtures
test/testdata/oc_cli/clusterresource_for_user.yaml, test/testdata/oc_cli/debugpod_48681.yaml, test/testdata/oc_cli/deploymentconfig_with_quota.yaml, test/testdata/oc_cli/idmsFile64921.yaml, test/testdata/oc_cli/initContainer.yaml, test/testdata/oc_cli/initContainer66989.yaml
Added various OpenShift/Kubernetes test manifests: ClusterResourceQuota, debug pod template, DeploymentConfig with resources, ImageDigestMirrorSet, and two Pod manifests with initContainers.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

✨ Finishing touches
  • 📝 Generate docstrings

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

Copy link

@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: 7

🤖 Fix all issues with AI agents
In `@test/e2e/util.go`:
- Around line 1288-1305: applyResourceFromTemplate builds the wrong command by
calling oc.Run("oc") which yields a double "oc" (e.g., "oc oc process ...");
change the invocation to use the verb only (e.g., oc.Run("process", ...)) or
otherwise call oc.execPath directly when building the process command so the
constructed command is "oc process ..."; update the call sites inside
applyResourceFromTemplate (references: function applyResourceFromTemplate,
method oc.Run, field oc.execPath, use of exec.Command) to ensure the processed
template step runs "oc process ..." and not "oc oc process ...", preserving the
rest of the logic (namespace and KUBECONFIG env handling) and returning
cmd.Run() as before.
- Around line 1086-1094: In sha256File, don't defer file.Close() before
verifying os.Open succeeded; check err returned by os.Open(fileName) first and
handle/return the error (or call o.Expect after confirming file is non-nil),
then defer file.Close(); ensure subsequent io.Copy and hex.EncodeToString still
run when file is valid and propagate any errors from io.Copy instead of causing
a nil-pointer panic.
- Around line 1307-1332: The function applyResourceFromTemplate48681 incorrectly
invokes oc.Run("oc") which constructs an invalid command; replace that call with
exec.Command using oc.execPath and the constructed fullArgs (i.e., build cmd :=
exec.Command(oc.execPath, fullArgs...) and call cmd.Output()), and make sure to
set cmd.Env to include "KUBECONFIG="+oc.kubeconfig when oc.kubeconfig is
non-empty (and include any necessary namespace flags in fullArgs if required) so
the template processing output is captured correctly and returned or error
propagated.
- Around line 886-899: In getLatestPayload, the defer res.Body.Close() is
currently placed after the http.Get error check but before ioutil.ReadAll, which
can still leak the body if ReadAll errors; move the defer immediately after
confirming http.Get returned no error and res != nil (i.e., right after the err
check) so the response body is guaranteed to be closed on every return, and
ensure any early e2e.Failf paths occur after that placement; keep existing error
handling for ioutil.ReadAll and gjson parsing.

In `@testdata/oc_cli/deploymentconfig_with_quota.yaml`:
- Around line 40-42: The memory request for the first container currently uses
the SI unit "40M" which is inconsistent with the second container's "40Mi" and
Kubernetes conventions; update the memory request value under the "requests:"
block (the entry currently "memory: 40M") to use the mebibyte unit "40Mi" so
both containers use the same unit and avoid quota calculation discrepancies.

In `@testdata/oc_cli/pod_mirror.yaml`:
- Around line 16-19: The shell loop condition in the args block currently uses
"[ ls /etc/foo/.dockerconfigjson ]" which always evaluates true; replace that
test with a proper file-existence check using the -f unary operator and negation
so the loop waits until /etc/foo/.dockerconfigjson exists (i.e., change the
while condition to test for "not -f /etc/foo/.dockerconfigjson" and keep the
surrounding "do sleep 1; done" and the subsequent exec oc adm release mirror
command intact).

In `@testdata/oc_cli/rc-match-service.yaml`:
- Around line 30-31: The volume entry named "config" under the "volumes" list is
missing a volume source and will fail validation; update the "config" volume
definition (the volumes -> name: config entry) to include an appropriate source
such as secret (e.g., secret: {secretName: ...}), configMap (e.g., configMap:
{name: ...}), or emptyDir, matching how the PodSpec mounts it (and ensure any
referenced secret/configMap exists and the mount path in the container matches).
🧹 Nitpick comments (3)
testdata/oc_cli/config_74099.yaml (1)

35-151: Consider security hardening for DeploymentConfig test fixture.

The static analysis flags missing allowPrivilegeEscalation: false (CKV_K8S_20). While this is acceptable for testdata captured from existing clusters, consider adding explicit security constraints if this fixture is meant to represent best practices:

securityContext:
  allowPrivilegeEscalation: false
  capabilities:
    drop:
    - ALL

Given this appears to be a captured cluster configuration for test purposes, this is a minor concern.

testdata/oc_cli/stable-storage.yaml (1)

33-46: Consider explicit security settings for test consistency.

The static analysis flags missing allowPrivilegeEscalation: false and runAsNonRoot: true. While this is test data, adding explicit security settings ensures the test fixtures align with security best practices and can validate that workloads with proper security contexts function correctly.

🔒 Optional: Add explicit security context settings
           securityContext:
             capabilities: {}
             privileged: false
+            allowPrivilegeEscalation: false
+            runAsNonRoot: true
test/e2e/util.go (1)

11-11: Deprecated io/ioutil package usage.

The io/ioutil package is deprecated since Go 1.16. Replace with os and io package equivalents:

  • ioutil.ReadAllio.ReadAll
  • ioutil.ReadFileos.ReadFile
  • ioutil.WriteFileos.WriteFile
  • ioutil.ReadDiros.ReadDir
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 4df0e94 and 6351427.

⛔ Files ignored due to path filters (176)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/containerd/typeurl/v2/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/containerd/typeurl/v2/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/containerd/typeurl/v2/types_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/go-logr/logr/.golangci.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/go-logr/logr/funcr/funcr.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goexpect/AUTHORS is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goexpect/CONTRIBUTING is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goexpect/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goexpect/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goexpect/expect.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goterm/AUTHORS is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goterm/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goterm/term/color.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goterm/term/ssh.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goterm/term/termios.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/CHANGELOG.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/format/format.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/gomega_dsl.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/assertion.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/async_assertion.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/duration_bundle.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/gomega.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/polling_signal_error.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/vetoptdesc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/and.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/assignable_to_type_of_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_a_directory.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_a_regular_file.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_an_existing_file.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_element_of_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_equivalent_to_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_false_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_identical_to.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_key_of_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_nil_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_numerically_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_temporally_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_true_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_zero_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/consist_of.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_substring_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/equal_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_cap_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_each_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_exact_elements.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_existing_field_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_field.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_header_with_value_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_status_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_key_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_len_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_prefix_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_suffix_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_value.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_iter.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_noiter.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_error_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_json_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_regexp_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_xml_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/not.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/or.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/panic_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/receive_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/satisfy_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/semi_structured_data_support.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/succeed_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/type_support.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/with_transform.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/types/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/opencontainers/image-spec/specs-go/version.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/gjson/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/gjson/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/gjson/SYNTAX.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/gjson/gjson.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/match/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/match/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/match/match.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/pretty/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/pretty/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/pretty/pretty.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/sjson/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/sjson/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/sjson/logo.png is excluded by !**/*.png, !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/sjson/sjson.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/attribute/filter.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/attribute/internal/attribute.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/attribute/rawhelpers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/attribute/value.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/internal/gen.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/internal/rawhelpers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/auto.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/internal/telemetry/status.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/internal/telemetry/traces.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/internal/telemetry/value.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/noop.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/blowfish/block.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/blowfish/cipher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/blowfish/const.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_arm64.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_arm64.s is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_generic.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_noasm.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_ppc64x.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_ppc64x.s is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_s390x.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_s390x.s is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/xor.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/curve25519/curve25519.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/buffer.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/certs.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/channel.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/cipher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/client.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/client_auth.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/common.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/connection.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/handshake.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/internal/bcrypt_pbkdf/bcrypt_pbkdf.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/kex.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/keys.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/mac.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/messages.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/mlkem.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/mux.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/server.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/session.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/ssh_gss.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/streamlocal.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/tcpip.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/transport.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/AUTHORS is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/NOTICE.txt is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/codes/code_string.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/codes/codes.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/connectivity/connectivity.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/grpclog/component.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/grpclog/grpclog.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/grpclog/internal/grpclog.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/grpclog/internal/logger.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/grpclog/internal/loggerv2.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/grpclog/logger.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/grpclog/loggerv2.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/internal/experimental.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/internal/internal.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/internal/status/status.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/internal/tcp_keepalive_others.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/internal/tcp_keepalive_unix.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/internal/tcp_keepalive_windows.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/serviceconfig/serviceconfig.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/status/status.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/protoadapt/convert.go is excluded by !vendor/**, !**/vendor/**
  • vendor/gopkg.in/evanphx/json-patch.v4/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/gopkg.in/evanphx/json-patch.v4/patch.go is excluded by !vendor/**, !**/vendor/**
  • vendor/modules.txt is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go is excluded by !vendor/**, !**/vendor/**
📒 Files selected for processing (36)
  • go.mod
  • test/e2e/cli.go
  • test/e2e/e2e.go
  • test/e2e/util.go
  • testdata/oc_cli/12708358_4.11.0-0.nightly-multi-2022-04-18-120932-release-imagestream.yaml
  • testdata/oc_cli/OWNERS
  • testdata/oc_cli/application-template-stibuild-with-mount-secret.json
  • testdata/oc_cli/auth.json
  • testdata/oc_cli/build_66672.yaml
  • testdata/oc_cli/case72217/cr-cat-72217.yaml
  • testdata/oc_cli/case72217/cr-cron-72217.yaml
  • testdata/oc_cli/case72217/cr-custom-72217.yaml
  • testdata/oc_cli/case72217/crd-cattoy-72217.yaml
  • testdata/oc_cli/case72217/crd-crontab-72217.yaml
  • testdata/oc_cli/case72217/crd-customtask-72217.yaml
  • testdata/oc_cli/clusterresource_for_user.yaml
  • testdata/oc_cli/config-images-75997.txt
  • testdata/oc_cli/config_74099.yaml
  • testdata/oc_cli/dc_66672.yaml
  • testdata/oc_cli/debugpod_48681.yaml
  • testdata/oc_cli/deploymentconfig_with_quota.yaml
  • testdata/oc_cli/egressnetworkpolicy.yaml
  • testdata/oc_cli/icsp60499.yaml
  • testdata/oc_cli/icspFile63855.yaml
  • testdata/oc_cli/icspFile64920.yaml
  • testdata/oc_cli/idmsFile63855.yaml
  • testdata/oc_cli/idmsFile64921.yaml
  • testdata/oc_cli/initContainer.yaml
  • testdata/oc_cli/initContainer66989.yaml
  • testdata/oc_cli/mirror-from-filesystem.txt
  • testdata/oc_cli/only-rc.yaml
  • testdata/oc_cli/pod_mirror.yaml
  • testdata/oc_cli/rc-match-service.yaml
  • testdata/oc_cli/stable-storage.yaml
  • testdata/oc_cli/testmapping.txt
  • testdata/oc_cli/update_egressnetworkpolicy.yaml
💤 Files with no reviewable changes (1)
  • test/e2e/e2e.go
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

Files:

  • testdata/oc_cli/initContainer66989.yaml
  • go.mod
  • testdata/oc_cli/case72217/cr-cron-72217.yaml
  • testdata/oc_cli/mirror-from-filesystem.txt
  • testdata/oc_cli/only-rc.yaml
  • testdata/oc_cli/case72217/crd-cattoy-72217.yaml
  • testdata/oc_cli/config_74099.yaml
  • testdata/oc_cli/debugpod_48681.yaml
  • testdata/oc_cli/deploymentconfig_with_quota.yaml
  • testdata/oc_cli/case72217/crd-crontab-72217.yaml
  • testdata/oc_cli/idmsFile63855.yaml
  • testdata/oc_cli/pod_mirror.yaml
  • testdata/oc_cli/config-images-75997.txt
  • testdata/oc_cli/initContainer.yaml
  • testdata/oc_cli/case72217/crd-customtask-72217.yaml
  • testdata/oc_cli/OWNERS
  • testdata/oc_cli/case72217/cr-custom-72217.yaml
  • testdata/oc_cli/idmsFile64921.yaml
  • testdata/oc_cli/icspFile63855.yaml
  • testdata/oc_cli/testmapping.txt
  • testdata/oc_cli/auth.json
  • testdata/oc_cli/icsp60499.yaml
  • testdata/oc_cli/dc_66672.yaml
  • testdata/oc_cli/stable-storage.yaml
  • testdata/oc_cli/icspFile64920.yaml
  • testdata/oc_cli/12708358_4.11.0-0.nightly-multi-2022-04-18-120932-release-imagestream.yaml
  • testdata/oc_cli/case72217/cr-cat-72217.yaml
  • testdata/oc_cli/update_egressnetworkpolicy.yaml
  • testdata/oc_cli/clusterresource_for_user.yaml
  • testdata/oc_cli/rc-match-service.yaml
  • testdata/oc_cli/application-template-stibuild-with-mount-secret.json
  • testdata/oc_cli/egressnetworkpolicy.yaml
  • test/e2e/util.go
  • testdata/oc_cli/build_66672.yaml
🪛 Checkov (3.2.334)
testdata/oc_cli/initContainer66989.yaml

[medium] 1-33: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)


[medium] 1-33: Minimize the admission of root containers

(CKV_K8S_23)

testdata/oc_cli/only-rc.yaml

[medium] 1-31: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)


[medium] 1-31: Minimize the admission of root containers

(CKV_K8S_23)

testdata/oc_cli/config_74099.yaml

[medium] 35-151: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)

testdata/oc_cli/deploymentconfig_with_quota.yaml

[medium] 1-62: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)

testdata/oc_cli/initContainer.yaml

[medium] 1-32: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)


[medium] 1-32: Minimize the admission of root containers

(CKV_K8S_23)

testdata/oc_cli/dc_66672.yaml

[medium] 1-19: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)

testdata/oc_cli/stable-storage.yaml

[medium] 17-60: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)


[medium] 17-60: Minimize the admission of root containers

(CKV_K8S_23)

testdata/oc_cli/rc-match-service.yaml

[medium] 1-31: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)


[medium] 1-31: Minimize the admission of root containers

(CKV_K8S_23)

🪛 Gitleaks (8.30.0)
testdata/oc_cli/auth.json

[high] 4-4: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (30)
testdata/oc_cli/dc_66672.yaml (1)

1-19: Test fixture looks good for CLI e2e testing.

The DeploymentConfig manifest is well-formed with properly matching selector and template labels, and uses a pinned image digest for reproducibility.

Regarding the static analysis hint (CKV_K8S_20): the missing allowPrivilegeEscalation: false is a valid security best practice for production workloads, but is acceptable to omit in test fixtures unless the test specifically validates security context behavior.

testdata/oc_cli/update_egressnetworkpolicy.yaml (1)

1-12: LGTM! Valid test manifest for EgressNetworkPolicy update scenario.

The manifest structure is correct for testing OpenShift egress policy updates. The use of the same metadata.name as the base egressnetworkpolicy.yaml file is appropriate for testing resource update operations.

testdata/oc_cli/egressnetworkpolicy.yaml (1)

1-12: LGTM! Valid test manifest for baseline EgressNetworkPolicy.

The manifest structure is correct for OpenShift egress policy testing. The Allow rule for a specific /32 CIDR followed by a deny-all rule provides appropriate test isolation.

testdata/oc_cli/OWNERS (1)

1-3: LGTM!

Standard OWNERS file format with designated approvers for the testdata directory.

testdata/oc_cli/auth.json (1)

1-7: LGTM - Dummy test credentials are appropriate.

The base64 value decodes to admin:123456, which is clearly placeholder test data. The static analysis false positive can be safely ignored since this is an intentional fixture for testing authentication flows, not real credentials.

testdata/oc_cli/clusterresource_for_user.yaml (1)

1-15: LGTM!

Valid ClusterResourceQuota manifest with reasonable test values. The annotation-based selector pattern is correct for user-scoped quotas.

testdata/oc_cli/mirror-from-filesystem.txt (1)

1-1: LGTM!

Valid image mirror mapping format for filesystem-to-registry test scenarios.

testdata/oc_cli/config-images-75997.txt (1)

1-2: LGTM!

Valid image mapping entries for multi-architecture test scenarios using a local registry destination.

testdata/oc_cli/testmapping.txt (1)

1-1: LGTM!

Valid image mapping format for test fixtures.

testdata/oc_cli/initContainer66989.yaml (1)

1-33: LGTM!

Well-structured Pod manifest for initContainer testing. The pinned image digests ensure test reproducibility. The static analysis security hints (CKV_K8S_20, CKV_K8S_23) are appropriately ignored for test fixtures where minimal security configuration is intentional.

testdata/oc_cli/initContainer.yaml (1)

1-32: LGTM!

Valid Pod manifest for initContainer testing with 10-second sleep. Static analysis security hints are appropriately ignored for test fixtures.

testdata/oc_cli/only-rc.yaml (1)

1-31: LGTM!

Well-structured ReplicationController manifest with properly configured secret volume mount. Static analysis security hints are appropriately ignored for test fixtures.

testdata/oc_cli/debugpod_48681.yaml (1)

1-39: Well-configured security context for test pod.

The template properly enforces security constraints: runAsNonRoot, seccompProfile: RuntimeDefault, allowPrivilegeEscalation: false, and dropped ALL capabilities. This is appropriate for testing secure pod configurations.

testdata/oc_cli/icspFile63855.yaml (1)

1-12: LGTM - valid ICSP test fixture.

The ImageContentSourcePolicy structure is correct for testing mirror configuration scenarios. The hardcoded EC2 hostname is acceptable for test fixtures.

testdata/oc_cli/build_66672.yaml (1)

1-14: LGTM - valid Build test fixture.

The Build configuration is well-structured with a pinned image digest for reproducibility. Appropriate for testing source strategy builds.

testdata/oc_cli/case72217/crd-crontab-72217.yaml (1)

1-30: LGTM!

The CRD manifest is well-structured and follows Kubernetes conventions. The schema, naming, and scope are appropriately defined for test purposes.

testdata/oc_cli/case72217/crd-customtask-72217.yaml (1)

1-30: LGTM!

The CRD manifest follows Kubernetes conventions and is consistent with the other test CRDs in this PR. The schema structure is appropriately defined for test purposes.

go.mod (1)

34-34: goexpect version is appropriate—no updates or security issues.

The goexpect dependency is pinned to v0.0.0-20210430020637, which is the final commit from the google/goexpect repository (April 30, 2021). The repository became archived in February 2023 and has no formal releases or newer versions available. No CVE entries or security vulnerabilities exist for this version. No action required.

testdata/oc_cli/12708358_4.11.0-0.nightly-multi-2022-04-18-120932-release-imagestream.yaml (1)

1-913: LGTM - Test fixture data for ImageStream scenarios.

This is a comprehensive ImageStream test fixture capturing a multi-arch nightly release with documented RPM inconsistencies. The structure is valid and serves its purpose for CLI testing.

test/e2e/util.go (2)

49-66: LGTM - CLI wrapper structure.

The CLI struct and constructor provide a clean fluent API for test command execution.


229-239: LGTM - Project setup with cleanup.

Good use of g.DeferCleanup to ensure test project cleanup.

testdata/oc_cli/icsp60499.yaml (1)

1-12: LGTM - ICSP test fixture.

Valid ImageContentSourcePolicy test fixture. The duplicate mirror entries may be intentional for testing deduplication or redundant configuration handling.

testdata/oc_cli/case72217/cr-cat-72217.yaml (1)

1-6: LGTM - Custom Resource test fixture.

Simple and valid CR instance for testing CRD scenarios with the corresponding Cattoy72217 CRD.

testdata/oc_cli/application-template-stibuild-with-mount-secret.json (1)

244-251: Inconsistent indentation in volume definition.

The volume definition uses mixed tabs and irregular spacing, which differs from the rest of the file's formatting. While JSON parsers will handle this, it reduces readability and maintainability.

🔧 Suggested fix for consistent formatting
-	    "volumes": [
- 	    	{
- 		"name": "mytest-volume",
- 		"secret": {
- 		"secretName": "my-secret"
- 		    }
- 	    	}
- 	    ]
+            "volumes": [
+              {
+                "name": "mytest-volume",
+                "secret": {
+                  "secretName": "my-secret"
+                }
+              }
+            ]

Likely an incorrect or invalid review comment.

testdata/oc_cli/case72217/cr-custom-72217.yaml (1)

1-6: LGTM!

Valid custom resource manifest that correctly references the example.com/v1 API group and Customtask72217 kind defined in the corresponding CRD.

testdata/oc_cli/case72217/cr-cron-72217.yaml (1)

1-6: LGTM!

Valid custom resource manifest for CronTab72217 with correct API group reference.

testdata/oc_cli/idmsFile64921.yaml (1)

1-18: LGTM!

Valid ImageDigestMirrorSet manifest with appropriate localhost mirrors for testing. The explicit mirrorSourcePolicy settings are good practice.

testdata/oc_cli/case72217/crd-cattoy-72217.yaml (1)

1-30: LGTM!

Well-structured CRD manifest with proper OpenAPI v3 schema, correct API version, and all required fields.

testdata/oc_cli/idmsFile63855.yaml (1)

1-12: LGTM!

Valid ImageDigestMirrorSet manifest. The hardcoded EC2 hostname is acceptable for test fixtures where actual connectivity isn't required during test execution.

testdata/oc_cli/icspFile64920.yaml (1)

1-2: Consider updating to the current ImageDigestMirrorSet API if this is not specifically testing backward compatibility.

The operator.openshift.io/v1alpha1 API version for ImageContentSourcePolicy is deprecated as of OpenShift 4.13 and replaced by ImageDigestMirrorSet (using config.openshift.io/v1). While still supported, new test data should use the current stable API unless this file is intended to specifically test ICSP compatibility or migration paths.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines 886 to 1061
func getLatestPayload(url string) string {
res, err := http.Get(url)
if err != nil {
e2e.Failf("unable to get http with error: %v", err)
}
body, err := ioutil.ReadAll(res.Body)
defer res.Body.Close()
if err != nil {
e2e.Failf("unable to parse the http result with error: %v", err)
}

pullSpec := gjson.Get(string(body), `pullSpec`).String()
return pullSpec
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Defer placement after error check can cause resource leak.

The defer res.Body.Close() is placed after error handling for http.Get but the body could still leak if ioutil.ReadAll fails since the defer comes after the first error check but before the read operation succeeds.

🐛 Recommended fix
 func getLatestPayload(url string) string {
 	res, err := http.Get(url)
 	if err != nil {
 		e2e.Failf("unable to get http with error: %v", err)
 	}
+	defer res.Body.Close()
 	body, err := ioutil.ReadAll(res.Body)
-	defer res.Body.Close()
 	if err != nil {
 		e2e.Failf("unable to parse the http result with error: %v", 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 getLatestPayload(url string) string {
res, err := http.Get(url)
if err != nil {
e2e.Failf("unable to get http with error: %v", err)
}
body, err := ioutil.ReadAll(res.Body)
defer res.Body.Close()
if err != nil {
e2e.Failf("unable to parse the http result with error: %v", err)
}
pullSpec := gjson.Get(string(body), `pullSpec`).String()
return pullSpec
}
func getLatestPayload(url string) string {
res, err := http.Get(url)
if err != nil {
e2e.Failf("unable to get http with error: %v", err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
e2e.Failf("unable to parse the http result with error: %v", err)
}
pullSpec := gjson.Get(string(body), `pullSpec`).String()
return pullSpec
}
🤖 Prompt for AI Agents
In `@test/e2e/util.go` around lines 886 - 899, In getLatestPayload, the defer
res.Body.Close() is currently placed after the http.Get error check but before
ioutil.ReadAll, which can still leak the body if ReadAll errors; move the defer
immediately after confirming http.Get returned no error and res != nil (i.e.,
right after the err check) so the response body is guaranteed to be closed on
every return, and ensure any early e2e.Failf paths occur after that placement;
keep existing error handling for ioutil.ReadAll and gjson parsing.

Comment on lines +40 to +42
requests:
cpu: 50m
memory: 40M
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Inconsistent memory unit notation.

Line 42 uses 40M (SI megabytes) while line 54 uses 40Mi (mebibytes). This inconsistency could cause confusion in quota calculations since 40M ≈ 38.15Mi.

For consistency with Kubernetes conventions and the second container's specification:

          requests:
            cpu: 50m
-           memory: 40M
+           memory: 40Mi
📝 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
requests:
cpu: 50m
memory: 40M
requests:
cpu: 50m
memory: 40Mi
🤖 Prompt for AI Agents
In `@testdata/oc_cli/deploymentconfig_with_quota.yaml` around lines 40 - 42, The
memory request for the first container currently uses the SI unit "40M" which is
inconsistent with the second container's "40Mi" and Kubernetes conventions;
update the memory request value under the "requests:" block (the entry currently
"memory: 40M") to use the mebibyte unit "40Mi" so both containers use the same
unit and avoid quota calculation discrepancies.

Copy link

@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

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 6351427 and e918a20.

⛔ Files ignored due to path filters (176)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/containerd/typeurl/v2/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/containerd/typeurl/v2/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/containerd/typeurl/v2/types_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/go-logr/logr/.golangci.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/go-logr/logr/funcr/funcr.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goexpect/AUTHORS is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goexpect/CONTRIBUTING is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goexpect/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goexpect/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goexpect/expect.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goterm/AUTHORS is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goterm/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goterm/term/color.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goterm/term/ssh.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/goterm/term/termios.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/CHANGELOG.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/format/format.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/gomega_dsl.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/assertion.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/async_assertion.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/duration_bundle.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/gomega.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/polling_signal_error.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/vetoptdesc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/and.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/assignable_to_type_of_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_a_directory.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_a_regular_file.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_an_existing_file.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_element_of_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_equivalent_to_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_false_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_identical_to.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_key_of_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_nil_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_numerically_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_temporally_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_true_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_zero_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/consist_of.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_substring_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/equal_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_cap_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_each_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_exact_elements.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_existing_field_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_field.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_header_with_value_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_status_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_key_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_len_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_prefix_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_suffix_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_value.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_iter.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_noiter.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_error_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_json_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_regexp_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_xml_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/not.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/or.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/panic_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/receive_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/satisfy_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/semi_structured_data_support.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/succeed_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/type_support.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/with_transform.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/types/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/opencontainers/image-spec/specs-go/version.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/gjson/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/gjson/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/gjson/SYNTAX.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/gjson/gjson.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/match/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/match/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/match/match.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/pretty/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/pretty/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/pretty/pretty.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/sjson/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/sjson/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/sjson/logo.png is excluded by !**/*.png, !vendor/**, !**/vendor/**
  • vendor/github.com/tidwall/sjson/sjson.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/attribute/filter.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/attribute/internal/attribute.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/attribute/rawhelpers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/attribute/value.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/internal/gen.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/internal/rawhelpers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/auto.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/internal/telemetry/status.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/internal/telemetry/traces.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/internal/telemetry/value.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/noop.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/blowfish/block.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/blowfish/cipher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/blowfish/const.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_arm64.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_arm64.s is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_generic.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_noasm.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_ppc64x.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_ppc64x.s is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_s390x.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/chacha_s390x.s is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/chacha20/xor.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/curve25519/curve25519.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/buffer.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/certs.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/channel.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/cipher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/client.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/client_auth.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/common.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/connection.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/handshake.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/internal/bcrypt_pbkdf/bcrypt_pbkdf.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/kex.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/keys.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/mac.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/messages.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/mlkem.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/mux.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/server.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/session.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/ssh_gss.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/streamlocal.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/tcpip.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/ssh/transport.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/AUTHORS is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/NOTICE.txt is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/codes/code_string.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/codes/codes.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/connectivity/connectivity.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/grpclog/component.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/grpclog/grpclog.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/grpclog/internal/grpclog.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/grpclog/internal/logger.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/grpclog/internal/loggerv2.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/grpclog/logger.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/grpclog/loggerv2.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/internal/experimental.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/internal/internal.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/internal/status/status.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/internal/tcp_keepalive_others.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/internal/tcp_keepalive_unix.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/internal/tcp_keepalive_windows.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/serviceconfig/serviceconfig.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/grpc/status/status.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/protobuf/protoadapt/convert.go is excluded by !vendor/**, !**/vendor/**
  • vendor/gopkg.in/evanphx/json-patch.v4/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/gopkg.in/evanphx/json-patch.v4/patch.go is excluded by !vendor/**, !**/vendor/**
  • vendor/modules.txt is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go is excluded by !vendor/**, !**/vendor/**
📒 Files selected for processing (1)
  • go.mod
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

Files:

  • go.mod
🔇 Additional comments (3)
go.mod (3)

244-244: Investigate the necessity and compatibility of the ginkgo fork.

The replace directive overrides github.com/onsi/ginkgo/v2 with an OpenShift fork based on v2.6.1, while line 40 requires v2.27.2. This represents a significant version gap (21 minor versions behind upstream).

Verify:

  1. Whether the OpenShift fork includes critical patches or OpenShift-specific features that justify the version gap
  2. If the fork is actively maintained and receives security updates
  3. Whether removing the replace directive and using upstream v2.27.2 directly is compatible with the codebase
  4. If this fork replacement is still necessary or can be removed

104-106: Verify compatibility and security for indirect dependency updates against release notes.

Multiple indirect dependencies have been updated including gRPC, Protobuf, OpenTelemetry, and Kubernetes ecosystem packages. While web searches reveal no critical unpatched vulnerabilities in the versions mentioned (Protobuf v1.36.8, OpenTelemetry v1.36.0, containerd/errdefs v1.0.0), check the release notes and changelogs for:

  • gRPC v1.72.2: Verify whether this version addresses known gRPC CVEs (CVE-2024-7246, CVE-2024-11407, and others)
  • All listed updates: Confirm no breaking changes or compatibility issues with your target Kubernetes/gRPC versions

The shell script approach in the original comment has limitations (requires gh CLI with proper authentication); a direct review of project release notes is more reliable.


40-41: No breaking changes or critical issues found in the test framework updates.

Release notes for ginkgo/v2 (v2.21.0→v2.27.2) and gomega (v1.35.1→v1.38.2) show only maintenance fixes and backwards-compatible features. Notable additions include new environment variables (GINKGO_TIME_FORMAT, GINKGO_NO_COLOR) and optional reporting formats (JSON output options, SemVer filtering), but these do not affect existing tests. The updates are safe to apply.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

go.mod Outdated
github.com/go-ldap/ldap/v3 v3.4.11
github.com/gonum/graph v0.0.0-20170401004347-50b27dea7ebb
github.com/google/go-cmp v0.7.0
github.com/google/goexpect v0.0.0-20210430020637-ab937bf7fd6f
Copy link

@coderabbitai coderabbitai bot Jan 15, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

google/goexpect github releases tagged versions

💡 Result:

google/goexpect has no GitHub releases — the repository is archived (read-only) and the Releases page shows "There aren’t any releases here." [1][2]

Sources:

  • google/goexpect repository (archived). [1]
  • google/goexpect Releases page (no releases). [2]

🏁 Script executed:

#!/bin/bash
# Check goexpect repository metadata and release information
# Using curl to query GitHub API without gh CLI

echo "=== Checking for goexpect releases ==="
curl -s https://api.github.com/repos/google/goexpect/releases | jq -r '.[].tag_name' | head -20

echo -e "\n=== Checking latest commits ==="
curl -s https://api.github.com/repos/google/goexpect/commits | jq -r '.[] | "\(.commit.committer.date) - \(.commit.message | split("\n")[0])"' | head -5

echo -e "\n=== Checking repository metadata ==="
curl -s https://api.github.com/repos/google/goexpect | jq '{archived: .archived, updated_at: .updated_at, forks: .forks_count, watchers: .watchers_count, open_issues: .open_issues_count}'

Repository: openshift/oc

Length of output: 168


🏁 Script executed:

#!/bin/bash
# Check if there are any Go security advisories for goexpect
# Search for known vulnerability databases

echo "=== Searching for security information about goexpect ==="
# Check Go vulnerability database
curl -s https://pkg.go.dev/github.com/google/goexpect | grep -i "vulnerability\|security\|deprecated" || echo "No direct security info found"

# Check for any Go mod issues documentation
echo -e "\n=== Checking go.dev package page metadata ==="
curl -s https://pkg.go.dev/api/gomod/github.com/google/goexpect/v0.0.0-20210430020637-ab937bf7fd6f 2>/dev/null | jq '.' || echo "No metadata available for this specific pseudo-version"

Repository: openshift/oc

Length of output: 168


Replace github.com/google/goexpect with an actively maintained alternative.

The google/goexpect repository is archived and has no tagged releases. The pseudo-version points to a commit from April 2021, and the library is no longer maintained. Using archived, unmaintained dependencies introduces maintainability and security risks.

Consider either switching to an actively maintained expect-style testing library or evaluating whether this dependency is still necessary.

Copy link
Member

Choose a reason for hiding this comment

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

We have several dependencies and for the sustainability we can't add new ones. So it is better to add the tests that are using our current libraries without any new dependency.

Copy link

Choose a reason for hiding this comment

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

@ardaguclu Understood — I appreciate you clarifying the project's dependency policy. Keeping the dependency footprint minimal is a sensible approach for sustainability and maintainability.

If the test infrastructure can be refactored to use existing dependencies or built-in Go functionality instead of adding google/goexpect, tidwall/gjson, and tidwall/sjson, that would align with your guidelines. Let me know if you'd like any suggestions on alternative approaches using the current dependency set.

@gangwgr
Copy link
Contributor Author

gangwgr commented Jan 15, 2026

/test unit

Copy link

@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

🤖 Fix all issues with AI agents
In `@testdata/oc_cli/application-template-stibuild-with-mount-secret.json`:
- Around line 200-251: The container "ruby-helloworld" is missing a volumeMount
for the defined secret volume "mytest-volume", so add a "volumeMounts" entry
inside the container spec for the "ruby-helloworld" container that mounts
"mytest-volume" at an appropriate path (e.g., /etc/secret or /etc/my-secret)
with "readOnly": true; ensure the "volumeMounts" array is at the same level as
"env", "resources", and "imagePullPolicy" in the "containers" element so the
secret becomes accessible inside the container.
♻️ Duplicate comments (2)
testdata/oc_cli/rc-match-service.yaml (1)

30-31: Incomplete volume definition will fail validation.

The config volume is missing a volume source (e.g., secret, configMap, emptyDir). Kubernetes will reject this manifest.

testdata/oc_cli/deploymentconfig_with_quota.yaml (1)

40-42: Inconsistent memory unit notation.

Line 42 uses 40M while line 54 uses 40Mi. This mismatch could cause subtle quota calculation differences (40M ≈ 38.15Mi). Align both containers to use 40Mi for consistency.

          requests:
            cpu: 50m
-           memory: 40M
+           memory: 40Mi
🧹 Nitpick comments (4)
testdata/oc_cli/initContainer.yaml (1)

8-26: Consider adding security hardening to match other test fixtures.

The static analysis correctly flags missing security constraints. Unlike debugpod_48681.yaml in this PR which properly configures security, this manifest lacks allowPrivilegeEscalation: false and runAsNonRoot: true. The initContainer also has no securityContext.

If this is intentional for testing permissive scenarios, consider adding a comment. Otherwise, aligning with the hardened pattern improves consistency.

🔒 Suggested security hardening
 spec:
+  securityContext:
+    runAsNonRoot: true
+    seccompProfile:
+      type: RuntimeDefault
   initContainers:
     - name: wait
       image: quay.io/openshifttest/base-alpine@sha256:3126e4eed4a3ebd8bf972b2453fa838200988ee07c01b2251e3ea47e4b1f245c
       command: ["/bin/sh", "-c", "sleep 10"]
+      securityContext:
+        allowPrivilegeEscalation: false
+        capabilities:
+          drop:
+            - ALL
   containers:
     - image: "quay.io/openshifttest/hello-openshift@sha256:4200f438cf2e9446f6bcff9d67ceea1f69ed07a2f83363b7fb52529f7ddd8a83"
       ...
       securityContext:
-        capabilities: {}
-        privileged: false
+        allowPrivilegeEscalation: false
+        capabilities:
+          drop:
+            - ALL
testdata/oc_cli/initContainer66989.yaml (1)

1-33: Same security hardening recommendation applies.

This manifest is nearly identical to initContainer.yaml with a longer sleep duration. The same security context improvements suggested for that file apply here.

The trailing status: {} on line 33 is typically server-populated and unnecessary in a source manifest, though it's harmless.

testdata/oc_cli/stable-storage.yaml (1)

31-32: Deprecated annotation present.

The annotation pod.alpha.kubernetes.io/initialized is from very old Kubernetes versions (pre-1.5) and is no longer functional. If this testdata is meant to test handling of legacy manifests, this is intentional. Otherwise, it can be removed.

testdata/oc_cli/application-template-stibuild-with-mount-secret.json (1)

244-251: Inconsistent indentation in volumes section.

This block uses tabs while the rest of the file uses spaces. Consider normalizing to spaces for consistency.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between e918a20 and 345db6f.

⛔ Files ignored due to path filters (94)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/containerd/typeurl/v2/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/containerd/typeurl/v2/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/containerd/typeurl/v2/types_gogo.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/go-logr/logr/.golangci.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/go-logr/logr/funcr/funcr.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/CHANGELOG.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/format/format.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/gomega_dsl.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/assertion.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/async_assertion.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/duration_bundle.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/gomega.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/polling_signal_error.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/vetoptdesc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/and.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/assignable_to_type_of_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_a_directory.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_a_regular_file.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_an_existing_file.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_element_of_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_equivalent_to_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_false_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_identical_to.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_key_of_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_nil_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_numerically_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_temporally_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_true_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_zero_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/consist_of.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_substring_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/equal_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_cap_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_each_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_exact_elements.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_existing_field_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_field.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_header_with_value_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_status_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_key_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_len_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_prefix_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_suffix_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_value.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_iter.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_noiter.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_error_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_json_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_regexp_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_xml_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/not.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/or.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/panic_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/receive_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/satisfy_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/semi_structured_data_support.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/succeed_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/type_support.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/with_transform.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/types/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/opencontainers/image-spec/specs-go/version.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/attribute/filter.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/attribute/internal/attribute.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/attribute/rawhelpers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/attribute/value.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/internal/gen.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/internal/rawhelpers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/auto.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/internal/telemetry/status.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/internal/telemetry/traces.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/internal/telemetry/value.go is excluded by !vendor/**, !**/vendor/**
  • vendor/go.opentelemetry.io/otel/trace/noop.go is excluded by !vendor/**, !**/vendor/**
  • vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go is excluded by !**/*.pb.go, !vendor/**, !**/vendor/**
  • vendor/gopkg.in/evanphx/json-patch.v4/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/gopkg.in/evanphx/json-patch.v4/patch.go is excluded by !vendor/**, !**/vendor/**
  • vendor/modules.txt is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go is excluded by !vendor/**, !**/vendor/**
📒 Files selected for processing (36)
  • go.mod
  • test/e2e/cli.go
  • test/e2e/e2e.go
  • test/e2e/util.go
  • testdata/oc_cli/12708358_4.11.0-0.nightly-multi-2022-04-18-120932-release-imagestream.yaml
  • testdata/oc_cli/OWNERS
  • testdata/oc_cli/application-template-stibuild-with-mount-secret.json
  • testdata/oc_cli/auth.json
  • testdata/oc_cli/build_66672.yaml
  • testdata/oc_cli/case72217/cr-cat-72217.yaml
  • testdata/oc_cli/case72217/cr-cron-72217.yaml
  • testdata/oc_cli/case72217/cr-custom-72217.yaml
  • testdata/oc_cli/case72217/crd-cattoy-72217.yaml
  • testdata/oc_cli/case72217/crd-crontab-72217.yaml
  • testdata/oc_cli/case72217/crd-customtask-72217.yaml
  • testdata/oc_cli/clusterresource_for_user.yaml
  • testdata/oc_cli/config-images-75997.txt
  • testdata/oc_cli/config_74099.yaml
  • testdata/oc_cli/dc_66672.yaml
  • testdata/oc_cli/debugpod_48681.yaml
  • testdata/oc_cli/deploymentconfig_with_quota.yaml
  • testdata/oc_cli/egressnetworkpolicy.yaml
  • testdata/oc_cli/icsp60499.yaml
  • testdata/oc_cli/icspFile63855.yaml
  • testdata/oc_cli/icspFile64920.yaml
  • testdata/oc_cli/idmsFile63855.yaml
  • testdata/oc_cli/idmsFile64921.yaml
  • testdata/oc_cli/initContainer.yaml
  • testdata/oc_cli/initContainer66989.yaml
  • testdata/oc_cli/mirror-from-filesystem.txt
  • testdata/oc_cli/only-rc.yaml
  • testdata/oc_cli/pod_mirror.yaml
  • testdata/oc_cli/rc-match-service.yaml
  • testdata/oc_cli/stable-storage.yaml
  • testdata/oc_cli/testmapping.txt
  • testdata/oc_cli/update_egressnetworkpolicy.yaml
💤 Files with no reviewable changes (1)
  • test/e2e/e2e.go
✅ Files skipped from review due to trivial changes (4)
  • testdata/oc_cli/case72217/cr-custom-72217.yaml
  • testdata/oc_cli/case72217/crd-cattoy-72217.yaml
  • testdata/oc_cli/mirror-from-filesystem.txt
  • testdata/oc_cli/idmsFile64921.yaml
🚧 Files skipped from review as they are similar to previous changes (15)
  • testdata/oc_cli/OWNERS
  • testdata/oc_cli/update_egressnetworkpolicy.yaml
  • testdata/oc_cli/build_66672.yaml
  • go.mod
  • testdata/oc_cli/idmsFile63855.yaml
  • testdata/oc_cli/pod_mirror.yaml
  • testdata/oc_cli/testmapping.txt
  • testdata/oc_cli/icspFile64920.yaml
  • testdata/oc_cli/case72217/cr-cat-72217.yaml
  • testdata/oc_cli/case72217/cr-cron-72217.yaml
  • testdata/oc_cli/case72217/crd-crontab-72217.yaml
  • testdata/oc_cli/config-images-75997.txt
  • testdata/oc_cli/egressnetworkpolicy.yaml
  • test/e2e/util.go
  • testdata/oc_cli/icsp60499.yaml
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

Files:

  • testdata/oc_cli/debugpod_48681.yaml
  • testdata/oc_cli/initContainer.yaml
  • testdata/oc_cli/clusterresource_for_user.yaml
  • testdata/oc_cli/stable-storage.yaml
  • testdata/oc_cli/12708358_4.11.0-0.nightly-multi-2022-04-18-120932-release-imagestream.yaml
  • testdata/oc_cli/application-template-stibuild-with-mount-secret.json
  • testdata/oc_cli/case72217/crd-customtask-72217.yaml
  • testdata/oc_cli/only-rc.yaml
  • testdata/oc_cli/icspFile63855.yaml
  • testdata/oc_cli/auth.json
  • testdata/oc_cli/config_74099.yaml
  • testdata/oc_cli/dc_66672.yaml
  • testdata/oc_cli/deploymentconfig_with_quota.yaml
  • testdata/oc_cli/initContainer66989.yaml
  • testdata/oc_cli/rc-match-service.yaml
🪛 Checkov (3.2.334)
testdata/oc_cli/initContainer.yaml

[medium] 1-32: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)


[medium] 1-32: Minimize the admission of root containers

(CKV_K8S_23)

testdata/oc_cli/stable-storage.yaml

[medium] 17-60: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)


[medium] 17-60: Minimize the admission of root containers

(CKV_K8S_23)

testdata/oc_cli/only-rc.yaml

[medium] 1-31: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)


[medium] 1-31: Minimize the admission of root containers

(CKV_K8S_23)

testdata/oc_cli/config_74099.yaml

[medium] 35-151: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)

testdata/oc_cli/dc_66672.yaml

[medium] 1-19: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)

testdata/oc_cli/deploymentconfig_with_quota.yaml

[medium] 1-62: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)

testdata/oc_cli/initContainer66989.yaml

[medium] 1-33: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)


[medium] 1-33: Minimize the admission of root containers

(CKV_K8S_23)

testdata/oc_cli/rc-match-service.yaml

[medium] 1-31: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)


[medium] 1-31: Minimize the admission of root containers

(CKV_K8S_23)

🪛 Gitleaks (8.30.0)
testdata/oc_cli/auth.json

[high] 4-4: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (11)
testdata/oc_cli/clusterresource_for_user.yaml (1)

1-15: LGTM!

This is a well-formed ClusterResourceQuota test fixture with valid structure, appropriate quota limits for testing, and correct annotation-based selector configuration.

testdata/oc_cli/auth.json (1)

1-7: LGTM — Test fixture with placeholder credentials.

The static analysis warning is a false positive. The base64 value decodes to admin:123456, which is clearly a dummy credential for test purposes, appropriately located in the testdata/ directory.

testdata/oc_cli/case72217/crd-customtask-72217.yaml (1)

1-30: LGTM!

This is a well-structured CRD test fixture. The manifest follows the Kubernetes apiextensions.k8s.io/v1 API specification correctly with proper versioning, schema definition, and naming configuration.

testdata/oc_cli/icspFile63855.yaml (1)

1-12: LGTM!

The ImageContentSourcePolicy manifest is well-structured with valid apiVersion, kind, metadata, and spec fields. The two repositoryDigestMirrors entries correctly map upstream sources to the mirror registry.

testdata/oc_cli/only-rc.yaml (1)

1-31: LGTM!

The ReplicationController manifest is well-formed with a properly configured secret volume source. Suitable for test data purposes.

testdata/oc_cli/deploymentconfig_with_quota.yaml (1)

45-56: LGTM!

Second container configuration is well-defined with consistent resource units.

testdata/oc_cli/debugpod_48681.yaml (1)

1-39: Well-configured security context for test pod.

The template properly enforces restricted Pod Security Standards with runAsNonRoot, seccompProfile: RuntimeDefault, allowPrivilegeEscalation: false, and drops all capabilities. This is a good practice even for test fixtures.

testdata/oc_cli/config_74099.yaml (1)

1-151: Testdata fixture looks appropriate for CLI testing.

This manifest provides good coverage for testing DeploymentConfig with secrets, probes, and deployment strategy. The hardcoded values (clusterIP, route host, namespace) are acceptable for test fixtures.

Regarding the static analysis hint (CKV_K8S_20): the allowPrivilegeEscalation warning is not actionable here since this is testdata for CLI validation, not a production deployment manifest.

testdata/oc_cli/dc_66672.yaml (1)

1-19: Minimal DeploymentConfig fixture is valid.

This provides a clean minimal manifest for testing basic DeploymentConfig operations. The static analysis warning (CKV_K8S_20) is not applicable for test fixtures.

testdata/oc_cli/stable-storage.yaml (1)

1-60: StatefulSet fixture is suitable for testing.

The manifest correctly defines a headless Service for StatefulSet DNS and includes PVC templates for storage testing. The static analysis warnings (CKV_K8S_20, CKV_K8S_23) are not actionable for test fixtures.

testdata/oc_cli/12708358_4.11.0-0.nightly-multi-2022-04-18-120932-release-imagestream.yaml (1)

1-913: ImageStream fixture is appropriate for release image testing.

This comprehensive release ImageStream snapshot provides excellent coverage for testing oc commands related to image operations (mirror, extract, info). The embedded inconsistency annotations accurately reflect real-world release scenarios and will help validate CLI handling of such metadata.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines 200 to 251
"spec": {
"containers": [
{
"name": "ruby-helloworld",
"image": "origin-ruby-sample",
"ports": [
{
"containerPort": 8080,
"protocol": "TCP"
}
],
"env": [
{
"name": "ADMIN_USERNAME",
"value": "${ADMIN_USERNAME}"
},
{
"name": "ADMIN_PASSWORD",
"value": "${ADMIN_PASSWORD}"
},
{
"name": "MYSQL_USER",
"value": "${MYSQL_USER}"
},
{
"name": "MYSQL_PASSWORD",
"value": "${MYSQL_PASSWORD}"
},
{
"name": "MYSQL_DATABASE",
"value": "${MYSQL_DATABASE}"
}
],
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"imagePullPolicy": "IfNotPresent",
"securityContext": {
"capabilities": {},
"privileged": false
}
}
],
"restartPolicy": "Always",
"dnsPolicy": "ClusterFirst",
"volumes": [
{
"name": "mytest-volume",
"secret": {
"secretName": "my-secret"
}
}
]
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Missing volumeMounts for the secret volume.

The volumes section defines mytest-volume backed by secret my-secret, but the container ruby-helloworld lacks a corresponding volumeMounts entry. The secret won't be accessible inside the container.

Given the template name emphasizes "with-mount-secret", this appears unintentional.

Proposed fix
               "resources": {},
               "terminationMessagePath": "/dev/termination-log",
               "imagePullPolicy": "IfNotPresent",
+              "volumeMounts": [
+                {
+                  "name": "mytest-volume",
+                  "mountPath": "/etc/secret-volume",
+                  "readOnly": true
+                }
+              ],
               "securityContext": {
                 "capabilities": {},
                 "privileged": false
               }
📝 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
"spec": {
"containers": [
{
"name": "ruby-helloworld",
"image": "origin-ruby-sample",
"ports": [
{
"containerPort": 8080,
"protocol": "TCP"
}
],
"env": [
{
"name": "ADMIN_USERNAME",
"value": "${ADMIN_USERNAME}"
},
{
"name": "ADMIN_PASSWORD",
"value": "${ADMIN_PASSWORD}"
},
{
"name": "MYSQL_USER",
"value": "${MYSQL_USER}"
},
{
"name": "MYSQL_PASSWORD",
"value": "${MYSQL_PASSWORD}"
},
{
"name": "MYSQL_DATABASE",
"value": "${MYSQL_DATABASE}"
}
],
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"imagePullPolicy": "IfNotPresent",
"securityContext": {
"capabilities": {},
"privileged": false
}
}
],
"restartPolicy": "Always",
"dnsPolicy": "ClusterFirst",
"volumes": [
{
"name": "mytest-volume",
"secret": {
"secretName": "my-secret"
}
}
]
"spec": {
"containers": [
{
"name": "ruby-helloworld",
"image": "origin-ruby-sample",
"ports": [
{
"containerPort": 8080,
"protocol": "TCP"
}
],
"env": [
{
"name": "ADMIN_USERNAME",
"value": "${ADMIN_USERNAME}"
},
{
"name": "ADMIN_PASSWORD",
"value": "${ADMIN_PASSWORD}"
},
{
"name": "MYSQL_USER",
"value": "${MYSQL_USER}"
},
{
"name": "MYSQL_PASSWORD",
"value": "${MYSQL_PASSWORD}"
},
{
"name": "MYSQL_DATABASE",
"value": "${MYSQL_DATABASE}"
}
],
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"imagePullPolicy": "IfNotPresent",
"volumeMounts": [
{
"name": "mytest-volume",
"mountPath": "/etc/secret-volume",
"readOnly": true
}
],
"securityContext": {
"capabilities": {},
"privileged": false
}
}
],
"restartPolicy": "Always",
"dnsPolicy": "ClusterFirst",
"volumes": [
{
"name": "mytest-volume",
"secret": {
"secretName": "my-secret"
}
}
]
🤖 Prompt for AI Agents
In `@testdata/oc_cli/application-template-stibuild-with-mount-secret.json` around
lines 200 - 251, The container "ruby-helloworld" is missing a volumeMount for
the defined secret volume "mytest-volume", so add a "volumeMounts" entry inside
the container spec for the "ruby-helloworld" container that mounts
"mytest-volume" at an appropriate path (e.g., /etc/secret or /etc/my-secret)
with "readOnly": true; ensure the "volumeMounts" array is at the same level as
"env", "resources", and "imagePullPolicy" in the "containers" element so the
secret becomes accessible inside the container.

@gangwgr gangwgr changed the title Migrating oc cli tests to ote [WIP]Migrating oc cli tests to ote Jan 15, 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 15, 2026
@gangwgr gangwgr force-pushed the cli-tests branch 13 times, most recently from 9135593 to fc528a8 Compare January 19, 2026 10:08
@gangwgr
Copy link
Contributor Author

gangwgr commented Jan 19, 2026

/test e2e-aws-ovn-serial-2of2

@gangwgr
Copy link
Contributor Author

gangwgr commented Jan 19, 2026

/retest

3 similar comments
@gangwgr
Copy link
Contributor Author

gangwgr commented Jan 19, 2026

/retest

@gangwgr
Copy link
Contributor Author

gangwgr commented Jan 19, 2026

/retest

@gangwgr
Copy link
Contributor Author

gangwgr commented Jan 19, 2026

/retest

Copy link

@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: 3

🤖 Fix all issues with AI agents
In `@test/e2e/cli.go`:
- Around line 123-125: The skip condition in the g.It test uses && with
isEnabledCapability but due to operator precedence it only applies to the last
isBaselineCapsSet call; update the if condition so the ORed baseline checks are
grouped before applying the capability gate (e.g., wrap the series of
isBaselineCapsSet(...) || ... || isBaselineCapsSet(...) in parentheses) so the
combined baseline check is evaluated first and then && !isEnabledCapability(oc,
"DeploymentConfig") is applied; locate the condition in the test function (g.It)
where isBaselineCapsSet and isEnabledCapability are used and add the grouping to
fix the precedence.
- Around line 272-274: The deferred cmd.Process.Kill() can panic if
oc.Run(...).Background() fails and returns a nil cmd; update the Background()
call handling around the cmd, err return (the variables named cmd and err from
oc.Run("debug").Args(...).Background()) so you only defer killing the process
when cmd and cmd.Process are non-nil—either by checking err==nil before
installing the defer or by using a safe deferred closure that verifies cmd !=
nil && cmd.Process != nil before calling Kill(); ensure the
Expect(err).NotTo(HaveOccurred()) remains after the creation check so failures
still fail the test.
- Around line 466-487: The current if/else chain uses Ginkgo assertions
(o.Expect(...).To(o.BeTrue())) as branch conditions which panic on failure and
prevent subsequent branches from running; change the detection logic to use
plain boolean checks with strings.Contains(architectureStr, "...") for each
architecture (e.g., "x86_64", "aarch64", "ppc64le", "s390x") to select the
correct branch, and then perform assertions only on imageInfo inside each branch
(use o.Expect(strings.Contains(imageInfo, "<expected>")).To(o.BeTrue()) and
e2e.Logf/e2e.Failf as before), referencing the existing architectureStr and
imageInfo variables and preserving the same branch messages.

Comment on lines +123 to +125
g.It("ROSA-OSD_CCS-ARO-NonPreRelease-Longduration-Author:yinzhou-High-42982-Describe quota output should always show units [Timeout:30m]", func() {
if isBaselineCapsSet(oc, "None") || isBaselineCapsSet(oc, "v4.13") || isBaselineCapsSet(oc, "v4.12") || isBaselineCapsSet(oc, "v4.14") || isBaselineCapsSet(oc, "v4.15") || isBaselineCapsSet(oc, "v4.11") && !isEnabledCapability(oc, "DeploymentConfig") {
skipMsg := "Skipping the test as baselinecaps have been set to None and some of API capabilities are not enabled!"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix baseline capability skip condition precedence.
&& !isEnabledCapability(...) only binds to the final isBaselineCapsSet check due to operator precedence, so the test can skip even when DeploymentConfig is enabled. Wrap the baseline-cap checks before applying the capability gate.

🔧 Proposed fix
-		if isBaselineCapsSet(oc, "None") || isBaselineCapsSet(oc, "v4.13") || isBaselineCapsSet(oc, "v4.12") || isBaselineCapsSet(oc, "v4.14") || isBaselineCapsSet(oc, "v4.15") || isBaselineCapsSet(oc, "v4.11") && !isEnabledCapability(oc, "DeploymentConfig") {
+		if (isBaselineCapsSet(oc, "None") || isBaselineCapsSet(oc, "v4.13") || isBaselineCapsSet(oc, "v4.12") || isBaselineCapsSet(oc, "v4.14") || isBaselineCapsSet(oc, "v4.15") || isBaselineCapsSet(oc, "v4.11")) && !isEnabledCapability(oc, "DeploymentConfig") {
📝 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
g.It("ROSA-OSD_CCS-ARO-NonPreRelease-Longduration-Author:yinzhou-High-42982-Describe quota output should always show units [Timeout:30m]", func() {
if isBaselineCapsSet(oc, "None") || isBaselineCapsSet(oc, "v4.13") || isBaselineCapsSet(oc, "v4.12") || isBaselineCapsSet(oc, "v4.14") || isBaselineCapsSet(oc, "v4.15") || isBaselineCapsSet(oc, "v4.11") && !isEnabledCapability(oc, "DeploymentConfig") {
skipMsg := "Skipping the test as baselinecaps have been set to None and some of API capabilities are not enabled!"
g.It("ROSA-OSD_CCS-ARO-NonPreRelease-Longduration-Author:yinzhou-High-42982-Describe quota output should always show units [Timeout:30m]", func() {
if (isBaselineCapsSet(oc, "None") || isBaselineCapsSet(oc, "v4.13") || isBaselineCapsSet(oc, "v4.12") || isBaselineCapsSet(oc, "v4.14") || isBaselineCapsSet(oc, "v4.15") || isBaselineCapsSet(oc, "v4.11")) && !isEnabledCapability(oc, "DeploymentConfig") {
skipMsg := "Skipping the test as baselinecaps have been set to None and some of API capabilities are not enabled!"
🤖 Prompt for AI Agents
In `@test/e2e/cli.go` around lines 123 - 125, The skip condition in the g.It test
uses && with isEnabledCapability but due to operator precedence it only applies
to the last isBaselineCapsSet call; update the if condition so the ORed baseline
checks are grouped before applying the capability gate (e.g., wrap the series of
isBaselineCapsSet(...) || ... || isBaselineCapsSet(...) in parentheses) so the
combined baseline check is evaluated first and then && !isEnabledCapability(oc,
"DeploymentConfig") is applied; locate the condition in the test function (g.It)
where isBaselineCapsSet and isEnabledCapability are used and add the grouping to
fix the precedence.

Comment on lines +272 to +277
cmd, _, _, err := oc.Run("debug").Args("pod/hello-pod", "--keep-init-containers=true").Background()
defer cmd.Process.Kill()
o.Expect(err).NotTo(o.HaveOccurred())
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard deferred Process.Kill() when background start fails.
If Background() returns an error, cmd.Process can be nil and the deferred kill will panic.

🔧 Proposed fix
-		cmd, _, _, err := oc.Run("debug").Args("pod/hello-pod", "--keep-init-containers=true").Background()
-		defer cmd.Process.Kill()
-		o.Expect(err).NotTo(o.HaveOccurred())
+		cmd, _, _, err := oc.Run("debug").Args("pod/hello-pod", "--keep-init-containers=true").Background()
+		o.Expect(err).NotTo(o.HaveOccurred())
+		if cmd != nil && cmd.Process != nil {
+			defer cmd.Process.Kill()
+		}
📝 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
cmd, _, _, err := oc.Run("debug").Args("pod/hello-pod", "--keep-init-containers=true").Background()
defer cmd.Process.Kill()
o.Expect(err).NotTo(o.HaveOccurred())
cmd, _, _, err := oc.Run("debug").Args("pod/hello-pod", "--keep-init-containers=true").Background()
o.Expect(err).NotTo(o.HaveOccurred())
if cmd != nil && cmd.Process != nil {
defer cmd.Process.Kill()
}
🤖 Prompt for AI Agents
In `@test/e2e/cli.go` around lines 272 - 274, The deferred cmd.Process.Kill() can
panic if oc.Run(...).Background() fails and returns a nil cmd; update the
Background() call handling around the cmd, err return (the variables named cmd
and err from oc.Run("debug").Args(...).Background()) so you only defer killing
the process when cmd and cmd.Process are non-nil—either by checking err==nil
before installing the defer or by using a safe deferred closure that verifies
cmd != nil && cmd.Process != nil before calling Kill(); ensure the
Expect(err).NotTo(HaveOccurred()) remains after the creation check so failures
still fail the test.

Comment on lines +466 to +490
o.Expect(err).NotTo(o.HaveOccurred())
architectureStr := string(architecture)
if o.Expect(strings.Contains(architectureStr, "x86_64")).To(o.BeTrue()) {
if o.Expect(strings.Contains(imageInfo, "amd64")).To(o.BeTrue()) {
e2e.Logf("Found the expected Arch amd64")
} else {
e2e.Failf("Failed to find the expected Arch for mirrored image")
}
} else if o.Expect(strings.Contains(architectureStr, "aarch64")).To(o.BeTrue()) {
if o.Expect(strings.Contains(imageInfo, "arm64")).To(o.BeTrue()) {
e2e.Logf("Found the expected Arch aarch64")
} else {
e2e.Failf("Failed to find the expected Arch for mirrored image")
}
} else if o.Expect(strings.Contains(architectureStr, "ppc64le")).To(o.BeTrue()) {
if o.Expect(strings.Contains(imageInfo, "ppc64le")).To(o.BeTrue()) {
e2e.Logf("Found the expected Arch ppc64le")
} else {
e2e.Failf("Failed to find the expected Arch for mirrored image")
}
} else {
if o.Expect(strings.Contains(imageInfo, "s390x")).To(o.BeTrue()) {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, verify the code exists at the specified location
cd /tmp && find . -name "cli.go" -path "*/e2e/*" 2>/dev/null | head -5

Repository: openshift/oc

Length of output: 38


🏁 Script executed:

# List repository structure to locate the test file
git ls-files test/e2e/ | head -20

Repository: openshift/oc

Length of output: 88


🏁 Script executed:

# Read the specific lines mentioned in the review
if git ls-files test/e2e/cli.go > /dev/null 2>&1; then
  echo "File found. Reading lines 466-487:"
  sed -n '466,487p' test/e2e/cli.go
fi

Repository: openshift/oc

Length of output: 1109


🏁 Script executed:

# Get more context around these lines to understand the function
if git ls-files test/e2e/cli.go > /dev/null 2>&1; then
  echo "Extended context (lines 450-500):"
  sed -n '450,500p' test/e2e/cli.go | cat -n
fi

Repository: openshift/oc

Length of output: 2727


🏁 Script executed:

# Search for similar patterns in the codebase
rg "if o\.Expect" test/e2e/ --context 2

Repository: openshift/oc

Length of output: 1434


🏁 Script executed:

# Check imports to confirm the assertion library
head -50 test/e2e/cli.go | grep -E "import|gomega|ginkgo"

Repository: openshift/oc

Length of output: 123


🌐 Web query:

Ginkgo Gomega o.Expect().To() return value conditional if statement

💡 Result:

Expect(x).To(matcher) does return a bool (true if it passed, false if it failed). [1]

However, under Ginkgo, a failed Gomega assertion calls Fail, and Fail panics to end the current spec, so you generally can’t use Expect(...).To(...) as a normal if condition for control flow (your code won’t reliably reach the else/next lines on failure). [2]

If you need a conditional check without failing the spec, use one of these patterns:

1) Call the matcher directly (pure boolean)

ok, err := Equal(42).Match(actual) // any GomegaMatcher works
if err != nil { /* matcher error */ }
if ok {
    // passed
} else {
    // failed (no Ginkgo failure triggered)
}

2) Intercept assertion failures (keeps Gomega style)

if err := gomega.InterceptGomegaFailure(func() {
    Expect(actual).To(Equal(42))
}); err == nil {
    // passed
} else {
    // failed; err contains the failure message
}

InterceptGomegaFailure prevents registering the failure with the global fail handler and returns it as an error. [3]


Separate detection from assertion to fix architecture branching on non-x86 systems.

Using o.Expect(...).To(o.BeTrue()) in if conditions causes Ginkgo to panic on assertion failure, preventing else-if branches from being reached. On aarch64, ppc64le, and s390x systems, the first condition fails immediately and terminates the test, bypassing the correct architecture path.

Use plain strings.Contains() checks for detection logic, then assert only on the imageInfo result:

Suggested refactor
 		architectureStr := string(architecture)
-		if o.Expect(strings.Contains(architectureStr, "x86_64")).To(o.BeTrue()) {
-			if o.Expect(strings.Contains(imageInfo, "amd64")).To(o.BeTrue()) {
-				e2e.Logf("Found the expected Arch amd64")
-			} else {
-				e2e.Failf("Failed to find the expected Arch for mirrored image")
-			}
-		} else if o.Expect(strings.Contains(architectureStr, "aarch64")).To(o.BeTrue()) {
-			if o.Expect(strings.Contains(imageInfo, "arm64")).To(o.BeTrue()) {
-				e2e.Logf("Found the expected Arch aarch64")
-			} else {
-				e2e.Failf("Failed to find the expected Arch for mirrored image")
-			}
-		} else if o.Expect(strings.Contains(architectureStr, "ppc64le")).To(o.BeTrue()) {
-			if o.Expect(strings.Contains(imageInfo, "ppc64le")).To(o.BeTrue()) {
-				e2e.Logf("Found the expected Arch ppc64le")
-			} else {
-				e2e.Failf("Failed to find the expected Arch for mirrored image")
-			}
-		} else {
-			if o.Expect(strings.Contains(imageInfo, "s390x")).To(o.BeTrue()) {
-				e2e.Logf("Found the expected Arch s390x")
-			} else {
-				e2e.Failf("Failed to find the expected Arch for mirrored image")
-			}
-		}
+		switch {
+		case strings.Contains(architectureStr, "x86_64"):
+			o.Expect(imageInfo).To(o.ContainSubstring("amd64"))
+			e2e.Logf("Found the expected Arch amd64")
+		case strings.Contains(architectureStr, "aarch64"):
+			o.Expect(imageInfo).To(o.ContainSubstring("arm64"))
+			e2e.Logf("Found the expected Arch aarch64")
+		case strings.Contains(architectureStr, "ppc64le"):
+			o.Expect(imageInfo).To(o.ContainSubstring("ppc64le"))
+			e2e.Logf("Found the expected Arch ppc64le")
+		case strings.Contains(architectureStr, "s390x"):
+			o.Expect(imageInfo).To(o.ContainSubstring("s390x"))
+			e2e.Logf("Found the expected Arch s390x")
+		default:
+			e2e.Failf("Unknown architecture: %s", architectureStr)
+		}
📝 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
o.Expect(err).NotTo(o.HaveOccurred())
architectureStr := string(architecture)
if o.Expect(strings.Contains(architectureStr, "x86_64")).To(o.BeTrue()) {
if o.Expect(strings.Contains(imageInfo, "amd64")).To(o.BeTrue()) {
e2e.Logf("Found the expected Arch amd64")
} else {
e2e.Failf("Failed to find the expected Arch for mirrored image")
}
} else if o.Expect(strings.Contains(architectureStr, "aarch64")).To(o.BeTrue()) {
if o.Expect(strings.Contains(imageInfo, "arm64")).To(o.BeTrue()) {
e2e.Logf("Found the expected Arch aarch64")
} else {
e2e.Failf("Failed to find the expected Arch for mirrored image")
}
} else if o.Expect(strings.Contains(architectureStr, "ppc64le")).To(o.BeTrue()) {
if o.Expect(strings.Contains(imageInfo, "ppc64le")).To(o.BeTrue()) {
e2e.Logf("Found the expected Arch ppc64le")
} else {
e2e.Failf("Failed to find the expected Arch for mirrored image")
}
} else {
if o.Expect(strings.Contains(imageInfo, "s390x")).To(o.BeTrue()) {
o.Expect(err).NotTo(o.HaveOccurred())
architectureStr := string(architecture)
switch {
case strings.Contains(architectureStr, "x86_64"):
o.Expect(imageInfo).To(o.ContainSubstring("amd64"))
e2e.Logf("Found the expected Arch amd64")
case strings.Contains(architectureStr, "aarch64"):
o.Expect(imageInfo).To(o.ContainSubstring("arm64"))
e2e.Logf("Found the expected Arch aarch64")
case strings.Contains(architectureStr, "ppc64le"):
o.Expect(imageInfo).To(o.ContainSubstring("ppc64le"))
e2e.Logf("Found the expected Arch ppc64le")
case strings.Contains(architectureStr, "s390x"):
o.Expect(imageInfo).To(o.ContainSubstring("s390x"))
e2e.Logf("Found the expected Arch s390x")
default:
e2e.Failf("Unknown architecture: %s", architectureStr)
}
🤖 Prompt for AI Agents
In `@test/e2e/cli.go` around lines 466 - 487, The current if/else chain uses
Ginkgo assertions (o.Expect(...).To(o.BeTrue())) as branch conditions which
panic on failure and prevent subsequent branches from running; change the
detection logic to use plain boolean checks with
strings.Contains(architectureStr, "...") for each architecture (e.g., "x86_64",
"aarch64", "ppc64le", "s390x") to select the correct branch, and then perform
assertions only on imageInfo inside each branch (use
o.Expect(strings.Contains(imageInfo, "<expected>")).To(o.BeTrue()) and
e2e.Logf/e2e.Failf as before), referencing the existing architectureStr and
imageInfo variables and preserving the same branch messages.

return string(buffer)
}

func (registry *registry) createregistry(oc *CLI) serviceInfo {
Copy link
Member

Choose a reason for hiding this comment

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

This function is only used by oc image mirror with multi-arch images and --filter-by-os test. Maybe we can remove it as well as this registry struct?

test/e2e/util.go Outdated
return true
}

func checkPodmanCred() bool {
Copy link
Member

Choose a reason for hiding this comment

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

Who is using this function?

test/e2e/util.go Outdated
return networkType
}

func checkDockerCred() bool {
Copy link
Member

Choose a reason for hiding this comment

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

Who is using this function?

@@ -0,0 +1,1636 @@
package e2e
Copy link
Member

Choose a reason for hiding this comment

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

Could you please remove the unused functions in this util.go

spec:
repositoryDigestMirrors:
- mirrors:
- ec2-3-133-161-121.us-east-2.compute.amazonaws.com:5000/ocp/release
Copy link
Member

Choose a reason for hiding this comment

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

This is hardcoded value which might be unwanted. Can we remove this file or use better dns name?

Comment on lines 8 to 27
initContainers:
- name: wait
image: quay.io/openshifttest/base-alpine@sha256:3126e4eed4a3ebd8bf972b2453fa838200988ee07c01b2251e3ea47e4b1f245c
command: ["/bin/sh", "-c", "sleep 10"]
containers:
- image: "quay.io/openshifttest/hello-openshift@sha256:4200f438cf2e9446f6bcff9d67ceea1f69ed07a2f83363b7fb52529f7ddd8a83"
imagePullPolicy: IfNotPresent
name: hello-pod
ports:
- containerPort: 8080
protocol: TCP
resources: {}
securityContext:
capabilities: {}
privileged: false
terminationMessagePath: /dev/termination-log
volumeMounts:
- mountPath: /tmp
name: tmp
dnsPolicy: ClusterFirst
Copy link
Member

Choose a reason for hiding this comment

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

Can we remove dnsPolicy as well as suggested updates ^^

Comment on lines 8 to 22
initContainers:
- name: wait
image: quay.io/openshifttest/base-alpine@sha256:3126e4eed4a3ebd8bf972b2453fa838200988ee07c01b2251e3ea47e4b1f245c
command: ["/bin/sh", "-c", "sleep 30"]
containers:
- image: "quay.io/openshifttest/hello-openshift@sha256:4200f438cf2e9446f6bcff9d67ceea1f69ed07a2f83363b7fb52529f7ddd8a83"
imagePullPolicy: IfNotPresent
name: hello-pod
ports:
- containerPort: 8080
protocol: TCP
resources: {}
securityContext:
capabilities: {}
privileged: false
Copy link
Member

Choose a reason for hiding this comment

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

same ^^

Comment on lines 14 to 27
containers:
- args:
- start
- master
- --config=/config/master-config.yaml
image: "quay.io/openshifttest/base-alpine@sha256:3126e4eed4a3ebd8bf972b2453fa838200988ee07c01b2251e3ea47e4b1f245c"
name: origin
ports:
- containerPort: 8443
name: openshift
volumeMounts:
- mountPath: /config
name: config
readOnly: true
Copy link
Member

Choose a reason for hiding this comment

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

same ^^

@gangwgr gangwgr force-pushed the cli-tests branch 2 times, most recently from d172801 to 3e0ec9e Compare January 27, 2026 10:56
Copy link

@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

🤖 Fix all issues with AI agents
In `@test/testdata/oc_cli/case72217/crd-cattoy-72217.yaml`:
- Around line 29-30: The CRDs crd-cattoy-72217.yaml, crd-crontab-72217.yaml, and
crd-customtask-72217.yaml all declare the identical shortName `ct72217`, which
will conflict when applied; update the shortNames in these manifests to unique
values (for example change `ct72217` in crd-cattoy-72217.yaml to `cat72217`, in
crd-crontab-72217.yaml to `cron72217`, and in crd-customtask-72217.yaml to
`ctask72217`) or confirm the duplicate is intentional for collision tests and
add a comment explaining that intent.
🧹 Nitpick comments (1)
test/e2e/util.go (1)

11-11: ioutil package is deprecated.

The io/ioutil package is deprecated since Go 1.16. Consider using io and os packages instead (e.g., io.ReadAll, os.ReadFile, os.WriteFile).

Comment on lines +29 to +30
shortNames:
- ct72217
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, list all YAML files in the case72217 directory
ls -la test/testdata/oc_cli/case72217/ | grep -E "\.yaml$|\.yml$"

Repository: openshift/oc

Length of output: 472


🏁 Script executed:

# Check all YAML files in the directory for shortName definitions
find test/testdata/oc_cli/case72217 -name "*.yaml" -o -name "*.yml" | head -20

Repository: openshift/oc

Length of output: 370


🏁 Script executed:

# Search for ct72217 shortName across all files in the directory
grep -r "ct72217" test/testdata/oc_cli/case72217/

Repository: openshift/oc

Length of output: 261


🏁 Script executed:

# Read the two specific CRD files to see the full context
echo "=== crd-cattoy-72217.yaml ===" && cat test/testdata/oc_cli/case72217/crd-cattoy-72217.yaml && echo -e "\n=== crd-crontab-72217.yaml ===" && cat test/testdata/oc_cli/case72217/crd-crontab-72217.yaml

Repository: openshift/oc

Length of output: 1463


🏁 Script executed:

# Check the third CRD file to confirm completeness
cat test/testdata/oc_cli/case72217/crd-customtask-72217.yaml

Repository: openshift/oc

Length of output: 730


Duplicate shortName ct72217 across three CRDs may cause conflicts.

Three CRDs in this directory define the same shortName: crd-cattoy-72217.yaml, crd-crontab-72217.yaml, and crd-customtask-72217.yaml. If all are applied to the same cluster, kubectl get ct72217 will be ambiguous. Verify if this is intentional for testing collision behavior, or update the shortNames to be unique (e.g., cat72217, cron72217, ctask72217).

🤖 Prompt for AI Agents
In `@test/testdata/oc_cli/case72217/crd-cattoy-72217.yaml` around lines 29 - 30,
The CRDs crd-cattoy-72217.yaml, crd-crontab-72217.yaml, and
crd-customtask-72217.yaml all declare the identical shortName `ct72217`, which
will conflict when applied; update the shortNames in these manifests to unique
values (for example change `ct72217` in crd-cattoy-72217.yaml to `cat72217`, in
crd-crontab-72217.yaml to `cron72217`, and in crd-customtask-72217.yaml to
`ctask72217`) or confirm the duplicate is intentional for collision tests and
add a comment explaining that intent.

Copy link
Member

@ardaguclu ardaguclu left a comment

Choose a reason for hiding this comment

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

I've detected many unused functions and files. Could you please remove them. Additionally, when I look at the sample run, I'm seeing that some tests are skipped https://prow.ci.openshift.org/view/gs/test-platform-results/pr-logs/pull/openshift_oc/2181/pull-ci-openshift-oc-main-e2e-aws-oc-ote/2016102965441466368. I don't think currently environment is disconnected, so either we need to fix the issues or remove those tests.

test/e2e/cli.go Outdated

// Extract secret and store it
extractTmpDirName := "/tmp/case64921"
err = os.MkdirAll(extractTmpDirName, 0755)
Copy link
Member

Choose a reason for hiding this comment

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

Needs to be less privileged rather than 0755

test/e2e/cli.go Outdated
}

extractTmpDirName := "/tmp/d71178"
err := os.MkdirAll(extractTmpDirName, 0755)
Copy link
Member

Choose a reason for hiding this comment

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

same

test/e2e/cli.go Outdated
}
extractTmpDirName := "/tmp/case71273"
defer os.RemoveAll(extractTmpDirName)
err := os.MkdirAll(extractTmpDirName, 0755)
Copy link
Member

Choose a reason for hiding this comment

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

same


if d.IsDir() {
// Create directory
return os.MkdirAll(target, 0755)
Copy link
Member

Choose a reason for hiding this comment

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

same

}

// Create parent directory
if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

same

test/e2e/util.go Outdated
}

// wait for DC to be ready
func waitForDeploymentconfigToBeReady(oc *CLI, namespace string, name string) {
Copy link
Member

Choose a reason for hiding this comment

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

unused and can be removed.

@@ -0,0 +1,421 @@
{
Copy link
Member

Choose a reason for hiding this comment

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

Unused and can be removed?

@@ -0,0 +1,31 @@
apiVersion: v1
Copy link
Member

Choose a reason for hiding this comment

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

Unused and can be removed?

@@ -0,0 +1,32 @@
apiVersion: v1
Copy link
Member

Choose a reason for hiding this comment

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

Unused and can be removed?

@@ -0,0 +1,23 @@
server:
Copy link
Member

Choose a reason for hiding this comment

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

Unused and can be removed?

Copy link

@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: 2

🤖 Fix all issues with AI agents
In `@test/e2e/cli.go`:
- Around line 856-857: The test writes sensitive credentials to a temp file via
OutputToFile("auth.dockerconfigjson") and never removes it; after the existing
error check (o.Expect(secretErr).NotTo(o.HaveOccurred())), delete the temp file
to avoid leaving secrets on disk by calling os.Remove on the path returned in
secretFile (or schedule a defer os.Remove(secretFile) immediately after the
successful OutputToFile call). Locate the OutputToFile call and the variable
secretFile to add the cleanup, ensuring the removal happens only after verifying
secretErr is nil.

In `@test/e2e/util.go`:
- Around line 267-276: The OutputToFile helper (CLICommand.OutputToFile)
currently writes sensitive pull-secret data using os.WriteFile with mode 0644,
making /tmp/auth.dockerconfigjson world-readable; change the file permission
mode passed to os.WriteFile from 0644 to 0600 so the file is created with owner
read/write only (restrictive permissions) while keeping the rest of the function
(filePath generation and return behavior) unchanged.

Comment on lines +856 to +857
secretFile, secretErr := oc.AsAdmin().WithoutNamespace().Run("get").Args("secret/pull-secret", "-n", "openshift-config", `--template={{index .data ".dockerconfigjson" | base64decode}}`).OutputToFile("auth.dockerconfigjson")
o.Expect(secretErr).NotTo(o.HaveOccurred())
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's look at the specific lines and surrounding context
cat -n test/e2e/cli.go | sed -n '845,870p'

Repository: openshift/oc

Length of output: 1586


🏁 Script executed:

# Let's search for OutputToFile to understand what it does
rg "OutputToFile" --type go -B 2 -A 2 | head -50

Repository: openshift/oc

Length of output: 1685


🏁 Script executed:

# Check if there's any cleanup code related to auth.dockerconfigjson in the file
rg "auth.dockerconfigjson|defer.*Remove|os.Remove" test/e2e/cli.go -B 2 -A 2

Repository: openshift/oc

Length of output: 2400


🏁 Script executed:

# Let's search for the OutputToFile method implementation
rg "func.*OutputToFile" --type go -B 2 -A 5

Repository: openshift/oc

Length of output: 395


🏁 Script executed:

# Get the full OutputToFile implementation
sed -n '/^func (cmd \*CLICommand) OutputToFile/,/^}/p' test/e2e/util.go

Repository: openshift/oc

Length of output: 314


Clean up the credentials file after use.

The OutputToFile() call creates a file at /tmp/auth.dockerconfigjson containing sensitive Docker credentials. This file is never removed and persists on disk after the test completes. Add cleanup immediately after the error check on line 857:

		secretFile, secretErr := oc.AsAdmin().WithoutNamespace().Run("get").Args("secret/pull-secret", "-n", "openshift-config", `--template={{index .data ".dockerconfigjson" | base64decode}}`).OutputToFile("auth.dockerconfigjson")
		o.Expect(secretErr).NotTo(o.HaveOccurred())
+		defer os.Remove(secretFile)
🤖 Prompt for AI Agents
In `@test/e2e/cli.go` around lines 856 - 857, The test writes sensitive
credentials to a temp file via OutputToFile("auth.dockerconfigjson") and never
removes it; after the existing error check
(o.Expect(secretErr).NotTo(o.HaveOccurred())), delete the temp file to avoid
leaving secrets on disk by calling os.Remove on the path returned in secretFile
(or schedule a defer os.Remove(secretFile) immediately after the successful
OutputToFile call). Locate the OutputToFile call and the variable secretFile to
add the cleanup, ensuring the removal happens only after verifying secretErr is
nil.

Comment on lines +267 to +276
// OutputToFile runs the CLI command and writes output to a file
func (cmd *CLICommand) OutputToFile(filename string) (string, error) {
output, err := cmd.Output()
if err != nil {
return "", err
}

filePath := filepath.Join("/tmp", filename)
err = os.WriteFile(filePath, []byte(output), 0644)
return filePath, err
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and view the function
cat -n test/e2e/util.go | sed -n '267,276p'

Repository: openshift/oc

Length of output: 447


🏁 Script executed:

# Search for usages of OutputToFile to understand the context
rg "OutputToFile" --type go -B 2 -A 2

Repository: openshift/oc

Length of output: 1685


🏁 Script executed:

# Check if this is indeed used for pull secrets
rg -i "pull.*secret|secret.*pull|credentials" test/e2e/ --type go -B 2 -A 2

Repository: openshift/oc

Length of output: 4689


🏁 Script executed:

# Examine the broader context around the function definition
cat -n test/e2e/util.go | sed -n '250,290p'

Repository: openshift/oc

Length of output: 1527


Use restrictive file permissions for sensitive credentials.
This helper writes pull-secret data to /tmp/auth.dockerconfigjson using 0644 permissions, making Docker registry credentials world-readable. Change to 0600 (owner read/write only).

🔧 Suggested fix
-	err = os.WriteFile(filePath, []byte(output), 0644)
+	err = os.WriteFile(filePath, []byte(output), 0600)
📝 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
// OutputToFile runs the CLI command and writes output to a file
func (cmd *CLICommand) OutputToFile(filename string) (string, error) {
output, err := cmd.Output()
if err != nil {
return "", err
}
filePath := filepath.Join("/tmp", filename)
err = os.WriteFile(filePath, []byte(output), 0644)
return filePath, err
// OutputToFile runs the CLI command and writes output to a file
func (cmd *CLICommand) OutputToFile(filename string) (string, error) {
output, err := cmd.Output()
if err != nil {
return "", err
}
filePath := filepath.Join("/tmp", filename)
err = os.WriteFile(filePath, []byte(output), 0600)
return filePath, err
🤖 Prompt for AI Agents
In `@test/e2e/util.go` around lines 267 - 276, The OutputToFile helper
(CLICommand.OutputToFile) currently writes sensitive pull-secret data using
os.WriteFile with mode 0644, making /tmp/auth.dockerconfigjson world-readable;
change the file permission mode passed to os.WriteFile from 0644 to 0600 so the
file is created with owner read/write only (restrictive permissions) while
keeping the rest of the function (filePath generation and return behavior)
unchanged.

Copy link

@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: 5

🤖 Fix all issues with AI agents
In `@test/e2e/cli.go`:
- Around line 803-805: The defer that calls cmd2.Process.Kill() is set before
checking err from Background(), which can cause a nil dereference if
Background() failed; update the block around cmd2/backgroundBufNs2 so that you
first call oc.AsAdmin().WithoutNamespace().Run("get").Args(...).Background(),
assert o.Expect(err).NotTo(o.HaveOccurred()) immediately, and only then add the
defer to kill cmd2 (or alternatively wrap the defer in a nil check for cmd2) to
ensure cmd2 is valid before calling cmd2.Process.Kill().
- Around line 816-818: Defer-before-error-check: move the defer that calls
cmd1.Process.Kill() so it runs only after confirming Background() returned no
error (or alternatively make the deferred function nil-safe); specifically,
after calling oc.AsAdmin().WithoutNamespace().Run(...).Background() and after
o.Expect(err).NotTo(o.HaveOccurred()), add the defer, or change the current
defer to check cmd1 != nil && cmd1.Process != nil before calling Kill() to avoid
panics; reference symbols:
oc.AsAdmin().WithoutNamespace().Run(...).Background(), cmd1,
cmd1.Process.Kill(), and err.
- Around line 714-716: The defer calling cmd.Process.Kill() may panic if
cmd.Process is nil; after starting the command (where err is checked) wrap the
deferred cleanup to guard against nil by deferring a closure that checks cmd !=
nil and cmd.Process != nil before calling cmd.Process.Kill() (referencing cmd,
cmd.Start, and cmd.Process.Kill in this section).

In `@test/e2e/util.go`:
- Around line 847-853: The slice upper bound in getShouldPruneRSFromCreateTime
can be negative when keepNum > totalCompletedRsListNum; fix by computing an end
index (e.g., end := totalCompletedRsListNum - keepNum) and clamp it to the valid
range (if end < 0 set end = 0 and also ensure end <= len(totalCompletedRsList)),
then use totalCompletedRsList[0:end]; keep the sort.Strings(rsList) and e2e.Logf
call unchanged so behavior remains the same for valid inputs.
- Around line 1304-1308: The temporary file created via tmpFile :=
filepath.Join(os.TempDir(), fmt.Sprintf("resource-%d.yaml",
time.Now().UnixNano())) and written with ioutil.WriteFile(tmpFile,
[]byte(output), 0644) is never removed; change this to use os.CreateTemp (or
keep tmpFile but ensure removal) and schedule cleanup with defer
os.Remove(tmpFile) (or explicitly remove the file after it's consumed) so tests
don't accumulate temp files—update the code around the tmpFile variable and the
write logic in test/e2e/util.go accordingly.
🧹 Nitpick comments (4)
test/testdata/fixtures.go (1)

117-128: fs.WalkDir error is silently ignored.

If WalkDir encounters an error (e.g., permission issues), it's silently discarded and partial results are returned. Consider logging or returning an error to aid debugging.

Suggested fix
 // ListFixtures returns all available fixture paths
 func ListFixtures() []string {
 	var fixtures []string
-	fs.WalkDir(embeddedFixtures, ".", func(path string, d fs.DirEntry, err error) error {
+	err := fs.WalkDir(embeddedFixtures, ".", func(path string, d fs.DirEntry, err error) error {
 		if err != nil {
 			return err
 		}
 		if !d.IsDir() {
 			fixtures = append(fixtures, path)
 		}
 		return nil
 	})
+	if err != nil {
+		// Log error but don't fail - embedded FS errors are unlikely
+		fmt.Fprintf(os.Stderr, "warning: error walking embedded fixtures: %v\n", err)
+	}
 	return fixtures
 }
test/e2e/util.go (3)

11-11: Deprecated ioutil package usage.

The ioutil package is deprecated since Go 1.16. Replace with io and os equivalents:

  • ioutil.ReadAllio.ReadAll
  • ioutil.ReadFileos.ReadFile
  • ioutil.ReadDiros.ReadDir
  • ioutil.WriteFileos.WriteFile

1029-1031: Unnecessary shell invocation to read file.

Using exec.Command("bash", "-c", "cat ...") to read a file is overly complex. Use os.ReadFile directly.

🔧 Proposed fix
 	oauthFilePath := dirName + "/.dockerconfigjson"
-	secretContent, err := exec.Command("bash", "-c", fmt.Sprintf("cat %v", oauthFilePath)).Output()
-	o.Expect(err).NotTo(o.HaveOccurred())
+	secretContent, err := os.ReadFile(oauthFilePath)
+	o.Expect(err).NotTo(o.HaveOccurred())

1132-1143: Inconsistent error handling - function fails test instead of returning error.

checkFileContent returns bool but calls e2e.Failf() on read error, which fails the test immediately. Consider returning an error or false to let the caller decide how to handle missing files.

🔧 Proposed fix
 func checkFileContent(filename string, expectedStr string) bool {
-	b, err := ioutil.ReadFile(filename)
+	b, err := os.ReadFile(filename)
 	if err != nil {
-		e2e.Failf("failed to read the file ")
+		e2e.Warningf("failed to read file %s: %v", filename, err)
+		return false
 	}

Comment on lines +714 to +716
err = cmd.Start()
o.Expect(err).NotTo(o.HaveOccurred())
defer cmd.Process.Kill()
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Same defer-before-error-check pattern in test 49395.

The cmd.Process.Kill() defer at line 716 should be guarded against nil.

Suggested fix
 		err = cmd.Start()
 		o.Expect(err).NotTo(o.HaveOccurred())
-		defer cmd.Process.Kill()
+		if cmd != nil && cmd.Process != nil {
+			defer cmd.Process.Kill()
+		}
🤖 Prompt for AI Agents
In `@test/e2e/cli.go` around lines 714 - 716, The defer calling cmd.Process.Kill()
may panic if cmd.Process is nil; after starting the command (where err is
checked) wrap the deferred cleanup to guard against nil by deferring a closure
that checks cmd != nil and cmd.Process != nil before calling cmd.Process.Kill()
(referencing cmd, cmd.Start, and cmd.Process.Kill in this section).

Comment on lines +803 to +805
cmd2, backgroundBufNs2, _, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("deployment", "-n", ns2, "-o", "name", "-w").Background()
defer cmd2.Process.Kill()
o.Expect(err).NotTo(o.HaveOccurred())
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Same defer-before-error-check pattern.

Like lines 275-277, if Background() fails, cmd2 may be nil causing a panic. Move error assertion before the defer or guard with nil check.

Suggested fix
 		cmd2, backgroundBufNs2, _, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("deployment", "-n", ns2, "-o", "name", "-w").Background()
-		defer cmd2.Process.Kill()
 		o.Expect(err).NotTo(o.HaveOccurred())
+		if cmd2 != nil && cmd2.Process != nil {
+			defer cmd2.Process.Kill()
+		}
📝 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
cmd2, backgroundBufNs2, _, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("deployment", "-n", ns2, "-o", "name", "-w").Background()
defer cmd2.Process.Kill()
o.Expect(err).NotTo(o.HaveOccurred())
cmd2, backgroundBufNs2, _, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("deployment", "-n", ns2, "-o", "name", "-w").Background()
o.Expect(err).NotTo(o.HaveOccurred())
if cmd2 != nil && cmd2.Process != nil {
defer cmd2.Process.Kill()
}
🤖 Prompt for AI Agents
In `@test/e2e/cli.go` around lines 803 - 805, The defer that calls
cmd2.Process.Kill() is set before checking err from Background(), which can
cause a nil dereference if Background() failed; update the block around
cmd2/backgroundBufNs2 so that you first call
oc.AsAdmin().WithoutNamespace().Run("get").Args(...).Background(), assert
o.Expect(err).NotTo(o.HaveOccurred()) immediately, and only then add the defer
to kill cmd2 (or alternatively wrap the defer in a nil check for cmd2) to ensure
cmd2 is valid before calling cmd2.Process.Kill().

Comment on lines +816 to +818
cmd1, backgroundBuf, _, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("deployment", "-n", ns1, "-o", "name", "-w").Background()
defer cmd1.Process.Kill()
o.Expect(err).NotTo(o.HaveOccurred())
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Same defer-before-error-check pattern.

Same issue as above — guard the deferred kill against nil process.

Suggested fix
 		cmd1, backgroundBuf, _, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("deployment", "-n", ns1, "-o", "name", "-w").Background()
-		defer cmd1.Process.Kill()
 		o.Expect(err).NotTo(o.HaveOccurred())
+		if cmd1 != nil && cmd1.Process != nil {
+			defer cmd1.Process.Kill()
+		}
📝 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
cmd1, backgroundBuf, _, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("deployment", "-n", ns1, "-o", "name", "-w").Background()
defer cmd1.Process.Kill()
o.Expect(err).NotTo(o.HaveOccurred())
cmd1, backgroundBuf, _, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("deployment", "-n", ns1, "-o", "name", "-w").Background()
o.Expect(err).NotTo(o.HaveOccurred())
if cmd1 != nil && cmd1.Process != nil {
defer cmd1.Process.Kill()
}
🤖 Prompt for AI Agents
In `@test/e2e/cli.go` around lines 816 - 818, Defer-before-error-check: move the
defer that calls cmd1.Process.Kill() so it runs only after confirming
Background() returned no error (or alternatively make the deferred function
nil-safe); specifically, after calling
oc.AsAdmin().WithoutNamespace().Run(...).Background() and after
o.Expect(err).NotTo(o.HaveOccurred()), add the defer, or change the current
defer to check cmd1 != nil && cmd1.Process != nil before calling Kill() to avoid
panics; reference symbols:
oc.AsAdmin().WithoutNamespace().Run(...).Background(), cmd1,
cmd1.Process.Kill(), and err.

Comment on lines +847 to +853
func getShouldPruneRSFromCreateTime(totalCompletedRsList []string, totalCompletedRsListNum int, keepNum int) []string {
rsList := totalCompletedRsList[0:(totalCompletedRsListNum - keepNum)]
sort.Strings(rsList)
e2e.Logf("rsList %v:", rsList)
return rsList

}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Missing bounds check can cause panic with negative slice index.

If keepNum > totalCompletedRsListNum, the slice totalCompletedRsList[0:(totalCompletedRsListNum - keepNum)] will have a negative upper bound, causing a panic.

🔧 Proposed fix
 func getShouldPruneRSFromCreateTime(totalCompletedRsList []string, totalCompletedRsListNum int, keepNum int) []string {
+	if totalCompletedRsListNum <= keepNum {
+		return []string{}
+	}
 	rsList := totalCompletedRsList[0:(totalCompletedRsListNum - keepNum)]
 	sort.Strings(rsList)
 	e2e.Logf("rsList %v:", rsList)
 	return rsList
 }
📝 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 getShouldPruneRSFromCreateTime(totalCompletedRsList []string, totalCompletedRsListNum int, keepNum int) []string {
rsList := totalCompletedRsList[0:(totalCompletedRsListNum - keepNum)]
sort.Strings(rsList)
e2e.Logf("rsList %v:", rsList)
return rsList
}
func getShouldPruneRSFromCreateTime(totalCompletedRsList []string, totalCompletedRsListNum int, keepNum int) []string {
if totalCompletedRsListNum <= keepNum {
return []string{}
}
rsList := totalCompletedRsList[0:(totalCompletedRsListNum - keepNum)]
sort.Strings(rsList)
e2e.Logf("rsList %v:", rsList)
return rsList
}
🤖 Prompt for AI Agents
In `@test/e2e/util.go` around lines 847 - 853, The slice upper bound in
getShouldPruneRSFromCreateTime can be negative when keepNum >
totalCompletedRsListNum; fix by computing an end index (e.g., end :=
totalCompletedRsListNum - keepNum) and clamp it to the valid range (if end < 0
set end = 0 and also ensure end <= len(totalCompletedRsList)), then use
totalCompletedRsList[0:end]; keep the sort.Strings(rsList) and e2e.Logf call
unchanged so behavior remains the same for valid inputs.

Comment on lines +1304 to +1308
// Create temp file with output
tmpFile := filepath.Join(os.TempDir(), fmt.Sprintf("resource-%d.yaml", time.Now().UnixNano()))
if err := ioutil.WriteFile(tmpFile, []byte(output), 0644); err != nil {
return "", err
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Temporary file is never cleaned up.

The temp file created at line 1305 is never deleted, which can lead to temp file accumulation over many test runs. Consider adding cleanup or using os.CreateTemp with deferred removal.

🔧 Proposed fix
 	// Create temp file with output
-	tmpFile := filepath.Join(os.TempDir(), fmt.Sprintf("resource-%d.yaml", time.Now().UnixNano()))
-	if err := ioutil.WriteFile(tmpFile, []byte(output), 0644); err != nil {
+	tmpFile, err := os.CreateTemp("", "resource-*.yaml")
+	if err != nil {
+		return "", err
+	}
+	tmpFilePath := tmpFile.Name()
+	if _, err := tmpFile.WriteString(output); err != nil {
+		tmpFile.Close()
+		os.Remove(tmpFilePath)
 		return "", err
 	}
+	tmpFile.Close()
+	// Note: caller should clean up tmpFilePath when done
🤖 Prompt for AI Agents
In `@test/e2e/util.go` around lines 1304 - 1308, The temporary file created via
tmpFile := filepath.Join(os.TempDir(), fmt.Sprintf("resource-%d.yaml",
time.Now().UnixNano())) and written with ioutil.WriteFile(tmpFile,
[]byte(output), 0644) is never removed; change this to use os.CreateTemp (or
keep tmpFile but ensure removal) and schedule cleanup with defer
os.Remove(tmpFile) (or explicitly remove the file after it's consumed) so tests
don't accumulate temp files—update the code around the tmpFile variable and the
write logic in test/e2e/util.go accordingly.

@gangwgr
Copy link
Contributor Author

gangwgr commented Jan 29, 2026

/test e2e-agnostic-ovn-cmd

@gangwgr
Copy link
Contributor Author

gangwgr commented Jan 29, 2026

/test security

@ardaguclu
Copy link
Member

ROSA-OSD_CCS-ARO-Author:knarra-LEVEL0-Critical-64921-Critical-63854-Verify oc adm release info and oc image extract using --idms-file flag is skipped due to the reliance to image-policy-aosqe ICSP file which does not exist in our CI system. So we either need to find another ICSP to make this test running or remove this test (former is preferable).

But I don't want to block this PR for this. I'll tag it and you can fix it in a followup PR. Thank you for this work.
/lgtm
/approve
/verified by CI
https://prow.ci.openshift.org/view/gs/test-platform-results/pr-logs/pull/openshift_oc/2181/pull-ci-openshift-oc-main-e2e-aws-oc-ote/2016514634940420096
https://prow.ci.openshift.org/view/gs/test-platform-results/pr-logs/pull/openshift_oc/2181/pull-ci-openshift-oc-main-e2e-aws-oc-ote-serial/2016514634973974528

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Jan 29, 2026
@openshift-ci-robot
Copy link

@ardaguclu: This PR has been marked as verified by CI.

Details

In response to this:

ROSA-OSD_CCS-ARO-Author:knarra-LEVEL0-Critical-64921-Critical-63854-Verify oc adm release info and oc image extract using --idms-file flag is skipped due to the reliance to image-policy-aosqe ICSP file which does not exist in our CI system. So we either need to find another ICSP to make this test running or remove this test (former is preferable).

But I don't want to block this PR for this. I'll tag it and you can fix it in a followup PR. Thank you for this work.
/lgtm
/approve
/verified by CI
https://prow.ci.openshift.org/view/gs/test-platform-results/pr-logs/pull/openshift_oc/2181/pull-ci-openshift-oc-main-e2e-aws-oc-ote/2016514634940420096
https://prow.ci.openshift.org/view/gs/test-platform-results/pr-logs/pull/openshift_oc/2181/pull-ci-openshift-oc-main-e2e-aws-oc-ote-serial/2016514634973974528

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.

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Jan 29, 2026
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 29, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: ardaguclu, gangwgr

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

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jan 29, 2026
@ardaguclu
Copy link
Member

@gangwgr you need the link Jira.

@gangwgr gangwgr changed the title Migrating oc cli tests to ote CNTRLPLANE-2656:Migrating oc cli tests to ote Jan 29, 2026
@openshift-ci-robot
Copy link

openshift-ci-robot commented Jan 29, 2026

@gangwgr: This pull request references CNTRLPLANE-2656 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 sub-task to target the "4.22.0" version, but no target version was set.

Details

In response to this:

This PR adds comprehensive CLI test infrastructure for the oc command, implementing a self-contained testing framework that avoids external test dependencies

  • Added cli.go (2,512 lines) - 30+ comprehensive CLI test cases covering:
    • Image operations (mirror, extract, info, prune)
    • IDMS/ICSP configuration
    • Deployment and pod management
    • Network policies
    • Build operations
    • Custom Resource Definitions (CRDs)
    • Version and event handling
  • Added util.go (1,397 lines) - Test utilities including:
    • CLI wrapper for oc command execution with fluent API
    • e2e compatibility layer (avoids k8s.io/kubernetes/test/e2e/framework)
    • Platform detection (AWS, Azure, GCP, VSphere, etc.)
    • Architecture helpers (Multi, ARM64, x86_64, PPC64LE, S390X)
    • Test helper functions for pods, deployments, nodes
    • Minimal stub implementations for unused code paths
  • Removed e2e.go (15 lines) - replaced by cli.go

New dependencies added:

  • github.com/tidwall/gjson - JSON parsing for test validation
  • golang.org/x/crypto/ssh - SSH support for node operations
  • github.com/google/goexpect - Terminal interaction testing
  • github.com/google/goterm - Terminal utilities
  • google.golang.org/grpc - gRPC support (transitive)

Vendor updates:

  • Added ~100+ new vendor packages for test dependencies
  • Updated existing vendor packages for compatibility

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.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jan 29, 2026
@gangwgr
Copy link
Contributor Author

gangwgr commented Jan 29, 2026

/test build-rpms-from-tar

@openshift-ci-robot
Copy link

/retest-required

Remaining retests: 0 against base HEAD f228b9e and 2 for PR HEAD 63b9258 in total

@gangwgr
Copy link
Contributor Author

gangwgr commented Jan 29, 2026

/retest-required

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 29, 2026

@gangwgr: all tests passed!

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.

@openshift-merge-bot openshift-merge-bot bot merged commit 2aba839 into openshift:main Jan 29, 2026
17 checks passed
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. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged. verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants