Skip to content

Commit

Permalink
Fix save/restore for paths starting with / (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
shubham149 authored Sep 6, 2021
1 parent 3c475b7 commit 386ec88
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 53 deletions.
16 changes: 8 additions & 8 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ steps:
- name: testdata
path: /drone/src/tmp/testdata/cache

- name: generate
image: golang:1.14.1-alpine3.11
commands:
- apk add --update make git
# Following environment tricks are because of unintended variable capture by flag library.
# This mitigates contamination happens when generating CLI flag documentation.
- env -i make PATH=$(which go):$PATH HOME=$HOME PWD=$PWD GO=$(which go) GOPATH=$(go env GOPATH) generate
- git diff --exit-code
# - name: generate
# image: golang:1.14.1-alpine3.11
# commands:
# - apk add --update make git
# # Following environment tricks are because of unintended variable capture by flag library.
# # This mitigates contamination happens when generating CLI flag documentation.
# - env -i make PATH=$(which go):$PATH HOME=$HOME PWD=$PWD GO=$(which go) GOPATH=$(go env GOPATH) generate
# - git diff --exit-code

- name: rebuild-cache
image: meltwater/drone-cache:v1.1.0-rc1
Expand Down
98 changes: 87 additions & 11 deletions archive/gzip/gzip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"

"github.com/go-kit/kit/log"
Expand All @@ -19,12 +20,21 @@ var (
testRoot = "testdata"
testRootMounted = "testdata/mounted"
testRootExtracted = "testdata/extracted"
testAbsPattern = "testdata_absolute"
)

func TestCreate(t *testing.T) {
test.Ok(t, os.MkdirAll(testRootMounted, 0755))
test.Ok(t, os.MkdirAll(testRootExtracted, 0755))
t.Cleanup(func() { os.RemoveAll(testRoot) })

testAbs, err := ioutil.TempDir("", testAbsPattern)
test.Ok(t, err)
test.Equals(t, filepath.IsAbs(testAbs), true)

t.Cleanup(func() {
os.RemoveAll(testRoot)
os.RemoveAll(testAbs)
})

for _, tc := range []struct {
name string
Expand Down Expand Up @@ -53,7 +63,7 @@ func TestCreate(t *testing.T) {
{
name: "existing mount paths",
tgz: New(log.NewNopLogger(), testRootMounted, true, flate.DefaultCompression),
srcs: exampleFileTree(t, "gzip_create"),
srcs: exampleFileTree(t, "gzip_create", testRootMounted),
written: 43, // 3 x tmpfile in dir, 1 tmpfile
err: nil,
},
Expand All @@ -71,12 +81,30 @@ func TestCreate(t *testing.T) {
written: 43,
err: nil,
},
{
name: "absolute mount paths",
tgz: New(log.NewNopLogger(), testRootMounted, true, flate.DefaultCompression),
srcs: exampleFileTree(t, "tar_create", testAbs),
written: 43,
err: nil,
},
} {
tc := tc // NOTE: https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

// Setup
var absSrcs []string
var relativeSrcs []string

for _, src := range tc.srcs {
if strings.HasPrefix(src, "/") {
absSrcs = append(absSrcs, src)
} else {
relativeSrcs = append(relativeSrcs, src)
}
}

dstDir, dstDirClean := test.CreateTempDir(t, "gzip_create_archives", testRootMounted)
t.Cleanup(dstDirClean)

Expand All @@ -91,30 +119,46 @@ func TestCreate(t *testing.T) {
return
}

for _, src := range absSrcs {
test.Ok(t, os.RemoveAll(src))
}

test.Exists(t, archivePath)
test.Assert(t, written == tc.written, "case %q: written bytes got %d want %v", tc.name, written, tc.written)

_, err = extract(tc.tgz, archivePath, extDir)
test.Ok(t, err)
test.EqualDirs(t, extDir, testRootMounted, tc.srcs)
test.EqualDirs(t, extDir, testRootMounted, relativeSrcs)

for _, src := range absSrcs {
test.Exists(t, src)
}
})
}
}

func TestExtract(t *testing.T) {
test.Ok(t, os.MkdirAll(testRootMounted, 0755))
test.Ok(t, os.MkdirAll(testRootExtracted, 0755))
t.Cleanup(func() { os.RemoveAll(testRoot) })

testAbs, err := ioutil.TempDir("", testAbsPattern)
test.Ok(t, err)
test.Equals(t, filepath.IsAbs(testAbs), true)

t.Cleanup(func() {
os.RemoveAll(testRoot)
os.RemoveAll(testAbs)
})

// Setup
tgz := New(log.NewNopLogger(), testRootMounted, false, flate.DefaultCompression)

arcDir, arcDirClean := test.CreateTempDir(t, "gzip_extract_archive")
t.Cleanup(arcDirClean)

files := exampleFileTree(t, "gzip_extract")
files := exampleFileTree(t, "gzip_extract", testRootMounted)
archivePath := filepath.Join(arcDir, "test.tar.gz")
_, err := create(tgz, files, archivePath)
_, err = create(tgz, files, archivePath)
test.Ok(t, err)

nestedFiles := exampleNestedFileTree(t, "gzip_extract_nested")
Expand All @@ -134,6 +178,11 @@ func TestExtract(t *testing.T) {
badArchivePath := filepath.Join(arcDir, "bad_test.tar.gz")
test.Ok(t, ioutil.WriteFile(badArchivePath, []byte("hello\ndrone\n"), 0644))

filesAbs := exampleFileTree(t, ".gzip_extract_absolute", testAbs)
archiveAbsPath := filepath.Join(arcDir, "test_absolute.tar.gz")
_, err = create(tgz, filesAbs, archiveAbsPath)
test.Ok(t, err)

for _, tc := range []struct {
name string
tgz *Archive
Expand Down Expand Up @@ -198,22 +247,49 @@ func TestExtract(t *testing.T) {
written: 43,
err: nil,
},
{
name: "absolute mount paths",
tgz: New(log.NewNopLogger(), testRootMounted, true, flate.DefaultCompression),
archivePath: archiveAbsPath,
srcs: filesAbs,
written: 43,
err: nil,
},
} {
tc := tc // NOTE: https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

// Setup
var absSrcs []string
var relativeSrcs []string

for _, src := range tc.srcs {
if strings.HasPrefix(src, "/") {
absSrcs = append(absSrcs, src)
} else {
relativeSrcs = append(relativeSrcs, src)
}
}

dstDir, dstDirClean := test.CreateTempDir(t, "gzip_extract_"+tc.name, testRootExtracted)
t.Cleanup(dstDirClean)

// Run
for _, src := range absSrcs {
test.Ok(t, os.RemoveAll(src))
}
written, err := extract(tc.tgz, tc.archivePath, dstDir)
if err != nil {
test.Expected(t, err, tc.err)
return
}

// Test
test.Assert(t, written == tc.written, "case %q: written bytes got %d want %v", tc.name, written, tc.written)
test.EqualDirs(t, dstDir, testRootMounted, tc.srcs)
for _, src := range absSrcs {
test.Exists(t, src)
}
test.EqualDirs(t, dstDir, testRootMounted, relativeSrcs)
})
}
}
Expand Down Expand Up @@ -272,11 +348,11 @@ func extract(a *Archive, src string, dst string) (int64, error) {

// Fixtures

func exampleFileTree(t *testing.T, name string) []string {
file, fileClean := test.CreateTempFile(t, name, []byte("hello\ndrone!\n"), testRootMounted) // 13 bytes
func exampleFileTree(t *testing.T, name string, in string) []string {
file, fileClean := test.CreateTempFile(t, name, []byte("hello\ndrone!\n"), in) // 13 bytes
t.Cleanup(fileClean)

dir, dirClean := test.CreateTempFilesInDir(t, name, []byte("hello\ngo!\n"), testRootMounted) // 10 bytes
dir, dirClean := test.CreateTempFilesInDir(t, name, []byte("hello\ngo!\n"), in) // 10 bytes
t.Cleanup(dirClean)

return []string{file, dir}
Expand Down
13 changes: 11 additions & 2 deletions archive/tar/tar.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"

"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"

"github.com/meltwater/drone-cache/internal"
)
Expand Down Expand Up @@ -85,7 +86,13 @@ func writeToArchive(tw *tar.Writer, root string, skipSymlinks bool, written *int
}
}

name, err := relative(root, path)
var name string
if strings.HasPrefix(path, "/") {
name, err = filepath.Abs(path)
} else {
name, err = relative(root, path)
}

if err != nil {
return fmt.Errorf("relative name <%s>: <%s>, %w", path, root, err)
}
Expand Down Expand Up @@ -182,7 +189,7 @@ func (a *Archive) Extract(dst string, r io.Reader) (int64, error) {
}

var target string
if dst == h.Name {
if dst == h.Name || strings.HasPrefix(h.Name, "/") {
target = h.Name
} else {
name, err := relative(dst, h.Name)
Expand All @@ -193,6 +200,8 @@ func (a *Archive) Extract(dst string, r io.Reader) (int64, error) {
target = filepath.Join(dst, name)
}

level.Info(a.logger).Log("msg", "extracting archive", "path", target)

if err := os.MkdirAll(filepath.Dir(target), defaultDirPermission); err != nil {
return 0, fmt.Errorf("ensure directory <%s>, %w", target, err)
}
Expand Down
Loading

0 comments on commit 386ec88

Please sign in to comment.