package unpack import ( "fmt" "io" "strings" "testing" "github.com/google/go-containerregistry/pkg/name" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "edge-infra.dev/pkg/f8n/warehouse/cluster" "edge-infra.dev/pkg/f8n/warehouse/lift" "edge-infra.dev/pkg/f8n/warehouse/oci/layer" "edge-infra.dev/pkg/f8n/warehouse/pallet" "edge-infra.dev/pkg/lib/uuid" ) func TestLayers(t *testing.T) { shoot, err := path.Get(name.MustParseReference("shoot:latest")) require.NoError(t, err) t.Run("infrastructure", func(t *testing.T) { ns := "desired-namespace" layers, err := Layers(shoot, ForLayerTypes(layer.Infra), ForProvider(cluster.Generic), ) assert.NoError(t, err) require.Len(t, layers, 1, "there should only be one infrastructure layer unpacked") assert.Equal(t, layer.Infra, layers[0].Type()) layers, err = Layers(shoot, ForLayerKeys(layer.Infra.String()), ForProvider(cluster.Generic), WithInfraNamespace(ns), ) assert.NoError(t, err) require.Len(t, layers, 1, "there should only be one infrastructure layer unpacked") assert.Equal(t, layer.Infra, layers[0].Type()) t.Run("WithInfraNamespace", func(t *testing.T) { objs, err := layers[0].Unstructured() assert.NoError(t, err) for _, o := range objs { if o.GetNamespace() != ns && o.GetNamespace() != "" { assert.Fail(t, "infrastructure object had incorrect namespace", o.GetNamespace(), o.GetKind(), o.GetName(), ) } } }) }) t.Run("runtime", func(t *testing.T) { layers, err := Layers(shoot, ForLayerTypes(layer.Runtime), ForProvider(cluster.Generic), ) assert.NoError(t, err) testRuntimeLayers(t, layers) layers, err = Layers(shoot, ForLayerKeys(layer.Runtime.String(), "prometheus", "linkerd"), ForProvider(cluster.Generic), ) assert.NoError(t, err) testRuntimeLayers(t, layers) }) t.Run("individual layer keys", func(t *testing.T) { layers, err := Layers(shoot, ForLayerKeys("prometheus"), ForProvider(cluster.Generic), ) assert.NoError(t, err) require.Len(t, layers, 1) l := layers[0] assert.Equal(t, layer.Runtime, l.Type()) assert.Equal(t, "prometheus", l.Key()) layers, err = Layers(shoot, ForLayerKeys(layer.Runtime.String()), ForProvider(cluster.Generic), ) assert.NoError(t, err) require.Len(t, layers, 1) l = layers[0] assert.Equal(t, layer.Runtime, l.Type()) assert.Equal(t, layer.Runtime.String(), l.Key()) }) t.Run("rendering", func(t *testing.T) { layers, err := Layers(shoot, ForLayerKeys("runtime"), ForProvider(cluster.Generic), RenderWith(map[string]string{lift.ClusterUUIDRenderingParameter: uuid.New().UUID}), ) assert.NoError(t, err) require.Len(t, layers, 1) checkLayerProcessing(t, layers[0]) }) t.Run("ForProvider required for some input types", func(t *testing.T) { _, err := Layers(shoot) assert.Error(t, err, "v1.ImageIndex should require ForProvider") p, err := pallet.New(shoot) assert.NoError(t, err) _, err = Layers(p) assert.Error(t, err, "Pallet should require ForProvider") cm, err := path.Get(name.MustParseReference("cert-manager:latest")) assert.NoError(t, err) _, err = Layers(cm) assert.NoError(t, err, "v1.Image should not require ForProvider") p, err = pallet.New(cm) assert.NoError(t, err) _, err = Layers(p) assert.NoError(t, err, "Pallet backed by v1.Image should not require ForProvider") }) t.Run("All layers returned by default", func(t *testing.T) { layers, err := Layers(shoot, ForProvider(cluster.Generic)) assert.NoError(t, err) assert.Len(t, layers, 4) for _, l := range layers { switch l.Key() { case "prometheus", "linkerd", layer.Infra.String(), layer.Runtime.String(): t.Log("expected layer key found", l.Key()) default: t.Log("unexpected layer key found", l.Key()) } } }) } func testRuntimeLayers(t *testing.T, layers []layer.Layer) { assert.Len(t, layers, 3) for _, l := range layers { t.Log("layer", l) assert.Equal(t, layer.Runtime, l.Type(), "non-runtime layer was returned") switch l.Key() { case "prometheus", "linkerd", layer.Runtime.String(): t.Log("expected layer key found", l.Key()) default: assert.Fail(t, "unexpected layer key discovered", l.Key()) } } } // verifies that a given layer has been rendered, which indicates that it was // ran through processLayer func checkLayerProcessing(t *testing.T, l layer.Layer) { r, err := l.Uncompressed() assert.NoError(t, err) data, err := io.ReadAll(r) assert.NoError(t, err) assert.False(t, strings.Contains(string(data), fmt.Sprintf("${%s}", lift.ClusterUUIDRenderingParameter), ), ) }