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 }