Use assertions in image package unit tests.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
parent
9ea5e02e92
commit
69d7362058
3 changed files with 192 additions and 451 deletions
332
image/fs_test.go
332
image/fs_test.go
|
@ -11,79 +11,51 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/docker/docker/pkg/testutil/assert"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFSGetSet(t *testing.T) {
|
func defaultFSStoreBackend(t *testing.T) (StoreBackend, func()) {
|
||||||
tmpdir, err := ioutil.TempDir("", "images-fs-store")
|
tmpdir, err := ioutil.TempDir("", "images-fs-store")
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
fs, err := NewFSStoreBackend(tmpdir)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
testGetSet(t, fs)
|
fsBackend, err := NewFSStoreBackend(tmpdir)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
return fsBackend, func() { os.RemoveAll(tmpdir) }
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFSGetInvalidData(t *testing.T) {
|
func TestFSGetInvalidData(t *testing.T) {
|
||||||
tmpdir, err := ioutil.TempDir("", "images-fs-store")
|
store, cleanup := defaultFSStoreBackend(t)
|
||||||
if err != nil {
|
defer cleanup()
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
fs, err := NewFSStoreBackend(tmpdir)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
id, err := fs.Set([]byte("foobar"))
|
id, err := store.Set([]byte("foobar"))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dgst := digest.Digest(id)
|
dgst := digest.Digest(id)
|
||||||
|
|
||||||
if err := ioutil.WriteFile(filepath.Join(tmpdir, contentDirName, string(dgst.Algorithm()), dgst.Hex()), []byte("foobar2"), 0600); err != nil {
|
err = ioutil.WriteFile(filepath.Join(store.(*fs).root, contentDirName, string(dgst.Algorithm()), dgst.Hex()), []byte("foobar2"), 0600)
|
||||||
t.Fatal(err)
|
assert.NilError(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fs.Get(id)
|
_, err = store.Get(id)
|
||||||
if err == nil {
|
assert.Error(t, err, "failed to verify")
|
||||||
t.Fatal("expected get to fail after data modification.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFSInvalidSet(t *testing.T) {
|
func TestFSInvalidSet(t *testing.T) {
|
||||||
tmpdir, err := ioutil.TempDir("", "images-fs-store")
|
store, cleanup := defaultFSStoreBackend(t)
|
||||||
if err != nil {
|
defer cleanup()
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
fs, err := NewFSStoreBackend(tmpdir)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
id := digest.FromBytes([]byte("foobar"))
|
id := digest.FromBytes([]byte("foobar"))
|
||||||
err = os.Mkdir(filepath.Join(tmpdir, contentDirName, string(id.Algorithm()), id.Hex()), 0700)
|
err := os.Mkdir(filepath.Join(store.(*fs).root, contentDirName, string(id.Algorithm()), id.Hex()), 0700)
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fs.Set([]byte("foobar"))
|
_, err = store.Set([]byte("foobar"))
|
||||||
if err == nil {
|
assert.Error(t, err, "is a directory")
|
||||||
t.Fatal("expected error from invalid filesystem data.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFSInvalidRoot(t *testing.T) {
|
func TestFSInvalidRoot(t *testing.T) {
|
||||||
tmpdir, err := ioutil.TempDir("", "images-fs-store")
|
tmpdir, err := ioutil.TempDir("", "images-fs-store")
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
tcases := []struct {
|
tcases := []struct {
|
||||||
|
@ -98,34 +70,29 @@ func TestFSInvalidRoot(t *testing.T) {
|
||||||
root := filepath.Join(tmpdir, tc.root)
|
root := filepath.Join(tmpdir, tc.root)
|
||||||
filePath := filepath.Join(tmpdir, tc.invalidFile)
|
filePath := filepath.Join(tmpdir, tc.invalidFile)
|
||||||
err := os.MkdirAll(filepath.Dir(filePath), 0700)
|
err := os.MkdirAll(filepath.Dir(filePath), 0700)
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
f, err := os.Create(filePath)
|
f, err := os.Create(filePath)
|
||||||
if err != nil {
|
defer f.Close()
|
||||||
t.Fatal(err)
|
assert.NilError(t, err)
|
||||||
}
|
|
||||||
f.Close()
|
|
||||||
|
|
||||||
_, err = NewFSStoreBackend(root)
|
_, err = NewFSStoreBackend(root)
|
||||||
if err == nil {
|
assert.Error(t, err, "not a directory")
|
||||||
t.Fatalf("expected error from root %q and invalid file %q", tc.root, tc.invalidFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
os.RemoveAll(root)
|
os.RemoveAll(root)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testMetadataGetSet(t *testing.T, store StoreBackend) {
|
func TestFSMetadataGetSet(t *testing.T) {
|
||||||
|
store, cleanup := defaultFSStoreBackend(t)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
id, err := store.Set([]byte("foo"))
|
id, err := store.Set([]byte("foo"))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
id2, err := store.Set([]byte("bar"))
|
id2, err := store.Set([]byte("bar"))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
tcases := []struct {
|
tcases := []struct {
|
||||||
id digest.Digest
|
id digest.Digest
|
||||||
|
@ -139,115 +106,51 @@ func testMetadataGetSet(t *testing.T, store StoreBackend) {
|
||||||
|
|
||||||
for _, tc := range tcases {
|
for _, tc := range tcases {
|
||||||
err = store.SetMetadata(tc.id, tc.key, tc.value)
|
err = store.SetMetadata(tc.id, tc.key, tc.value)
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual, err := store.GetMetadata(tc.id, tc.key)
|
actual, err := store.GetMetadata(tc.id, tc.key)
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if bytes.Compare(actual, tc.value) != 0 {
|
if bytes.Compare(actual, tc.value) != 0 {
|
||||||
t.Fatalf("Metadata expected %q, got %q", tc.value, actual)
|
t.Fatalf("Metadata expected %q, got %q", tc.value, actual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = store.GetMetadata(id2, "tkey2")
|
_, err = store.GetMetadata(id2, "tkey2")
|
||||||
if err == nil {
|
assert.Error(t, err, "no such file or directory")
|
||||||
t.Fatal("expected error for getting metadata for unknown key")
|
|
||||||
}
|
|
||||||
|
|
||||||
id3 := digest.FromBytes([]byte("baz"))
|
id3 := digest.FromBytes([]byte("baz"))
|
||||||
err = store.SetMetadata(id3, "tkey", []byte("tval"))
|
err = store.SetMetadata(id3, "tkey", []byte("tval"))
|
||||||
if err == nil {
|
assert.Error(t, err, "no such file or directory")
|
||||||
t.Fatal("expected error for setting metadata for unknown ID.")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = store.GetMetadata(id3, "tkey")
|
_, err = store.GetMetadata(id3, "tkey")
|
||||||
if err == nil {
|
assert.Error(t, err, "no such file or directory")
|
||||||
t.Fatal("expected error for getting metadata for unknown ID.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFSMetadataGetSet(t *testing.T) {
|
|
||||||
tmpdir, err := ioutil.TempDir("", "images-fs-store")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
fs, err := NewFSStoreBackend(tmpdir)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
testMetadataGetSet(t, fs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFSDelete(t *testing.T) {
|
|
||||||
tmpdir, err := ioutil.TempDir("", "images-fs-store")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
fs, err := NewFSStoreBackend(tmpdir)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
testDelete(t, fs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFSWalker(t *testing.T) {
|
|
||||||
tmpdir, err := ioutil.TempDir("", "images-fs-store")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
fs, err := NewFSStoreBackend(tmpdir)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
testWalker(t, fs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFSInvalidWalker(t *testing.T) {
|
func TestFSInvalidWalker(t *testing.T) {
|
||||||
tmpdir, err := ioutil.TempDir("", "images-fs-store")
|
store, cleanup := defaultFSStoreBackend(t)
|
||||||
if err != nil {
|
defer cleanup()
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
fs, err := NewFSStoreBackend(tmpdir)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fooID, err := fs.Set([]byte("foo"))
|
fooID, err := store.Set([]byte("foo"))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ioutil.WriteFile(filepath.Join(tmpdir, contentDirName, "sha256/foobar"), []byte("foobar"), 0600); err != nil {
|
err = ioutil.WriteFile(filepath.Join(store.(*fs).root, contentDirName, "sha256/foobar"), []byte("foobar"), 0600)
|
||||||
t.Fatal(err)
|
assert.NilError(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
n := 0
|
n := 0
|
||||||
err = fs.Walk(func(id digest.Digest) error {
|
err = store.Walk(func(id digest.Digest) error {
|
||||||
if id != fooID {
|
assert.Equal(t, id, fooID)
|
||||||
t.Fatalf("invalid walker ID %q, expected %q", id, fooID)
|
|
||||||
}
|
|
||||||
n++
|
n++
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatalf("invalid data should not have caused walker error, got %v", err)
|
assert.Equal(t, n, 1)
|
||||||
}
|
|
||||||
if n != 1 {
|
|
||||||
t.Fatalf("expected 1 walk initialization, got %d", n)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetSet(t *testing.T, store StoreBackend) {
|
func TestFSGetSet(t *testing.T) {
|
||||||
|
store, cleanup := defaultFSStoreBackend(t)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
type tcase struct {
|
type tcase struct {
|
||||||
input []byte
|
input []byte
|
||||||
expected digest.Digest
|
expected digest.Digest
|
||||||
|
@ -258,15 +161,13 @@ func testGetSet(t *testing.T, store StoreBackend) {
|
||||||
|
|
||||||
randomInput := make([]byte, 8*1024)
|
randomInput := make([]byte, 8*1024)
|
||||||
_, err := rand.Read(randomInput)
|
_, err := rand.Read(randomInput)
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
// skipping use of digest pkg because it is used by the implementation
|
// skipping use of digest pkg because it is used by the implementation
|
||||||
h := sha256.New()
|
h := sha256.New()
|
||||||
_, err = h.Write(randomInput)
|
_, err = h.Write(randomInput)
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
tcases = append(tcases, tcase{
|
tcases = append(tcases, tcase{
|
||||||
input: randomInput,
|
input: randomInput,
|
||||||
expected: digest.Digest("sha256:" + hex.EncodeToString(h.Sum(nil))),
|
expected: digest.Digest("sha256:" + hex.EncodeToString(h.Sum(nil))),
|
||||||
|
@ -274,83 +175,74 @@ func testGetSet(t *testing.T, store StoreBackend) {
|
||||||
|
|
||||||
for _, tc := range tcases {
|
for _, tc := range tcases {
|
||||||
id, err := store.Set([]byte(tc.input))
|
id, err := store.Set([]byte(tc.input))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
assert.Equal(t, id, tc.expected)
|
||||||
}
|
|
||||||
if id != tc.expected {
|
|
||||||
t.Fatalf("expected ID %q, got %q", tc.expected, id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, emptyData := range [][]byte{nil, {}} {
|
|
||||||
_, err := store.Set(emptyData)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal("expected error for nil input.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range tcases {
|
for _, tc := range tcases {
|
||||||
data, err := store.Get(tc.expected)
|
data, err := store.Get(tc.expected)
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if bytes.Compare(data, tc.input) != 0 {
|
if bytes.Compare(data, tc.input) != 0 {
|
||||||
t.Fatalf("expected data %q, got %q", tc.input, data)
|
t.Fatalf("expected data %q, got %q", tc.input, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFSGetUnsetKey(t *testing.T) {
|
||||||
|
store, cleanup := defaultFSStoreBackend(t)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
for _, key := range []digest.Digest{"foobar:abc", "sha256:abc", "sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2a"} {
|
for _, key := range []digest.Digest{"foobar:abc", "sha256:abc", "sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2a"} {
|
||||||
_, err := store.Get(key)
|
_, err := store.Get(key)
|
||||||
if err == nil {
|
assert.Error(t, err, "no such file or directory")
|
||||||
t.Fatalf("expected error for ID %q.", key)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDelete(t *testing.T, store StoreBackend) {
|
func TestFSGetEmptyData(t *testing.T) {
|
||||||
|
store, cleanup := defaultFSStoreBackend(t)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
for _, emptyData := range [][]byte{nil, {}} {
|
||||||
|
_, err := store.Set(emptyData)
|
||||||
|
assert.Error(t, err, "invalid empty data")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFSDelete(t *testing.T) {
|
||||||
|
store, cleanup := defaultFSStoreBackend(t)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
id, err := store.Set([]byte("foo"))
|
id, err := store.Set([]byte("foo"))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
id2, err := store.Set([]byte("bar"))
|
id2, err := store.Set([]byte("bar"))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = store.Delete(id)
|
err = store.Delete(id)
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = store.Get(id)
|
_, err = store.Get(id)
|
||||||
if err == nil {
|
assert.Error(t, err, "no such file or directory")
|
||||||
t.Fatalf("expected getting deleted item %q to fail", id)
|
|
||||||
}
|
|
||||||
_, err = store.Get(id2)
|
_, err = store.Get(id2)
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = store.Delete(id2)
|
err = store.Delete(id2)
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
_, err = store.Get(id2)
|
_, err = store.Get(id2)
|
||||||
if err == nil {
|
assert.Error(t, err, "no such file or directory")
|
||||||
t.Fatalf("expected getting deleted item %q to fail", id2)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWalker(t *testing.T, store StoreBackend) {
|
func TestFSWalker(t *testing.T) {
|
||||||
|
store, cleanup := defaultFSStoreBackend(t)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
id, err := store.Set([]byte("foo"))
|
id, err := store.Set([]byte("foo"))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
id2, err := store.Set([]byte("bar"))
|
id2, err := store.Set([]byte("bar"))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
tcases := make(map[digest.Digest]struct{})
|
tcases := make(map[digest.Digest]struct{})
|
||||||
tcases[id] = struct{}{}
|
tcases[id] = struct{}{}
|
||||||
|
@ -361,24 +253,22 @@ func testWalker(t *testing.T, store StoreBackend) {
|
||||||
n++
|
n++
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
assert.Equal(t, n, 2)
|
||||||
}
|
assert.Equal(t, len(tcases), 0)
|
||||||
|
}
|
||||||
|
|
||||||
if n != 2 {
|
func TestFSWalkerStopOnError(t *testing.T) {
|
||||||
t.Fatalf("expected 2 walk initializations, got %d", n)
|
store, cleanup := defaultFSStoreBackend(t)
|
||||||
}
|
defer cleanup()
|
||||||
if len(tcases) != 0 {
|
|
||||||
t.Fatalf("expected empty unwalked set, got %+v", tcases)
|
|
||||||
}
|
|
||||||
|
|
||||||
// stop on error
|
id, err := store.Set([]byte("foo"))
|
||||||
tcases = make(map[digest.Digest]struct{})
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
tcases := make(map[digest.Digest]struct{})
|
||||||
tcases[id] = struct{}{}
|
tcases[id] = struct{}{}
|
||||||
err = store.Walk(func(id digest.Digest) error {
|
err = store.Walk(func(id digest.Digest) error {
|
||||||
return errors.New("")
|
return errors.New("what")
|
||||||
})
|
})
|
||||||
if err == nil {
|
assert.Error(t, err, "what")
|
||||||
t.Fatalf("expected error from walker.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/docker/docker/pkg/testutil/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
const sampleImageJSON = `{
|
const sampleImageJSON = `{
|
||||||
|
@ -17,22 +19,15 @@ const sampleImageJSON = `{
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
func TestJSON(t *testing.T) {
|
func TestNewFromJSON(t *testing.T) {
|
||||||
img, err := NewFromJSON([]byte(sampleImageJSON))
|
img, err := NewFromJSON([]byte(sampleImageJSON))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
assert.Equal(t, string(img.RawJSON()), sampleImageJSON)
|
||||||
}
|
|
||||||
rawJSON := img.RawJSON()
|
|
||||||
if string(rawJSON) != sampleImageJSON {
|
|
||||||
t.Fatalf("raw JSON of config didn't match: expected %+v, got %v", sampleImageJSON, rawJSON)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInvalidJSON(t *testing.T) {
|
func TestNewFromJSONWithInvalidJSON(t *testing.T) {
|
||||||
_, err := NewFromJSON([]byte("{}"))
|
_, err := NewFromJSON([]byte("{}"))
|
||||||
if err == nil {
|
assert.Error(t, err, "invalid image JSON, no RootFS key")
|
||||||
t.Fatal("expected JSON parse error")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMarshalKeyOrder(t *testing.T) {
|
func TestMarshalKeyOrder(t *testing.T) {
|
||||||
|
@ -43,9 +38,7 @@ func TestMarshalKeyOrder(t *testing.T) {
|
||||||
Architecture: "c",
|
Architecture: "c",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expectedOrder := []string{"architecture", "author", "comment"}
|
expectedOrder := []string{"architecture", "author", "comment"}
|
||||||
var indexes []int
|
var indexes []int
|
||||||
|
|
|
@ -1,292 +1,150 @@
|
||||||
package image
|
package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/docker/layer"
|
"github.com/docker/docker/layer"
|
||||||
|
"github.com/docker/docker/pkg/testutil/assert"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRestore(t *testing.T) {
|
func TestRestore(t *testing.T) {
|
||||||
tmpdir, err := ioutil.TempDir("", "images-fs-store")
|
fs, cleanup := defaultFSStoreBackend(t)
|
||||||
if err != nil {
|
defer cleanup()
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
fs, err := NewFSStoreBackend(tmpdir)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
id1, err := fs.Set([]byte(`{"comment": "abc", "rootfs": {"type": "layers"}}`))
|
id1, err := fs.Set([]byte(`{"comment": "abc", "rootfs": {"type": "layers"}}`))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
_, err = fs.Set([]byte(`invalid`))
|
_, err = fs.Set([]byte(`invalid`))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
id2, err := fs.Set([]byte(`{"comment": "def", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`))
|
id2, err := fs.Set([]byte(`{"comment": "def", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
err = fs.SetMetadata(id2, "parent", []byte(id1))
|
err = fs.SetMetadata(id2, "parent", []byte(id1))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
is, err := NewImageStore(fs, &mockLayerGetReleaser{})
|
is, err := NewImageStore(fs, &mockLayerGetReleaser{})
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
imgs := is.Map()
|
assert.Equal(t, len(is.Map()), 2)
|
||||||
if actual, expected := len(imgs), 2; actual != expected {
|
|
||||||
t.Fatalf("invalid images length, expected 2, got %q", len(imgs))
|
|
||||||
}
|
|
||||||
|
|
||||||
img1, err := is.Get(ID(id1))
|
img1, err := is.Get(ID(id1))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
assert.Equal(t, img1.computedID, ID(id1))
|
||||||
}
|
assert.Equal(t, img1.computedID.String(), string(id1))
|
||||||
|
|
||||||
if actual, expected := img1.computedID, ID(id1); actual != expected {
|
|
||||||
t.Fatalf("invalid image ID: expected %q, got %q", expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
if actual, expected := img1.computedID.String(), string(id1); actual != expected {
|
|
||||||
t.Fatalf("invalid image ID string: expected %q, got %q", expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
img2, err := is.Get(ID(id2))
|
img2, err := is.Get(ID(id2))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
assert.Equal(t, img1.Comment, "abc")
|
||||||
}
|
assert.Equal(t, img2.Comment, "def")
|
||||||
|
|
||||||
if actual, expected := img1.Comment, "abc"; actual != expected {
|
|
||||||
t.Fatalf("invalid comment for image1: expected %q, got %q", expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
if actual, expected := img2.Comment, "def"; actual != expected {
|
|
||||||
t.Fatalf("invalid comment for image2: expected %q, got %q", expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err := is.GetParent(ID(id1))
|
p, err := is.GetParent(ID(id1))
|
||||||
if err == nil {
|
assert.Error(t, err, "no such file")
|
||||||
t.Fatal("expected error for getting parent")
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err = is.GetParent(ID(id2))
|
p, err = is.GetParent(ID(id2))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
assert.Equal(t, p, ID(id1))
|
||||||
}
|
|
||||||
if actual, expected := p, ID(id1); actual != expected {
|
|
||||||
t.Fatalf("invalid parent: expected %q, got %q", expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
children := is.Children(ID(id1))
|
children := is.Children(ID(id1))
|
||||||
if len(children) != 1 {
|
assert.Equal(t, len(children), 1)
|
||||||
t.Fatalf("invalid children length: %q", len(children))
|
assert.Equal(t, children[0], ID(id2))
|
||||||
}
|
assert.Equal(t, len(is.Heads()), 1)
|
||||||
if actual, expected := children[0], ID(id2); actual != expected {
|
|
||||||
t.Fatalf("invalid child for id1: expected %q, got %q", expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
heads := is.Heads()
|
|
||||||
if actual, expected := len(heads), 1; actual != expected {
|
|
||||||
t.Fatalf("invalid images length: expected %q, got %q", expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
sid1, err := is.Search(string(id1)[:10])
|
sid1, err := is.Search(string(id1)[:10])
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
assert.Equal(t, sid1, ID(id1))
|
||||||
}
|
|
||||||
if actual, expected := sid1, ID(id1); actual != expected {
|
|
||||||
t.Fatalf("searched ID mismatch: expected %q, got %q", expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
sid1, err = is.Search(digest.Digest(id1).Hex()[:6])
|
sid1, err = is.Search(digest.Digest(id1).Hex()[:6])
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
assert.Equal(t, sid1, ID(id1))
|
||||||
}
|
|
||||||
if actual, expected := sid1, ID(id1); actual != expected {
|
|
||||||
t.Fatalf("searched ID mismatch: expected %q, got %q", expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
invalidPattern := digest.Digest(id1).Hex()[1:6]
|
invalidPattern := digest.Digest(id1).Hex()[1:6]
|
||||||
_, err = is.Search(invalidPattern)
|
_, err = is.Search(invalidPattern)
|
||||||
if err == nil {
|
assert.Error(t, err, "No such image")
|
||||||
t.Fatalf("expected search for %q to fail", invalidPattern)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddDelete(t *testing.T) {
|
func TestAddDelete(t *testing.T) {
|
||||||
tmpdir, err := ioutil.TempDir("", "images-fs-store")
|
is, cleanup := defaultImageStore(t)
|
||||||
if err != nil {
|
defer cleanup()
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
fs, err := NewFSStoreBackend(tmpdir)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
is, err := NewImageStore(fs, &mockLayerGetReleaser{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
id1, err := is.Create([]byte(`{"comment": "abc", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`))
|
id1, err := is.Create([]byte(`{"comment": "abc", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
assert.Equal(t, id1, ID("sha256:8d25a9c45df515f9d0fe8e4a6b1c64dd3b965a84790ddbcc7954bb9bc89eb993"))
|
||||||
}
|
|
||||||
|
|
||||||
if actual, expected := id1, ID("sha256:8d25a9c45df515f9d0fe8e4a6b1c64dd3b965a84790ddbcc7954bb9bc89eb993"); actual != expected {
|
|
||||||
t.Fatalf("create ID mismatch: expected %q, got %q", expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
img, err := is.Get(id1)
|
img, err := is.Get(id1)
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
assert.Equal(t, img.Comment, "abc")
|
||||||
}
|
|
||||||
|
|
||||||
if actual, expected := img.Comment, "abc"; actual != expected {
|
|
||||||
t.Fatalf("invalid comment in image: expected %q, got %q", expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
id2, err := is.Create([]byte(`{"comment": "def", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`))
|
id2, err := is.Create([]byte(`{"comment": "def", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = is.SetParent(id2, id1)
|
err = is.SetParent(id2, id1)
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
pid1, err := is.GetParent(id2)
|
pid1, err := is.GetParent(id2)
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
assert.Equal(t, pid1, id1)
|
||||||
}
|
|
||||||
if actual, expected := pid1, id1; actual != expected {
|
|
||||||
t.Fatalf("invalid parent for image: expected %q, got %q", expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = is.Delete(id1)
|
_, err = is.Delete(id1)
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
_, err = is.Get(id1)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("expected get for deleted image %q to fail", id1)
|
|
||||||
}
|
|
||||||
_, err = is.Get(id2)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
pid1, err = is.GetParent(id2)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("expected parent check for image %q to fail, got %q", id2, pid1)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
_, err = is.Get(id1)
|
||||||
|
assert.Error(t, err, "no such file or directory")
|
||||||
|
|
||||||
|
_, err = is.Get(id2)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
_, err = is.GetParent(id2)
|
||||||
|
assert.Error(t, err, "no such file or directory")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSearchAfterDelete(t *testing.T) {
|
func TestSearchAfterDelete(t *testing.T) {
|
||||||
tmpdir, err := ioutil.TempDir("", "images-fs-store")
|
is, cleanup := defaultImageStore(t)
|
||||||
if err != nil {
|
defer cleanup()
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
fs, err := NewFSStoreBackend(tmpdir)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
is, err := NewImageStore(fs, &mockLayerGetReleaser{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
id, err := is.Create([]byte(`{"comment": "abc", "rootfs": {"type": "layers"}}`))
|
id, err := is.Create([]byte(`{"comment": "abc", "rootfs": {"type": "layers"}}`))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
id1, err := is.Search(string(id)[:15])
|
id1, err := is.Search(string(id)[:15])
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
assert.Equal(t, id1, id)
|
||||||
}
|
|
||||||
|
|
||||||
if actual, expected := id1, id; expected != actual {
|
_, err = is.Delete(id)
|
||||||
t.Fatalf("wrong id returned from search: expected %q, got %q", expected, actual)
|
assert.NilError(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := is.Delete(id); err != nil {
|
_, err = is.Search(string(id)[:15])
|
||||||
t.Fatal(err)
|
assert.Error(t, err, "No such image")
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := is.Search(string(id)[:15]); err == nil {
|
|
||||||
t.Fatal("expected search after deletion to fail")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParentReset(t *testing.T) {
|
func TestParentReset(t *testing.T) {
|
||||||
tmpdir, err := ioutil.TempDir("", "images-fs-store")
|
is, cleanup := defaultImageStore(t)
|
||||||
if err != nil {
|
defer cleanup()
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
fs, err := NewFSStoreBackend(tmpdir)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
is, err := NewImageStore(fs, &mockLayerGetReleaser{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
id, err := is.Create([]byte(`{"comment": "abc1", "rootfs": {"type": "layers"}}`))
|
id, err := is.Create([]byte(`{"comment": "abc1", "rootfs": {"type": "layers"}}`))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
id2, err := is.Create([]byte(`{"comment": "abc2", "rootfs": {"type": "layers"}}`))
|
id2, err := is.Create([]byte(`{"comment": "abc2", "rootfs": {"type": "layers"}}`))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
id3, err := is.Create([]byte(`{"comment": "abc3", "rootfs": {"type": "layers"}}`))
|
id3, err := is.Create([]byte(`{"comment": "abc3", "rootfs": {"type": "layers"}}`))
|
||||||
if err != nil {
|
assert.NilError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := is.SetParent(id, id2); err != nil {
|
assert.NilError(t, is.SetParent(id, id2))
|
||||||
t.Fatal(err)
|
assert.Equal(t, len(is.Children(id2)), 1)
|
||||||
}
|
|
||||||
|
|
||||||
ids := is.Children(id2)
|
assert.NilError(t, is.SetParent(id, id3))
|
||||||
if actual, expected := len(ids), 1; expected != actual {
|
assert.Equal(t, len(is.Children(id2)), 0)
|
||||||
t.Fatalf("wrong number of children: %d, got %d", expected, actual)
|
assert.Equal(t, len(is.Children(id3)), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := is.SetParent(id, id3); err != nil {
|
func defaultImageStore(t *testing.T) (Store, func()) {
|
||||||
t.Fatal(err)
|
fsBackend, cleanup := defaultFSStoreBackend(t)
|
||||||
}
|
|
||||||
|
|
||||||
ids = is.Children(id2)
|
store, err := NewImageStore(fsBackend, &mockLayerGetReleaser{})
|
||||||
if actual, expected := len(ids), 0; expected != actual {
|
assert.NilError(t, err)
|
||||||
t.Fatalf("wrong number of children after parent reset: %d, got %d", expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
ids = is.Children(id3)
|
|
||||||
if actual, expected := len(ids), 1; expected != actual {
|
|
||||||
t.Fatalf("wrong number of children after parent reset: %d, got %d", expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return store, cleanup
|
||||||
}
|
}
|
||||||
|
|
||||||
type mockLayerGetReleaser struct{}
|
type mockLayerGetReleaser struct{}
|
||||||
|
|
Loading…
Reference in a new issue