Skip to content

Commit b81f818

Browse files
authored
Unit test improvements (#234)
1. Add unit tests for config package 2. Fix names of test suites 3. Upgrade golangci-lint to v1.60.1 (to get golang 1.23 support) 4. Add unit tests for appwrapper annotations 5. Do unit tests with both inferred and declared pod specs
1 parent 69f9fdc commit b81f818

File tree

9 files changed

+228
-47
lines changed

9 files changed

+228
-47
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ lint: golangci-lint ## Run golangci-lint linter & yamllint
129129

130130
.PHONY: lint-fix
131131
lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes
132-
$(GOLANGCI_LINT) run --fix
132+
$(GOLANGCI_LINT) run --fix --timeout=2m
133133

134134
##@ Build
135135

go.mod

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.22.4
55
require (
66
github.com/distribution/reference v0.5.0
77
github.com/go-logr/logr v1.4.2
8-
github.com/golangci/golangci-lint v1.55.2
8+
github.com/golangci/golangci-lint v1.60.1
99
github.com/onsi/ginkgo/v2 v2.19.0
1010
github.com/onsi/gomega v1.33.1
1111
github.com/open-policy-agent/cert-controller v0.10.1
@@ -28,7 +28,7 @@ require (
2828
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
2929
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
3030
github.com/evanphx/json-patch/v5 v5.8.0 // indirect
31-
github.com/fatih/color v1.16.0 // indirect
31+
github.com/fatih/color v1.17.0 // indirect
3232
github.com/fsnotify/fsnotify v1.7.0 // indirect
3333
github.com/go-errors/errors v1.4.2 // indirect
3434
github.com/go-logr/zapr v1.3.0 // indirect
@@ -71,15 +71,15 @@ require (
7171
go.uber.org/atomic v1.11.0 // indirect
7272
go.uber.org/multierr v1.11.0 // indirect
7373
golang.org/x/exp v0.0.0-20240530194437-404ba88c7ed0 // indirect
74-
golang.org/x/mod v0.17.0 // indirect
75-
golang.org/x/net v0.25.0 // indirect
74+
golang.org/x/mod v0.20.0 // indirect
75+
golang.org/x/net v0.28.0 // indirect
7676
golang.org/x/oauth2 v0.20.0 // indirect
77-
golang.org/x/sync v0.7.0 // indirect
78-
golang.org/x/sys v0.20.0 // indirect
79-
golang.org/x/term v0.20.0 // indirect
80-
golang.org/x/text v0.15.0 // indirect
77+
golang.org/x/sync v0.8.0 // indirect
78+
golang.org/x/sys v0.23.0 // indirect
79+
golang.org/x/term v0.23.0 // indirect
80+
golang.org/x/text v0.17.0 // indirect
8181
golang.org/x/time v0.5.0 // indirect
82-
golang.org/x/tools v0.21.0 // indirect
82+
golang.org/x/tools v0.24.0 // indirect
8383
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
8484
google.golang.org/protobuf v1.34.1 // indirect
8585
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect

go.sum

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lSh
2626
github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
2727
github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro=
2828
github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ=
29-
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
30-
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
29+
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
30+
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
3131
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
3232
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
3333
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
@@ -62,8 +62,8 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
6262
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
6363
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
6464
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
65-
github.com/golangci/golangci-lint v1.55.2 h1:yllEIsSJ7MtlDBwDJ9IMBkyEUz2fYE0b5B8IUgO1oP8=
66-
github.com/golangci/golangci-lint v1.55.2/go.mod h1:H60CZ0fuqoTwlTvnbyjhpZPWp7KmsjwV2yupIMiMXbM=
65+
github.com/golangci/golangci-lint v1.60.1 h1:DRKNqNTQRLBJZ1il5u4fvgLQCjQc7QFs0DbhksJtVJE=
66+
github.com/golangci/golangci-lint v1.60.1/go.mod h1:jDIPN1rYaIA+ijp9OZcUmUCoQOtZ76pOlFbi15FlLJY=
6767
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
6868
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
6969
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -198,8 +198,8 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx
198198
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
199199
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
200200
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
201-
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
202-
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
201+
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
202+
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
203203
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
204204
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
205205
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -208,8 +208,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
208208
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
209209
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
210210
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
211-
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
212-
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
211+
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
212+
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
213213
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
214214
golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
215215
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
@@ -218,8 +218,8 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
218218
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
219219
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
220220
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
221-
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
222-
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
221+
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
222+
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
223223
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
224224
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
225225
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -228,15 +228,15 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
228228
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
229229
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
230230
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
231-
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
232-
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
231+
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
232+
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
233233
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
234-
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
235-
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
234+
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
235+
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
236236
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
237237
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
238-
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
239-
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
238+
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
239+
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
240240
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
241241
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
242242
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -247,8 +247,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
247247
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
248248
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
249249
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
250-
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
251-
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
250+
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
251+
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
252252
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
253253
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
254254
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

internal/controller/appwrapper/appwrapper_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ func clearCondition(aw *workloadv1beta2.AppWrapper, condition workloadv1beta2.Ap
900900
}
901901
}
902902

903-
// podMapFunc maps pods to appwrappers
903+
// podMapFunc maps pods to appwrappers and generates reconcile.Requests for those whose Status.Phase is PodSucceeded
904904
func (r *AppWrapperReconciler) podMapFunc(ctx context.Context, obj client.Object) []reconcile.Request {
905905
pod := obj.(*v1.Pod)
906906
if name, ok := pod.Labels[AppWrapperLabel]; ok {

internal/controller/appwrapper/appwrapper_controller_test.go

Lines changed: 120 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
. "github.com/onsi/gomega"
2424
v1 "k8s.io/api/core/v1"
2525
"k8s.io/apimachinery/pkg/api/meta"
26+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2627
"k8s.io/apimachinery/pkg/types"
2728
"k8s.io/client-go/tools/record"
2829
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@@ -173,7 +174,7 @@ var _ = Describe("AppWrapper Controller", func() {
173174
})
174175

175176
It("Happy Path Lifecycle", func() {
176-
advanceToResuming(pod(100, 1), pod(100, 0))
177+
advanceToResuming(pod(100, 1, true), pod(100, 0, false))
177178
beginRunning()
178179
fullyRunning()
179180

@@ -223,7 +224,7 @@ var _ = Describe("AppWrapper Controller", func() {
223224
})
224225

225226
It("Running Workloads can be Suspended", func() {
226-
advanceToResuming(pod(100, 0), pod(100, 1))
227+
advanceToResuming(pod(100, 0, false), pod(100, 1, true))
227228
beginRunning()
228229
fullyRunning()
229230

@@ -262,7 +263,7 @@ var _ = Describe("AppWrapper Controller", func() {
262263
})
263264

264265
It("A Pod Failure leads to a failed AppWrapper", func() {
265-
advanceToResuming(pod(100, 0), pod(100, 0))
266+
advanceToResuming(pod(100, 0, false), pod(100, 0, true))
266267
beginRunning()
267268
fullyRunning()
268269

@@ -300,7 +301,7 @@ var _ = Describe("AppWrapper Controller", func() {
300301
})
301302

302303
It("Failure during resource creation leads to a failed AppWrapper", func() {
303-
advanceToResuming(pod(100, 0), malformedPod(100))
304+
advanceToResuming(pod(100, 0, false), malformedPod(100))
304305

305306
By("Reconciling: Resuming -> Failed")
306307
_, err := awReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: awName})
@@ -317,5 +318,120 @@ var _ = Describe("AppWrapper Controller", func() {
317318
Expect(err).NotTo(HaveOccurred())
318319
Expect(podStatus.pending).Should(Equal(int32(1)))
319320
})
321+
})
322+
323+
var _ = Describe("AppWrapper Annotations", func() {
324+
var awReconciler *AppWrapperReconciler
325+
326+
BeforeEach(func() {
327+
awReconciler = &AppWrapperReconciler{
328+
Client: k8sClient,
329+
Recorder: &record.FakeRecorder{},
330+
Scheme: k8sClient.Scheme(),
331+
Config: config.NewAppWrapperConfig(),
332+
}
333+
})
334+
335+
It("Unannotated appwrappers use defaults", func() {
336+
aw := &workloadv1beta2.AppWrapper{}
337+
Expect(awReconciler.admissionGraceDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.AdmissionGracePeriod))
338+
Expect(awReconciler.warmupGraceDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.WarmupGracePeriod))
339+
Expect(awReconciler.failureGraceDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.FailureGracePeriod))
340+
Expect(awReconciler.retryLimit(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.RetryLimit))
341+
Expect(awReconciler.retryPauseDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.RetryPausePeriod))
342+
Expect(awReconciler.forcefulDeletionGraceDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.ForcefulDeletionGracePeriod))
343+
Expect(awReconciler.deletionOnFailureGraceDuration(ctx, aw)).Should(Equal(0 * time.Second))
344+
Expect(awReconciler.timeToLiveAfterSucceededDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.SuccessTTL))
345+
})
346+
347+
It("Valid annotations override defaults", func() {
348+
allowed := 10 * time.Second
349+
aw := &workloadv1beta2.AppWrapper{
350+
ObjectMeta: metav1.ObjectMeta{
351+
Annotations: map[string]string{
352+
workloadv1beta2.AdmissionGracePeriodDurationAnnotation: allowed.String(),
353+
workloadv1beta2.WarmupGracePeriodDurationAnnotation: allowed.String(),
354+
workloadv1beta2.FailureGracePeriodDurationAnnotation: allowed.String(),
355+
workloadv1beta2.RetryPausePeriodDurationAnnotation: allowed.String(),
356+
workloadv1beta2.RetryLimitAnnotation: "101",
357+
workloadv1beta2.ForcefulDeletionGracePeriodAnnotation: allowed.String(),
358+
workloadv1beta2.DeletionOnFailureGracePeriodAnnotation: allowed.String(),
359+
workloadv1beta2.SuccessTTLAnnotation: allowed.String(),
360+
},
361+
},
362+
}
363+
Expect(awReconciler.admissionGraceDuration(ctx, aw)).Should(Equal(allowed))
364+
Expect(awReconciler.warmupGraceDuration(ctx, aw)).Should(Equal(allowed))
365+
Expect(awReconciler.failureGraceDuration(ctx, aw)).Should(Equal(allowed))
366+
Expect(awReconciler.retryLimit(ctx, aw)).Should(Equal(int32(101)))
367+
Expect(awReconciler.retryPauseDuration(ctx, aw)).Should(Equal(allowed))
368+
Expect(awReconciler.forcefulDeletionGraceDuration(ctx, aw)).Should(Equal(allowed))
369+
Expect(awReconciler.deletionOnFailureGraceDuration(ctx, aw)).Should(Equal(allowed))
370+
Expect(awReconciler.timeToLiveAfterSucceededDuration(ctx, aw)).Should(Equal(allowed))
371+
})
372+
373+
It("Malformed annotations use defaults", func() {
374+
malformed := "222badTime"
375+
aw := &workloadv1beta2.AppWrapper{
376+
ObjectMeta: metav1.ObjectMeta{
377+
Annotations: map[string]string{
378+
workloadv1beta2.AdmissionGracePeriodDurationAnnotation: malformed,
379+
workloadv1beta2.WarmupGracePeriodDurationAnnotation: malformed,
380+
workloadv1beta2.FailureGracePeriodDurationAnnotation: malformed,
381+
workloadv1beta2.RetryPausePeriodDurationAnnotation: malformed,
382+
workloadv1beta2.RetryLimitAnnotation: "abc",
383+
workloadv1beta2.ForcefulDeletionGracePeriodAnnotation: malformed,
384+
workloadv1beta2.DeletionOnFailureGracePeriodAnnotation: malformed,
385+
workloadv1beta2.SuccessTTLAnnotation: malformed,
386+
},
387+
},
388+
}
389+
Expect(awReconciler.admissionGraceDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.AdmissionGracePeriod))
390+
Expect(awReconciler.warmupGraceDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.WarmupGracePeriod))
391+
Expect(awReconciler.failureGraceDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.FailureGracePeriod))
392+
Expect(awReconciler.retryLimit(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.RetryLimit))
393+
Expect(awReconciler.retryPauseDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.RetryPausePeriod))
394+
Expect(awReconciler.forcefulDeletionGraceDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.ForcefulDeletionGracePeriod))
395+
Expect(awReconciler.deletionOnFailureGraceDuration(ctx, aw)).Should(Equal(0 * time.Second))
396+
Expect(awReconciler.timeToLiveAfterSucceededDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.SuccessTTL))
397+
})
398+
399+
It("Out of bounds annotations are clipped", func() {
400+
negative := -10 * time.Minute
401+
tooLong := 2 * awReconciler.Config.FaultTolerance.GracePeriodMaximum
402+
aw := &workloadv1beta2.AppWrapper{
403+
ObjectMeta: metav1.ObjectMeta{
404+
Annotations: map[string]string{
405+
workloadv1beta2.AdmissionGracePeriodDurationAnnotation: negative.String(),
406+
workloadv1beta2.WarmupGracePeriodDurationAnnotation: tooLong.String(),
407+
workloadv1beta2.FailureGracePeriodDurationAnnotation: tooLong.String(),
408+
workloadv1beta2.RetryPausePeriodDurationAnnotation: negative.String(),
409+
workloadv1beta2.ForcefulDeletionGracePeriodAnnotation: tooLong.String(),
410+
workloadv1beta2.DeletionOnFailureGracePeriodAnnotation: tooLong.String(),
411+
workloadv1beta2.SuccessTTLAnnotation: (awReconciler.Config.FaultTolerance.SuccessTTL + 10*time.Second).String(),
412+
},
413+
},
414+
}
415+
Expect(awReconciler.admissionGraceDuration(ctx, aw)).Should(Equal(0 * time.Second))
416+
Expect(awReconciler.warmupGraceDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.GracePeriodMaximum))
417+
Expect(awReconciler.failureGraceDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.GracePeriodMaximum))
418+
Expect(awReconciler.retryPauseDuration(ctx, aw)).Should(Equal(0 * time.Second))
419+
Expect(awReconciler.forcefulDeletionGraceDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.GracePeriodMaximum))
420+
Expect(awReconciler.deletionOnFailureGraceDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.GracePeriodMaximum))
421+
Expect(awReconciler.timeToLiveAfterSucceededDuration(ctx, aw)).Should(Equal(awReconciler.Config.FaultTolerance.SuccessTTL))
422+
})
423+
424+
It("Parsing of terminal exits codes", func() {
425+
aw := &workloadv1beta2.AppWrapper{
426+
ObjectMeta: metav1.ObjectMeta{
427+
Annotations: map[string]string{
428+
workloadv1beta2.TerminalExitCodesAnnotation: "3,10,abc,42",
429+
workloadv1beta2.RetryableExitCodesAnnotation: "x,10,20",
430+
},
431+
},
432+
}
433+
Expect(awReconciler.terminalExitCodes(ctx, aw)).Should(Equal([]int{3, 10, 42}))
434+
Expect(awReconciler.retryableExitCodes(ctx, aw)).Should(Equal([]int{10, 20}))
435+
})
320436

321437
})

internal/controller/appwrapper/fixtures_test.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ spec:
110110
limits:
111111
nvidia.com/gpu: %v`
112112

113-
func pod(milliCPU int64, numGPU int64) workloadv1beta2.AppWrapperComponent {
113+
func pod(milliCPU int64, numGPU int64, declarePodSets bool) workloadv1beta2.AppWrapperComponent {
114114
yamlString := fmt.Sprintf(podYAML,
115115
randName("pod"),
116116
resource.NewMilliQuantity(milliCPU, resource.DecimalSI),
@@ -119,10 +119,13 @@ func pod(milliCPU int64, numGPU int64) workloadv1beta2.AppWrapperComponent {
119119

120120
jsonBytes, err := yaml.YAMLToJSON([]byte(yamlString))
121121
Expect(err).NotTo(HaveOccurred())
122-
return workloadv1beta2.AppWrapperComponent{
123-
DeclaredPodSets: []workloadv1beta2.AppWrapperPodSet{{Replicas: ptr.To(int32(1)), Path: "template"}},
124-
Template: runtime.RawExtension{Raw: jsonBytes},
122+
awc := &workloadv1beta2.AppWrapperComponent{
123+
Template: runtime.RawExtension{Raw: jsonBytes},
124+
}
125+
if declarePodSets {
126+
awc.DeclaredPodSets = []workloadv1beta2.AppWrapperPodSet{{Replicas: ptr.To(int32(1)), Path: "template"}}
125127
}
128+
return *awc
126129
}
127130

128131
const malformedPodYAML = `

internal/webhook/suite_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ const limitedUserID = "8da0fcfe-6d7f-4f44-b433-d91d22cc1b8c"
6565
const defaultQueueName = "default-queue"
6666
const userProvidedQueueName = "user-queue"
6767

68-
func TestControllers(t *testing.T) {
68+
func TestWebhooks(t *testing.T) {
6969
RegisterFailHandler(Fail)
7070

71-
RunSpecs(t, "Workload Controller Unit Tests")
71+
RunSpecs(t, "Webhook Unit Tests")
7272
}
7373

7474
var _ = BeforeSuite(func() {

0 commit comments

Comments
 (0)