undocker/rootfs/rootfs_test.go

191 lines
4.6 KiB
Go
Raw Normal View History

2021-05-24 00:11:57 +03:00
package rootfs
import (
"bytes"
"testing"
2021-05-24 00:11:57 +03:00
2021-05-24 00:11:58 +03:00
"github.com/motiejus/code/undocker/rootfs/rootfstest"
2021-05-24 00:11:57 +03:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
2021-05-24 00:11:57 +03:00
)
2021-05-24 00:11:58 +03:00
type (
file = rootfstest.File
dir = rootfstest.Dir
hardlink = rootfstest.Hardlink
manifest = rootfstest.Manifest
extractable = rootfstest.Extractable
tarball = rootfstest.Tarball
)
var (
extract = rootfstest.Extract
)
2021-05-24 00:11:58 +03:00
func TestRootFS(t *testing.T) {
layer0 := tarball{
2021-05-24 00:11:58 +03:00
dir{Name: "/", Uid: 0},
file{Name: "/file", Uid: 0, Contents: bytes.NewBufferString("from 0")},
2021-05-24 00:11:58 +03:00
}
layer1 := tarball{
2021-05-24 00:11:58 +03:00
file{Name: "/file", Uid: 1, Contents: bytes.NewBufferString("from 1")},
2021-05-24 00:11:58 +03:00
}
layer2 := tarball{
2021-05-24 00:11:58 +03:00
dir{Name: "/", Uid: 2},
2021-05-24 00:11:58 +03:00
}
tests := []struct {
name string
image tarball
want []extractable
wantErr string
}{
{
name: "empty tarball",
image: tarball{manifest{}},
want: []extractable{},
},
{
name: "missing layer",
image: tarball{manifest{"layer0/layer.tar"}},
wantErr: "bad or missing manifest.json",
},
{
name: "basic file overwrite, layer order mixed",
image: tarball{
2021-05-24 00:11:58 +03:00
file{Name: "layer1/layer.tar", Contents: layer1.Buffer()},
file{Name: "layer0/layer.tar", Contents: layer0.Buffer()},
2021-05-24 00:11:58 +03:00
manifest{"layer0/layer.tar", "layer1/layer.tar"},
},
want: []extractable{
2021-05-24 00:11:58 +03:00
dir{Name: "/", Uid: 0},
file{Name: "/file", Uid: 1, Contents: bytes.NewBufferString("from 1")},
2021-05-24 00:11:58 +03:00
},
},
2021-05-24 00:11:58 +03:00
{
name: "overwrite file with hardlink",
image: tarball{
file{Name: "layer0/layer.tar", Contents: tarball{
file{Name: "a"},
2021-05-24 00:11:58 +03:00
}.Buffer()},
2021-05-24 00:11:58 +03:00
file{Name: "layer1/layer.tar", Contents: tarball{
hardlink{Name: "a"},
2021-05-24 00:11:58 +03:00
}.Buffer()},
2021-05-24 00:11:58 +03:00
manifest{"layer0/layer.tar", "layer1/layer.tar"},
},
want: []extractable{
hardlink{Name: "a"},
},
},
2021-05-24 00:11:58 +03:00
{
name: "directory overwrite retains original dir",
image: tarball{
2021-05-24 00:11:58 +03:00
file{Name: "layer2/layer.tar", Contents: layer2.Buffer()},
file{Name: "layer0/layer.tar", Contents: layer0.Buffer()},
file{Name: "layer1/layer.tar", Contents: layer1.Buffer()},
2021-05-24 00:11:58 +03:00
manifest{"layer0/layer.tar", "layer1/layer.tar", "layer2/layer.tar"},
},
want: []extractable{
2021-05-24 00:11:58 +03:00
dir{Name: "/", Uid: 0},
file{Name: "/file", Uid: 1, Contents: bytes.NewBufferString("from 1")},
dir{Name: "/", Uid: 2},
2021-05-24 00:11:58 +03:00
},
},
2021-05-24 00:11:58 +03:00
{
name: "simple whiteout",
image: tarball{
2021-05-24 00:11:58 +03:00
file{Name: "layer0/layer.tar", Contents: tarball{
file{Name: "filea"},
file{Name: "fileb"},
dir{Name: "dira"},
dir{Name: "dirb"},
2021-05-24 00:11:58 +03:00
}.Buffer()},
2021-05-24 00:11:58 +03:00
file{Name: "layer1/layer.tar", Contents: tarball{
hardlink{Name: ".wh.filea"},
hardlink{Name: ".wh.dira"},
2021-05-24 00:11:58 +03:00
}.Buffer()},
2021-05-24 00:11:58 +03:00
manifest{"layer0/layer.tar", "layer1/layer.tar"},
},
want: []extractable{
2021-05-24 00:11:58 +03:00
file{Name: "fileb"},
dir{Name: "dirb"},
2021-05-24 00:11:58 +03:00
},
},
{
name: "whiteout with override",
image: tarball{
2021-05-24 00:11:58 +03:00
file{Name: "layer0/layer.tar", Contents: tarball{
file{Name: "file", Contents: bytes.NewBufferString("from 0")},
2021-05-24 00:11:58 +03:00
}.Buffer()},
2021-05-24 00:11:58 +03:00
file{Name: "layer1/layer.tar", Contents: tarball{
hardlink{Name: ".wh.file"},
2021-05-24 00:11:58 +03:00
}.Buffer()},
2021-05-24 00:11:58 +03:00
file{Name: "layer2/layer.tar", Contents: tarball{
file{Name: "file", Contents: bytes.NewBufferString("from 3")},
2021-05-24 00:11:58 +03:00
}.Buffer()},
2021-05-24 00:11:58 +03:00
manifest{
"layer0/layer.tar",
"layer1/layer.tar",
"layer2/layer.tar",
},
},
want: []extractable{
2021-05-24 00:11:58 +03:00
file{Name: "file", Contents: bytes.NewBufferString("from 3")},
2021-05-24 00:11:58 +03:00
},
},
{
2021-05-24 00:11:58 +03:00
name: "directories do not whiteout",
2021-05-24 00:11:58 +03:00
image: tarball{
2021-05-24 00:11:58 +03:00
file{Name: "layer0/layer.tar", Contents: tarball{
dir{Name: "dir"},
2021-05-24 00:11:58 +03:00
}.Buffer()},
2021-05-24 00:11:58 +03:00
file{Name: "layer1/layer.tar", Contents: tarball{
dir{Name: ".wh.dir"},
2021-05-24 00:11:58 +03:00
}.Buffer()},
2021-05-24 00:11:58 +03:00
manifest{"layer0/layer.tar", "layer1/layer.tar"},
2021-05-24 00:11:58 +03:00
},
want: []extractable{
2021-05-24 00:11:58 +03:00
dir{Name: "dir"},
dir{Name: ".wh.dir"},
2021-05-24 00:11:58 +03:00
},
},
{
name: "simple readdir whiteout",
image: tarball{
2021-05-24 00:11:58 +03:00
file{Name: "layer0/layer.tar", Contents: tarball{
dir{Name: "a"},
file{Name: "a/filea"},
2021-05-24 00:11:58 +03:00
}.Buffer()},
2021-05-24 00:11:58 +03:00
file{Name: "layer1/layer.tar", Contents: tarball{
dir{Name: "a"},
file{Name: "a/fileb"},
hardlink{Name: "a/.wh..wh..opq"},
2021-05-24 00:11:58 +03:00
}.Buffer()},
2021-05-24 00:11:58 +03:00
manifest{"layer0/layer.tar", "layer1/layer.tar"},
},
want: []extractable{
2021-05-24 00:11:58 +03:00
dir{Name: "a"},
file{Name: "a/fileb"},
2021-05-24 00:11:58 +03:00
},
},
2021-05-24 00:11:58 +03:00
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
2021-05-24 00:11:58 +03:00
in := bytes.NewReader(tt.image.Buffer().Bytes())
2021-05-24 00:11:58 +03:00
out := bytes.Buffer{}
2021-05-24 00:11:58 +03:00
err := New(in).WriteTo(&out)
2021-05-24 00:11:58 +03:00
if tt.wantErr != "" {
assert.EqualError(t, err, tt.wantErr)
return
}
require.NoError(t, err)
got := extract(t, &out)
2021-05-24 00:11:58 +03:00
assert.Equal(t, tt.want, got)
2021-05-24 00:11:58 +03:00
})
}
}