Skip to content

Commit cb2d8f1

Browse files
authored
Use envtest for CRD validation tests (#3948)
* Use envtest for cel validation instead of a KinD cluster * Add CRD validation tests to gh actions * Move manifest test to use envtest * Remove the crd testing shell script * Fix boilerplate of test file
1 parent ff47627 commit cb2d8f1

File tree

7 files changed

+294
-167
lines changed

7 files changed

+294
-167
lines changed

.github/workflows/crd-validation.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: CRD Validation
2+
3+
on:
4+
pull_request:
5+
types: [opened, edited, synchronize, reopened]
6+
7+
# Remove all permissions from GITHUB_TOKEN except metadata.
8+
permissions: {}
9+
10+
jobs:
11+
crd-validation:
12+
name: CEL
13+
runs-on: ubuntu-latest
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
# Available versions at https://raw.githubusercontent.com/kubernetes-sigs/controller-tools/HEAD/envtest-releases.yaml
18+
k8s_version: [v1.33.0, v1.32.0, v1.31.0, v1.30.3, v1.29.5]
19+
crd_channel: [standard, experimental]
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
23+
with:
24+
persist-credentials: false
25+
- name: Set up Go
26+
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # tag=v5.5.0
27+
- name: Run CRD Validation tests
28+
env:
29+
K8S_VERSION: ${{ matrix.k8s_version }}
30+
CRD_CHANNEL: ${{ matrix.crd_channel }}
31+
run: |
32+
make CEL_TEST_K8S_VERSION="${K8S_VERSION}" CEL_TEST_CRD_CHANNEL="${CRD_CHANNEL}" test.crds-validation

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ ROOT := $(abspath $(TOP))
5454
CONFORMANCE_FLAGS ?=
5555
GO_TEST_FLAGS ?=
5656

57+
# Flags for CRD validation tests
58+
CEL_TEST_K8S_VERSION ?=
59+
CEL_TEST_CRD_CHANNEL ?= standard
60+
5761
all: generate vet fmt verify test
5862

5963
# Run generators for protos, Deepcopy funcs, CRDs, and docs.
@@ -85,7 +89,8 @@ test:
8589
# Run tests for CRDs validation
8690
.PHONY: test.crds-validation
8791
test.crds-validation:
88-
./hack/test-crds-validation.sh $(VERSION)
92+
K8S_VERSION=$(CEL_TEST_K8S_VERSION) CRD_CHANNEL=$(CEL_TEST_CRD_CHANNEL) go test ${GO_TEST_FLAGS} -count=1 -timeout=120s --tags=$(CEL_TEST_CRD_CHANNEL) -v ./pkg/test/cel
93+
K8S_VERSION=$(CEL_TEST_K8S_VERSION) CRD_CHANNEL=$(CEL_TEST_CRD_CHANNEL) go test ${GO_TEST_FLAGS} -count=1 -timeout=120s -v ./pkg/test/crd
8994

9095
# Run conformance tests against controller implementation
9196
.PHONY: conformance

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ require (
2828
github.com/Masterminds/goutils v1.1.1 // indirect
2929
github.com/Masterminds/semver v1.5.0 // indirect
3030
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
31+
github.com/blang/semver/v4 v4.0.0 // indirect
3132
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
3233
github.com/emicklei/go-restful/v3 v3.12.0 // indirect
3334
github.com/evanphx/json-patch/v5 v5.9.11 // indirect

go.sum

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZC
66
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
77
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
88
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
9+
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
10+
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
911
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
1012
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
13+
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
14+
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
1115
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
1216
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1317
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -120,6 +124,14 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
120124
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
121125
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
122126
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
127+
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
128+
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
129+
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
130+
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
131+
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
132+
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
133+
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
134+
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
123135
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
124136
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
125137
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -209,6 +221,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
209221
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
210222
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
211223
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
224+
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
225+
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
212226
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g=
213227
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
214228
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=

hack/test-crds-validation.sh

Lines changed: 0 additions & 152 deletions
This file was deleted.

pkg/test/cel/main_test.go

Lines changed: 64 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package main
1919
import (
2020
"fmt"
2121
"os"
22-
"path"
22+
"path/filepath"
2323
"strings"
2424
"testing"
2525

@@ -29,34 +29,84 @@ import (
2929
"sigs.k8s.io/gateway-api/apis/v1beta1"
3030
apisxv1alpha1 "sigs.k8s.io/gateway-api/apisx/v1alpha1"
3131

32+
corev1 "k8s.io/api/core/v1"
33+
"k8s.io/apimachinery/pkg/runtime"
34+
"k8s.io/client-go/rest"
3235
"k8s.io/client-go/tools/clientcmd"
3336
"sigs.k8s.io/controller-runtime/pkg/client"
37+
"sigs.k8s.io/controller-runtime/pkg/envtest"
3438
)
3539

3640
var k8sClient client.Client
3741

3842
func TestMain(m *testing.M) {
43+
scheme := runtime.NewScheme()
44+
var restConfig *rest.Config
45+
var testEnv *envtest.Environment
46+
var err error
47+
48+
v1alpha3.Install(scheme)
49+
v1alpha2.Install(scheme)
50+
v1beta1.Install(scheme)
51+
v1.Install(scheme)
52+
apisxv1alpha1.Install(scheme)
53+
54+
// Add core APIs in case we refer secrets, services and configmaps
55+
corev1.AddToScheme(scheme)
56+
57+
// If one wants to use a local cluster, a KUBECONFIG envvar should be passed,
58+
// otherwise testenv will be used
3959
kubeconfig := os.Getenv("KUBECONFIG")
40-
if kubeconfig == "" {
41-
kubeconfig = path.Join(os.Getenv("HOME"), ".kube/config")
60+
if kubeconfig != "" {
61+
restConfig, err = clientcmd.BuildConfigFromFlags("", kubeconfig)
62+
if err != nil {
63+
panic(fmt.Sprintf("Failed to get restConfig from BuildConfigFromFlags: %v", err))
64+
}
65+
} else {
66+
// The version used here MUST reflect the available versions at
67+
// controller-runtime repo: https://raw.githubusercontent.com/kubernetes-sigs/controller-tools/HEAD/envtest-releases.yaml
68+
// If the envvar is not passed, the latest GA will be used
69+
k8sVersion := os.Getenv("K8S_VERSION")
70+
71+
crdChannel := "standard"
72+
if requestedCRDChannel, ok := os.LookupEnv("CRD_CHANNEL"); ok {
73+
crdChannel = requestedCRDChannel
74+
}
75+
76+
testEnv = &envtest.Environment{
77+
Scheme: scheme,
78+
ErrorIfCRDPathMissing: true,
79+
DownloadBinaryAssets: true,
80+
DownloadBinaryAssetsVersion: k8sVersion,
81+
CRDInstallOptions: envtest.CRDInstallOptions{
82+
Paths: []string{
83+
filepath.Join("..", "..", "..", "config", "crd", crdChannel),
84+
},
85+
CleanUpAfterUse: true,
86+
},
87+
}
88+
89+
restConfig, err = testEnv.Start()
90+
if err != nil {
91+
panic(fmt.Sprintf("Error initializing test environment: %v", err))
92+
}
4293
}
4394

44-
restConfig, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
95+
k8sClient, err = client.New(restConfig, client.Options{
96+
Scheme: scheme,
97+
})
4598
if err != nil {
46-
panic(fmt.Sprintf("Failed to get restConfig from BuildConfigFromFlags: %v", err))
99+
panic(fmt.Sprintf("Error initializing Kubernetes client: %v", err))
47100
}
48101

49-
k8sClient, err = client.New(restConfig, client.Options{})
50-
if err != nil {
51-
panic(fmt.Sprintf("Error initializing Kubernetes client: %v", err))
102+
rc := m.Run()
103+
if testEnv != nil {
104+
if err := testEnv.Stop(); err != nil {
105+
panic(fmt.Sprintf("error stopping test environment: %v", err))
106+
}
52107
}
53-
v1alpha3.Install(k8sClient.Scheme())
54-
v1alpha2.Install(k8sClient.Scheme())
55-
v1beta1.Install(k8sClient.Scheme())
56-
v1.Install(k8sClient.Scheme())
57-
apisxv1alpha1.Install(k8sClient.Scheme())
58108

59-
os.Exit(m.Run())
109+
os.Exit(rc)
60110
}
61111

62112
func ptrTo[T any](a T) *T {

0 commit comments

Comments
 (0)