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

     1  //go:build integration
     2  
     3  package integration
     4  
     5  import (
     6  	"crypto/sha256"
     7  	"fmt"
     8  	"io"
     9  	"runtime"
    10  	"testing"
    11  
    12  	"get.porter.sh/porter/pkg"
    13  	"get.porter.sh/porter/pkg/porter"
    14  	"get.porter.sh/porter/tests"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  // Validate that archiving a bundle twice results in the same digest
    20  func TestArchive_StableDigest(t *testing.T) {
    21  	t.Parallel()
    22  	p := porter.NewTestPorter(t)
    23  	defer p.Close()
    24  	ctx := p.SetupIntegrationTest()
    25  
    26  	// Use a fixed bundle to work with so that we can rely on the registry and layer digests
    27  	const reference = "ghcr.io/getporter/examples/whalegap:v0.2.0"
    28  
    29  	// Archive bundle
    30  	archive1Opts := porter.ArchiveOptions{}
    31  	archive1Opts.Reference = reference
    32  	archiveFile1 := "mybuns1.tgz"
    33  	err := archive1Opts.Validate(ctx, []string{archiveFile1}, p.Porter)
    34  	require.NoError(p.T(), err, "validation of archive opts for bundle failed")
    35  
    36  	err = p.Archive(ctx, archive1Opts)
    37  	require.NoError(p.T(), err, "archival of bundle failed")
    38  
    39  	info, err := p.FileSystem.Stat(archiveFile1)
    40  	require.NoError(p.T(), err)
    41  	if runtime.GOOS != "windows" {
    42  		// permission bits make no sense on windows
    43  		tests.AssertFilePermissionsEqual(t, archiveFile1, pkg.FileModeWritable, info.Mode())
    44  	}
    45  
    46  	hash1 := getHash(p, archiveFile1)
    47  
    48  	// Check to be sure the shasum is stable after archiving a second time
    49  	archive2Opts := porter.ArchiveOptions{}
    50  	archive2Opts.Reference = reference
    51  	archiveFile2 := "mybuns2.tgz"
    52  	err = archive2Opts.Validate(ctx, []string{archiveFile2}, p.Porter)
    53  	require.NoError(p.T(), err, "validation of archive opts for bundle failed")
    54  
    55  	err = archive1Opts.Validate(ctx, []string{archiveFile2}, p.Porter)
    56  	require.NoError(t, err, "Second validate failed")
    57  
    58  	err = p.Archive(ctx, archive2Opts)
    59  	require.NoError(t, err, "Second archive failed")
    60  	assert.Equal(p.T(), hash1, getHash(p, archiveFile2), "shasum of archive did not stay the same on the second call to archive")
    61  
    62  	// the archive should match the hash below regardless of OS architecture, user and execution time
    63  	consistentHash := "6f63a27bd8fa3886192ce9d4d561d9b2f5d5235b17a140af6d1608921fe00e7f"
    64  	assert.Equal(p.T(), consistentHash, hash1, "shasum of archive did not match expected hash")
    65  
    66  	// Publish bundle from archive, with new reference
    67  	localReference := "localhost:5000/archived-whalegap:v0.2.0"
    68  	publishFromArchiveOpts := porter.PublishOptions{
    69  		ArchiveFile: archiveFile1,
    70  		BundlePullOptions: porter.BundlePullOptions{
    71  			Reference: localReference,
    72  		},
    73  	}
    74  	err = publishFromArchiveOpts.Validate(p.Config)
    75  	require.NoError(p.T(), err, "validation of publish opts for bundle failed")
    76  
    77  	err = p.Publish(ctx, publishFromArchiveOpts)
    78  	require.NoError(p.T(), err, "publish of bundle from archive failed")
    79  
    80  	// Archive from the newly published bundle in local registry
    81  	archive3Opts := porter.ArchiveOptions{}
    82  	archive3Opts.Reference = localReference
    83  	archiveFile3 := "mybuns3.tgz"
    84  	err = archive3Opts.Validate(ctx, []string{archiveFile3}, p.Porter)
    85  	require.NoError(p.T(), err, "validation of archive opts for bundle failed")
    86  	err = p.Archive(ctx, archive3Opts)
    87  	require.NoError(t, err, "archive from the published bundle in local registry failed")
    88  }
    89  
    90  func getHash(p *porter.TestPorter, path string) string {
    91  	f, err := p.FileSystem.Open(path)
    92  	require.NoError(p.T(), err, "opening archive failed")
    93  	defer f.Close()
    94  
    95  	h := sha256.New()
    96  	_, err = io.Copy(h, f)
    97  	require.NoError(p.T(), err, "hashing of archive failed")
    98  
    99  	return fmt.Sprintf("%x", h.Sum(nil))
   100  }
   101  
   102  // Validate that a bundle archived with NoCompression can be published
   103  func TestArchive_WithNoCompression(t *testing.T) {
   104  	t.Parallel()
   105  	p := porter.NewTestPorter(t)
   106  	defer p.Close()
   107  	ctx := p.SetupIntegrationTest()
   108  
   109  	// Use a fixed bundle to work with so that we can rely on the registry and layer digests
   110  	const reference = "ghcr.io/getporter/examples/whalegap:v0.2.0"
   111  
   112  	// Archive bundle
   113  	archiveOpts := porter.ArchiveOptions{}
   114  	archiveOpts.Reference = reference
   115  	archiveOpts.CompressionLevel = "NoCompression"
   116  	archiveFile := "mybuns1nocomp.tgz"
   117  	err := archiveOpts.Validate(ctx, []string{archiveFile}, p.Porter)
   118  	require.NoError(p.T(), err, "validation of archive opts for bundle failed")
   119  
   120  	err = p.Archive(ctx, archiveOpts)
   121  	require.NoError(p.T(), err, "archival of bundle failed")
   122  
   123  	hash := getHash(p, archiveFile)
   124  
   125  	// different compressions yields different (but consistent) hashes
   126  	consistentHash := "191a249d861f41492ee568080a063718ad77e9b18ad0672cbf4fc2f0e4d1c07c"
   127  	assert.Equal(p.T(), consistentHash, hash, "shasum of archive did not match expected hash")
   128  
   129  	// Publish bundle from archive, with new reference
   130  	localReference := "localhost:5000/archived-nocompression-whalegap:v0.2.0"
   131  	publishFromArchiveOpts := porter.PublishOptions{
   132  		ArchiveFile: archiveFile,
   133  		BundlePullOptions: porter.BundlePullOptions{
   134  			Reference: localReference,
   135  		},
   136  	}
   137  	err = publishFromArchiveOpts.Validate(p.Config)
   138  	require.NoError(p.T(), err, "validation of publish opts for bundle failed")
   139  
   140  	err = p.Publish(ctx, publishFromArchiveOpts)
   141  	require.NoError(p.T(), err, "publish of bundle from archive failed")
   142  }