Skip to content

Commit dfa515d

Browse files
authored
🌱 Remove ginkgo from internal/controller unit tests (#541)
* Remove ginkgo from internal/controller unit tests Fix #190 Signed-off-by: Todd Short <[email protected]> * Always allocate cl Signed-off-by: Todd Short <[email protected]> * Move admissions tests to tables Signed-off-by: Todd Short <[email protected]> * Use random name for operators Signed-off-by: Todd Short <[email protected]> * Parallelize the admission tests Signed-off-by: Todd Short <[email protected]> * Consolidate client/reconciler initialization Signed-off-by: Todd Short <[email protected]> --------- Signed-off-by: Todd Short <[email protected]>
1 parent 2105d1a commit dfa515d

File tree

3 files changed

+1273
-1176
lines changed

3 files changed

+1273
-1176
lines changed

internal/controllers/admission_test.go

Lines changed: 187 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ package controllers_test
22

33
import (
44
"context"
5+
"testing"
56

6-
. "github.com/onsi/ginkgo/v2"
7-
. "github.com/onsi/gomega"
7+
"github.com/stretchr/testify/require"
88
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
99

1010
operatorsv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1"
@@ -13,165 +13,211 @@ import (
1313
func operator(spec operatorsv1alpha1.OperatorSpec) *operatorsv1alpha1.Operator {
1414
return &operatorsv1alpha1.Operator{
1515
ObjectMeta: metav1.ObjectMeta{
16-
Name: "test-operator",
16+
GenerateName: "test-operator",
1717
},
1818
Spec: spec,
1919
}
2020
}
2121

22-
var _ = Describe("Operator Spec Validations", func() {
23-
var (
24-
ctx context.Context
25-
cancel context.CancelFunc
26-
)
27-
BeforeEach(func() {
28-
ctx, cancel = context.WithCancel(context.Background())
29-
})
30-
AfterEach(func() {
31-
cancel()
32-
})
33-
It("should fail if the spec is empty", func() {
34-
err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{}))
35-
Expect(err).To(HaveOccurred())
36-
Expect(err.Error()).To(ContainSubstring("spec.packageName in body should match '^[a-z0-9]+(-[a-z0-9]+)*$'"))
37-
})
38-
It("should fail if package name length is greater than 48 characters", func() {
39-
err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{
22+
var operatorData = []struct {
23+
spec *operatorsv1alpha1.Operator
24+
comment string
25+
errMsg string
26+
}{
27+
{
28+
operator(operatorsv1alpha1.OperatorSpec{}),
29+
"operator spec is empty",
30+
"spec.packageName in body should match '^[a-z0-9]+(-[a-z0-9]+)*$'",
31+
},
32+
{
33+
operator(operatorsv1alpha1.OperatorSpec{
4034
PackageName: "this-is-a-really-long-package-name-that-is-greater-than-48-characters",
41-
}))
42-
Expect(err).To(HaveOccurred())
43-
Expect(err.Error()).To(ContainSubstring("Too long: may not be longer than 48"))
44-
})
45-
It("should fail if version is valid semver but length is greater than 64 characters", func() {
46-
err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{
35+
}),
36+
"long package name",
37+
"spec.packageName: Too long: may not be longer than 48",
38+
},
39+
{
40+
operator(operatorsv1alpha1.OperatorSpec{
4741
PackageName: "package",
4842
Version: "1234567890.1234567890.12345678901234567890123456789012345678901234",
49-
}))
50-
Expect(err).To(HaveOccurred())
51-
Expect(err.Error()).To(ContainSubstring("Too long: may not be longer than 64"))
52-
})
53-
It("should fail if an invalid semver is given", func() {
54-
invalidSemvers := []string{
55-
"1.2.3.4",
56-
"1.02.3",
57-
"1.2.03",
58-
"1.2.3-beta!",
59-
"1.2.3.alpha",
60-
"1..2.3",
61-
"1.2.3-pre+bad_metadata",
62-
"1.2.-3",
63-
".1.2.3",
64-
"<<1.2.3",
65-
">>1.2.3",
66-
">~1.2.3",
67-
"==1.2.3",
68-
"=!1.2.3",
69-
"!1.2.3",
70-
"1.Y",
71-
">1.2.3 && <2.3.4",
72-
">1.2.3;<2.3.4",
73-
"1.2.3 - 2.3.4",
74-
}
75-
for _, invalidSemver := range invalidSemvers {
43+
}),
44+
"long valid semver",
45+
"spec.version: Too long: may not be longer than 64",
46+
},
47+
{
48+
operator(operatorsv1alpha1.OperatorSpec{
49+
PackageName: "package",
50+
Channel: "longname01234567890123456789012345678901234567890",
51+
}),
52+
"long channel name",
53+
"spec.channel: Too long: may not be longer than 48",
54+
},
55+
}
56+
57+
func TestOperatorSpecs(t *testing.T) {
58+
t.Parallel()
59+
ctx, cancel := context.WithCancel(context.Background())
60+
t.Cleanup(cancel)
61+
62+
for _, od := range operatorData {
63+
d := od
64+
t.Run(d.comment, func(t *testing.T) {
65+
t.Parallel()
66+
cl := newClient(t)
67+
err := cl.Create(ctx, d.spec)
68+
require.Error(t, err)
69+
require.ErrorContains(t, err, d.errMsg)
70+
})
71+
}
72+
}
73+
74+
func TestOperatorInvalidSemver(t *testing.T) {
75+
t.Parallel()
76+
ctx, cancel := context.WithCancel(context.Background())
77+
t.Cleanup(cancel)
78+
79+
invalidSemvers := []string{
80+
"1.2.3.4",
81+
"1.02.3",
82+
"1.2.03",
83+
"1.2.3-beta!",
84+
"1.2.3.alpha",
85+
"1..2.3",
86+
"1.2.3-pre+bad_metadata",
87+
"1.2.-3",
88+
".1.2.3",
89+
"<<1.2.3",
90+
">>1.2.3",
91+
">~1.2.3",
92+
"==1.2.3",
93+
"=!1.2.3",
94+
"!1.2.3",
95+
"1.Y",
96+
">1.2.3 && <2.3.4",
97+
">1.2.3;<2.3.4",
98+
"1.2.3 - 2.3.4",
99+
}
100+
for _, sm := range invalidSemvers {
101+
d := sm
102+
t.Run(d, func(t *testing.T) {
103+
t.Parallel()
104+
cl := newClient(t)
76105
err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{
77106
PackageName: "package",
78-
Version: invalidSemver,
107+
Version: d,
79108
}))
80-
81-
Expect(err).To(HaveOccurred(), "expected error for invalid semver %q", invalidSemver)
109+
require.Errorf(t, err, "expected error for invalid semver %q", d)
82110
// Don't need to include the whole regex, this should be enough to match the MasterMinds regex
83-
Expect(err.Error()).To(ContainSubstring("spec.version in body should match '^(\\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\\^)"))
84-
}
85-
})
86-
It("should pass if a valid semver range given", func() {
87-
validSemvers := []string{
88-
">=1.2.3",
89-
"=>1.2.3",
90-
">= 1.2.3",
91-
">=v1.2.3",
92-
">= v1.2.3",
93-
"<=1.2.3",
94-
"=<1.2.3",
95-
"=1.2.3",
96-
"!=1.2.3",
97-
"<1.2.3",
98-
">1.2.3",
99-
"~1.2.2",
100-
"~>1.2.3",
101-
"^1.2.3",
102-
"1.2.3",
103-
"v1.2.3",
104-
"1.x",
105-
"1.X",
106-
"1.*",
107-
"1.2.x",
108-
"1.2.X",
109-
"1.2.*",
110-
">=1.2.3 <2.3.4",
111-
">=1.2.3,<2.3.4",
112-
">=1.2.3, <2.3.4",
113-
"<1.2.3||>2.3.4",
114-
"<1.2.3|| >2.3.4",
115-
"<1.2.3 ||>2.3.4",
116-
"<1.2.3 || >2.3.4",
117-
">1.0.0,<1.2.3 || >2.1.0",
118-
"<1.2.3-abc >2.3.4-def",
119-
"<1.2.3-abc+def >2.3.4-ghi+jkl",
120-
}
121-
for _, validSemver := range validSemvers {
111+
require.ErrorContains(t, err, "spec.version in body should match '^(\\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\\^)")
112+
})
113+
}
114+
}
115+
116+
func TestOperatorValidSemver(t *testing.T) {
117+
t.Parallel()
118+
ctx, cancel := context.WithCancel(context.Background())
119+
t.Cleanup(cancel)
120+
121+
validSemvers := []string{
122+
">=1.2.3",
123+
"=>1.2.3",
124+
">= 1.2.3",
125+
">=v1.2.3",
126+
">= v1.2.3",
127+
"<=1.2.3",
128+
"=<1.2.3",
129+
"=1.2.3",
130+
"!=1.2.3",
131+
"<1.2.3",
132+
">1.2.3",
133+
"~1.2.2",
134+
"~>1.2.3",
135+
"^1.2.3",
136+
"1.2.3",
137+
"v1.2.3",
138+
"1.x",
139+
"1.X",
140+
"1.*",
141+
"1.2.x",
142+
"1.2.X",
143+
"1.2.*",
144+
">=1.2.3 <2.3.4",
145+
">=1.2.3,<2.3.4",
146+
">=1.2.3, <2.3.4",
147+
"<1.2.3||>2.3.4",
148+
"<1.2.3|| >2.3.4",
149+
"<1.2.3 ||>2.3.4",
150+
"<1.2.3 || >2.3.4",
151+
">1.0.0,<1.2.3 || >2.1.0",
152+
"<1.2.3-abc >2.3.4-def",
153+
"<1.2.3-abc+def >2.3.4-ghi+jkl",
154+
}
155+
for _, smx := range validSemvers {
156+
d := smx
157+
t.Run(d, func(t *testing.T) {
158+
t.Parallel()
159+
cl := newClient(t)
122160
op := operator(operatorsv1alpha1.OperatorSpec{
123161
PackageName: "package",
124-
Version: validSemver,
162+
Version: d,
125163
})
126164
err := cl.Create(ctx, op)
127-
Expect(err).NotTo(HaveOccurred(), "expected success for semver range '%q': %w", validSemver, err)
128-
err = cl.Delete(ctx, op)
129-
Expect(err).NotTo(HaveOccurred(), "unexpected error deleting valid semver '%q': %w", validSemver, err)
130-
}
131-
})
132-
It("should fail if an invalid channel name is given", func() {
133-
invalidChannels := []string{
134-
"spaces spaces",
135-
"Capitalized",
136-
"camelCase",
137-
"many/invalid$characters+in_name",
138-
"-start-with-hyphen",
139-
"end-with-hyphen-",
140-
".start-with-period",
141-
"end-with-period.",
142-
}
143-
for _, invalidChannel := range invalidChannels {
165+
require.NoErrorf(t, err, "unexpected error for semver range %q: %w", d, err)
166+
})
167+
}
168+
}
169+
170+
func TestOperatorInvalidChannel(t *testing.T) {
171+
t.Parallel()
172+
ctx, cancel := context.WithCancel(context.Background())
173+
t.Cleanup(cancel)
174+
175+
invalidChannels := []string{
176+
"spaces spaces",
177+
"Capitalized",
178+
"camelCase",
179+
"many/invalid$characters+in_name",
180+
"-start-with-hyphen",
181+
"end-with-hyphen-",
182+
".start-with-period",
183+
"end-with-period.",
184+
}
185+
for _, ch := range invalidChannels {
186+
d := ch
187+
t.Run(d, func(t *testing.T) {
188+
t.Parallel()
189+
cl := newClient(t)
144190
err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{
145191
PackageName: "package",
146-
Channel: invalidChannel,
192+
Channel: d,
147193
}))
148-
Expect(err).To(HaveOccurred(), "expected error for invalid channel '%q'", invalidChannel)
149-
Expect(err.Error()).To(ContainSubstring("spec.channel in body should match '^[a-z0-9]+([\\.-][a-z0-9]+)*$'"))
150-
}
151-
})
152-
It("should pass if a valid channel name is given", func() {
153-
validChannels := []string{
154-
"hyphenated-name",
155-
"dotted.name",
156-
"channel-has-version-1.0.1",
157-
}
158-
for _, validChannel := range validChannels {
194+
require.Errorf(t, err, "expected error for invalid channel %q", d)
195+
require.ErrorContains(t, err, "spec.channel in body should match '^[a-z0-9]+([\\.-][a-z0-9]+)*$'")
196+
})
197+
}
198+
}
199+
200+
func TestOperatorValidChannel(t *testing.T) {
201+
t.Parallel()
202+
ctx, cancel := context.WithCancel(context.Background())
203+
t.Cleanup(cancel)
204+
205+
validChannels := []string{
206+
"hyphenated-name",
207+
"dotted.name",
208+
"channel-has-version-1.0.1",
209+
}
210+
for _, ch := range validChannels {
211+
d := ch
212+
t.Run(d, func(t *testing.T) {
213+
t.Parallel()
214+
cl := newClient(t)
159215
op := operator(operatorsv1alpha1.OperatorSpec{
160216
PackageName: "package",
161-
Channel: validChannel,
217+
Channel: d,
162218
})
163219
err := cl.Create(ctx, op)
164-
Expect(err).NotTo(HaveOccurred(), "unexpected error creating valid channel '%q': %w", validChannel, err)
165-
err = cl.Delete(ctx, op)
166-
Expect(err).NotTo(HaveOccurred(), "unexpected error deleting valid channel '%q': %w", validChannel, err)
167-
}
168-
})
169-
It("should fail if an invalid channel name length", func() {
170-
err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{
171-
PackageName: "package",
172-
Channel: "longname01234567890123456789012345678901234567890",
173-
}))
174-
Expect(err).To(HaveOccurred(), "expected error for invalid channel length")
175-
Expect(err.Error()).To(ContainSubstring("spec.channel: Too long: may not be longer than 48"))
176-
})
177-
})
220+
require.NoErrorf(t, err, "unexpected error creating valid channel %q: %w", d, err)
221+
})
222+
}
223+
}

0 commit comments

Comments
 (0)