-
Notifications
You must be signed in to change notification settings - Fork 112
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds tests for normalizing reader and writer
Signed-off-by: Emily Casey <ecasey@vmware.com>
- Loading branch information
Showing
8 changed files
with
393 additions
and
137 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package archive_test | ||
|
||
import ( | ||
"archive/tar" | ||
"io/ioutil" | ||
"math/rand" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
"time" | ||
|
||
"github.com/sclevine/spec" | ||
"github.com/sclevine/spec/report" | ||
|
||
"github.com/buildpacks/lifecycle/archive" | ||
h "github.com/buildpacks/lifecycle/testhelpers" | ||
) | ||
|
||
func TestArchiveExtract(t *testing.T) { | ||
rand.Seed(time.Now().UTC().UnixNano()) | ||
spec.Run(t, "extract", testExtract, spec.Report(report.Terminal{})) | ||
} | ||
|
||
func testExtract(t *testing.T, when spec.G, it spec.S) { | ||
var tmpDir string | ||
|
||
it.Before(func() { | ||
var err error | ||
tmpDir, err = ioutil.TempDir("", "archive-extract-test") | ||
h.AssertNil(t, err) | ||
}) | ||
|
||
it.After(func() { | ||
h.AssertNil(t, os.RemoveAll(tmpDir)) | ||
}) | ||
|
||
when("#Extract", func() { | ||
var pathModes = []archive.PathMode{ | ||
{"root", os.ModeDir + 0755}, | ||
{"root/readonly", os.ModeDir + 0500}, | ||
{"root/standarddir", os.ModeDir + 0755}, | ||
{"root/standarddir/somefile", 0644}, | ||
{"root/readonly/readonlysub/somefile", 0444}, | ||
{"root/readonly/readonlysub", os.ModeDir + 0500}, | ||
} | ||
|
||
it.After(func() { | ||
// Make all files os.ModePerm so they can all be cleaned up. | ||
for _, pathMode := range pathModes { | ||
extractedFile := filepath.Join(tmpDir, pathMode.Path) | ||
if _, err := os.Stat(extractedFile); err == nil { | ||
if err := os.Chmod(extractedFile, os.ModePerm); err != nil { | ||
h.AssertNil(t, err) | ||
} | ||
} | ||
} | ||
}) | ||
|
||
it("extracts a tar file", func() { | ||
file, err := os.Open(filepath.Join("testdata", "tar-to-dir", "some-archive.tar")) | ||
h.AssertNil(t, err) | ||
defer file.Close() | ||
|
||
tr := archive.NewNormalizingTarReader(tar.NewReader(file)) | ||
tr.PrependDir(tmpDir) | ||
h.AssertNil(t, archive.Extract(tr)) | ||
|
||
for _, pathMode := range pathModes { | ||
extractedFile := filepath.Join(tmpDir, pathMode.Path) | ||
fileInfo, err := os.Stat(extractedFile) | ||
h.AssertNil(t, err) | ||
h.AssertEq(t, fileInfo.Mode(), pathMode.Mode) | ||
} | ||
}) | ||
|
||
it("fails if file exists where directory needs to be created", func() { | ||
_, err := os.Create(filepath.Join(tmpDir, "root")) | ||
h.AssertNil(t, err) | ||
|
||
file, err := os.Open(filepath.Join("testdata", "tar-to-dir", "some-archive.tar")) | ||
h.AssertNil(t, err) | ||
defer file.Close() | ||
tr := archive.NewNormalizingTarReader(tar.NewReader(file)) | ||
tr.PrependDir(tmpDir) | ||
|
||
h.AssertError(t, archive.Extract(tr), "root: not a directory") | ||
}) | ||
|
||
it("doesn't alter permissions of existing folders", func() { | ||
h.AssertNil(t, os.Mkdir(filepath.Join(tmpDir, "root"), 0744)) | ||
// Update permissions in case umask was applied. | ||
h.AssertNil(t, os.Chmod(filepath.Join(tmpDir, "root"), 0744)) | ||
|
||
file, err := os.Open(filepath.Join("testdata", "tar-to-dir", "some-archive.tar")) | ||
h.AssertNil(t, err) | ||
defer file.Close() | ||
tr := archive.NewNormalizingTarReader(tar.NewReader(file)) | ||
tr.PrependDir(tmpDir) | ||
|
||
h.AssertNil(t, archive.Extract(tr)) | ||
fileInfo, err := os.Stat(filepath.Join(tmpDir, "root")) | ||
h.AssertNil(t, err) | ||
h.AssertEq(t, fileInfo.Mode(), os.ModeDir+0744) | ||
}) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package archive_test | ||
|
||
import ( | ||
"archive/tar" | ||
"io" | ||
"math/rand" | ||
"runtime" | ||
"testing" | ||
"time" | ||
|
||
"github.com/sclevine/spec" | ||
"github.com/sclevine/spec/report" | ||
|
||
"github.com/buildpacks/lifecycle/archive" | ||
h "github.com/buildpacks/lifecycle/testhelpers" | ||
) | ||
|
||
func TestReader(t *testing.T) { | ||
rand.Seed(time.Now().UTC().UnixNano()) | ||
spec.Run(t, "tar", testNormalizingTarReader, spec.Report(report.Terminal{})) | ||
} | ||
|
||
func testNormalizingTarReader(t *testing.T, when spec.G, it spec.S) { | ||
when("NormalizingTarWriter", func() { | ||
var ( | ||
ftr *fakeTarReader | ||
ntr *archive.NormalizingTarReader | ||
) | ||
|
||
it.Before(func() { | ||
ftr = &fakeTarReader{} | ||
ntr = archive.NewNormalizingTarReader(ftr) | ||
ftr.pushHeader(&tar.Header{Name: "some/path"}) | ||
}) | ||
|
||
when("#Strip", func() { | ||
it("removes leading dirs", func() { | ||
ntr.Strip("some") | ||
hdr, err := ntr.Next() | ||
h.AssertNil(t, err) | ||
h.AssertEq(t, hdr.Name, "/path") | ||
}) | ||
}) | ||
|
||
when("#FromSlash", func() { | ||
it("converts path separators", func() { | ||
ntr.FromSlash() | ||
hdr, err := ntr.Next() | ||
h.AssertNil(t, err) | ||
if runtime.GOOS == "windows" { | ||
h.AssertEq(t, hdr.Name, `some\path`) | ||
} else { | ||
h.AssertEq(t, hdr.Name, `some/path`) | ||
} | ||
}) | ||
}) | ||
|
||
when("#PrependDir", func() { | ||
it("prepends the dir", func() { | ||
ntr.PrependDir("/super-dir") | ||
hdr, err := ntr.Next() | ||
h.AssertNil(t, err) | ||
h.AssertEq(t, hdr.Name, `/super-dir/some/path`) | ||
}) | ||
}) | ||
|
||
when("#Exclude", func() { | ||
it("skips excluded entries", func() { | ||
ftr.pushHeader(&tar.Header{Name: "excluded-dir"}) | ||
ftr.pushHeader(&tar.Header{Name: "excluded-dir/file"}) | ||
ntr.ExcludePaths([]string{"excluded-dir"}) | ||
hdr, err := ntr.Next() | ||
h.AssertNil(t, err) | ||
h.AssertEq(t, hdr.Name, `some/path`) | ||
}) | ||
}) | ||
}) | ||
} | ||
|
||
type fakeTarReader struct { | ||
hdrs []*tar.Header | ||
} | ||
|
||
func (r *fakeTarReader) Next() (*tar.Header, error) { | ||
if len(r.hdrs) == 0 { | ||
return nil, io.EOF | ||
} | ||
hdr := r.hdrs[0] | ||
r.hdrs = r.hdrs[1:] | ||
return hdr, nil | ||
} | ||
|
||
func (r *fakeTarReader) Read(b []byte) (int, error) { | ||
return len(b), nil | ||
} | ||
|
||
func (r *fakeTarReader) pushHeader(hdr *tar.Header) { | ||
r.hdrs = append([]*tar.Header{hdr}, r.hdrs...) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package archive | ||
|
||
import ( | ||
"archive/tar" | ||
"io" | ||
"os" | ||
"path/filepath" | ||
) | ||
|
||
type PathInfo struct { | ||
Path string | ||
Info os.FileInfo | ||
} | ||
|
||
func WriteFilesToArchive(tw TarWriter, files []PathInfo) error { | ||
for _, file := range files { | ||
if err := AddFileToArchive(tw, file.Path, file.Info); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func AddFileToArchive(tw TarWriter, path string, fi os.FileInfo) error { | ||
if fi.Mode()&os.ModeSocket != 0 { | ||
return nil | ||
} | ||
var target string | ||
if fi.Mode()&os.ModeSymlink != 0 { | ||
var err error | ||
target, err = os.Readlink(path) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
header, err := tar.FileInfoHeader(fi, target) | ||
if err != nil { | ||
return err | ||
} | ||
header.Name = path | ||
|
||
if err := tw.WriteHeader(header); err != nil { | ||
return err | ||
} | ||
if fi.Mode().IsRegular() { | ||
f, err := os.Open(path) | ||
if err != nil { | ||
return err | ||
} | ||
defer f.Close() | ||
if _, err := io.Copy(tw, f); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func AddDirToArchive(tw TarWriter, srcDir string) error { | ||
srcDir = filepath.Clean(srcDir) | ||
|
||
return filepath.Walk(srcDir, func(file string, fi os.FileInfo, err error) error { | ||
if err != nil { | ||
return err | ||
} | ||
return AddFileToArchive(tw, file, fi) | ||
}) | ||
} |
Oops, something went wrong.