github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/internal/file/zip_file_helpers_test.go (about)

     1  package file
     2  
     3  import (
     4  	"os"
     5  	"os/exec"
     6  	"path"
     7  	"path/filepath"
     8  	"syscall"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  var expectedZipArchiveEntries = []string{
    15  	"some-dir" + string(os.PathSeparator),
    16  	filepath.Join("some-dir", "a-file.txt"),
    17  	"b-file.txt",
    18  	"nested.zip",
    19  }
    20  
    21  // createZipArchive creates a new ZIP archive file at destinationArchivePath based on the directory found at
    22  // sourceDirPath. It forces a zip64 archive if zip64 is "0".
    23  func createZipArchive(t testing.TB, sourceDirPath, destinationArchivePath string, zip64 bool) {
    24  	t.Helper()
    25  
    26  	cwd, err := os.Getwd()
    27  	if err != nil {
    28  		t.Fatalf("unable to get cwd: %+v", err)
    29  	}
    30  	zip64Arg := "0"
    31  	if zip64 {
    32  		zip64Arg = "1"
    33  	}
    34  
    35  	cmd := exec.Command("./generate-zip-fixture-from-source-dir.sh", destinationArchivePath, path.Base(sourceDirPath), zip64Arg)
    36  	cmd.Dir = filepath.Join(cwd, "test-fixtures")
    37  
    38  	if err := cmd.Start(); err != nil {
    39  		t.Fatalf("unable to start generate zip fixture script: %+v", err)
    40  	}
    41  
    42  	if err := cmd.Wait(); err != nil {
    43  		if exiterr, ok := err.(*exec.ExitError); ok {
    44  			// The program has exited with an exit code != 0
    45  
    46  			// This works on both Unix and Windows. Although package
    47  			// syscall is generally platform dependent, WaitStatus is
    48  			// defined for both Unix and Windows and in both cases has
    49  			// an ExitStatus() method with the same signature.
    50  			if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
    51  				if status.ExitStatus() != 0 {
    52  					t.Fatalf("failed to generate fixture: rc=%d", status.ExitStatus())
    53  				}
    54  			}
    55  		} else {
    56  			t.Fatalf("unable to get generate fixture script result: %+v", err)
    57  		}
    58  	}
    59  
    60  }
    61  
    62  func assertNoError(t testing.TB, fn func() error) func() {
    63  	return func() {
    64  		assert.NoError(t, fn())
    65  	}
    66  }
    67  
    68  // setupZipFileTest encapsulates common test setup work for zip file tests. It returns a cleanup function,
    69  // which should be called (typically deferred) by the caller, the path of the created zip archive, and an error,
    70  // which should trigger a fatal test failure in the consuming test. The returned cleanup function will never be nil
    71  // (even if there's an error), and it should always be called.
    72  func setupZipFileTest(t testing.TB, sourceDirPath string, zip64 bool) string {
    73  	t.Helper()
    74  
    75  	archivePrefix := path.Join(t.TempDir(), "syft-ziputil-archive-TEST-")
    76  	destinationArchiveFilePath := archivePrefix + ".zip"
    77  	t.Logf("archive path: %s", destinationArchiveFilePath)
    78  	createZipArchive(t, sourceDirPath, destinationArchiveFilePath, zip64)
    79  
    80  	cwd, err := os.Getwd()
    81  	if err != nil {
    82  		t.Fatalf("unable to get cwd: %+v", err)
    83  	}
    84  
    85  	t.Logf("running from: %s", cwd)
    86  
    87  	return destinationArchiveFilePath
    88  }
    89  
    90  // TODO: Consider moving any non-git asset generation to a task (e.g. make) that's run ahead of running go tests.
    91  func ensureNestedZipExists(t *testing.T, sourceDirPath string) error {
    92  	t.Helper()
    93  
    94  	nestedArchiveFilePath := path.Join(sourceDirPath, "nested.zip")
    95  	createZipArchive(t, sourceDirPath, nestedArchiveFilePath, false)
    96  
    97  	return nil
    98  }