1 package integration
2
3 import (
4 "context"
5 _ "embed"
6 "fmt"
7 "os"
8 "testing"
9 "time"
10
11 "gotest.tools/v3/assert/cmp"
12 ctrl "sigs.k8s.io/controller-runtime"
13 "sigs.k8s.io/controller-runtime/pkg/client"
14 "sigs.k8s.io/kustomize/api/filters/namespace"
15
16 "edge-infra.dev/pkg/f8n/warehouse/capability"
17 "edge-infra.dev/pkg/f8n/warehouse/cluster"
18 whv1 "edge-infra.dev/pkg/f8n/warehouse/k8s/apis/v1alpha2"
19 "edge-infra.dev/pkg/f8n/warehouse/k8s/controllers/lumperctl"
20 "edge-infra.dev/pkg/f8n/warehouse/k8s/controllers/lumperctl/internal"
21 "edge-infra.dev/pkg/f8n/warehouse/oci"
22 "edge-infra.dev/pkg/f8n/warehouse/oci/cache"
23 "edge-infra.dev/pkg/f8n/warehouse/oci/layer"
24 "edge-infra.dev/pkg/f8n/warehouse/pallet"
25 "edge-infra.dev/pkg/k8s/object"
26 "edge-infra.dev/pkg/k8s/runtime/conditions"
27 "edge-infra.dev/pkg/k8s/runtime/inventory"
28 "edge-infra.dev/pkg/k8s/unstructured"
29 "edge-infra.dev/pkg/lib/fog"
30 "edge-infra.dev/test/f2"
31 "edge-infra.dev/test/f2/x/ktest"
32 "edge-infra.dev/test/f2/x/warehouse"
33 )
34
35
36
37 var f f2.Framework
38
39
40
41 type testPallet struct {
42 inv *inventory.ResourceInventory
43 digest string
44 name string
45 tag string
46 pallet pallet.Pallet
47 }
48
49
50 var (
51
52 minimalv1 []byte
53
54 minimalv2 []byte
55
56 fakeInfra []byte
57
58 fakeMeshConfig []byte
59
60 linkerdCapablityProvider []byte
61
62 meshConfig []byte
63
64 sapInitial []byte
65
66 sapFinal []byte
67
68 l5dCap capability.Capability = "linkerd"
69 )
70
71 const fixtureSemVer = "0.2.5-test.1711660462+commit.d34db33f"
72
73 func TestMain(m *testing.M) {
74
75
76
77 lumperctl.SetPackageLoggers(fog.New())
78
79 healthzChecker := internal.New(ctrl.Log.WithName("lumper-liveness"))
80 f = f2.New(context.Background(),
81 f2.WithExtensions(
82 ktest.New(
83 ktest.WithCtrlManager(lumperctl.CreateMgr(healthzChecker)),
84 ktest.WithMetricsAddress(8080),
85 ),
86 &warehouse.Registry{},
87 ),
88 ).
89 Setup(func(ctx f2.Context) (f2.Context, error) {
90 k, err := ktest.FromContext(ctx)
91 if err != nil {
92 return ctx, err
93 }
94
95
96 if !*k.Env.UseExistingCluster {
97 k.Timeout = 5 * time.Second
98 k.Tick = 10 * time.Millisecond
99 }
100
101 warehouseCache, err := cache.New(
102 cache.WithMemoryCacheSize(250),
103 )
104 if err != nil {
105 return ctx, err
106 }
107
108
109
110
111 if err := lumperctl.RegisterControllers(
112 k.Manager,
113 &lumperctl.Config{
114 Provider: cluster.Generic,
115 SvcAct: "lumperctl",
116 Namespace: k.Namespace,
117 UpCfg: lumperctl.UnpackedPalletCfg{
118 Concurrent: 32,
119 DepRequeueInterval: k.Tick,
120 },
121 ShipCfg: lumperctl.ShipmentCfg{
122 Concurrent: 8,
123 },
124 Cache: warehouseCache,
125 },
126 healthzChecker,
127 ); err != nil {
128 return ctx, err
129 }
130 fmt.Println("after register controllers")
131
132 fmt.Println("was able to register the controllers")
133 return ctx, nil
134 })
135
136 os.Exit(f.Run(m))
137 }
138
139 func unpackedPallet(
140 ctx f2.Context,
141 t *testing.T,
142 name string,
143 p pallet.Pallet,
144 opts ...whv1.Option,
145 ) *whv1.UnpackedPallet {
146 t.Helper()
147 reg := warehouse.FromContextT(ctx, t)
148
149 digest, err := p.Digest()
150 if err != nil {
151 t.Fatalf("failed to compute digest of test pallet %s: %v", p.Name(), err)
152 }
153
154 repo := fmt.Sprintf("%s/%s", reg.URL, p.Name())
155 return whv1.NewUnpackedPallet(name,
156 append([]whv1.Option{
157 whv1.WithArtifact(whv1.NewArtifact(p.Name(), digest.String(), repo)),
158 whv1.ForProvider(cluster.Generic),
159 whv1.WithRuntime(),
160 whv1.WithTimeout(ktest.FromContextT(ctx, t).Tick * 3),
161 whv1.WithRetryInterval(ktest.FromContextT(ctx, t).Tick),
162 }, opts...)...,
163 )
164 }
165
166 func shipment(
167 ctx f2.Context,
168 t *testing.T,
169 name string,
170 pallets []whv1.BaseArtifact,
171 opts ...whv1.Option,
172 ) *whv1.Shipment {
173 t.Helper()
174
175 return whv1.NewShipment(name,
176 append([]whv1.Option{
177 whv1.FromRepo(warehouse.FromContextT(ctx, t).URL),
178 whv1.WithArtifacts(pallets...),
179 whv1.ForProvider(cluster.Generic),
180 whv1.WithRuntime(),
181 whv1.WithRetryInterval(ktest.FromContextT(ctx, t).Tick),
182 }, opts...)...,
183 )
184 }
185
186 func createAndPushPallet(
187 ctx f2.Context,
188 t *testing.T,
189 name,
190 tag string,
191 layers ...layer.Layer,
192 ) testPallet {
193 t.Helper()
194
195 p := testPallet{name: name, tag: tag}
196
197 var objs []*unstructured.Unstructured
198 for i, l := range layers {
199
200
201 l, err := layer.Filter(
202 l,
203 namespace.Filter{Namespace: ktest.FromContextT(ctx, t).Namespace},
204 )
205 if err != nil {
206 t.Fatal("failed to render test pallet manifests", err)
207 }
208
209 r, err := l.Uncompressed()
210 if err != nil {
211 t.Fatal(name, err)
212 }
213 lobjs, err := object.ReadObjects(r)
214 if err != nil {
215 t.Fatal("failed to read test pallet objects", name, err)
216 }
217 objs = append(objs, lobjs...)
218
219 layers[i] = l
220 }
221 p.inv = inventory.New(inventory.FromUnstructured(objs...))
222
223 a, err := pallet.Image(pallet.Options{
224 Metadata: pkgMeta(name),
225 ClusterProviders: cluster.BuiltInProviders(),
226 }, layers...)
227 if err != nil {
228 t.Fatal("failed to create test pallet", name, err)
229 }
230 p.pallet = a
231
232 d, err := a.Digest()
233 if err != nil {
234 t.Fatal(name, err)
235 }
236 p.digest = d.String()
237
238
239 pushPkg(ctx, t, a, name, tag)
240
241 return p
242 }
243
244 func createAndPushPalletWithDeps(
245 ctx f2.Context,
246 t *testing.T,
247 name,
248 tag string,
249 deps ...oci.Artifact,
250 ) testPallet {
251 t.Helper()
252
253 p := testPallet{name: name, tag: tag}
254
255 a, err := pallet.ImageIndex(pallet.Options{
256 Metadata: pkgMeta(name),
257 ClusterProviders: cluster.BuiltInProviders(),
258 }, deps...)
259 if err != nil {
260 t.Fatal("failed to create test pallet", name, err)
261 }
262 p.pallet = a
263
264 d, err := a.Digest()
265 if err != nil {
266 t.Fatal(name, err)
267 }
268 p.digest = d.String()
269
270
271 pushPkg(ctx, t, a, name, tag)
272
273 return p
274 }
275
276 func createLayer(
277 t *testing.T,
278 lt layer.Type,
279 yaml []byte,
280 opts ...layer.Option,
281 ) layer.Layer {
282 t.Helper()
283
284 l, err := layer.New(lt, yaml, opts...)
285 if err != nil {
286 t.Fatal("failed to create test pallet layer", err)
287 }
288
289 return l
290 }
291
292 func pushPkg(ctx f2.Context, t *testing.T, a oci.Artifact, name, tag string) {
293 t.Helper()
294
295 if err := warehouse.FromContextT(ctx, t).Push(a, name, tag); err != nil {
296 t.Fatal("failed to push test pallet", err)
297 }
298 }
299
300 func pkgMeta(name string) pallet.Metadata {
301 return pallet.Metadata{
302 Name: name,
303 Team: "@ncrvoyix-swt-retail/edge-foundation",
304 BuildInfo: pallet.BuildInfo{
305 Created: "yesterday",
306 Source: "https://gothub.com/ncrvoyix-swt-retail/edge-infra",
307 Revision: "d34db33f",
308 Version: "0.2.5-test.1711660462+commit.d34db33f",
309 },
310 }
311 }
312
313 func fakeL5dLayer(t *testing.T) layer.Layer {
314 return createLayer(t, layer.Runtime, fakeMeshConfig,
315 layer.ForCapability(l5dCap))
316 }
317
318 func fakeInfraLayer(t *testing.T) layer.Layer {
319 return createLayer(t, layer.Infra, fakeInfra)
320 }
321
322 func id(ctx f2.Context, name string) string {
323 return fmt.Sprintf("%s-%s", name, ctx.RunID)
324 }
325
326 func unpackedPalletReady(o client.Object) cmp.Result {
327 u := o.(*whv1.UnpackedPallet)
328 if conditions.IsReady(u) &&
329 u.Status.ObservedGeneration == u.Generation &&
330 u.IsUpToDate() {
331 return cmp.ResultSuccess
332 }
333 return cmp.ResultFailure(fmt.Sprintf("%s not ready", object.FmtObject(u)))
334 }
335
336 func shipmentReady(o client.Object) cmp.Result {
337 s := o.(*whv1.Shipment)
338 if conditions.IsReady(s) && s.IsUpToDate() {
339 return cmp.ResultSuccess
340 }
341 return cmp.ResultFailure(fmt.Sprintf("%s not ready", object.FmtObject(s)))
342 }
343
344 func shipmentStalled(o client.Object) cmp.Result {
345 s := o.(*whv1.Shipment)
346 if conditions.IsStalled(s) && s.IsUpToDate() {
347 return cmp.ResultSuccess
348 }
349 return cmp.ResultFailure(fmt.Sprintf("%s not stalled", object.FmtObject(s)))
350 }
351
View as plain text