mirror of
https://github.com/anchore/syft.git
synced 2025-11-18 00:43:20 +01:00
* Refactor zip file tests Signed-off-by: Dan Luhring <dan.luhring@anchore.com> * Add glob support for leading slashes Signed-off-by: Dan Luhring <dan.luhring@anchore.com> * Update zip testing to account for glob matching Signed-off-by: Dan Luhring <dan.luhring@anchore.com> * Ignore .DS_STORE Signed-off-by: Dan Luhring <dan.luhring@anchore.com> * Improve normalization of zip entry names Signed-off-by: Dan Luhring <dan.luhring@anchore.com> * Rename zip test helpers file Signed-off-by: Dan Luhring <dan.luhring@anchore.com>
132 lines
3.7 KiB
Go
132 lines
3.7 KiB
Go
package file
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"path/filepath"
|
|
"syscall"
|
|
"testing"
|
|
)
|
|
|
|
var expectedZipArchiveEntries = []string{
|
|
"some-dir" + string(os.PathSeparator),
|
|
filepath.Join("some-dir", "a-file.txt"),
|
|
"b-file.txt",
|
|
"nested.zip",
|
|
}
|
|
|
|
// fatalIfError calls the supplied function. If the function returns a non-nil error, t.Fatal(err) is called.
|
|
func fatalIfError(t *testing.T, fn func() error) {
|
|
t.Helper()
|
|
|
|
if fn == nil {
|
|
return
|
|
}
|
|
|
|
err := fn()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// createZipArchive creates a new ZIP archive file at destinationArchivePath based on the directory found at
|
|
// sourceDirPath.
|
|
func createZipArchive(t *testing.T, sourceDirPath, destinationArchivePath string) error {
|
|
t.Helper()
|
|
|
|
cwd, err := os.Getwd()
|
|
if err != nil {
|
|
return fmt.Errorf("unable to get cwd: %+v", err)
|
|
}
|
|
|
|
cmd := exec.Command("./generate-zip-fixture.sh", destinationArchivePath, path.Base(sourceDirPath))
|
|
cmd.Dir = filepath.Join(cwd, "test-fixtures")
|
|
|
|
if err := cmd.Start(); err != nil {
|
|
return fmt.Errorf("unable to start generate zip fixture script: %+v", err)
|
|
}
|
|
|
|
if err := cmd.Wait(); err != nil {
|
|
if exiterr, ok := err.(*exec.ExitError); ok {
|
|
// The program has exited with an exit code != 0
|
|
|
|
// This works on both Unix and Windows. Although package
|
|
// syscall is generally platform dependent, WaitStatus is
|
|
// defined for both Unix and Windows and in both cases has
|
|
// an ExitStatus() method with the same signature.
|
|
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
|
if status.ExitStatus() != 0 {
|
|
return fmt.Errorf("failed to generate fixture: rc=%d", status.ExitStatus())
|
|
}
|
|
}
|
|
} else {
|
|
return fmt.Errorf("unable to get generate fixture script result: %+v", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// setupZipFileTest encapsulates common test setup work for zip file tests. It returns a cleanup function,
|
|
// which should be called (typically deferred) by the caller, the path of the created zip archive, and an error,
|
|
// which should trigger a fatal test failure in the consuming test. The returned cleanup function will never be nil
|
|
// (even if there's an error), and it should always be called.
|
|
func setupZipFileTest(t *testing.T, sourceDirPath string) (func() error, string, error) {
|
|
t.Helper()
|
|
|
|
// Keep track of any needed cleanup work as we go
|
|
var cleanupFns []func() error
|
|
cleanup := func(fns []func() error) func() error {
|
|
return func() error {
|
|
for _, fn := range fns {
|
|
err := fn()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
}
|
|
|
|
archivePrefix, err := ioutil.TempFile("", "syft-ziputil-archive-TEST-")
|
|
if err != nil {
|
|
return cleanup(cleanupFns), "", fmt.Errorf("unable to create tempfile: %+v", err)
|
|
}
|
|
cleanupFns = append(cleanupFns, func() error { return os.Remove(archivePrefix.Name()) })
|
|
|
|
destinationArchiveFilePath := archivePrefix.Name() + ".zip"
|
|
t.Logf("archive path: %s", destinationArchiveFilePath)
|
|
err = createZipArchive(t, sourceDirPath, destinationArchiveFilePath)
|
|
cleanupFns = append(cleanupFns, func() error { return os.Remove(destinationArchiveFilePath) })
|
|
if err != nil {
|
|
return cleanup(cleanupFns), "", err
|
|
}
|
|
|
|
cwd, err := os.Getwd()
|
|
if err != nil {
|
|
return cleanup(cleanupFns), "", fmt.Errorf("unable to get cwd: %+v", err)
|
|
}
|
|
|
|
t.Logf("running from: %s", cwd)
|
|
|
|
return cleanup(cleanupFns), destinationArchiveFilePath, nil
|
|
}
|
|
|
|
// TODO: Consider moving any non-git asset generation to a task (e.g. make) that's run ahead of running go tests.
|
|
func ensureNestedZipExists(t *testing.T, sourceDirPath string) error {
|
|
t.Helper()
|
|
|
|
nestedArchiveFilePath := path.Join(sourceDirPath, "nested.zip")
|
|
err := createZipArchive(t, sourceDirPath, nestedArchiveFilePath)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("unable to create nested archive for test fixture: %+v", err)
|
|
}
|
|
|
|
return nil
|
|
}
|