Skip to content

Commit 59fceeb

Browse files
committed
Update golden test framework
* Add support for envtest (instead of mock-kubeapiserver) * Create shared code for capturing requests / normalization. * Use a more conventional env var WRITE_GOLDEN_OUTPUT * Support object rewriting
1 parent 11d31d2 commit 59fceeb

File tree

20 files changed

+828
-225
lines changed

20 files changed

+828
-225
lines changed

dev/test

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ cd "${REPO_ROOT}"
2727

2828
set -x
2929

30+
# Download the kubebuilder assets for envtest
31+
export KUBEBUILDER_ASSETS=$(go run sigs.k8s.io/controller-runtime/tools/setup-envtest@latest use -p path)
32+
3033
pushd mockkubeapiserver
3134
CGO_ENABLED=0 go test -count=1 -v ./...
3235
popd

docs/addon/walkthrough/tests.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ This means that the output is materialized and checked in to the repo; this
3333
proves to be very handy for understanding the impact of a change.
3434

3535
There's also a helpful "cheat" function, which rewrite the output when you run
36-
the tests locally - set the HACK_AUTOFIX_EXPECTED_OUTPUT env var to a non-empty
36+
the tests locally - set the WRITE_GOLDEN_OUTPUT env var to a non-empty
3737
string. This is useful when you have a big set of changes; it's just as easy to
3838
review the changes yourself in the diff and there's not a ton of value in typing
3939
them out.
@@ -87,7 +87,7 @@ the env-var cheat code.
8787
```bash
8888
cd pkg/controller/{{operator}}/tests
8989
touch tests/simple.out.yaml
90-
HACK_AUTOFIX_EXPECTED_OUTPUT=1 go test ./...
90+
WRITE_GOLDEN_OUTPUT=1 go test ./...
9191
```
9292

9393
1. Verify the output is reproducible

examples/guestbook-operator/controllers/guestbook_controller_test.go

+37-7
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,51 @@ limitations under the License.
1717
package controllers
1818

1919
import (
20+
"path/filepath"
2021
"testing"
2122

23+
"k8s.io/klog/v2/klogr"
24+
"sigs.k8s.io/controller-runtime/pkg/envtest"
25+
"sigs.k8s.io/controller-runtime/pkg/log"
26+
"sigs.k8s.io/controller-runtime/pkg/manager"
27+
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
28+
2229
api "sigs.k8s.io/kubebuilder-declarative-pattern/examples/guestbook-operator/api/v1alpha1"
30+
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative"
2331
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/test/golden"
2432
)
2533

2634
func TestGuestbook(t *testing.T) {
27-
v := golden.NewValidator(t, api.SchemeBuilder)
28-
dr := &GuestbookReconciler{
29-
Client: v.Client(),
35+
log.SetLogger(klogr.New())
36+
37+
env := &envtest.Environment{
38+
CRDInstallOptions: envtest.CRDInstallOptions{
39+
ErrorIfPathMissing: true,
40+
Paths: []string{
41+
filepath.Join("..", "config", "crd", "bases"),
42+
},
43+
},
3044
}
31-
err := dr.setupReconciler(v.Manager())
32-
if err != nil {
33-
t.Fatalf("creating reconciler: %v", err)
45+
opt := golden.ValidatorOptions{
46+
EnvtestEnvironment: env,
47+
ManagerOptions: manager.Options{
48+
Metrics: metricsserver.Options{
49+
BindAddress: "0",
50+
},
51+
},
3452
}
53+
opt.WithSchema(api.AddToScheme)
54+
55+
v := golden.NewValidator(t, opt)
3556

36-
v.Validate(dr.Reconciler)
57+
v.Validate(func(mgr manager.Manager) (*declarative.Reconciler, error) {
58+
gr := &GuestbookReconciler{
59+
Client: mgr.GetClient(),
60+
}
61+
err := gr.setupReconciler(mgr)
62+
if err != nil {
63+
return nil, err
64+
}
65+
return &gr.Reconciler, nil
66+
})
3767
}

examples/guestbook-operator/controllers/tests/patches-stable.in.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ apiVersion: addons.example.org/v1alpha1
22
kind: Guestbook
33
metadata:
44
name: guestbook-sample
5+
namespace: default
56
spec:
67
channel: stable
78
patches:

examples/guestbook-operator/controllers/tests/simple-stable.in.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ apiVersion: addons.example.org/v1alpha1
22
kind: Guestbook
33
metadata:
44
name: guestbook-sample
5+
namespace: default
56
spec:
67
channel: stable

examples/guestbook-operator/go.mod

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require (
88
github.com/go-logr/logr v1.4.2
99
k8s.io/apimachinery v0.32.1
1010
k8s.io/client-go v0.32.1
11+
k8s.io/klog/v2 v2.130.1
1112
sigs.k8s.io/controller-runtime v0.20.4
1213
sigs.k8s.io/kubebuilder-declarative-pattern v0.0.0-20210922163802-cac4a6cf1977
1314
)
@@ -102,14 +103,13 @@ require (
102103
k8s.io/apiextensions-apiserver v0.32.1 // indirect
103104
k8s.io/cli-runtime v0.29.1 // indirect
104105
k8s.io/component-base v0.32.1 // indirect
105-
k8s.io/klog/v2 v2.130.1 // indirect
106106
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
107107
k8s.io/kubectl v0.29.1 // indirect
108108
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
109109
sigs.k8s.io/cli-utils v0.33.0 // indirect
110110
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
111111
sigs.k8s.io/kubebuilder-declarative-pattern/applylib v0.0.0-20230420203711-4abaa68e1923 // indirect
112-
sigs.k8s.io/kubebuilder-declarative-pattern/mockkubeapiserver v0.0.0-20230303024857-d1f76c15e05b // indirect
112+
sigs.k8s.io/kubebuilder-declarative-pattern/ktest v0.0.0-20240909164454-57a043fb3ad5 // indirect
113113
sigs.k8s.io/kustomize/api v0.14.0 // indirect
114114
sigs.k8s.io/kustomize/kstatus v0.0.2-0.20200509233124-065f70705d4d // indirect
115115
sigs.k8s.io/kustomize/kyaml v0.14.3 // indirect

go.work.sum

+4-2
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j
368368
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
369369
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
370370
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
371+
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
371372
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
372373
github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk=
373374
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
@@ -391,7 +392,6 @@ github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7y
391392
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
392393
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
393394
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
394-
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
395395
github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
396396
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
397397
github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY=
@@ -404,7 +404,6 @@ github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65
404404
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
405405
github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY=
406406
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
407-
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
408407
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
409408
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
410409
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
@@ -565,6 +564,7 @@ golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxb
565564
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
566565
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
567566
google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw=
567+
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
568568
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
569569
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
570570
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
@@ -646,7 +646,9 @@ k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt
646646
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0/go.mod h1:VHVDI/KrK4fjnV61bE2g3sA7tiETLn8sooImelsCx3Y=
647647
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
648648
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
649+
sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4=
649650
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
651+
sigs.k8s.io/kubebuilder-declarative-pattern/applylib v0.0.0-20250315190147-cfd0b42f94ef/go.mod h1:5nbwg87jPbpR+/oCJg7pe5Jn6Bctgu55yTbo9uO1j3M=
650652
sigs.k8s.io/kustomize/kustomize/v5 v5.0.4-0.20230601165947-6ce0bf390ce3/go.mod h1:/d88dHCvoy7d0AKFT0yytezSGZKjsZBVs9YTkBHSGFk=
651653
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca h1:6dsH6AYQWbyZmtttJNe8Gq1cXOeS1BdV3eW37zHilAQ=
652654
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=

ktest/go.mod

+29-3
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,51 @@ toolchain go1.24.1
77
require (
88
github.com/google/go-cmp v0.6.0
99
k8s.io/apimachinery v0.32.1
10+
k8s.io/client-go v0.32.1
1011
k8s.io/klog/v2 v2.130.1
12+
sigs.k8s.io/controller-runtime v0.20.4
13+
sigs.k8s.io/kubebuilder-declarative-pattern/applylib v0.0.0-20250315190147-cfd0b42f94ef
1114
sigs.k8s.io/yaml v1.4.0
1215
)
1316

1417
require (
18+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
19+
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
20+
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
1521
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
1622
github.com/go-logr/logr v1.4.2 // indirect
23+
github.com/go-openapi/jsonpointer v0.21.0 // indirect
24+
github.com/go-openapi/jsonreference v0.21.0 // indirect
25+
github.com/go-openapi/swag v0.23.0 // indirect
1726
github.com/gogo/protobuf v1.3.2 // indirect
27+
github.com/golang/protobuf v1.5.4 // indirect
28+
github.com/google/gnostic-models v0.6.8 // indirect
1829
github.com/google/gofuzz v1.2.0 // indirect
30+
github.com/google/uuid v1.6.0 // indirect
31+
github.com/josharian/intern v1.0.0 // indirect
1932
github.com/json-iterator/go v1.1.12 // indirect
20-
github.com/kr/pretty v0.3.1 // indirect
33+
github.com/mailru/easyjson v0.7.7 // indirect
2134
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
2235
github.com/modern-go/reflect2 v1.0.2 // indirect
23-
github.com/rogpeppe/go-internal v1.12.0 // indirect
36+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
37+
github.com/pkg/errors v0.9.1 // indirect
38+
github.com/prometheus/client_golang v1.20.4 // indirect
39+
github.com/prometheus/common v0.59.1 // indirect
40+
github.com/spf13/pflag v1.0.5 // indirect
2441
github.com/x448/float16 v0.8.4 // indirect
2542
golang.org/x/net v0.30.0 // indirect
43+
golang.org/x/oauth2 v0.23.0 // indirect
44+
golang.org/x/sys v0.26.0 // indirect
45+
golang.org/x/term v0.25.0 // indirect
2646
golang.org/x/text v0.19.0 // indirect
27-
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
47+
golang.org/x/time v0.7.0 // indirect
48+
google.golang.org/protobuf v1.35.1 // indirect
49+
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
2850
gopkg.in/inf.v0 v0.9.1 // indirect
51+
gopkg.in/yaml.v3 v3.0.1 // indirect
52+
k8s.io/api v0.32.1 // indirect
53+
k8s.io/apiextensions-apiserver v0.32.1 // indirect
54+
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
2955
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
3056
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
3157
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect

0 commit comments

Comments
 (0)