Skip to content

Add unit tests for internal packages - #2656

Open
abrarshivani wants to merge 13 commits into
NVIDIA:mainfrom
abrarshivani:unit-test-internal
Open

Add unit tests for internal packages#2656
abrarshivani wants to merge 13 commits into
NVIDIA:mainfrom
abrarshivani:unit-test-internal

Conversation

@abrarshivani

@abrarshivani abrarshivani commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Description

Adds unit tests to raise coverage across the internal/ packages, plus a few small production cleanups noted below. Each package was driven to full statement coverage of every reachable path (both success and error paths), verified with go test -covermode=count.

Note: the ImagePath validation change that previously lived here has been split into its own PR (#2682) per review, so this PR is test-coverage-only aside from the small cleanups below.

Packages covered

  • internal/imageImagePath: tag vs sha256: digest joining, kbld image pass-through, CR-over-env priority, env fallback, and the empty-CR error path. 100%
  • internal/infoGetVersionParts / GetVersionString: with/without gitCommit, empty/whitespace values, variadic joining, fresh-slice / no-mutation guarantees. 100%
  • internal/conditions — ClusterPolicy and NVIDIADriver updaters: Ready/Error success, type-assertion guard, failed-Get, unknown-status-type default, retry-on-conflict, non-conflict update-error propagation, and status.state defaulting/preservation. Uses the controller-runtime fake client + interceptors; condition assertions use cmp.Diff; schemes are built per-test. 100%
  • internal/utilsGetFilesWithSuffix and the object-hash helpers. 100%
  • internal/nodeinfo — the previously untested Reset methods on both filter builders. 100%
  • internal/validatorValidate error paths (driver-list failure, invalid listed selector, node-list failure). 100%
  • internal/nvidiadriverAssignOwners error paths (driver-list, node-list, owner-label patch add/remove). 98.5% (one unreachable nil-map guard).

Production changes (small cleanups)

  1. internal/utils/utils.goGetStringHash: removed an unreachable error branch. fnv.New32a's Write never returns an error (per the hash.Hash contract), so the error check and the panic it guarded were dead code.
  2. internal/utils/utils.goGetFilesWithSuffix: deduplicate results. The function appended a path once per matching suffix, so a file matching more than one of the provided suffixes was returned multiple times. It now breaks after the first matching suffix (behavior-identical for the only current caller, which passes the non-overlapping yaml/yml/json).
  3. internal/utils/utils.goGetObjectHashIgnoreEmptyKeys: documented (no behavior change) that the argument must be a struct or pointer-to-struct and that other kinds/nil panic.

The ImagePath incomplete-spec validation (production behavior change) and its tests were moved to #2682.

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/... -covermode=count
golangci-lint run ./...     # 0 issues (run with GOOS=linux; pathrs-lite is Linux-only)

@copy-pr-bot

copy-pr-bot Bot commented Jul 21, 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 changed the title Add unit tests for internal/image and internal/info Add unit tests for internal packages Jul 22, 2026
@abrarshivani abrarshivani self-assigned this Jul 22, 2026
@abrarshivani
abrarshivani marked this pull request as ready for review July 22, 2026 20:50
Add table-driven unit tests covering the previously untested
internal/image (ImagePath) and internal/info (GetVersionParts,
GetVersionString) packages.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
Comment thread api/nvidia/v1/clusterpolicy_types.go Outdated
Cover positive and negative edge cases:
- internal/image: tag vs digest selection (including empty digest, missing
  colon, and case-sensitive sha256 prefix), kbld passthrough, partial-CR
  paths taking priority over env, env fallback, no-input-validation edges,
  and the error path with its message contents.
- internal/info: empty/whitespace version and commit, variadic joining with
  empty elements, and fresh-slice / no-mutation guarantees.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
Cover every path in clusterpolicy.go: SetConditionsReady/SetConditionsError
success cases, the type-assertion guard for non-ClusterPolicy objects, the
Ready->Error transition, the failed-Get path, the unknown-status-type default
branch, retry-on-conflict, and non-conflict status-update error propagation.
clusterpolicy.go reaches 100% statement coverage.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
Cover the paths in nvidiadriver.go not exercised by the existing tests:
the type-assertion guard for non-NVIDIADriver objects, the failed-Get path,
the unknown-status-type default branch, retry-on-conflict, non-conflict
status-update error propagation, and the status.state defaulting/preservation
logic in the Error case. The internal/conditions package now reaches 100%
statement coverage.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
Cover the previously untested GetFilesWithSuffix: recursive matching across
subdirectories, multiple suffixes, no-match and no-suffix cases, the
traversal-error path for a missing directory, an empty directory, a file
passed as the base path, and a file matching more than one suffix.

The only remaining uncovered line in the package is the defensive panic in
GetStringHash, which is unreachable: fnv.New32a's Write never returns an
error and the hasher is constructed internally.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
fnv.New32a's Write never returns an error (guaranteed by the hash.Hash
contract: "Write ... never returns an error"), so the error check and the
panic it guarded were dead code that could never execute. Drop them and
ignore the always-nil error explicitly. This makes internal/utils reach
100% statement coverage.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
Cover the previously untested Reset methods on NodeLabelFilterBuilder and
NodeLabelNoValFilterBuilder, verifying that Reset clears accumulated label
criteria. internal/nodeinfo now reaches 100% statement coverage.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
Cover the driver-list failure, GPU-node-list failure, and owner-label patch
failures for both the add/update and removal cases, using fake-client
interceptors. The only remaining uncovered line is the defensive nil-Labels
guard, which is unreachable in AssignOwners because nodes are listed by the
GPU-present label and therefore always carry labels.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
Cover the driver-list failure, an invalid nodeSelector on a listed driver,
and the node-list failure. internal/validator now reaches 100% statement
coverage.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
Address maintainer naming preference (avoid abbreviations, per review
feedback on prior unit-test PRs): rename the local cp variable to
clusterPolicy in clusterpolicy_test.go.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
Adopt Kubernetes-idiomatic testing patterns in the conditions and validator
tests:
- Replace field-by-field metav1.Condition assertions with a single
  cmp.Diff against the expected condition slice (ignoring server-set
  LastTransitionTime/ObservedGeneration), which reads clearer and prints a
  precise diff on failure.
- Build a fresh runtime.NewScheme() per test instead of mutating the global
  client-go scheme.Scheme, keeping the tests hermetic.

Promotes github.com/google/go-cmp to a direct dependency and vendors
cmp/cmpopts. Coverage unchanged (100%).

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
GetFilesWithSuffix appended a path once per matching suffix, so a file that
matched more than one of the provided suffixes was returned multiple times.
Break after the first matching suffix so each file is returned at most once;
this is behavior-identical for non-overlapping suffixes (the only current
caller passes yaml/yml/json). Update the test to assert the single result.

Also document that GetObjectHashIgnoreEmptyKeys requires a struct (or pointer
to struct) and panics on other kinds, matching what all callers already pass.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
Remove comments that merely restate what the code and test/case names already
convey, keeping only the few that explain non-obvious context (why a default
branch is reached via the unexported setConditions, why a bare trailing colon
is the expected value, the append-aliasing regression a test guards against,
and why certain node setups drive specific patch branches).

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
Comment thread internal/utils/utils.go
panic(err)
}
// hash.Hash's Write never returns an error, per its documented contract.
_, _ = hasher.Write([]byte(s))

@tariq1890 tariq1890 Jul 27, 2026

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.

I would revert this change. We know that the hasher.Write will never return an error which is why we panic should err != nil ever evaluate to true. One of the purposes of panic is to throw an error when a fundamental assumption is broken or when we operate under an inconceivable scenario.

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.

2 participants