Skip to content

Commit e10c2f5

Browse files
committed
Port tests for the List workflow to test list.List
1 parent 63a7141 commit e10c2f5

File tree

4 files changed

+478
-0
lines changed

4 files changed

+478
-0
lines changed

pkg/envtest/setup/list/list_test.go

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
package list_test
2+
3+
import (
4+
"cmp"
5+
"context"
6+
"regexp"
7+
"slices"
8+
"testing"
9+
10+
"github.com/go-logr/logr"
11+
12+
. "github.com/onsi/ginkgo/v2"
13+
. "github.com/onsi/gomega"
14+
15+
"sigs.k8s.io/controller-runtime/pkg/envtest/setup/env"
16+
"sigs.k8s.io/controller-runtime/pkg/envtest/setup/list"
17+
"sigs.k8s.io/controller-runtime/pkg/envtest/setup/remote"
18+
"sigs.k8s.io/controller-runtime/pkg/envtest/setup/testhelpers"
19+
"sigs.k8s.io/controller-runtime/pkg/envtest/setup/versions"
20+
)
21+
22+
var (
23+
testLog logr.Logger
24+
ctx context.Context
25+
)
26+
27+
func TestEnv(t *testing.T) {
28+
testLog = testhelpers.GetLogger()
29+
ctx = logr.NewContext(context.Background(), testLog)
30+
31+
RegisterFailHandler(Fail)
32+
RunSpecs(t, "List Suite")
33+
}
34+
35+
var _ = Describe("List", func() {
36+
var (
37+
envOpts []env.Option
38+
)
39+
40+
JustBeforeEach(func() {
41+
addr, shutdown := testhelpers.NewServer()
42+
DeferCleanup(shutdown)
43+
44+
envOpts = append(
45+
envOpts,
46+
env.WithClient(&remote.Client{
47+
Log: testLog.WithName("test-remote-client"),
48+
Bucket: "kubebuilder-tools-test",
49+
Server: addr,
50+
Insecure: true,
51+
}),
52+
env.WithStore(testhelpers.NewMockStore()),
53+
)
54+
})
55+
56+
Context("when downloads are disabled", func() {
57+
JustBeforeEach(func() {
58+
envOpts = append(envOpts, env.WithClient(nil)) // ensure tests fail if we try to contact remote
59+
})
60+
61+
It("should include local contents sorted by version", func() {
62+
result, err := list.List(
63+
ctx,
64+
versions.AnyVersion,
65+
list.NoDownload(true),
66+
list.WithPlatform("*", "*"),
67+
list.WithEnvOptions(envOpts...),
68+
)
69+
Expect(err).NotTo(HaveOccurred())
70+
71+
// build this list based on test data, to avoid having to change
72+
// in two places if we add some more test cases
73+
expected := make([]list.Result, 0)
74+
for _, v := range testhelpers.LocalVersions {
75+
for _, p := range v.Platforms {
76+
expected = append(expected, list.Result{
77+
Version: v.Version,
78+
Platform: p.Platform,
79+
Status: list.Installed,
80+
})
81+
}
82+
}
83+
// this sorting ensures the List method fulfils the contract of
84+
// returning the most relevant items first
85+
slices.SortFunc(expected, func(a, b list.Result) int {
86+
return cmp.Or(
87+
// we want the results sorted in descending order by version
88+
cmp.Compare(b.Version.Major, a.Version.Major),
89+
cmp.Compare(b.Version.Minor, a.Version.Minor),
90+
cmp.Compare(b.Version.Patch, a.Version.Patch),
91+
// ..and then in ascending order by platform
92+
cmp.Compare(a.Platform.OS, b.Platform.OS),
93+
cmp.Compare(a.Platform.Arch, b.Platform.Arch),
94+
)
95+
})
96+
97+
Expect(result).To(HaveExactElements(expected))
98+
})
99+
})
100+
101+
Context("when downloads are enabled", func() {
102+
It("should sort local & remote by version", func() {
103+
result, err := list.List(
104+
ctx,
105+
versions.AnyVersion,
106+
list.WithPlatform("*", "*"),
107+
list.WithEnvOptions(envOpts...),
108+
)
109+
Expect(err).NotTo(HaveOccurred())
110+
111+
// build this list based on test data, to avoid having to change
112+
// in two places if we add some more test cases
113+
expected := make([]list.Result, 0)
114+
for _, v := range testhelpers.LocalVersions {
115+
for _, p := range v.Platforms {
116+
expected = append(expected, list.Result{
117+
Version: v.Version,
118+
Platform: p.Platform,
119+
Status: list.Installed,
120+
})
121+
}
122+
}
123+
rx := regexp.MustCompile(`^kubebuilder-tools-(\d+\.\d+\.\d+)-(\w+)-(\w+).tar.gz$`)
124+
for _, v := range testhelpers.RemoteNames {
125+
if m := rx.FindStringSubmatch(v); m != nil {
126+
s, err := versions.FromExpr(m[1])
127+
Expect(err).NotTo(HaveOccurred())
128+
129+
expected = append(expected, list.Result{
130+
Version: *s.AsConcrete(),
131+
Platform: versions.Platform{
132+
OS: m[2],
133+
Arch: m[3],
134+
},
135+
Status: list.Available,
136+
})
137+
}
138+
}
139+
// this sorting ensures the List method fulfils the contract of
140+
// returning the most relevant items first
141+
slices.SortFunc(expected, func(a, b list.Result) int {
142+
return cmp.Or(
143+
// we want installed versions first, available after;
144+
// compare in reverse order since "installed > "available"
145+
cmp.Compare(b.Status, a.Status),
146+
// then, sort in descending order by version
147+
cmp.Compare(b.Version.Major, a.Version.Major),
148+
cmp.Compare(b.Version.Minor, a.Version.Minor),
149+
cmp.Compare(b.Version.Patch, a.Version.Patch),
150+
// ..and then in ascending order by platform
151+
cmp.Compare(a.Platform.OS, b.Platform.OS),
152+
cmp.Compare(a.Platform.Arch, b.Platform.Arch),
153+
)
154+
})
155+
156+
Expect(result).To(HaveExactElements(expected))
157+
})
158+
159+
It("should skip non-matching remote contents", func() {
160+
result, err := list.List(
161+
ctx,
162+
versions.Spec{
163+
Selector: versions.PatchSelector{Major: 1, Minor: 16, Patch: versions.AnyPoint},
164+
},
165+
list.WithPlatform("*", "*"),
166+
list.WithEnvOptions(envOpts...),
167+
)
168+
Expect(err).NotTo(HaveOccurred())
169+
170+
// build this list based on test data, to avoid having to change
171+
// in two places if we add some more test cases
172+
expected := make([]list.Result, 0)
173+
for _, v := range testhelpers.LocalVersions {
174+
// ignore versions not matching the filter in the options
175+
if v.Version.Major != 1 || v.Version.Minor != 16 {
176+
continue
177+
}
178+
for _, p := range v.Platforms {
179+
expected = append(expected, list.Result{
180+
Version: v.Version,
181+
Platform: p.Platform,
182+
Status: list.Installed,
183+
})
184+
}
185+
}
186+
rx := regexp.MustCompile(`^kubebuilder-tools-(\d+\.\d+\.\d+)-(\w+)-(\w+).tar.gz$`)
187+
for _, v := range testhelpers.RemoteNames {
188+
if m := rx.FindStringSubmatch(v); m != nil {
189+
s, err := versions.FromExpr(m[1])
190+
Expect(err).NotTo(HaveOccurred())
191+
v := *s.AsConcrete()
192+
// ignore versions not matching the filter in the options
193+
if v.Major != 1 || v.Minor != 16 {
194+
continue
195+
}
196+
expected = append(expected, list.Result{
197+
Version: v,
198+
Platform: versions.Platform{
199+
OS: m[2],
200+
Arch: m[3],
201+
},
202+
Status: list.Available,
203+
})
204+
}
205+
}
206+
// this sorting ensures the List method fulfils the contract of
207+
// returning the most relevant items first
208+
slices.SortFunc(expected, func(a, b list.Result) int {
209+
return cmp.Or(
210+
// we want installed versions first, available after;
211+
// compare in reverse order since "installed > "available"
212+
cmp.Compare(b.Status, a.Status),
213+
// then, sort in descending order by version
214+
cmp.Compare(b.Version.Major, a.Version.Major),
215+
cmp.Compare(b.Version.Minor, a.Version.Minor),
216+
cmp.Compare(b.Version.Patch, a.Version.Patch),
217+
// ..and then in ascending order by platform
218+
cmp.Compare(a.Platform.OS, b.Platform.OS),
219+
cmp.Compare(a.Platform.Arch, b.Platform.Arch),
220+
)
221+
})
222+
223+
Expect(result).To(HaveExactElements(expected))
224+
})
225+
})
226+
})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package testhelpers
2+
3+
import (
4+
"github.com/go-logr/logr"
5+
"github.com/go-logr/zapr"
6+
"go.uber.org/zap"
7+
"go.uber.org/zap/zapcore"
8+
9+
"github.com/onsi/ginkgo/v2"
10+
)
11+
12+
// GetLogger configures a logger that's suitable for testing
13+
func GetLogger() logr.Logger {
14+
testOut := zapcore.AddSync(ginkgo.GinkgoWriter)
15+
enc := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig())
16+
17+
zapLog := zap.New(zapcore.NewCore(enc, testOut, zap.DebugLevel),
18+
zap.ErrorOutput(testOut), zap.Development(), zap.AddStacktrace(zap.WarnLevel))
19+
20+
return zapr.NewLogger(zapLog)
21+
}

0 commit comments

Comments
 (0)