Skip to content

Commit

Permalink
Merge pull request #943 from buildpacks/add-archive-tests
Browse files Browse the repository at this point in the history
Add archive tests
  • Loading branch information
jromero authored Nov 10, 2020
2 parents 79b505b + f6fddbd commit bb00e12
Show file tree
Hide file tree
Showing 4 changed files with 231 additions and 8 deletions.
3 changes: 2 additions & 1 deletion internal/archive/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ func WriteDirToTar(tw TarWriter, srcDir, basePath string, uid, gid int, mode int
return err
}

header, err = tar.FileInfoHeader(fi, target)
// Ensure that symlinks have Linux link names, independent of source OS
header, err = tar.FileInfoHeader(fi, filepath.ToSlash(target))
if err != nil {
return err
}
Expand Down
153 changes: 147 additions & 6 deletions internal/archive/archive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ import (
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"time"

"github.com/pkg/errors"

"github.com/heroku/color"
"github.com/sclevine/spec"
"github.com/sclevine/spec/report"
Expand Down Expand Up @@ -45,6 +48,56 @@ func testArchive(t *testing.T, when spec.G, it spec.S) {
}
})

when("#ReadDirAsTar", func() {
var src string
it.Before(func() {
src = filepath.Join("testdata", "dir-to-tar")
})

it("returns a TarReader of the dir", func() {
rc := archive.ReadDirAsTar(src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, nil)

tr := tar.NewReader(rc)
verify := h.NewTarVerifier(t, tr, 1234, 2345)
verify.NextFile("/nested/dir/dir-in-archive/some-file.txt", "some-content", int64(os.ModePerm))
verify.NextDirectory("/nested/dir/dir-in-archive/sub-dir", int64(os.ModePerm))
if runtime.GOOS != "windows" {
verify.NextSymLink("/nested/dir/dir-in-archive/sub-dir/link-file", "../some-file.txt")
verify.NoMoreFilesExist()
h.AssertNil(t, rc.Close())
}
})

it("returns error if closed multiple times", func() {
rc := archive.ReadDirAsTar(src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, func(s string) bool { return false })
tr := tar.NewReader(rc)
verify := h.NewTarVerifier(t, tr, 1234, 2345)
verify.NoMoreFilesExist()
h.AssertNil(t, rc.Close())
h.AssertError(t, rc.Close(), "reader already closed")
})
})

when("#ReadZipAsTar", func() {
var src string
it.Before(func() {
src = filepath.Join("testdata", "zip-to-tar.zip")
})

it("returns a TarReader of the dir", func() {
rc := archive.ReadZipAsTar(src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, nil)

tr := tar.NewReader(rc)
verify := h.NewTarVerifier(t, tr, 1234, 2345)
verify.NextFile("/nested/dir/dir-in-archive/some-file.txt", "some-content", int64(os.ModePerm))
verify.NextDirectory("/nested/dir/dir-in-archive/sub-dir", int64(os.ModePerm))
verify.NextSymLink("/nested/dir/dir-in-archive/sub-dir/link-file", "../some-file.txt")

verify.NoMoreFilesExist()
h.AssertNil(t, rc.Close())
})
})

when("#ReadTarEntry", func() {
var (
err error
Expand Down Expand Up @@ -84,6 +137,43 @@ func testArchive(t *testing.T, when spec.G, it spec.S) {
h.AssertEq(t, string(contents), "file-1 content")
})
})

when("path doesn't exist", func() {
it.Before(func() {
err = archive.CreateSingleFileTar(tarFile.Name(), "file1", "file-1 content")
h.AssertNil(t, err)
})

it("returns the file contents", func() {
_, _, err := archive.ReadTarEntry(tarFile, "file2")
h.AssertError(t, err, "could not find entry path")
h.AssertTrue(t, archive.IsEntryNotExist(err))
})
})

when("reader isn't tar", func() {
it("returns the file contents", func() {
reader := strings.NewReader("abcde")
_, _, err := archive.ReadTarEntry(reader, "file1")
h.AssertError(t, err, "get next tar entry")
})
})
})

when("#CreateSingleFileTarReader", func() {
it("returns the file contents", func() {
rc := archive.CreateSingleFileTarReader("file1", "file-1 content")
_, contents, err := archive.ReadTarEntry(rc, "file1")
h.AssertNil(t, err)
h.AssertEq(t, string(contents), "file-1 content")
})
})

when("#IsEntryNotExist", func() {
it("works", func() {
h.AssertTrue(t, archive.IsEntryNotExist(errors.Wrap(archive.ErrEntryNotExist, "something")))
h.AssertFalse(t, archive.IsEntryNotExist(errors.New("something not err not exist")))
})
})

when("#WriteDirToTar", func() {
Expand Down Expand Up @@ -146,6 +236,35 @@ func testArchive(t *testing.T, when spec.G, it spec.S) {
})
})

when("has file filter", func() {
it("does not add files against the file filter", func() {
tarFile := filepath.Join(tmpDir, "some.tar")
fh, err := os.Create(tarFile)
h.AssertNil(t, err)

tw := tar.NewWriter(fh)

err = archive.WriteDirToTar(tw, src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, func(path string) bool {
return !strings.Contains(path, "some-file.txt")
})
h.AssertNil(t, err)
h.AssertNil(t, tw.Close())
h.AssertNil(t, fh.Close())

file, err := os.Open(filepath.Join(tmpDir, "some.tar"))
h.AssertNil(t, err)
defer file.Close()

tr := tar.NewReader(file)

verify := h.NewTarVerifier(t, tr, 1234, 2345)
verify.NextDirectory("/nested/dir/dir-in-archive/sub-dir", int64(os.ModePerm))
if runtime.GOOS != "windows" {
verify.NextSymLink("/nested/dir/dir-in-archive/sub-dir/link-file", "../some-file.txt")
}
})
})

when("normalize mod time is false", func() {
it("does not normalize mod times", func() {
tarFile := filepath.Join(tmpDir, "some.tar")
Expand Down Expand Up @@ -270,9 +389,7 @@ func testArchive(t *testing.T, when spec.G, it spec.S) {
verify := h.NewTarVerifier(t, tr, 1234, 2345)
verify.NextFile("/nested/dir/dir-in-archive/some-file.txt", "some-content", 0777)
verify.NextDirectory("/nested/dir/dir-in-archive/sub-dir", 0777)
if runtime.GOOS != "windows" {
verify.NextSymLink("/nested/dir/dir-in-archive/sub-dir/link-file", "../some-file.txt")
}
verify.NextSymLink("/nested/dir/dir-in-archive/sub-dir/link-file", "../some-file.txt")
})
})

Expand All @@ -297,9 +414,7 @@ func testArchive(t *testing.T, when spec.G, it spec.S) {
verify := h.NewTarVerifier(t, tr, 1234, 2345)
verify.NextFile("/nested/dir/dir-in-archive/some-file.txt", "some-content", 0644)
verify.NextDirectory("/nested/dir/dir-in-archive/sub-dir", 0755)
if runtime.GOOS != "windows" {
verify.NextSymLink("/nested/dir/dir-in-archive/sub-dir/link-file", "../some-file.txt")
}
verify.NextSymLink("/nested/dir/dir-in-archive/sub-dir/link-file", "../some-file.txt")
})

when("files are compressed in fat (MSDOS) format", func() {
Expand Down Expand Up @@ -331,6 +446,32 @@ func testArchive(t *testing.T, when spec.G, it spec.S) {
})
})

when("has file filter", func() {
it("follows it when adding files", func() {
fh, err := os.Create(filepath.Join(tmpDir, "some.tar"))
h.AssertNil(t, err)

tw := tar.NewWriter(fh)

err = archive.WriteZipToTar(tw, src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, func(path string) bool {
return !strings.Contains(path, "some-file.txt")
})
h.AssertNil(t, err)
h.AssertNil(t, tw.Close())
h.AssertNil(t, fh.Close())

file, err := os.Open(filepath.Join(tmpDir, "some.tar"))
h.AssertNil(t, err)
defer file.Close()

tr := tar.NewReader(file)

verify := h.NewTarVerifier(t, tr, 1234, 2345)
verify.NextDirectory("/nested/dir/dir-in-archive/sub-dir", 0777)
verify.NextSymLink("/nested/dir/dir-in-archive/sub-dir/link-file", "../some-file.txt")
})
})

when("normalize mod time is false", func() {
it("does not normalize mod times", func() {
tarFile := filepath.Join(tmpDir, "some.tar")
Expand Down
80 changes: 80 additions & 0 deletions internal/archive/tar_builder_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package archive_test

import (
"archive/tar"
"io/ioutil"
"math/rand"
"os"
"path/filepath"
"testing"
"time"

"github.com/buildpacks/pack/internal/archive"

h "github.com/buildpacks/pack/testhelpers"

"github.com/heroku/color"
"github.com/sclevine/spec"
"github.com/sclevine/spec/report"
)

func TestTarBuilder(t *testing.T) {
color.Disable(true)
defer color.Disable(false)
rand.Seed(time.Now().UTC().UnixNano())
spec.Run(t, "TarBuilder", testTarBuilder, spec.Sequential(), spec.Report(report.Terminal{}))
}

func testTarBuilder(t *testing.T, when spec.G, it spec.S) {
var (
tmpDir string
tarBuilder archive.TarBuilder
)

it.Before(func() {
var err error
tmpDir, err = ioutil.TempDir("", "tar-builder-test")
h.AssertNil(t, err)
tarBuilder = archive.TarBuilder{}
})

it.After(func() {
h.AssertNil(t, os.RemoveAll(tmpDir))
})

when("#AddFile", func() {
it("adds file", func() {
tarBuilder.AddFile("file1", 0777, archive.NormalizedDateTime, []byte("file-1 content"))
reader := tarBuilder.Reader(archive.DefaultTarWriterFactory())
tr := tar.NewReader(reader)

verify := h.NewTarVerifier(t, tr, 0, 0)
verify.NextFile("file1", "file-1 content", int64(os.ModePerm))
verify.NoMoreFilesExist()
})
})

when("#AddDir", func() {
it("adds dir", func() {
tarBuilder.AddDir("path/of/dir", 0777, archive.NormalizedDateTime)
reader := tarBuilder.Reader(archive.DefaultTarWriterFactory())
tr := tar.NewReader(reader)

verify := h.NewTarVerifier(t, tr, 0, 0)
verify.NextDirectory("path/of/dir", int64(os.ModePerm))
verify.NoMoreFilesExist()
})
})

when("#WriteToPath", func() {
it("writes to path", func() {
path := filepath.Join(tmpDir, "some.txt")
h.AssertNil(t, tarBuilder.WriteToPath(path, archive.DefaultTarWriterFactory()))
})

it("fails if dir doesn't exist", func() {
path := "dir/some.txt"
h.AssertError(t, tarBuilder.WriteToPath(path, archive.DefaultTarWriterFactory()), "create file for tar")
})
})
}
3 changes: 2 additions & 1 deletion testhelpers/tar_verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,9 @@ func (v *TarVerifier) NextSymLink(name, link string) {
v.t.Fatalf(`expected %s to have Gid %d but, got: %d`, header.Name, v.gid, header.Gid)
}

// tar names and linknames should be Linux formatted paths, regardless of OS
if header.Linkname != "../some-file.txt" {
v.t.Fatalf(`expected to link-file to have target %s got: %s`, link, header.Linkname)
v.t.Fatalf(`expected link-file to have target %s got: %s`, link, header.Linkname)
}
if !header.ModTime.Equal(time.Date(1980, time.January, 1, 0, 0, 1, 0, time.UTC)) {
v.t.Fatalf(`expected %s to have been normalized, got: %s`, header.Name, header.ModTime.String())
Expand Down

0 comments on commit bb00e12

Please sign in to comment.