get.porter.sh/porter@v1.3.0/pkg/porter/archive_test.go (about)

     1  package porter
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"get.porter.sh/porter/pkg"
     8  	"get.porter.sh/porter/pkg/cnab"
     9  	"get.porter.sh/porter/tests"
    10  	"github.com/cnabio/cnab-go/bundle"
    11  	"github.com/cnabio/cnab-to-oci/relocation"
    12  	"github.com/cnabio/image-relocation/pkg/image"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  func TestArchive_ParentDirDoesNotExist(t *testing.T) {
    17  	p := NewTestPorter(t)
    18  	defer p.Close()
    19  
    20  	opts := ArchiveOptions{}
    21  	opts.Reference = "myreg/mybuns:v0.1.0"
    22  
    23  	err := opts.Validate(context.Background(), []string{"/path/to/file"}, p.Porter)
    24  	require.NoError(t, err, "expected no validation error to occur")
    25  
    26  	err = p.Archive(context.Background(), opts)
    27  	require.EqualError(t, err, "parent directory \"/path/to\" does not exist")
    28  }
    29  
    30  func TestArchive_Validate(t *testing.T) {
    31  	p := NewTestPorter(t)
    32  	defer p.Close()
    33  
    34  	testcases := []struct {
    35  		name             string
    36  		args             []string
    37  		reference        string
    38  		compressionLevel string
    39  		wantError        string
    40  	}{
    41  		{"no arg", nil, "", "", "destination file is required"},
    42  		{"no tag", []string{"/path/to/file"}, "", "", "must provide a value for --reference of the form REGISTRY/bundle:tag"},
    43  		{"too many args", []string{"/path/to/file", "moar args!"}, "myreg/mybuns:v0.1.0", "", "only one positional argument may be specified, the archive file name, but multiple were received: [/path/to/file moar args!]"},
    44  		{"invalid compression level", []string{"/path/to/file"}, "myreg/mybuns:v0.1.0", "NotValidCompression", "invalid compression level: NotValidCompression"},
    45  		{"no compression level", []string{"/path/to/file"}, "myreg/mybuns:v0.1.0", "NoCompression", ""},
    46  		{"just right", []string{"/path/to/file"}, "myreg/mybuns:v0.1.0", "", ""},
    47  	}
    48  
    49  	for _, tc := range testcases {
    50  		t.Run(tc.name, func(t *testing.T) {
    51  			opts := ArchiveOptions{}
    52  			opts.Reference = tc.reference
    53  			opts.CompressionLevel = tc.compressionLevel
    54  
    55  			err := opts.Validate(context.Background(), tc.args, p.Porter)
    56  			if tc.wantError != "" {
    57  				require.EqualError(t, err, tc.wantError)
    58  			} else {
    59  				require.NoError(t, err, "expected no validation error to occur")
    60  			}
    61  		})
    62  	}
    63  }
    64  
    65  func TestArchive_ArchiveDirectory(t *testing.T) {
    66  	p := NewTestPorter(t)
    67  	defer p.Close()
    68  	ex := exporter{
    69  		fs: p.FileSystem,
    70  	}
    71  
    72  	dir, err := ex.createArchiveFolder("examples/test-bundle-0.2.0")
    73  	require.NoError(t, err)
    74  	require.Contains(t, dir, "examples-test-bundle-0.2.0")
    75  
    76  	tests.AssertDirectoryPermissionsEqual(t, dir, pkg.FileModeDirectory)
    77  }
    78  
    79  func TestArchive_AddImage(t *testing.T) {
    80  	p := NewTestPorter(t)
    81  	defer p.Close()
    82  
    83  	testcases := []struct {
    84  		name           string
    85  		relocationMap  relocation.ImageRelocationMap
    86  		inputImg       string
    87  		expectedImg    string
    88  		hasErr         bool
    89  		expectedErrMsg string
    90  	}{
    91  		{"no relocation map set", nil, "image:v0.1.0", "", true, "relocation map is not provided"},
    92  		{"image not found in relocation map", relocation.ImageRelocationMap{"image:v0.1.0": "image@sha256:123"}, "not-found-image:v0.2.0", "", true, "can not locate the referenced image"},
    93  		{"image successfully added", relocation.ImageRelocationMap{"image:v0.1.0": "image@sha256:123"}, "image:v0.1.0", "image@sha256:123", false, ""},
    94  	}
    95  
    96  	for _, tc := range testcases {
    97  		tc := tc
    98  		t.Run(tc.name, func(t *testing.T) {
    99  			baseImage := bundle.BaseImage{Image: tc.inputImg, Digest: "digest"}
   100  			ex := exporter{relocationMap: tc.relocationMap, imageStore: mockImageStore{t: t, expected: tc.expectedImg}}
   101  			err := ex.addImage(baseImage)
   102  			if tc.hasErr {
   103  				tests.RequireErrorContains(t, err, tc.expectedErrMsg)
   104  			} else {
   105  				require.NoError(t, err)
   106  			}
   107  		})
   108  	}
   109  
   110  }
   111  
   112  func TestArchive_PrepareArtifacts_Sorting(t *testing.T) {
   113  	p := NewTestPorter(t)
   114  	defer p.Close()
   115  
   116  	testcases := []struct {
   117  		name          string
   118  		relocationMap relocation.ImageRelocationMap
   119  		inputImgs     []string
   120  		expectedImgs  []string
   121  	}{
   122  		{"images sorted", relocation.ImageRelocationMap{"c:v0.1.0": "c@sha256:789", "a:v0.1.0": "a@sha256:123", "b:v0.1.0": "b@sha256:456"},
   123  			[]string{"b:v0.1.0", "c:v0.1.0", "a:v0.1.0"},
   124  			[]string{"a@sha256:123", "b@sha256:456", "c@sha256:789"}},
   125  		{"numbers too", relocation.ImageRelocationMap{"a:v0.1.0": "a@sha256:123", "0b:v0.1.0": "0b@sha256:456"},
   126  			[]string{"0b:v0.1.0", "a:v0.1.0"},
   127  			[]string{"0b@sha256:456", "a@sha256:123"}},
   128  	}
   129  
   130  	for _, tc := range testcases {
   131  		tc := tc
   132  		t.Run(tc.name, func(t *testing.T) {
   133  			images := make(map[string]bundle.Image)
   134  			b := cnab.NewBundle(bundle.Bundle{Images: images})
   135  			for _, inputImg := range tc.inputImgs {
   136  				images[inputImg] = bundle.Image{BaseImage: bundle.BaseImage{Image: inputImg, Digest: "digest"}}
   137  			}
   138  			collectedImages := make([]string, 0)
   139  			imageStore := mockCollectingImageStore{t: t, addedImages: &collectedImages}
   140  			ex := exporter{relocationMap: tc.relocationMap, imageStore: imageStore}
   141  
   142  			err := ex.prepareArtifacts(b)
   143  
   144  			require.Equal(t, tc.expectedImgs, collectedImages)
   145  			require.NoError(t, err)
   146  		})
   147  	}
   148  
   149  }
   150  
   151  type mockCollectingImageStore struct {
   152  	t           *testing.T
   153  	addedImages *[]string
   154  }
   155  
   156  func (m mockCollectingImageStore) Add(img string) (contentDigest string, err error) {
   157  	*m.addedImages = append(*m.addedImages, img)
   158  	return "digest", nil
   159  }
   160  
   161  func (m mockCollectingImageStore) Push(dig image.Digest, src image.Name, dst image.Name) error {
   162  	return nil
   163  }
   164  
   165  type mockImageStore struct {
   166  	t        *testing.T
   167  	expected string
   168  }
   169  
   170  func (m mockImageStore) Add(img string) (contentDigest string, err error) {
   171  	require.Equal(m.t, m.expected, img)
   172  	return "digest", nil
   173  }
   174  
   175  func (m mockImageStore) Push(dig image.Digest, src image.Name, dst image.Name) error {
   176  	return nil
   177  }