Skip to content

Add unit tests for internal/state - #2658

Open
abrarshivani wants to merge 1 commit into
NVIDIA:mainfrom
abrarshivani:unit-test-state
Open

Add unit tests for internal/state#2658
abrarshivani wants to merge 1 commit into
NVIDIA:mainfrom
abrarshivani:unit-test-state

Conversation

@abrarshivani

@abrarshivani abrarshivani commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Description

Adds unit tests across internal/state. Statement coverage of the package is 93.6%, measured against the current rebased head (go test ./internal/state/... -covermode=count). Tests only — no production source changed. Tests use the controller-runtime fake client with interceptor.Funcs to inject Get/List/Create/Update/Delete errors, a fake manager, a fake REST mapper for generic cleanup, the real manifest renderer, and computed DaemonSet hashes — exercising real success and error paths rather than tautologies.

Now at 100%: info_source.go in full, and NewStateDriver, Sync, cleanupStaleDriverDaemonsets, getDaemonsetFromObjects, getObjectOfKind, getDriverName, getDriverSpec, createConfigMapVolumeMounts, buildDriverInstallConfig, renderManifestObjects, getGDSSpec/getGDRCopySpec/getRuntimeSpec, createOrUpdateObjs, isDaemonSetReady, isDeploymentReady, handleStateObjectsDeletion, getSupportedGVKs, newStates, and the stateManager methods. deleteStateRelatedObjects reaches 100% (a fake REST mapper covers the non-NoMatch mapping-error branch).

Coverage rerun against the rebased head

The branch was rebased onto source that added Deployment readiness (isDeploymentReady) and generic state-object deletion (handleStateObjectsDeletion/deleteStateRelatedObjects). Those reachable paths are now directly tested: a readiness table (including the stale-generation and still-terminating-replica cases), an exact getSupportedGVKs set comparison, and deletion coverage for namespaced-vs-cluster scoping, forbidden-list skip, NotFound-on-delete, list/delete error propagation, and already-deleting objects. The remaining uncovered statements are genuinely not exercisable by a unit test:

  • GetWatchSources — the uncovered block is an inline predicate.NewTypedPredicateFuncs closure only invoked by a live controller-runtime informer on a DaemonSet watch event; the outer construction is covered via a fake manager.
  • NewManager / newNVIDIADriverStates success returns — require loading the hardcoded on-disk path /opt/gpu-operator/manifests/state-driver (a string literal, not an overridable var). All error paths are covered.
  • getManifestObjects / handleDefaultImagesInObjects — in-loop error branches unreachable with a valid NVIDIADriver spec (the spec is always populated, so templates render and always yield a DaemonSet); the renderManifestObjects error itself is covered directly.
  • mergeServiceAccount — two SetNestedField writebacks that cannot error (single top-level field on a map, value sourced from a valid NestedSlice).

Behaviors pinned by characterization tests

While maximizing coverage, several blocks turned out to encode questionable or unreachable behavior. Per the tests-only scope these are not changed here; instead they are pinned by tests with comments so any future fix is a conscious change:

  • isDaemonSetReady nonzero-desired path does not re-check ObservedGeneration, so status from a previous generation can be reported ready right after a spec change (Kubernetes rollout-status gates on ObservedGeneration first). Pinned by TestIsDaemonSetReadyStaleGeneration.
  • isDeploymentReady does not require Status.Replicas == desired, so a rollout with a superseded replica still terminating is reported ready (Kubernetes' DeploymentComplete requires it). Pinned by the "old replica still terminating" case.
  • deleteStateRelatedObjects treats a Forbidden List as "nothing to clean up", which can leave operands behind if list permission is revoked after creation. Pinned by TestDeleteStateRelatedObjectsForbiddenListSkipped.
  • driver_volumes.go (~L224-243) — the SUSE /lib/modules mount for precompiled drivers is nested inside if !cr.Spec.UsePrecompiledDrivers() yet guarded by if cr.Spec.UsePrecompiledDrivers(), a contradiction, so it can never execute (likely a real bug).
  • nodepool.go (~L102-104) — the error branch for getOSTag is dead because getOSTag unconditionally returns a nil error.

Happy to address any of these in a separate production PR if desired.

Checklist

  • No secrets, sensitive information, or unrelated changes
  • Lint checks passing (make lint)
  • Generated assets in-sync (make validate-generated-assets)
  • Go mod artifacts in-sync (make validate-modules)
  • Test cases are added for new code paths

Testing

go test ./internal/state/... -covermode=count    # coverage: 93.6% of statements
golangci-lint run ./internal/state/...            # 0 issues (GOOS=linux)

@copy-pr-bot

copy-pr-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@abrarshivani
abrarshivani force-pushed the unit-test-state branch 5 times, most recently from 6d26bb8 to dbc251d Compare July 23, 2026 19:38
@abrarshivani
abrarshivani force-pushed the unit-test-state branch 13 times, most recently from 91ffc55 to 7fa5f4c Compare July 30, 2026 21:35
Raise internal/state statement coverage from 37.8% to 97.2% with tests only.
Cover info_source (100%), manager SyncState/GetWatchSources/newStates error
paths, state_skel create/update/merge/getSyncState/isDaemonSetReady, driver
Sync/getManifestObjects/handleDefaultImagesInObjects/cleanupStaleDriverDaemonsets,
the GDS/GDRCopy/runtime spec helpers, driver spec/name/volume-config helpers,
and nodepool selection, using the controller-runtime fake client with
interceptors for injected errors and a fake manager where needed.

The ~2.8% that remains is the reachable ceiling: each uncovered statement is
either dead code (the getOSTag error branch that never fires; the SUSE
/lib/modules block gated by contradictory UsePrecompiledDrivers conditions),
a success return that loads the hardcoded on-disk path
/opt/gpu-operator/manifests/state-driver, a live-informer predicate closure in
GetWatchSources, or a provably-impossible SetNestedField error.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
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.

1 participant