1 package unpack
2
3 import (
4 "fmt"
5 "io"
6 "strings"
7 "testing"
8
9 "github.com/google/go-containerregistry/pkg/name"
10 "github.com/stretchr/testify/assert"
11 "github.com/stretchr/testify/require"
12
13 "edge-infra.dev/pkg/f8n/warehouse/cluster"
14 "edge-infra.dev/pkg/f8n/warehouse/lift"
15 "edge-infra.dev/pkg/f8n/warehouse/oci/layer"
16 "edge-infra.dev/pkg/f8n/warehouse/pallet"
17 "edge-infra.dev/pkg/lib/uuid"
18 )
19
20 func TestLayers(t *testing.T) {
21 shoot, err := path.Get(name.MustParseReference("shoot:latest"))
22 require.NoError(t, err)
23
24 t.Run("infrastructure", func(t *testing.T) {
25 ns := "desired-namespace"
26 layers, err := Layers(shoot,
27 ForLayerTypes(layer.Infra),
28 ForProvider(cluster.Generic),
29 )
30 assert.NoError(t, err)
31
32 require.Len(t, layers, 1, "there should only be one infrastructure layer unpacked")
33 assert.Equal(t, layer.Infra, layers[0].Type())
34
35 layers, err = Layers(shoot,
36 ForLayerKeys(layer.Infra.String()),
37 ForProvider(cluster.Generic),
38 WithInfraNamespace(ns),
39 )
40 assert.NoError(t, err)
41
42 require.Len(t, layers, 1, "there should only be one infrastructure layer unpacked")
43 assert.Equal(t, layer.Infra, layers[0].Type())
44
45 t.Run("WithInfraNamespace", func(t *testing.T) {
46 objs, err := layers[0].Unstructured()
47 assert.NoError(t, err)
48
49 for _, o := range objs {
50 if o.GetNamespace() != ns && o.GetNamespace() != "" {
51 assert.Fail(t, "infrastructure object had incorrect namespace",
52 o.GetNamespace(), o.GetKind(), o.GetName(),
53 )
54 }
55 }
56 })
57 })
58
59 t.Run("runtime", func(t *testing.T) {
60 layers, err := Layers(shoot,
61 ForLayerTypes(layer.Runtime),
62 ForProvider(cluster.Generic),
63 )
64 assert.NoError(t, err)
65
66 testRuntimeLayers(t, layers)
67
68 layers, err = Layers(shoot,
69 ForLayerKeys(layer.Runtime.String(), "prometheus", "linkerd"),
70 ForProvider(cluster.Generic),
71 )
72 assert.NoError(t, err)
73
74 testRuntimeLayers(t, layers)
75 })
76
77 t.Run("individual layer keys", func(t *testing.T) {
78 layers, err := Layers(shoot,
79 ForLayerKeys("prometheus"),
80 ForProvider(cluster.Generic),
81 )
82 assert.NoError(t, err)
83
84 require.Len(t, layers, 1)
85 l := layers[0]
86 assert.Equal(t, layer.Runtime, l.Type())
87 assert.Equal(t, "prometheus", l.Key())
88
89 layers, err = Layers(shoot,
90 ForLayerKeys(layer.Runtime.String()),
91 ForProvider(cluster.Generic),
92 )
93 assert.NoError(t, err)
94 require.Len(t, layers, 1)
95 l = layers[0]
96 assert.Equal(t, layer.Runtime, l.Type())
97 assert.Equal(t, layer.Runtime.String(), l.Key())
98 })
99
100 t.Run("rendering", func(t *testing.T) {
101 layers, err := Layers(shoot,
102 ForLayerKeys("runtime"),
103 ForProvider(cluster.Generic),
104 RenderWith(map[string]string{lift.ClusterUUIDRenderingParameter: uuid.New().UUID}),
105 )
106 assert.NoError(t, err)
107
108 require.Len(t, layers, 1)
109 checkLayerProcessing(t, layers[0])
110 })
111
112 t.Run("ForProvider required for some input types", func(t *testing.T) {
113 _, err := Layers(shoot)
114 assert.Error(t, err, "v1.ImageIndex should require ForProvider")
115
116 p, err := pallet.New(shoot)
117 assert.NoError(t, err)
118 _, err = Layers(p)
119 assert.Error(t, err, "Pallet should require ForProvider")
120
121 cm, err := path.Get(name.MustParseReference("cert-manager:latest"))
122 assert.NoError(t, err)
123 _, err = Layers(cm)
124 assert.NoError(t, err, "v1.Image should not require ForProvider")
125
126 p, err = pallet.New(cm)
127 assert.NoError(t, err)
128 _, err = Layers(p)
129 assert.NoError(t, err, "Pallet backed by v1.Image should not require ForProvider")
130 })
131
132 t.Run("All layers returned by default", func(t *testing.T) {
133 layers, err := Layers(shoot, ForProvider(cluster.Generic))
134 assert.NoError(t, err)
135
136 assert.Len(t, layers, 4)
137 for _, l := range layers {
138 switch l.Key() {
139 case "prometheus", "linkerd", layer.Infra.String(), layer.Runtime.String():
140 t.Log("expected layer key found", l.Key())
141 default:
142 t.Log("unexpected layer key found", l.Key())
143 }
144 }
145 })
146 }
147
148 func testRuntimeLayers(t *testing.T, layers []layer.Layer) {
149 assert.Len(t, layers, 3)
150 for _, l := range layers {
151 t.Log("layer", l)
152 assert.Equal(t, layer.Runtime, l.Type(), "non-runtime layer was returned")
153 switch l.Key() {
154 case "prometheus", "linkerd", layer.Runtime.String():
155 t.Log("expected layer key found", l.Key())
156 default:
157 assert.Fail(t, "unexpected layer key discovered", l.Key())
158 }
159 }
160 }
161
162
163
164 func checkLayerProcessing(t *testing.T, l layer.Layer) {
165 r, err := l.Uncompressed()
166 assert.NoError(t, err)
167
168 data, err := io.ReadAll(r)
169 assert.NoError(t, err)
170 assert.False(t,
171 strings.Contains(string(data),
172 fmt.Sprintf("${%s}", lift.ClusterUUIDRenderingParameter),
173 ),
174 )
175 }
176
View as plain text