Repository navigation
build(images): run the tests of the packages the patches touch - #4326
Conversation
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: cozystack/cozystack/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (1)
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 4 remain after this review. 📝 WalkthroughWalkthroughDockerfiles now test Go packages touched by applied patches before building images. The Redis operator also runs integration-tagged vet checks. The cluster autoscaler patch removes the upper-bound replica-size check and adds coverage for node deletion above the annotated maximum. The Multus Dockerfile explains why its package tests are not run during the image build. ChangesPatched package validation
Replica size validation
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Feature Merge Risk: ⚪ Minimal · up to The PR adds patch-scoped build checks, retains the KubeOVN migration-retry test, and allows scale-down of oversized autoscaler resources without bypassing the scale-up maximum. No actionable merge-blocking risk remains. Architecture SummaryArchitecture risk: 🔵 Low · up to The change affects 2 systems. Changed systems: Architecture concerns Review detailsSystems and components
Before / after behavior
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🧪 Generate unit tests (beta)
🛠️ Fix failing CI checks 💡
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
IvanHunters
left a comment
There was a problem hiding this comment.
Verdict
LGTM with non-blocking notes
Build-stage only. Nothing here touches a chart, a values file, a schema, a CRD, an RBAC rule or an image digest, and the one patch edit lands on a _test.go hunk that make build never compiles, so none of it reaches a running cluster.
The mechanism holds up. I applied the modified fix-downscale.diff against a real cluster-autoscaler-1.32.0 checkout and git apply --check came back clean, which is worth saying because that image had not actually been built at the reviewed revision. git apply --numstat also works outside a git repository, which is what the keycloak-operator and objectstorage builder stages are, and on a rename it prints only the new path. So the enumeration is sound in every shape the repo's 21 patch files currently take.
Findings
- [MINOR]
packages/system/keycloak-operator/images/keycloak-operator/Dockerfile:29, the gate reports success when its own input command fails
- [MINOR]
packages/system/redis-operator/images/redis-operator/Dockerfile:29, the integration arm is hardcoded while the derived loop already visits that directory vacuously
- [MINOR]
packages/apps/kubernetes/images/cluster-autoscaler/fix-downscale.diff:22, the first real signal from the new runner is answered by deleting the assertion
Caveats
kilo,kubeovnandkeycloak-operatorare absent from the rootMakefilebuild:recipe, so their new step only runs on a manualmake image. Those are also two of the images whose patches carry the most test code, so the step pays least where it would pay most. Worth a follow-up to get them into a build lane.Build packages/apps/kuberneteswas still pending onba53e15d. I checked that image statically instead: the patch applies clean at the pinned tag and the enumeration resolves to the right directory. I did not run the suite itself.- Checked and sound: a rename in a patch is safe, an empty list runs nothing,
go testis never cross-compiled since no workflow setsPLATFORM, and no patch in the tree deletes a file, so the loop never meets a directorygit applyhas pruned.
| # packages the patches touch. Each package is tested from its own directory: | ||
| # that finds the module it belongs to, and an empty list runs nothing. | ||
| COPY --from=source /patches /patches | ||
| RUN for dir in $(git apply --numstat /patches/*.diff | cut -f3 | grep '\.go$' | xargs -n1 dirname | sort -u); do \ |
There was a problem hiding this comment.
[MINOR] the gate reports success when its own input command fails
git apply --numstat feeds the loop through a command substitution, so its exit status is dropped. When it errors the list comes back empty, the loop body never runs, and the step passes having tested nothing. The git apply a few lines up fails closed on the same argument, so the two disagree about the same input; in this image and in objectstorage they do not even read the same copy of it, since the gate reads a second COPY --from=source /patches /patches in another stage.
Reproduced with the argument pointed at a path that does not resolve:
$ sh -c 'for dir in $(git apply --numstat /nonexistent/*.diff | cut -f3 | grep "\.go$" | xargs -n1 dirname | sort -u); do
echo "RAN FOR: $dir"
done
echo "LOOP FINISHED, RUN EXIT WOULD BE 0"'
error: can't open patch '/nonexistent/*.diff': No such file or directory
LOOP FINISHED, RUN EXIT WOULD BE 0
shell exit=0
Capturing the list on its own line under set -e closes it, and I checked both halves behave:
RUN set -e; \
files=$(git apply --numstat /patches/*.diff); \
for dir in $(printf '%s\n' "$files" | cut -f3 | grep '\.go$' | xargs -n1 -r dirname | sort -u); do \
(cd "$dir" && go test .); \
done
set -e does abort on the assignment (exit=128, the loop is never reached), and an empty .go list still iterates zero times without tripping it. The -r on xargs is worth adding for its own reason: without it GNU xargs runs dirname once with no operands on an empty list, which is where the stray dirname: missing operand in the build log comes from.
The same line appears in the other 11 images.
There was a problem hiding this comment.
Fixed in a08ccca, same change as in the kamaji thread. It also removes the stray dirname: missing operand. I used || exit 1 on the assignment instead of set -e: it fails in the same cases and matches the || exit 1 already in the loop body.
|
|
||
| # The integration tests the patches edit sit behind a build tag and need a | ||
| # cluster, so they are only type-checked here. | ||
| RUN go vet -tags integration ./test/integration/redisfailover |
There was a problem hiding this comment.
[MINOR] the integration arm is hardcoded while the derived loop already visits that directory vacuously
valkey-cli-auth.diff touches test/integration/redisfailover/database_engine_test.go, so the derived list already contains that directory. At v3.3.5 it holds creation_test.go and database_engine_test.go, both behind //go:build integration in package redisfailover_test, plus an untagged doc.go in package redisfailover. So the loop's go test . there compiles only doc.go, reports no test files and asserts nothing; this hardcoded go vet line is the real check.
Two consequences. Unlike everything else in this change the path is not derived from the patches, so a later patch touching build-tagged tests in any other directory is silently uncovered. And the directory's coverage rests on doc.go continuing to exist: if upstream drops it, the loop's own visit fails outright rather than passing empty.
$ mkdir -p /tmp/tagtest/pkg && cd /tmp/tagtest
$ printf 'module tagtest\n\ngo 1.21\n' > go.mod
$ printf '//go:build integration\n\npackage pkg\n\nimport "testing"\n\nfunc TestX(t *testing.T) {}\n' > pkg/only_tagged_test.go
$ cd pkg && go test .
# tagtest/pkg
package tagtest/pkg: build constraints exclude all Go files in /tmp/tagtest/pkg
FAIL tagtest/pkg [setup failed]
FAIL
exit=1
Deriving the tagged arm from the patches the same way the untagged one is derived would close both.
There was a problem hiding this comment.
Fixed in 357f57a, details in the newer thread on this line. The tagged arm is now derived from the patches like the untagged one.
The doc.go dependency is still there. If upstream drops it, go test . in that directory fails the build with "build constraints exclude all Go files". That failure is loud, so I left it as is.
| initial: 3, | ||
| errorMsg: "size increase must be positive", | ||
| - }, { | ||
| - description: "errors because initial+delta > maxSize", |
There was a problem hiding this comment.
[MINOR] the first real signal from the new runner is answered by deleting the assertion
This hunk drops the errors because initial+delta > maxSize case from TestNodeGroupIncreaseSizeErrors, because the carried patch's other hunk removes the case nreplicas > r.maxSize refusal from SetSize and the test caught the mismatch. The image's behaviour does not change, and the commit message says so plainly, so this is not a regression and it is not why the note is here.
It is here because of what the assertion was holding. At cluster-autoscaler-1.32.0, IncreaseSize in clusterapi_nodegroup.go checks only that the delta is positive and then delegates:
func (ng *nodegroup) IncreaseSize(delta int) error {
if delta <= 0 {
return fmt.Errorf("size increase must be positive")
}
size, err := ng.scalableResource.Replicas()
if err != nil {
return err
}
return ng.scalableResource.SetSize(size + delta)
}
So the SetSize guard was the only enforcement of maxSize on this path, and that deleted case was its only assertion across the package's test files. The patch is named fix-downscale, yet the hunk it carries removes the size-increase refusal and leaves the size-decrease one intact, which reads more like the wrong case was deleted in January 2025 than like a decision. That predates this PR by twenty months and is not this PR's to fix.
What is this PR's: the change whose whole purpose is to stop carried patches from drifting away from what upstream asserts resolves its own first finding by removing the assertion, inside a build(...) commit, without a line on whether the guard removal was intended. Suggest keeping the deletion so the build goes green, and opening a separate issue against fix-downscale.diff so the question does not disappear with the test that raised it.
There was a problem hiding this comment.
I don't think the wrong case was deleted. DeleteNodes lowers a group through SetSize(replicas - 1), so with the old nreplicas > r.maxSize check a group already above its max size could not shed a node at all. Every step was refused as an increase, and that is the downscale the patch is named for.
On the increase side, the core scale-up orchestrator skips a group that is already at MaxSize() before it calls IncreaseSize (the currentTargetSize >= nodeGroup.MaxSize() check in core/scaleup/orchestrator/orchestrator.go). So the provider check was a second line of defence, not the only one. 70667a8 adds a test for the downscale path, so the patched behaviour now has an assertion, and I don't think a separate issue is needed.
ba53e15 to
94fd062
Compare
IvanHunters
left a comment
There was a problem hiding this comment.
Verdict
NOT LGTM
The new generic test loop breaks the opensearch-operator image build on this head, so the package can no longer be built.
Findings
- [MAJOR]
packages/system/opensearch-operator/images/opensearch-operator/Dockerfile:84, genericgo test .loop drags the envtest controller suite into the build and fails it
- [MINOR]
packages/system/kamaji/images/kamaji/Dockerfile:18,for dir in $(git apply --numstat ...)swallows the substitution's exit status (same pattern in every image)
- [MINOR]
packages/system/redis-operator/images/redis-operator/Dockerfile:29, the integration arm is hardcoded while the loop already visits that directory vacuously
- [MINOR]
packages/apps/kubernetes/images/cluster-autoscaler/fix-downscale.diff:22, the first real failure from the new runner is answered by deleting the assertion
Caveats
- Dockerfile-only diff: no chart, CRD, or values change, so upgrade and config-matrix paths are not exercised by this PR.
| # go build never compiles a _test.go, so nothing else runs the tests of the | ||
| # packages the patches touch. Each package is tested from its own directory: | ||
| # that finds the module it belongs to, and an empty list runs nothing. | ||
| RUN for dir in $(git apply --numstat /patches/*.diff | cut -f3 | grep '\.go$' | xargs -n1 dirname | sort -u); do \ |
There was a problem hiding this comment.
[MAJOR] generic go test . loop drags the envtest controller suite into the build and fails it
The loop runs go test . in every directory the patch touches. The opensearch patch edits controllers/opensearchController.go, so the loop enters opensearch-operator/controllers and compiles its pre-existing suite_test.go, an envtest BeforeSuite that execs /usr/local/kubebuilder/bin/etcd. That binary is absent in the builder, TestAPIs fails, and the RUN exits 1. All 11 other image builds on this head pass; only this one is red, for exactly this step. The curated line just below (go test -race ./opensearch-gateway/... ./pkg/reconcilers/...) already runs the patch's real unit tests, and its comment says both trees run without a cluster. The generic loop is redundant here and additionally pulls in the one tree that needs a cluster. Drop the loop for this image, or exclude cluster-bound suites from it.
$ gh api repos/cozystack/cozystack/actions/jobs/109706697882/logs
unable to start control plane itself: failed to start the controlplane. retried 5 times: fork/exec /usr/local/kubebuilder/bin/etcd: no such file or directory
--- FAIL: TestAPIs (0.01s)
FAIL github.com/Opster/opensearch-k8s-operator/opensearch-operator/controllers 0.023s
#14 ERROR: process for the added test loop did not complete successfully: exit code: 1
There was a problem hiding this comment.
Fixed in 0979736. After the stall-tracing patch landed on main, the loop started entering controllers/, and that suite starts an envtest control plane the builder has no binaries for. The step now skips that one directory.
I also moved the -race flag into the loop and dropped the hand-picked go test -race line, so the same packages are not tested twice and a patch in a new directory is still picked up. Locally the builder stage builds and reports ok for opensearch-gateway/services and pkg/reconcilers.
| # go build never compiles a _test.go, so nothing else runs the tests of the | ||
| # packages the patches touch. Each package is tested from its own directory: | ||
| # that finds the module it belongs to, and an empty list runs nothing. | ||
| RUN for dir in $(git apply --numstat /patches/*.diff | cut -f3 | grep '\.go$' | xargs -n1 dirname | sort -u); do \ |
There was a problem hiding this comment.
[MINOR] for dir in $(git apply --numstat ...) swallows the substitution's exit status (same pattern in every image)
If the patch glob is missing or git apply --numstat errors, the substitution yields an empty list, the loop body never runs, and the RUN still exits 0. A runner that silently runs zero tests reads as green, which defeats the point of the change. Capture the list first and fail when the apply itself errored or the list is empty when a test was expected.
There was a problem hiding this comment.
Fixed in all 12 images, for kamaji in 509ce5d. The list goes into a variable with || exit 1 before the loop, and xargs -r keeps dirname from running with no operand.
Checked under dash in the golang builder image: a patch path that does not resolve exits 1, a patch with no Go file exits 0 and runs nothing, and a normal patch runs the test. I didn't add a "list must not be empty" check. Once git has read the patches, the list depends only on what they contain, so an empty list just means no Go file was touched.
|
|
||
| # The integration tests the patches edit sit behind a build tag and need a | ||
| # cluster, so they are only type-checked here. | ||
| RUN go vet -tags integration ./test/integration/redisfailover |
There was a problem hiding this comment.
[MINOR] the integration arm is hardcoded while the loop already visits that directory vacuously
The derived loop runs go test . in test/integration/redisfailover, where the tests sit behind a build tag, so it compiles and asserts nothing there; the separate go vet -tags integration ./test/integration/redisfailover then covers the same directory by hand. Keep one path, not both.
There was a problem hiding this comment.
Fixed in 357f57a. The loop now runs go vet -tags integration . next to go test . in every directory it visits, and the hand-written go vet line is gone. All 11 touched directories vet clean with the tag.
To check it, I added an undefined call to database_engine_test.go. go vet -tags integration fails on it, while go test . still reports no test files. The tag name is still written in the Dockerfile, so a test behind some other tag would need an edit.
| initial: 3, | ||
| errorMsg: "size increase must be positive", | ||
| - }, { | ||
| - description: "errors because initial+delta > maxSize", |
There was a problem hiding this comment.
[MINOR] the first real failure from the new runner is answered by deleting the assertion
The new hunk removes the errors because initial+delta > maxSize case rather than updating it to the patched scale-up behavior, so the exact path the production patch changes loses its only assertion.
There was a problem hiding this comment.
Fixed in 70667a8. The patch now also carries TestNodeGroupDeleteNodesAboveMaxSize, which deletes a node from a group with 4 replicas and max size 2 and expects 3.
Against the unpatched SetSize the test fails with size increase too large - desired:3 max:2. With the patch the touched package passes. I ran both from the cluster-autoscaler-1.32.0 tag tarball, and the CI build of the image passes the step too. The deleted case still has to go, because it asserts the exact refusal the patch removes.
6fb9ad4 to
533c7cd
Compare
|
The branch has been rebased since my replies of 2026-10-01, so the commit hashes in them no longer appear in this PR's history. The fixes they describe now live in 293a780 (opensearch-operator), e2757ba (redis-operator), 1ffc858 (keycloak-operator), 59c3174 (kamaji) and b2a5f12 (kubernetes, |
… touch The image build ran go test on two package trees listed by hand, and go build never compiles a _test.go. A patch that reaches a directory nobody listed brings tests that are proven once, by hand, when the patch is cut, and nothing notices them failing after the next version bump. Run go test in the builder stage on the packages the patches touch. The list is read from the patches themselves, so a new patch is covered without an edit to the Dockerfile. It replaces the hand-picked go test line, keeping its -race flag: two lines testing the same packages is one too many. The hand-picked line also covered pkg/reconcilers/util, which no patch touches. controllers/ is left out. The stall-tracing patch touches it, and its suite starts an envtest control plane from etcd and kube-apiserver binaries the builder does not have, so testing it fails the build. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
The image build ran go build only, and go build never compiles a _test.go, so nothing ran the tests of the code the patches change. Run go test in the builder stage on the packages the patches touch. The list is read from the patches themselves, so a new patch is covered without an edit to the Dockerfile. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
The image build ran go build only, and go build never compiles a _test.go, so nothing ran the tests of the code the patches change. Run go test in the builder stage on the packages the patches touch. The list is read from the patches themselves, so a new patch is covered without an edit to the Dockerfile. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
The image build ran go build only, and go build never compiles a _test.go, so nothing ran the tests of the code the patches change. Run go test in the builder stage on the packages the patches touch. The list is read from the patches themselves, so a new patch is covered without an edit to the Dockerfile. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
The image build ran go build only, and go build never compiles a _test.go, so nothing ran the tests of the code the patches change. Run go test in the builder stage on the packages the patches touch. The list is read from the patches themselves, so a new patch is covered without an edit to the Dockerfile. Two of the files the patches edit are upstream integration tests behind the integration build tag, which go test compiles none of, so each directory is also vetted with that tag. Doing it per derived directory rather than for the one directory those tests live in today keeps a later patch to a tagged test elsewhere covered. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
…ouch The image build ran go build only, and go build never compiles a _test.go, so nothing ran the tests of the code the patches change. Run go test in the builder stage on the packages the patches touch. The list is read from the patches themselves, so a new patch is covered without an edit to the Dockerfile. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
…atches touch The image build ran go build only, and go build never compiles a _test.go, so nothing ran the tests of the code the patches change. Run go test in the builder stage on the packages the patches touch. The list is read from the patches themselves, so a new patch is covered without an edit to the Dockerfile. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
The image build ran go build only, and go build never compiles a _test.go, so nothing ran the tests of the code the patches change. Run go test in the builder stage on the packages the patches touch. The list is read from the patches themselves, so a new patch is covered without an edit to the Dockerfile. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
The image build ran one test by name, the one shipped next to the migration patch, and go build never compiles a _test.go, so the rest of the tests in the packages the patches change never ran. Run go test in the builder stage on the packages the patches touch. The list is read from the patches themselves, so a new patch is covered without an edit to the Dockerfile. It replaces the hand-picked go test line: the shipped test lives in pkg/controller, which a patch touches, so the loop runs it with the rest of that package. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
The cluster-autoscaler and kubevirt-cloud-provider image builds ran go build only, and go build never compiles a _test.go, so nothing ran the tests of the code the patches change. Run go test in the builder stage on the packages the patches touch. The list is read from the patches themselves, so a new patch is covered without an edit to the Dockerfile. Both builder stages export GOOS and GOARCH for the target, so the tests unset them: a local make image builds amd64 and arm64 by default, and a test binary for the other architecture runs on the build host only under binfmt emulation. The first run of that step on cluster-autoscaler found the carried downscale patch out of step with the upstream tests it leaves in place: SetSize no longer refuses a size above maxSize, while one case of TestNodeGroupIncreaseSizeErrors still expected that refusal. The patch now drops that case, and carries a test for the downscale it is named for instead. DeleteNodes lowers a group one node at a time through SetSize, so with the refusal in place a group standing above its max size could not shed a node at all. The new test deletes a node from such a group and expects the replica count to drop; against the unpatched SetSize it fails with the refusal the patch removes. Scale-up past maxSize stays bounded by the core scale-up orchestrator, which skips a node group already at MaxSize. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
…tches touch The image build ran go build only, and go build never compiles a _test.go, so nothing ran the tests of the code the patches change. Run go test in the builder stage on the packages the patches touch. The list is read from the patches themselves, so a new patch is covered without an edit to the Dockerfile. Each package is tested from its own directory rather than as a ./... path of the root module, because internal/ is a module of its own and the root module cannot name ./internal/runtime. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
…ackage The other patched Go images now test the packages their patches touch in the builder stage. The one package the multus patch touches, pkg/multus, creates network namespaces in its tests, which a build container is not allowed to do, so that image keeps building without a test step. The Dockerfile records the reason, so the absence reads as a decision and not as an omission. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <[email protected]>
533c7cd to
89a1fe5
Compare
IvanHunters
left a comment
There was a problem hiding this comment.
Verdict
LGTM
This round is build-stage only: every edit lands inside an image Dockerfile, plus a _test.go added to the cluster-autoscaler patch. Nothing touches a chart, values file, schema, CRD, RBAC rule or image digest. The added step runs the unit tests of the Go packages each image's patch touches, at build time, so a patch that breaks a test file or its assertions now fails the image build instead of shipping silently.
I checked the core shell semantics against a real git/go rather than by reading. git apply --numstat on an already-applied patch lists the files without touching the tree (exit 0), and works outside a git work tree too, which the keycloak-operator and objectstorage stages rely on. files=$(...) || exit 1 captures a git-apply error (rc 128). The cut -f3 | grep '\.go$' | xargs -r -n1 dirname | sort -u pipeline yields the right package dirs, and an empty list runs nothing and exits 0 by design. go test . without a build tag skips an integration-tagged file while go vet -tags integration . type-checks it and fails on an undefined symbol, so the redis-operator change is not vacuous.
GOOS/GOARCH handling is correct per stage: only cluster-autoscaler and kubevirt-cloud-provider set them stage-wide, and both drop them with env -u for the test run; every other image sets them inline on the go build line only, so its test runs on the native builder. All twelve touched image builds, including opensearch-operator, pass on this head.
The branch advanced from the revision I first read to the current head while I was reviewing (a rebase onto newer main). I re-checked the content: of this PR's own files only packages/system/kubeovn/images/kubeovn/Dockerfile changed, dropping the explicit go test ./pkg/controller -run ... line in favour of the generic loop. That is correct: the carried patch fix-vmim-target-pod-retry.diff touches pkg/controller/kubevirt.go, so the loop derives pkg/controller and runs the copied kubevirt_migration_test.go there, and pkg/controller is not envtest so a plain go test . runs it. Everything else is unchanged.
Non-blocking notes
-
[NIT]
packages/system/opensearch-operator/images/opensearch-operator/Dockerfile:84— the envtest suite is skipped withgrep -vx 'opensearch-operator/controllers', which is exactly right for the current patches (they touch controllers, opensearch-gateway/responses, opensearch-gateway/services and pkg/reconcilers, and only controllers starts a control plane). Because it is an exact match, a future patch touching a sub-package of controllers, or another envtest-bound package, would not be excluded and would break this build. Current CI is green. -
[MINOR]
packages/system/multus/images/multus-cni/Dockerfile:306— this PR's only multus change is the comment: pkg/multus tests create network namespaces the builder cannot, so the image does not run them (true: 55 of 56 specs fail onmount --make-rshared /var/run/netns). Separately, the pre-existing carried patchfix-del-without-cache.diffrewrites CmdDel to return nil when the cache file is missing, while upstream v4.3.0 still ships threeDelete pod without cachespecs asserting DEL reaches both delegates; a focused privileged run shows them red (0 passed, 3 failed). That mismatch is pre-existing and this PR does not introduce it, but if the netns limitation is ever lifted the suite will be red for that reason, not only un-runnable. Worth either updating those three specs in the patch or noting the divergence in the comment.
Pull request was closed
What this PR does
Twelve first-party images that are built from an upstream tree with patches on top now run
go teston the packages those patches touch. The step sits in the builder stage, right after the patches are applied. Before this, ten of them rango buildonly, andgo buildnever compiles a_test.go, so a test carried inside a patch was proven once by hand and never again. The other two, opensearch-operator and kube-ovn, ran ago testline written by hand, which a patch reaching a new directory would slip past; the loop replaces both lines.The package list is read from the patches themselves with
git apply --numstat, so a new patch is covered without an edit to the Dockerfile. Each package is tested from its own directory, which finds nested modules: in objectstorage,internal/is a module of its own and the root module cannot name./internal/runtime. An empty list runs nothing. The list is read into a variable before the loop, because aforloop drops the exit status of a command substitution, and a patch that git cannot read would otherwise give an empty list and a green step.A few images need more than the plain loop:
controllers/. A patch touches it, but its suite starts an envtest control plane from etcd and kube-apiserver binaries the builder does not have. The loop runs with-raceand replaces the hand-pickedgo test -raceline, which also coveredpkg/reconcilers/util, a package no patch touches.go test -run '^TestVMIMigrationSchedulingRetry$'line. The test it named is copied intopkg/controller, which a patch touches, so the loop runs it along with the rest of that package.go vet -tags integrationin each touched directory. Two of the files its patches edit are upstream integration tests behind that tag, andgo testcompiles none of them.GOOSandGOARCHfor the target in the whole builder stage, so their tests unset both. A localmake imagebuilds amd64 and arm64 by default, and a test binary for the other architecture runs on the build host only under binfmt emulation. CI is not affected either way: the jobs that build package images each pin onePLATFORMthat matches the runner's architecture.The first run of the step on cluster-autoscaler found the carried
fix-downscale.diffout of step with the upstream tests it leaves in place. The patch removes themaxSizerefusal fromSetSize, and one case ofTestNodeGroupIncreaseSizeErrorsstill expected that refusal. The patch now drops that case and carriesTestNodeGroupDeleteNodesAboveMaxSizeinstead. That test covers the downscale the patch is named for:DeleteNodeslowers a group throughSetSize, so with the refusal in place a group standing above its max size could not shed a node. Against the unpatchedSetSizethe new test fails. The image's behaviour does not change, and scale-up stays bounded by the core scale-up orchestrator, which skips a node group already at its max size.CI builds all twelve images, and the step reports
okorno test filesfor every package it tests. Locally, the redis-operator, opensearch-operator and kube-ovn builder stages pass. The cluster-autoscaler package was checked from thecluster-autoscaler-1.32.0tag tarball, because the Dockerfile's full clone of kubernetes/autoscaler does not survive my network. As negative controls, an undefined call added to a redis integration test failsgo vet -tags integrationwhilego teststill passes, and the new autoscaler test fails without the patch.Left out on purpose, and the Dockerfile says so:
multus. Its only touched package,pkg/multus, creates network namespaces in its tests, which a build container cannot do (mount --make-rshared /var/run/netns: operation not permitted).cilium(C, no compile step) andpiraeus-server(Java) are out of scope.Closes #4318
Screenshots
Not a UI change.
Downstream repositories
Walked the trigger map against the diff: Dockerfiles under
packages/*/images/and one patch file. No values key, schema, make target,hack/file or documented workflow changes.Release note