github.com/anchore/syft@v1.38.2/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  
    12  var expectedZipArchiveEntries = []string{
    13  	"some-dir/",
    14  	"some-dir/a-file.txt",
    15  	"b-file.txt",
    16  	"b-file/",
    17  	"b-file/in-subdir.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  // setupZipFileTest encapsulates common test setup work for zip file tests. It returns a cleanup function,
    63  // which should be called (typically deferred) by the caller, the path of the created zip archive, and an error,
    64  // which should trigger a fatal test failure in the consuming test. The returned cleanup function will never be nil
    65  // (even if there's an error), and it should always be called.
    66  func setupZipFileTest(t testing.TB, sourceDirPath string, zip64 bool) string {
    67  	t.Helper()
    68  
    69  	archivePrefix := path.Join(t.TempDir(), "syft-ziputil-archive-TEST-")
    70  	destinationArchiveFilePath := archivePrefix + ".zip"
    71  	t.Logf("archive path: %s", destinationArchiveFilePath)
    72  	createZipArchive(t, sourceDirPath, destinationArchiveFilePath, zip64)
    73  
    74  	cwd, err := os.Getwd()
    75  	if err != nil {
    76  		t.Fatalf("unable to get cwd: %+v", err)
    77  	}
    78  
    79  	t.Logf("running from: %s", cwd)
    80  
    81  	return destinationArchiveFilePath
    82  }
    83  
    84  // TODO: Consider moving any non-git asset generation to a task (e.g. make) that's run ahead of running go tests.
    85  func ensureNestedZipExists(t *testing.T, sourceDirPath string) error {
    86  	t.Helper()
    87  
    88  	nestedArchiveFilePath := path.Join(sourceDirPath, "nested.zip")
    89  	createZipArchive(t, sourceDirPath, nestedArchiveFilePath, false)
    90  
    91  	return nil
    92  }