...

Source file src/edge-infra.dev/pkg/f8n/warehouse/oci/layer/layer_test.go

Documentation: edge-infra.dev/pkg/f8n/warehouse/oci/layer

     1  package layer_test
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rand"
     6  	"io"
     7  	"testing"
     8  	"time"
     9  
    10  	v1 "github.com/google/go-containerregistry/pkg/v1"
    11  	"github.com/google/go-containerregistry/pkg/v1/mutate"
    12  	"github.com/google/go-containerregistry/pkg/v1/partial"
    13  	"github.com/google/go-containerregistry/pkg/v1/static"
    14  
    15  	wh "edge-infra.dev/pkg/f8n/warehouse"
    16  	"edge-infra.dev/pkg/f8n/warehouse/capability"
    17  	"edge-infra.dev/pkg/f8n/warehouse/cluster"
    18  	"edge-infra.dev/pkg/f8n/warehouse/oci/layer"
    19  	"edge-infra.dev/pkg/f8n/warehouse/pallet"
    20  )
    21  
    22  func TestLayer_Descriptor(t *testing.T) {
    23  	v1Layer := testLayer(t, layer.Runtime)
    24  	d, err := partial.Descriptor(v1Layer)
    25  	if err != nil {
    26  		t.Error(err)
    27  	}
    28  	annos := v1Layer.Annotations()
    29  
    30  	for k, v := range d.Annotations {
    31  		if annos[k] != v {
    32  			t.Errorf("annotation %s did not match between Descriptor and Layer. "+
    33  				"Expected %s and got %s", k, v, annos[k])
    34  		}
    35  	}
    36  }
    37  
    38  func TestType(t *testing.T) {
    39  	l := testLayer(t, layer.Runtime)
    40  	if l.Type() != layer.Runtime {
    41  		t.Errorf("incorrect layer type: expected %s, got %s",
    42  			layer.Runtime, l.Type())
    43  	}
    44  }
    45  
    46  func TestForCapability(t *testing.T) {
    47  	c := capability.Capability("linkerd")
    48  	annos := testLayer(t, layer.Runtime, layer.ForCapability(c)).Annotations()
    49  
    50  	if annos[wh.AnnotationLayerRuntimeCapability] != string(c) {
    51  		t.Errorf("annotation %s has unexpected value: wanted %s, got %s",
    52  			wh.AnnotationLayerRuntimeCapability,
    53  			c,
    54  			annos[wh.AnnotationLayerRuntimeCapability],
    55  		)
    56  	}
    57  }
    58  
    59  func TestKey(t *testing.T) {
    60  	tcs := map[string]struct {
    61  		layer    layer.Layer
    62  		expected string
    63  	}{
    64  		"base runtime layer": {testLayer(t, layer.Runtime), string(layer.Runtime)},
    65  		"infra layer":        {testLayer(t, layer.Infra), string(layer.Infra)},
    66  		"config layer":       {testLayer(t, layer.Config), string(layer.Config)},
    67  		"runtime capability layer": {
    68  			testLayer(t, layer.Runtime, layer.ForCapability(capability.Capability("prometheus"))),
    69  			"prometheus",
    70  		},
    71  	}
    72  
    73  	for name, tc := range tcs {
    74  		t.Run(name, func(t *testing.T) {
    75  			if tc.layer.Key() != tc.expected {
    76  				t.Errorf("incorrect layer key. expected %s, got %s",
    77  					tc.expected, tc.layer.Key())
    78  			}
    79  		})
    80  	}
    81  }
    82  
    83  func TestSort(t *testing.T) {
    84  	tcs := []struct {
    85  		input    []string
    86  		expected []string
    87  	}{
    88  		{
    89  			[]string{"runtime", "infrastructure", "prometheus", "linkerd"},
    90  			[]string{"runtime", "infrastructure", "prometheus", "linkerd"},
    91  		},
    92  		{
    93  			[]string{"infrastructure", "prometheus", "runtime"},
    94  			[]string{"runtime", "infrastructure", "prometheus"},
    95  		},
    96  		{
    97  			[]string{"prometheus", "runtime", "linkerd", "infrastructure"},
    98  			[]string{"runtime", "infrastructure", "prometheus", "linkerd"},
    99  		},
   100  		{
   101  			[]string{"prometheus", "linkerd", "runtime", "infrastructure", "gatekeeper"},
   102  			[]string{"runtime", "infrastructure", "prometheus", "linkerd", "gatekeeper"},
   103  		},
   104  	}
   105  
   106  	for _, tc := range tcs {
   107  		layers := make([]layer.Layer, 0, len(tc.input))
   108  		for _, key := range tc.input {
   109  			lt := layer.Runtime
   110  			opts := []layer.Option{}
   111  			if key == layer.Infra.String() {
   112  				lt = layer.Infra
   113  			}
   114  			if !layer.IsType(key) {
   115  				opts = append(opts, layer.ForCapability(capability.Capability(key)))
   116  			}
   117  			layers = append(layers, testLayer(t, lt, opts...))
   118  		}
   119  
   120  		layer.Sort(layers)
   121  
   122  		for i, l := range layers {
   123  			if l.Key() != tc.expected[i] {
   124  				t.Errorf("incorrect order, got %s for element %d instead of %s",
   125  					l.Key(), i, tc.expected[i])
   126  			}
   127  		}
   128  	}
   129  }
   130  
   131  func TestFromImage(t *testing.T) {
   132  	t.Run("drops non-warehouse layers", func(t *testing.T) {
   133  		img, err := pallet.Image(pallet.Options{
   134  			ClusterProviders: []cluster.Provider{cluster.Generic},
   135  			Metadata: pallet.Metadata{
   136  				Team: "@ncrvoyix-swt-retail/sorry-suckers",
   137  				Name: "includes-non-warehouse-layers",
   138  				BuildInfo: pallet.BuildInfo{
   139  					Source:   "https://github.com/ncrvoyix-swt-retail/foo",
   140  					Version:  "0.0.1",
   141  					Revision: "d34db33f",
   142  					Created:  time.Now().Format(time.RFC3339),
   143  				},
   144  				Vendor: "NCR",
   145  			},
   146  		}, testLayer(t, layer.Infra), testLayer(t, layer.Runtime))
   147  		if err != nil {
   148  			t.Fatal("failed to create test image", err)
   149  		}
   150  
   151  		i, err := mutate.AppendLayers(img.Unwrap().(v1.Image), staticLayer(t))
   152  		if err != nil {
   153  			t.Fatal("failed to create test image", err)
   154  		}
   155  
   156  		layers, err := layer.FromImage(i)
   157  		if err != nil {
   158  			t.Error("unexpected error", err)
   159  		}
   160  		if len(layers) != 2 {
   161  			t.Errorf("unexpected number of layers %d, expected %d", len(layers), 2)
   162  		}
   163  	})
   164  }
   165  
   166  func testLayer(t *testing.T, ty layer.Type, o ...layer.Option) layer.Layer {
   167  	c, err := randomContents(256)
   168  	if err != nil {
   169  		t.Fatal("failed to create layer content", err)
   170  	}
   171  	l, err := layer.New(ty, c, o...)
   172  	if err != nil {
   173  		t.Fatal("failed to instantiate layer", err)
   174  	}
   175  
   176  	return l
   177  }
   178  
   179  func staticLayer(t *testing.T) v1.Layer {
   180  	c, err := randomContents(256)
   181  	if err != nil {
   182  		t.Fatal("failed to create layer content", err)
   183  	}
   184  	return static.NewLayer(c, layer.YAML)
   185  }
   186  
   187  func randomContents(byteSize int64) ([]byte, error) {
   188  	var b bytes.Buffer
   189  	_, err := io.CopyN(&b, rand.Reader, byteSize)
   190  	if err != nil {
   191  		return nil, err
   192  	}
   193  
   194  	return b.Bytes(), nil
   195  }
   196  

View as plain text