Skip to content

test: establish OSAC SP contract coverage - #65

Merged
testetson22 merged 19 commits into
dcm-project:mainfrom
testetson22:stacked/FLPATH-4788-sp-contract
Oct 27, 2026
Merged

testetson22 merged 19 commits into
dcm-project:mainfrom
testetson22:stacked/FLPATH-4788-sp-contract

Conversation

@testetson22

@testetson22 testetson22 commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Establishes the OSAC Service Provider contract-test foundation and real fulfillment-service E2E path.

Scope

  • Cluster and VM API validation.
  • Provider registration and health checks.
  • CRUD and idempotency behavior.
  • Status projection and CloudEvents/NATS coverage.
  • Real fulfillment-service backend fixtures and OSAC SP Compose wiring.
  • JUnit-compatible SP test targets.
  • Initial backend deployment safety and ownership checks.
  • Clear separation between SP contract validation and downstream Agent, BMFO, AAP, BMC, HostedCluster, and infrastructure behavior.

Shared Harness Impact

This branch includes shared environment-agent/SPRM migration compatibility and rehydration contract/failover test updates required by the current E2E architecture. These tests are not OSAC-specific, but are included because the OSAC SP integration depends on the same provider-registration, restart, and E2E helper paths.

Validation

  • E2E suite compiles.
  • SP contract tests run against the real fulfillment-service backend.
  • Provider registration, health, CRUD/idempotency, status, and CloudEvent coverage are included.
  • Rehydration/auth/network conflict-sensitive suites compile and retain their intended skip/enable gates.
  • Known product issue: FLPATH-4945 is reproduced by the enabled max_page_size > 100 assertion. The SP currently returns HTTP 200 instead of the required HTTP 400.
  • CI compiles and validates the E2E suite and scripts; it does not execute live OCP or AAP deployment.

Review Boundary

This PR validates the OSAC SP contract and its real fulfillment-service integration. It does not claim Agent registration, BMFO/BMI/BMH allocation, Ironic/BMC provisioning, AAP playbook correctness, HostedCluster/NodePool readiness, VM networking, or physical infrastructure lifecycle.

Stack

Both dependent PRs remain draft.

Signed-off-by: Thomas Stetson <tstetson@redhat.com>
…E tests

- Add `scripts/deploy-osac-backend.sh` and Makefile targets to deploy/teardown
  the backend on OCP, plus macOS `port-forward-osac` helpers.
- Integrate `--deploy-osac-backend` into `deploy-dcm.sh`: auto-detects backend
  credentials, injects TLS and Darwin port-forward compose overlays, tears down
  with `--tear-down`, and patches profile-gated `depends_on` for podman-compose
  compatibility.
- Activate the `environment-agent` profile so the merged agent service starts
  under podman-compose, and fix the OSAC SP registration URL path.
- Harden OSAC SP E2E tests: exact provider registration assertions, AEP-132
  `results` wrapper, stricter CloudEvent envelope checks, 502 skip handling,
  RFC 9457 "Bad Request" title, and idempotent create returns original resource.
- Document setup in CLAUDE.md and Cursor prompts; ignore `deploy/` artifacts.

Signed-off-by: Thomas Stetson <tstetson@redhat.com>
…t skipped coverage

- Update the CLI provider test suite to target `/agents`, rename provider
  references to agent, and document the CLI + assertion blockers (FLPATH-4895)
  keeping the suite pending (`PDescribe`).
- Implement the previously pending RFC 7807 contract test for 422/406
  provider-error responses by stopping all providers.
- Implement sequential failover orphan cleanup and deferred-deletion queue
  checks, tracking superseded resource IDs across rehydrations.
- Update `restartSPRM()` to restart the merged `environment-agent` container.
- Annotate the pending OSAC `max_page_size > 100` test with the known backend
  gap and Jira references (FLPATH-4459/4463).

Signed-off-by: Thomas Stetson <tstetson@redhat.com>
…y for Phase 2

- Strengthen cluster/VM API assertions: RFC 9457 problem details for missing
  and invalid fields, explicit non-null `results` array checks, and
  table-driven boundary tests for storage and query parameters.
- Align health/status tests with observed SP behavior: detail required when
  degraded, accept "PROGRESSING" cluster status, and expect CloudEvent source
  prefix `dcm/providers/osac-sp`.
- Capture `spec` in cluster/VM structs to enable persisted-field round-trip
  checks.
- Extend `scripts/deploy-osac-backend.sh` with optional Phase 2 components
  (osac-operator, BMFO, aap-mock, fixtures), upstream manifest pinning,
  `--skip-phase2`, and safer teardown of cluster-scoped/APIService resources.
- Document test-credential provenance and gRPC TLS CA-cert troubleshooting in
  CLAUDE.md and Cursor prompts.

Signed-off-by: Thomas Stetson <tstetson@redhat.com>
@testetson22
testetson22 marked this pull request as ready for review October 6, 2026 15:44
@testetson22
testetson22 requested review from a team as code owners October 6, 2026 15:44
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Establish OSAC service-provider contract and backend E2E coverage

🧪 Tests ✨ Enhancement 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Adds OSAC cluster and VM contract tests for registration, validation, CRUD, status, and
 CloudEvents.
• Deploys a self-contained fulfillment-service backend so tests can exercise real API integration.
• Aligns shared E2E helpers with environment-agent migration and documents the boundary with
 infrastructure testing.
Diagram

graph TD
  Deploy["Backend deploy"] --> Backend["OSAC backend"]
  Deploy --> Compose["Compose overlays"] --> SP["OSAC provider"] --> Backend
  SP --> Agent["Environment agent"] --> Control["Control plane"]
  Tests["E2E tests"] --> SP --> NATS["NATS events"] --> Tests
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Reuse upstream kind-based Tier B
  • ➕ Avoids maintaining an OCP deployment script and cluster-scoped test resources.
  • ➕ Keeps fixtures close to the upstream provider tests.
  • ➖ Does not exercise DCM Compose registration and integration against an OCP-hosted backend.
  • ➖ Would require separate connectivity and integration wiring for this E2E harness.

Recommendation: Keep the OCP-hosted backend for DCM integration coverage and the explicit separation from real-infrastructure Tier C testing. Because this path manages cluster-scoped resources, ownership and teardown checks deserve particular review. The diff leaves the max_page_size > 100 assertion pending with PIt, so it should not be described as an enabled failing check.

Files changed (38) +4912 / -61

Documentation (7) +678 / -5
README.mdIndex the OSAC backend deployment prompt +8/-5

Index the OSAC backend deployment prompt

• Adds the backend runbook to the prompt list and example workflow.

.cursor/prompts/README.md

deploy-osac-backend.mdDocument backend deployment and troubleshooting +209/-0

Document backend deployment and troubleshooting

• Explains OCP prerequisites, deployment, teardown, credentials, macOS port-forwarding, and known limitations.

.cursor/prompts/deploy-osac-backend.md

e2e-tests.mdcDocument OSAC E2E endpoints and overlays +4/-0

Document OSAC E2E endpoints and overlays

• Records the environment-agent and OSAC API URLs and their provider-registry Compose overlays.

.cursor/rules/e2e-tests.mdc

project-overview.mdcExpose the OSAC deployment prompt +1/-0

Expose the OSAC deployment prompt

• Adds the backend setup prompt to the project overview.

.cursor/rules/project-overview.mdc

CLAUDE.mdAdd OSAC backend and test runbook +83/-0

Add OSAC backend and test runbook

• Documents deployment modes, contract-test prerequisites, teardown, test-only credentials, and macOS connectivity.

CLAUDE.md

README.mdDocument real-AAP manifest requirement +6/-0

Document real-AAP manifest requirement

• Adds an example invocation that supplies an externally procured subscription manifest for real-AAP mode.

README.md

OSAC-tier-c-test-plan.mdDefine future real-infrastructure Tier C coverage +367/-0

Define future real-infrastructure Tier C coverage

• Separates existing contract and self-contained backend coverage from proposed real AAP, bare-metal, networking, and provisioning tests. Lists prerequisites, blockers, test cases, and future CI needs; the Tier C Go cases are not implemented here.

test-plans/OSAC-tier-c-test-plan.md

Other (31) +4234 / -56
.gitignoreIgnore generated OSAC deployment artifacts +4/-0

Ignore generated OSAC deployment artifacts

• Excludes locally generated backend environment files and CA material, plus the optional AAP manifest.

.gitignore

MakefileAdd OSAC deployment and SP test targets +23/-1

Add OSAC deployment and SP test targets

• Adds backend deploy/teardown, macOS port-forward controls, and an OSAC-filtered Ginkgo target using existing JUnit support.

Makefile

environment-agent.confRegister environment-agent deployment profile +26/-0

Register environment-agent deployment profile

• Adds a provider-registry entry that enables the agent profile and its self-contained test overlay.

providers/environment-agent.conf

osac.confRegister OSAC service-provider overlay +33/-0

Register OSAC service-provider overlay

• Adds the OSAC deployment flag, Compose overlay, and prerequisite-validation hook.

providers/osac.conf

deploy-dcm.shWire OSAC backend and provider into DCM deployment +149/-5

Wire OSAC backend and provider into DCM deployment

• Adds opt-in backend deployment and teardown, credential and agent-dependency validation, and automatic TLS and Darwin overlays. Also accommodates namespace-free provider entries and patches an inactive Keycloak dependency in cloned Compose configuration for podman-compose compatibility.

scripts/deploy-dcm.sh

deploy-osac-backend.shDeploy an OCP-hosted fulfillment test backend +1192/-0

Deploy an OCP-hosted fulfillment test backend

• Provisions cert-manager CA material, Postgres, Keycloak, fulfillment-service, Routes, and optional operator/BMFO fixtures. Generates local connection artifacts and uses ownership checks when removing shared or cluster-scoped resources.

scripts/deploy-osac-backend.sh

osac-port-forward.shManage persistent macOS backend tunnels +127/-0

Manage persistent macOS backend tunnels

• Uses launchd-managed oc port-forwards for Keycloak and fulfillment gRPC, with start and targeted stop paths.

scripts/osac-port-forward.sh

compose-environment-agent-test.yamlDefine the E2E environment-agent service +36/-0

Define the E2E environment-agent service

• Adds its image, registration and messaging settings, embedded-provider inputs, and published test port.

tests/compose-environment-agent-test.yaml

compose-osac-sp-darwin-pf.yamlRoute macOS provider traffic through port-forwards +58/-0

Route macOS provider traffic through port-forwards

• Overrides backend host resolution and endpoints while retaining TLS hostnames and matching the fulfillment-service OIDC issuer.

tests/compose-osac-sp-darwin-pf.yaml

compose-osac-sp-tls.yamlMount backend CA into the OSAC provider +23/-0

Mount backend CA into the OSAC provider

• Adds a read-only CA mount and configures provider gRPC TLS trust.

tests/compose-osac-sp-tls.yaml

compose-osac-sp.yamlDefine the OSAC provider test service +39/-0

Define the OSAC provider test service

• Sets cluster and VM provider names, environment-agent registration, NATS, backend credentials, and the direct API port.

tests/compose-osac-sp.yaml

compose-podman-compat.yamlProvide an optional Keycloak dependency overlay +22/-0

Provide an optional Keycloak dependency overlay

• Defines an inactive-profile dependency workaround for podman-compose. The deployment script separately patches the cloned base Compose file for versions that do not support required: false.

tests/compose-podman-compat.yaml

api_helpers_test.goInitialize OSAC availability during suite setup +1/-0

Initialize OSAC availability during suite setup

• Adds the OSAC SP probe to the shared BeforeSuite initialization.

tests/e2e/api_helpers_test.go

cli_providers_test.goPrepare pending CLI cases for the agents API +40/-35

Prepare pending CLI cases for the agents API

• Changes API setup and naming from providers to agents while retaining the pending gate until CLI commands support the migration.

tests/e2e/cli_providers_test.go

problem_detail_test.goRecord the OSAC validation-error title +5/-0

Record the OSAC validation-error title

• Adds the Bad Request title expected by OSAC's RFC 9457 error assertions.

tests/e2e/problem_detail_test.go

rehydration_api_contract_test.goExercise placement failure problem details +48/-2

Exercise placement failure problem details

• Enables a disruptive multi-provider case that checks the error-body contract when all providers become unhealthy.

tests/e2e/rehydration_api_contract_test.go

rehydration_failover_test.goAssert failover cleanup and deferred deletion +75/-10

Assert failover cleanup and deferred deletion

• Tracks superseded resources across bidirectional failover and checks for orphaned deployments. Adds a deferred-deletion API assertion for the stopped-provider case.

tests/e2e/rehydration_failover_test.go

rehydration_helpers_test.goRestart embedded SPRM through environment-agent +6/-3

Restart embedded SPRM through environment-agent

• Changes the restart helper to target the service that now contains SPRM.

tests/e2e/rehydration_helpers_test.go

sp_osac_cluster_api_test.goCover OSAC cluster registration and API contract +652/-0

Cover OSAC cluster registration and API contract

• Tests provider registration, health, validation, pagination shape, error details, CRUD, idempotency, status, and kubeconfig visibility. Backend-dependent cases use availability or template gates; the >100 page-size assertion is pending.

tests/e2e/sp_osac_cluster_api_test.go

sp_osac_helpers_test.goAdd shared OSAC request and response helpers +392/-0

Add shared OSAC request and response helpers

• Defines payloads, response and CloudEvent types, endpoint probes, cleanup, status vocabularies, and environment-agent provider-list access.

tests/e2e/sp_osac_helpers_test.go

sp_osac_status_test.goVerify cluster and VM status CloudEvents +198/-0

Verify cluster and VM status CloudEvents

• Subscribes to NATS before creating resources and checks matching event envelopes and status payloads. Event cases require backend template IDs.

tests/e2e/sp_osac_status_test.go

sp_osac_vm_api_test.goCover OSAC VM validation and lifecycle contract +499/-0

Cover OSAC VM validation and lifecycle contract

• Tests storage and request validation, list and error shapes, unknown IDs, CRUD, idempotency, status, and IP-field presence. Full VM creation remains gated on a template and pre-seeded network infrastructure.

tests/e2e/sp_osac_vm_api_test.go

cert-manager-ca.yamlDefine the backend test CA chain +40/-0

Define the backend test CA chain

• Adds a self-signed issuer, CA certificate, and cluster issuer for backend TLS.

tests/osac-backend/cert-manager-ca.yaml

fulfillment-secrets.yamlSupply test-only fulfillment credentials +31/-0

Supply test-only fulfillment credentials

• Defines controller-client and database connection secrets using documented static test credentials.

tests/osac-backend/fulfillment-secrets.yaml

keycloak.yamlDeploy the OCP Keycloak test service +104/-0

Deploy the OCP Keycloak test service

• Defines Keycloak with realm import, Postgres backing, TLS, health probes, and a ClusterIP service for Route exposure.

tests/osac-backend/keycloak.yaml

aap-mock.yamlDeploy the Phase 2 AAP mock +66/-0

Deploy the Phase 2 AAP mock

• Defines a pinned, pullable mock Deployment and Service with a test authentication token.

tests/osac-backend/phase2/aap-mock.yaml

agent-crd-stub.yamlSatisfy operator Agent CRD startup dependency +37/-0

Satisfy operator Agent CRD startup dependency

• Adds a labeled minimal Assisted Installer Agent CRD without creating real Agents or claiming provisioning readiness.

tests/osac-backend/phase2/agent-crd-stub.yaml

osac-operator-values.yamlPin compatible Phase 2 operator settings +47/-0

Pin compatible Phase 2 operator settings

• Selects a fulfillment-compatible operator image and configures cluster controllers, the AAP mock, and test CA.

tests/osac-backend/phase2/osac-operator-values.yaml

postgres.yamlDeploy databases for Keycloak and fulfillment-service +86/-0

Deploy databases for Keycloak and fulfillment-service

• Defines a Postgres deployment, service, readiness checks, and initialization of the fulfillment database.

tests/osac-backend/postgres.yaml

realm.jsonDefine the OSAC test OIDC realm +159/-0

Define the OSAC test OIDC realm

• Adds the realm's API audience, claim mappers, CLI client, and test-only admin and controller clients.

tests/osac-backend/realm.json

run-e2e.shForward OSAC deployment flags from the E2E runner +16/-0

Forward OSAC deployment flags from the E2E runner

• Accepts environment-agent and OSAC provider flags and documents their direct API and NATS environment variables.

tests/run-e2e.sh

@qodo-code-review

qodo-code-review Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (5) 📘 Rule violations (1) 📜 Skill insights (0)

Grey Divider


Action required

1. Backend deploy fails on a fresh checkout ✓ Resolved
Description
deploy() redirects the existing ingress default-enable-http2 setting into
${DEPLOY_DIR}/osac-previous-http2 before creating ${DEPLOY_DIR}. On a clean checkout, the
missing directory makes the redirection fail under set -euo pipefail, stopping both `make
deploy-osac-backend and deploy-dcm.sh --deploy-osac-backend` before the backend namespace is
created.
Code

scripts/deploy-osac-backend.sh[R495-497]

+    oc get ingresses.config.openshift.io cluster \
+        -o jsonpath='{.metadata.annotations.ingress\.operator\.openshift\.io/default-enable-http2}' \
+        2>/dev/null > "${DEPLOY_DIR}/osac-previous-http2"
Evidence
DEPLOY_DIR points to the checkout’s deploy directory (line 44), which is newly gitignored and
therefore absent from a clean clone. The redirection at line 497 precedes namespace creation and the
later mkdir -p calls in extract_ca_cert() (line 460) and write_env_file() (line 1162), so the
shell cannot open the output file on a clean checkout.

scripts/deploy-osac-backend.sh[44-44]
scripts/deploy-osac-backend.sh[458-461]
scripts/deploy-osac-backend.sh[495-497]
.gitignore[5-6]
scripts/deploy-osac-backend.sh[37-44]
scripts/deploy-osac-backend.sh[477-505]
scripts/deploy-osac-backend.sh[1158-1163]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`deploy()` writes `${DEPLOY_DIR}/osac-previous-http2` before `${DEPLOY_DIR}` exists, causing a fresh checkout to abort under `set -e` before deployment begins.

## Fix Focus Areas
- scripts/deploy-osac-backend.sh[477-497]

## Recommended Fix
Create `${DEPLOY_DIR}` with `mkdir -p "${DEPLOY_DIR}"` before the `oc get ... > "${DEPLOY_DIR}/osac-previous-http2"` redirection. Place it at the start of `deploy()` or in a main entry point that runs on every deployment path.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Health tests wait with a fixed sleep ✓ Resolved
Description
The new uptime assertion calls time.Sleep(2 * time.Second) between two health requests instead of
polling for the expected condition. On slow or fast environments the fixed delay can make the test
unnecessarily slow or flaky while the ordered health context is running.
Code

tests/e2e/sp_osac_cluster_api_test.go[141]

+			time.Sleep(2 * time.Second)
Evidence
The changed E2E test contains a direct time.Sleep in the uptime assertion, while the checklist
requires Eventually or Consistently for all E2E waits.

Rule 3176558: Never use time.Sleep in E2E test assertions
tests/e2e/sp_osac_cluster_api_test.go[134-150]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The OSAC health uptime test uses a fixed two-second sleep before its second request, contrary to the E2E waiting policy and making the assertion timing-dependent.

## Fix Focus Areas
- tests/e2e/sp_osac_cluster_api_test.go[134-150]

## Recommended Fix
Replace `time.Sleep` with Gomega `Eventually` polling that repeatedly requests the health endpoint and asserts that the observed uptime becomes greater than the initial value within a bounded timeout.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Hub credential expires an hour after deploy 🐞 Bug ☼ Reliability
Description
_register_fixtures_body embeds a token minted with oc create token ... --duration=1h in the
kubeconfig sent to Hubs/Create, while grpc_create treats AlreadyExists as success without
replacing that credential. After the token expires, fulfillment-service can no longer reach the Hub,
and deployment reruns leave the expired kubeconfig in place, causing cluster and VM dispatch tests
to fail on long-lived backends.
Code

scripts/deploy-osac-backend.sh[R1081-1083]

+    local hub_token hub_ca
+    hub_token="$(oc create token osac-fulfillment-hub -n default --duration=1h)"
+    hub_ca="$(oc get configmap kube-root-ca.crt -n default -o jsonpath='{.data.ca\.crt}' | base64 | tr -d '\n')"
Evidence
The token request specifies a one-hour duration, and that token is embedded in kubeconfig_b64 used
to register the Hub. On subsequent runs, the AlreadyExists branch accepts the existing Hub without
updating its kubeconfig, so the stored credential remains expired.

scripts/deploy-osac-backend.sh[1081-1104]
scripts/deploy-osac-backend.sh[1123-1134]
scripts/deploy-osac-backend.sh[1139-1142]
scripts/deploy-osac-backend.sh[1070-1104]
scripts/deploy-osac-backend.sh[1121-1138]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The registered Hub retains a one-hour token in its kubeconfig, and deployment reruns do not refresh the credential when the Hub already exists.

## Fix Focus Areas
- scripts/deploy-osac-backend.sh[1081-1104]
- scripts/deploy-osac-backend.sh[1121-1138]
- scripts/deploy-osac-backend.sh[1139-1142]

## Recommended Fix
Use a renewable Hub authentication mechanism, such as reading the token from a `kubernetes.io/service-account-token` Secret for `osac-fulfillment-hub`, or use a much longer token duration. Ensure an existing Hub receives a fresh kubeconfig on reruns and before credential expiry, using an Update method or deleting and recreating the Hub rather than treating `AlreadyExists` as completion.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


4. Existing cluster API types get overwritten ✓ Resolved
Description
deploy_phase2() server-side-applies the pinned CRD manifests without an ownership or compatibility
check for seven of the eight types. On a cluster where any of those CRDs already exists, the test
deployment attempts to modify a shared cluster-scoped API definition; only the BareMetalHost CRD has
an existing-resource guard.
Code

scripts/deploy-osac-backend.sh[R795-803]

+        # baremetalhosts.metal3.io is owned by CNV/metal3 on OCP; applying it
+        # conflicts with the cluster-version-operator. Skip if already present.
+        if [[ "${crd}" == "baremetalhosts.metal3.io.yaml" ]] \
+                && oc get crd baremetalhosts.metal3.io &>/dev/null; then
+            info "baremetalhosts.metal3.io already present (CNV/metal3) — skipping"
+            continue
+        fi
+        # --server-side avoids annotation size limit on large CRDs.
+        oc_apply_filtered -f "${crds_tmp}/${crd}" --server-side
Evidence
The loop explicitly skips an existing BareMetalHost CRD but has no equivalent guard for the other
fetched CRDs before applying them.

scripts/deploy-osac-backend.sh[780-804]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Phase 2 setup applies pinned CRDs over existing cluster-scoped definitions without checking their ownership or compatibility.
## Fix Focus Areas
- scripts/deploy-osac-backend.sh[780-804]
## Recommended Fix
Inspect every CRD before applying it. Skip compatible pre-existing definitions and refuse incompatible ones rather than applying the test fixture over them.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Fixture setup failures are silently ignored 🐞 Bug ☼ Reliability
Description
register_fixtures calls _register_fixtures_body ... || rc=$?. Bash turns off set -e for the
whole function body when it runs in a || context, so failed `oc create
serviceaccount/clusterrole/clusterrolebinding/label/create token/get configmap` commands
do not stop the function. For example, if oc create token fails, hub_token is empty and a Hub
with a token-less kubeconfig is registered, while the deploy still reports success.
Code

scripts/deploy-osac-backend.sh[1023]

+    else
Evidence
The function is invoked as the left operand of ||, so errexit is ignored inside it. Only the token
emptiness check and the grpc_create calls have explicit return 1. Every oc command between lines
1072-1083 is unchecked.

scripts/deploy-osac-backend.sh[1017-1024]
scripts/deploy-osac-backend.sh[1072-1083]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`set -e` is disabled inside `_register_fixtures_body` because it is called with `|| rc=$?`, so failed oc commands are ignored.

## Fix Focus Areas
- scripts/deploy-osac-backend.sh[1023-1023]
- scripts/deploy-osac-backend.sh[1072-1083]

## Recommended Fix
Append `|| return 1` to each oc command in `_register_fixtures_body`, and check that `hub_token` and `hub_ca` are non-empty before building the kubeconfig. Alternatively, run the body in a subshell with `( set -e; _register_fixtures_body ... )` and capture its exit status.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


View medium (10)
6. Deferred-delete test misses resources past page 1 🐞 Bug ≡ Correctness
Description
findOldResource and the active-list check call GET /service-type-instances once and read only
body["instances"], ignoring next_page_token. On an environment with more instances than one page
holds, the old resource may not be on page 1: the Eventually then times out with a false failure,
and the "absent from active list" assertion passes without really checking anything.
Code

tests/e2e/rehydration_failover_test.go[R190-193]

+				resp, err := doRequest(http.MethodGet, "/service-type-instances?show_deleted=true", "")
+				if err != nil || resp.StatusCode != http.StatusOK {
+					return nil
+				}
Evidence
The SPRM list API is paginated: the existing helper listServiceTypeInstanceIDs loops on
next_page_token with max_page_size=100. The new test reads a single page for both the
show_deleted lookup and the active-list check. It also returns without closing the body on non-200
responses.

tests/e2e/rehydration_failover_test.go[189-228]
tests/e2e/api_helpers_test.go[89-121]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The deferred-delete test reads only the first page of `/service-type-instances`.

## Fix Focus Areas
- tests/e2e/rehydration_failover_test.go[189-228]
- tests/e2e/api_helpers_test.go[89-121]

## Recommended Fix
Add a paginated helper, modelled on `listServiceTypeInstanceIDs`, that takes an optional `show_deleted` flag and returns the instance maps across all pages using `max_page_size=100` and `next_page_token`. Use it both in `findOldResource` and in the active-list absence check. Close the body on non-200 responses.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


7. Custom namespaces break Mac connections ✓ Resolved
Description
compose-osac-sp-darwin-pf.yaml hardcodes osac-test-backend into both forwarded-service hostnames
and the credential endpoints. When the backend and port forwards use a different namespace, the
automatically selected overlay still points the provider at the default namespace.
Code

tests/compose-osac-sp-darwin-pf.yaml[R40-43]

+      - "ffs-keycloak.osac-test-backend.svc.cluster.local:192.168.127.254"
+      # gRPC: internal service hostname (cert SANs include this; OCP route cert does not).
+      # Port-forwarded to OCP fulfillment-grpc-server:8000.
+      - "fulfillment-grpc-server.osac-test-backend:192.168.127.254"
Evidence
Both deployment and port forwarding accept a namespace, but every backend hostname in the injected
Darwin overlay contains the default namespace literally.

scripts/deploy-osac-backend.sh[104-116]
scripts/osac-port-forward.sh[31-36]
scripts/deploy-dcm.sh[475-492]
tests/compose-osac-sp-darwin-pf.yaml[40-50]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Darwin overlay ignores the backend's configurable namespace.
## Fix Focus Areas
- tests/compose-osac-sp-darwin-pf.yaml[32-50]
- scripts/deploy-dcm.sh[475-492]
## Recommended Fix
Generate or parameterize the overlay hostnames and endpoint URLs using the configured backend namespace, including when deciding whether to inject the overlay.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. The new backend script fails ShellCheck 📘 Rule violation ✧ Quality
Description
tear_down iterates over $(oc get clusterorder ...) without safely handling command output,
triggering ShellCheck's unquoted command-substitution warning. Running ShellCheck on the newly added
script therefore reports a warning instead of exiting successfully.
Code

scripts/deploy-osac-backend.sh[240]

+    for co in $(oc get clusterorder -n "${NS}" -o name 2>/dev/null); do
Evidence
The new shell script contains for co in $(oc get clusterorder ...), which is the
command-substitution pattern ShellCheck flags for word splitting, violating the requirement that
scripts in scripts/*.sh pass ShellCheck.

Rule 3176316: Shell scripts must pass ShellCheck in specified directories
scripts/deploy-osac-backend.sh[240-240]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The backend deployment script uses an unquoted command substitution in the ClusterOrder cleanup loop, which causes ShellCheck to report a warning under the project's shell-script compliance rule.

## Fix Focus Areas
- scripts/deploy-osac-backend.sh[240-240]

## Recommended Fix
Rewrite the loop to avoid iterating over unquoted command-substitution output, such as by using a safely read array or a null-delimited/read-based approach that preserves resource names and satisfies ShellCheck.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


9. Teardown edits ClusterOrders it does not own ✓ Resolved
Description
tear_down removes /metadata/finalizers from every ClusterOrder in ${NS} before checking
phase2_owned namespace. When a selected namespace is pre-existing and not owned by this
deployment, teardown leaves it intact but has already changed its orders, which can then be deleted
without controller cleanup.
Code

scripts/deploy-osac-backend.sh[R240-243]

+    for co in $(oc get clusterorder -n "${NS}" -o name 2>/dev/null); do
+        oc patch "${co}" -n "${NS}" \
+            --type=json \
+            -p='[{"op":"remove","path":"/metadata/finalizers"}]' \
Evidence
The finalizer-removal loop at lines 240–245 runs unconditionally, before the namespace ownership
check at lines 247–254. Thus, the check can leave an unowned namespace in place only after its
ClusterOrders have been patched.

scripts/deploy-osac-backend.sh[237-254]
scripts/deploy-osac-backend.sh[237-251]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Teardown strips ClusterOrder finalizers before determining whether this deployment owns the selected namespace, potentially changing orders in a namespace it leaves intact.

## Fix Focus Areas
- scripts/deploy-osac-backend.sh[237-254]

## Recommended Fix
Check namespace ownership before patching any ClusterOrder. Move the finalizer-removal loop inside the `if phase2_owned namespace "${NS}"; then` branch, just before `oc delete namespace`, and limit finalizer removal to resources owned by this deployment.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


10. Teardown leaves the test CA behind ✓ Resolved
Description
deploy() applies an Issuer and Certificate in the shared cert-manager namespace but labels only
their ClusterIssuer for ownership. Teardown removes that ClusterIssuer while leaving the Issuer,
Certificate, and generated CA Secret in the shared namespace.
Code

scripts/deploy-osac-backend.sh[R523-524]

+    oc apply -f "${MANIFESTS_DIR}/cert-manager-ca.yaml"
+    oc label clusterissuer osac-ca "${PHASE2_PART_OF_KEY}=${PHASE2_PART_OF_LABEL}" --overwrite
Evidence
The manifest creates both namespace-scoped resources and the Certificate specifies the Secret name;
the deployment and teardown ownership operations mention only the ClusterIssuer.

tests/osac-backend/cert-manager-ca.yaml[11-40]
scripts/deploy-osac-backend.sh[517-524]
scripts/deploy-osac-backend.sh[256-263]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test CA's namespace-scoped resources outlive backend teardown.
## Fix Focus Areas
- scripts/deploy-osac-backend.sh[517-526]
- scripts/deploy-osac-backend.sh[256-263]
- tests/osac-backend/cert-manager-ca.yaml[11-40]
## Recommended Fix
Check and mark ownership of the Issuer and Certificate when creating them, then delete only owned CA resources and their generated Secret during teardown.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


11. Teardown leaves test API types installed ✓ Resolved
Description
deploy_phase2() installs eight CRDs, but the teardown CRD logic checks and deletes only the
labeled Agent stub. After a Phase 2 deployment is removed, the other test-applied API definitions
remain cluster-wide.
Code

scripts/deploy-osac-backend.sh[R802-804]

+        # --server-side avoids annotation size limit on large CRDs.
+        oc_apply_filtered -f "${crds_tmp}/${crd}" --server-side
+    done
Evidence
The install loop applies the eight listed CRDs, whereas the cluster-scoped teardown handles only
agents.agent-install.openshift.io as a CRD.

scripts/deploy-osac-backend.sh[265-282]
scripts/deploy-osac-backend.sh[780-804]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Phase 2 teardown does not remove the CRDs that Phase 2 installs.
## Fix Focus Areas
- scripts/deploy-osac-backend.sh[780-804]
- scripts/deploy-osac-backend.sh[265-282]
## Recommended Fix
Record which CRDs this deployment created, label only those as owned, and delete those owned definitions during teardown without deleting pre-existing CRDs.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


12. Delete tests miss valid unknown IDs ✓ Resolved
Description
The cluster and VM delete-idempotency tests describe their target IDs as UUID-format, but both
literals contain non-hex characters and have an overlong final group. They therefore duplicate the
malformed-ID cases rather than exercising deletion of a well-formed, nonexistent resource.
Code

tests/e2e/sp_osac_cluster_api_test.go[R429-431]

+			// Use a UUID-format ID so OSAC does not reject it as malformed.
+			resp, err := doOsacClusterRequest(http.MethodDelete,
+				"/clusters/00000000-e2e0-4000-8000-delete0cl0000", "")
Evidence
The two request literals are not UUIDs, while separate tests already cover malformed IDs and the
request helper forwards the supplied ID unchanged.

tests/e2e/sp_osac_cluster_api_test.go[382-394]
tests/e2e/sp_osac_cluster_api_test.go[425-438]
tests/e2e/sp_osac_vm_api_test.go[268-278]
tests/e2e/sp_osac_vm_api_test.go[289-299]
tests/e2e/sp_osac_helpers_test.go[324-343]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Both supposed valid-UUID delete cases send malformed IDs, leaving the valid-but-nonexistent case untested.
## Fix Focus Areas
- tests/e2e/sp_osac_cluster_api_test.go[425-438]
- tests/e2e/sp_osac_vm_api_test.go[289-299]
## Recommended Fix
Replace both literals with syntactically valid UUIDs that do not identify fixtures, retaining the separate malformed-ID tests.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


13. Later tests run against downed providers 🐞 Bug ☼ Reliability
Description
The new 422/406 contract test stops every three-tier provider and only defers startProvider(p). It
never waits for the providers to report ready again, and the deferred deleteInstance runs right
after the containers restart. Specs that follow can run against providers that are still
unavailable, and the test instance's resources may not be cleaned up.
Code

tests/e2e/rehydration_api_contract_test.go[R110-113]

+		for _, p := range threeTierProviders {
+			if p.ContainerName != "" {
+				stopProvider(p)
+				defer startProvider(p)
Evidence
Defers run LIFO, so the providers restart first, then deleteInstance and deletePlacementPolicy
run immediately. startProvider only runs podman start, and deleteInstance sends a single
DELETE with no wait. The failover suite's AfterAll does call `waitForProviderHealth(..., "ready",
...)` after restarting; this test does not.

tests/e2e/rehydration_api_contract_test.go[101-118]
tests/e2e/rehydration_helpers_test.go[529-537]
tests/e2e/rehydration_helpers_test.go[372-379]
tests/e2e/rehydration_failover_test.go[41-45]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
After stopping all providers, cleanup restarts them but never waits for readiness before deleting the instance or handing over to later specs.

## Fix Focus Areas
- tests/e2e/rehydration_api_contract_test.go[101-118]

## Recommended Fix
Replace the per-provider `defer startProvider(p)` with a single `DeferCleanup` registered after the stop loop. It should start every stopped provider, call `waitForProviderHealth(p.Name, "ready", healthTimeout)` for each, and then delete the instance and policy, so cleanup order is explicit.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


14. Teardown can leave cluster HTTP/2 wrongly set 🐞 Bug ≡ Correctness
Description
deploy() overwrites osac-previous-http2 on every run, while tear_down() treats a missing
record file as though the ingress annotation was originally absent. A second deploy can therefore
replace the original value with the true set by the first, and teardown either restores that wrong
value or removes an existing cluster-wide annotation when the record file is missing.
Code

scripts/deploy-osac-backend.sh[R299-302]

+    log "Restoring OCP ingress HTTP/2 setting"
+    local previous_http2=""
+    if [[ -f "${DEPLOY_DIR}/osac-previous-http2" ]]; then
+        previous_http2="$(<"${DEPLOY_DIR}/osac-previous-http2")"
Evidence
Deployment unconditionally saves the current annotation to a local file before forcing it to true,
so a repeated deploy replaces the original value in that file. Teardown reads the file but runs the
default-enable-http2- annotation-removal command when the file is empty or missing;
deploy-dcm.sh re-invokes the script on every --deploy-osac-backend.

scripts/deploy-osac-backend.sh[494-500]
scripts/deploy-osac-backend.sh[297-313]
scripts/deploy-dcm.sh[1285-1288]
scripts/deploy-osac-backend.sh[493-500]
scripts/deploy-osac-backend.sh[298-314]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Repeated deployment overwrites the saved original HTTP/2 annotation, and teardown without a record file removes a cluster-wide annotation that this deployment might never have changed.

## Fix Focus Areas
- scripts/deploy-osac-backend.sh[494-500]
- scripts/deploy-osac-backend.sh[297-314]

## Recommended Fix
In `deploy()`, write `osac-previous-http2` only if it does not already exist, using an explicit sentinel such as `__absent__` when the annotation was originally missing. In `tear_down()`, skip restoration if the record file does not exist; remove the annotation only when the record contains the absent sentinel, otherwise restore the recorded value. Delete the record file after restoration.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


15. Documented credentials fail validation ✓ Resolved
Description
validate_osac_provider() checks the shell for four credentials but never reads deploy/.env,
which the new provider configuration and Compose overlay both identify as a supported source. A user
who puts credentials only in that documented file is rejected before Compose can use them.
Code

scripts/deploy-dcm.sh[R501-505]

+    local missing=()
+    for var in SP_OSAC_FULFILLMENT_ADDRESS SP_OSAC_OIDC_ISSUER_URL \
+                SP_OSAC_OIDC_CLIENT_ID SP_OSAC_OIDC_CLIENT_SECRET; do
+        [[ -z "${!var:-}" ]] && missing+=("${var}")
+    done
Evidence
Both new configuration files document deploy/.env; validation sources only
deploy/osac-backend.env before inspecting shell variables, and the deploy script explicitly does
not source deploy/.env.

providers/osac.conf[6-10]
tests/compose-osac-sp.yaml[8-11]
scripts/deploy-dcm.sh[457-461]
scripts/deploy-dcm.sh[501-514]
scripts/deploy-dcm.sh[1132-1137]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The OSAC validation hook rejects credentials supplied through the documented `deploy/.env` path.
## Fix Focus Areas
- scripts/deploy-dcm.sh[450-514]
- providers/osac.conf[6-10]
## Recommended Fix
Read and validate credentials from the Compose environment-file path as well as exported shell variables, or remove that path from the instructions if it is intentionally unsupported.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

16. Known page-size bug is not actually exercised ✓ Resolved
Description
The max_page_size > 100 assertion is declared with PIt, so Ginkgo never runs it, and the VM
suite has no such case at all. Yet the PR description says the enabled assertion reproduces
FLPATH-4945, and the code comment cites a different ticket (FLPATH-4459/4463), so the known SP
defect is untracked by any running test.
Code

tests/e2e/sp_osac_cluster_api_test.go[R327-330]

+		// KNOWN BACKEND GAP: fulfillment-service does not enforce the AEP-132 constraint
+		// that max_page_size > 100 must be rejected with 400. It returns 200 instead.
+		// Tracked under FLPATH-4459 (epic) / FLPATH-4463 (story).
+		PIt("rejects max_page_size > 100 with 400 (AEP-132)", func() {
Evidence
Line 330 uses PIt (pending). sp_osac_vm_api_test.go's query-parameter context has only the -1, abc
and 0 cases.

tests/e2e/sp_osac_cluster_api_test.go[327-339]
tests/e2e/sp_osac_vm_api_test.go[195-230]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The max_page_size>100 test is pending (PIt) and cites a different ticket than the PR, so FLPATH-4945 is not reproduced by any running test.

## Fix Focus Areas
- tests/e2e/sp_osac_cluster_api_test.go[327-339]
- tests/e2e/sp_osac_vm_api_test.go[195-230]

## Recommended Fix
Either turn the test back into `It` (and add the VM equivalent) so it reproduces FLPATH-4945 as the PR states, or keep it pending and correct the ticket references and the PR description.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


17. Cluster list check misses results past page 1 ✓ Resolved
Description
list includes the created cluster decodes a single GET /clusters response and asserts that
Results contains clusterID, without following pagination. The test comments say the SP keeps
clusters from earlier runs, so once the list grows past one page the new cluster may not be on page
1 and the CRUD lifecycle fails for no real reason.
Code

tests/e2e/sp_osac_cluster_api_test.go[R594-597]

+			var listResp osacClusterListResponse
+			decodeJSON(resp, &listResp)
+			Expect(listResp.Results).To(ContainElement(HaveField("ID", clusterID)),
+				"created cluster %s should appear in the list", clusterID)
Evidence
The list is read once with no page token handling. The earlier spec states that "the SP may retain
clusters from prior runs or concurrent tests".

tests/e2e/sp_osac_cluster_api_test.go[466-479]
tests/e2e/sp_osac_cluster_api_test.go[588-598]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The created-cluster list check reads only the first page of results.

## Fix Focus Areas
- tests/e2e/sp_osac_cluster_api_test.go[588-634]

## Recommended Fix
Add a helper that pages through `/clusters` using `next_page_token`/`page_token`, as the SP supports, and use it for both the "includes" and the "no longer appears" checks. The same applies to the VM list tests.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


18. Old backend env file overrides user credentials ✓ Resolved
Description
validate_osac_provider always sources deploy/osac-backend.env when the file exists. That file
exports SP_OSAC_FULFILLMENT_ADDRESS, SP_OSAC_OIDC_* and OSAC_CA_CERT_FILE, silently
replacing any credentials the user exported, even though the error text says "export the SP_OSAC_*
vars yourself". A leftover file from an earlier backend deployment therefore points the OSAC SP at a
stale or torn-down backend and auto-injects the TLS overlay.
Code

scripts/deploy-dcm.sh[R458-461]

+    if [[ -f "${osac_backend_env}" ]]; then
+        info "Found OSAC backend env file: ${osac_backend_env} (sourcing)"
+        # shellcheck source=/dev/null
+        source "${osac_backend_env}"
Evidence
The env file is sourced unconditionally, and the generated file contains plain export SP_OSAC_...=
assignments. The validation message offers user-exported vars as an alternative, but they cannot win
while the file exists.

scripts/deploy-dcm.sh[457-467]
scripts/deploy-dcm.sh[512-513]
scripts/deploy-osac-backend.sh[1171-1175]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A stale `deploy/osac-backend.env` silently overrides user-exported SP_OSAC_* credentials.

## Fix Focus Areas
- scripts/deploy-dcm.sh[457-467]

## Recommended Fix
Source the env file only when `SP_OSAC_FULFILLMENT_ADDRESS` is unset, or when `--deploy-osac-backend` is given. Otherwise, log that the user-provided values take precedence.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
⚠️ Tickets: not configured — ticket URL found in PR but could not be fetched — check ticket provider credentials
✅ Compliance rules (platform): 21 rules
Review mode: Auto: 🧠 Deep: Many independent test, deployment, authentication, and integration paths create high defect density.

Grey Divider

Tip of the day
💡 Did you know, you can describe a rule in plain language on the Rules page and Qodo drafts it for you

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread scripts/deploy-osac-backend.sh Resolved
Comment thread tests/e2e/sp_osac_cluster_api_test.go Resolved
Comment thread scripts/deploy-osac-backend.sh Resolved
Comment thread scripts/deploy-osac-backend.sh Resolved
Comment thread scripts/deploy-osac-backend.sh Resolved
Comment thread tests/e2e/rehydration_failover_test.go Resolved
Comment thread scripts/deploy-dcm.sh Resolved
Comment thread tests/e2e/sp_osac_cluster_api_test.go Resolved
Comment thread tests/e2e/sp_osac_cluster_api_test.go Resolved
log "Enabling HTTP/2 on the OCP ingress controller"
oc get ingresses.config.openshift.io cluster \
-o jsonpath='{.metadata.annotations.ingress\.operator\.openshift\.io/default-enable-http2}' \
2>/dev/null > "${DEPLOY_DIR}/osac-previous-http2"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P1] Create the output directory before this redirected write. The deploy/ directory is ignored by git and is not created before the shell opens this redirect, so on a fresh checkout the command fails before oc runs and set -e exits before deployment. Add mkdir -p before the first write.

"name": "OSAC administrator",
"enabled": true,
"clientAuthenticatorType": "client-secret",
"secret": "tierb-osac-admin-secret",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P1] This reuses the static osac-admin secret that the peer repo's Tier B README scopes to throwaway Kind CI and says not to reuse for real deployments: https://github.com/dcm-project/osac-service-provider/blob/main/test/e2e/tierb-config/README.md#L11-L14. This PR provisions that secret in its OCP path and creates a Keycloak Route. If the target OCP is persistent or reachable beyond an isolated test boundary, the committed credential is reusable against the routed service. Please enforce the disposable/isolated boundary or generate per-deployment credentials before exposing the route.

Comment thread scripts/deploy-osac-backend.sh Resolved
| oc apply -f -
oc create clusterrolebinding osac-fulfillment-hub-reader --clusterrole=osac-fulfillment-hub-reader \
--serviceaccount=default:osac-fulfillment-hub --dry-run=client -o yaml | oc apply -f -
oc label clusterrole osac-fulfillment-hub-reader "${PHASE2_PART_OF_KEY}=${PHASE2_PART_OF_LABEL}" --overwrite

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] Check ownership before applying and relabeling these fixed-name cluster RBAC resources. On a same-name unowned collision, this can replace existing ClusterRole rules or binding subjects and then mark the objects as owned; teardown may delete the preexisting resources. Refuse unowned collisions or use deployment-specific names.

Comment thread scripts/deploy-osac-backend.sh Resolved
oc label clusterrole osac-fulfillment-hub-reader "${PHASE2_PART_OF_KEY}=${PHASE2_PART_OF_LABEL}" --overwrite
oc label clusterrolebinding osac-fulfillment-hub-reader "${PHASE2_PART_OF_KEY}=${PHASE2_PART_OF_LABEL}" --overwrite
local hub_token hub_ca
hub_token="$(oc create token osac-fulfillment-hub -n default --duration=1h)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] This requests a 1h service-account token and persists it in the Hub kubeconfig. The AlreadyExists branch below treats the existing Hub as success without refreshing its spec, so a later setup can retain an expired token. The requested duration is server-controlled; update the existing Hub with a fresh credential or add a renewal path.

Comment thread tests/e2e/sp_osac_cluster_api_test.go Outdated
// KNOWN BACKEND GAP: fulfillment-service does not enforce the AEP-132 constraint
// that max_page_size > 100 must be rejected with 400. It returns 200 instead.
// Tracked under FLPATH-4459 (epic) / FLPATH-4463 (story).
PIt("rejects max_page_size > 100 with 400 (AEP-132)", func() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] PIt marks this case pending, so Ginkgo does not execute the assertion. The PR description says the max_page_size > 100 assertion is enabled and reproduces the issue, but this test currently provides no CI evidence for that claim. Please align the description with the pending status or add executable coverage that reflects the tracked backend gap.

Comment thread tests/e2e/sp_osac_cluster_api_test.go Outdated

var listResp osacClusterListResponse
decodeJSON(resp, &listResp)
Expect(listResp.Results).To(ContainElement(HaveField("ID", clusterID)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] This assertion checks only the first Results page; the post-delete absence check does the same. The peer implementation supports page_token/next_page_token pagination (https://github.com/dcm-project/osac-service-provider/blob/main/internal/cluster/list.go#L25-L82), so a created cluster can be on a later page and a lingering deleted cluster can be missed. Follow next_page_token until exhausted or constrain the fixture to one page.

Comment thread tests/e2e/sp_osac_cluster_api_test.go Resolved
@testetson22

Copy link
Copy Markdown
Contributor Author

@gabriel-farache I think I covered everything that I can, plus some missing Qodo stuff. Keep me honest when you have time.

@testetson22

Copy link
Copy Markdown
Contributor Author

Worth noting: The rehydration-specific pagination and provider-stop findings remain intentionally out of scope for this PR stack. There's a broader follow-up to build out a production-like environment and expand testing across all SPs and whatever other integrations.

Comment thread tests/e2e/sp_osac_status_test.go Outdated
// drains messages until a matching VM ID is found.
// ------------------------------------------------------------------ #

Context("VM status events", Label("cluster"), func() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This Context is Label("cluster") but it covers VM NATS events. Running with --label-filter=cluster will execute these VM specs, and --label-filter=vm will miss them. Change to Label("vm").

Comment thread tests/e2e/sp_osac_vm_api_test.go Outdated
})

It("deleted VM no longer appears in the list", func() {
resp, err := doOsacVMRequest(http.MethodGet, "/vms", "")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The cluster suite uses paginated listAllOsacClusters() but this VM check reads one page. osacVMListResponse also lacks NextPageToken. A listAllOsacVMs() helper would keep the two suites consistent.

// Use a UUID-format ID so OSAC does not reject it as malformed.
resp, err := doOsacClusterRequest(http.MethodDelete,
"/clusters/00000000-e2e0-4000-8000-delete0cl0000", "")
Expect(err).NotTo(HaveOccurred())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

delete0cl0000 has non-hex chars (l, t), same for delete0vm0000 (v, m). These duplicate the malformed-ID tests instead of exercising well-formed nonexistent delete. Use real hex, e.g. 00000000-e2e0-4000-8000-de1e7ec10000.

Comment thread providers/osac.conf Outdated
# provisioning OpenShift clusters (serviceType: cluster) and VMs (serviceType: vm)
# via OSAC's gRPC fulfillment API.
#
# Requires: OSAC dev/MOC credentials set in the shell or deploy/.env:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This says credentials can be in "the shell or deploy/.env" but validate_osac_provider only sources deploy/osac-backend.env. Remove the deploy/.env mention or note it only applies at compose runtime.

})

It("coerces max_page_size > 100 to the contract maximum", func() {
resp, err := doOsacVMRequest(http.MethodGet, "/vms?max_page_size=101", "")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The cluster suite has a PIt for max_page_size > 100 but the VM suite has no matching pending case. Adding one keeps both suites symmetric.

@testetson22
testetson22 merged commit 8075589 into dcm-project:main Oct 27, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants