c0c146fc82
Both of these were deprecated in55f675811a
, but the format of the GoDoc comments didn't follow the correct format, which caused them not being picked up by tools as "deprecated". This patch updates uses in the codebase to use the alternatives. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> (cherry picked from commit0f7c9cd27e
) Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
266 lines
6.3 KiB
Go
266 lines
6.3 KiB
Go
package image // import "github.com/docker/docker/image"
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/opencontainers/go-digest"
|
|
"gotest.tools/v3/assert"
|
|
is "gotest.tools/v3/assert/cmp"
|
|
)
|
|
|
|
func defaultFSStoreBackend(t *testing.T) (StoreBackend, func()) {
|
|
tmpdir, err := os.MkdirTemp("", "images-fs-store")
|
|
assert.Check(t, err)
|
|
|
|
fsBackend, err := NewFSStoreBackend(tmpdir)
|
|
assert.Check(t, err)
|
|
|
|
return fsBackend, func() { os.RemoveAll(tmpdir) }
|
|
}
|
|
|
|
func TestFSGetInvalidData(t *testing.T) {
|
|
store, cleanup := defaultFSStoreBackend(t)
|
|
defer cleanup()
|
|
|
|
dgst, err := store.Set([]byte("foobar"))
|
|
assert.Check(t, err)
|
|
|
|
err = os.WriteFile(filepath.Join(store.(*fs).root, contentDirName, string(dgst.Algorithm()), dgst.Encoded()), []byte("foobar2"), 0o600)
|
|
assert.Check(t, err)
|
|
|
|
_, err = store.Get(dgst)
|
|
assert.Check(t, is.ErrorContains(err, "failed to verify"))
|
|
}
|
|
|
|
func TestFSInvalidSet(t *testing.T) {
|
|
store, cleanup := defaultFSStoreBackend(t)
|
|
defer cleanup()
|
|
|
|
id := digest.FromBytes([]byte("foobar"))
|
|
err := os.Mkdir(filepath.Join(store.(*fs).root, contentDirName, string(id.Algorithm()), id.Encoded()), 0o700)
|
|
assert.Check(t, err)
|
|
|
|
_, err = store.Set([]byte("foobar"))
|
|
assert.Check(t, is.ErrorContains(err, "failed to write digest data"))
|
|
}
|
|
|
|
func TestFSInvalidRoot(t *testing.T) {
|
|
tmpdir, err := os.MkdirTemp("", "images-fs-store")
|
|
assert.Check(t, err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
tcases := []struct {
|
|
root, invalidFile string
|
|
}{
|
|
{"root", "root"},
|
|
{"root", "root/content"},
|
|
{"root", "root/metadata"},
|
|
}
|
|
|
|
for _, tc := range tcases {
|
|
root := filepath.Join(tmpdir, tc.root)
|
|
filePath := filepath.Join(tmpdir, tc.invalidFile)
|
|
err := os.MkdirAll(filepath.Dir(filePath), 0700)
|
|
assert.Check(t, err)
|
|
|
|
f, err := os.Create(filePath)
|
|
assert.Check(t, err)
|
|
f.Close()
|
|
|
|
_, err = NewFSStoreBackend(root)
|
|
assert.Check(t, is.ErrorContains(err, "failed to create storage backend"))
|
|
|
|
os.RemoveAll(root)
|
|
}
|
|
}
|
|
|
|
func TestFSMetadataGetSet(t *testing.T) {
|
|
store, cleanup := defaultFSStoreBackend(t)
|
|
defer cleanup()
|
|
|
|
id, err := store.Set([]byte("foo"))
|
|
assert.Check(t, err)
|
|
|
|
id2, err := store.Set([]byte("bar"))
|
|
assert.Check(t, err)
|
|
|
|
tcases := []struct {
|
|
id digest.Digest
|
|
key string
|
|
value []byte
|
|
}{
|
|
{id, "tkey", []byte("tval1")},
|
|
{id, "tkey2", []byte("tval2")},
|
|
{id2, "tkey", []byte("tval3")},
|
|
}
|
|
|
|
for _, tc := range tcases {
|
|
err = store.SetMetadata(tc.id, tc.key, tc.value)
|
|
assert.Check(t, err)
|
|
|
|
actual, err := store.GetMetadata(tc.id, tc.key)
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, is.DeepEqual(tc.value, actual))
|
|
}
|
|
|
|
_, err = store.GetMetadata(id2, "tkey2")
|
|
assert.Check(t, is.ErrorContains(err, "failed to read metadata"))
|
|
|
|
id3 := digest.FromBytes([]byte("baz"))
|
|
err = store.SetMetadata(id3, "tkey", []byte("tval"))
|
|
assert.Check(t, is.ErrorContains(err, "failed to get digest"))
|
|
|
|
_, err = store.GetMetadata(id3, "tkey")
|
|
assert.Check(t, is.ErrorContains(err, "failed to get digest"))
|
|
}
|
|
|
|
func TestFSInvalidWalker(t *testing.T) {
|
|
store, cleanup := defaultFSStoreBackend(t)
|
|
defer cleanup()
|
|
|
|
fooID, err := store.Set([]byte("foo"))
|
|
assert.Check(t, err)
|
|
|
|
err = os.WriteFile(filepath.Join(store.(*fs).root, contentDirName, "sha256/foobar"), []byte("foobar"), 0600)
|
|
assert.Check(t, err)
|
|
|
|
n := 0
|
|
err = store.Walk(func(id digest.Digest) error {
|
|
assert.Check(t, is.Equal(fooID, id))
|
|
n++
|
|
return nil
|
|
})
|
|
assert.Check(t, err)
|
|
assert.Check(t, is.Equal(1, n))
|
|
}
|
|
|
|
func TestFSGetSet(t *testing.T) {
|
|
store, cleanup := defaultFSStoreBackend(t)
|
|
defer cleanup()
|
|
|
|
type tcase struct {
|
|
input []byte
|
|
expected digest.Digest
|
|
}
|
|
tcases := []tcase{
|
|
{[]byte("foobar"), digest.Digest("sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2")},
|
|
}
|
|
|
|
randomInput := make([]byte, 8*1024)
|
|
_, err := rand.Read(randomInput)
|
|
assert.Check(t, err)
|
|
|
|
// skipping use of digest pkg because it is used by the implementation
|
|
h := sha256.New()
|
|
_, err = h.Write(randomInput)
|
|
assert.Check(t, err)
|
|
|
|
tcases = append(tcases, tcase{
|
|
input: randomInput,
|
|
expected: digest.Digest("sha256:" + hex.EncodeToString(h.Sum(nil))),
|
|
})
|
|
|
|
for _, tc := range tcases {
|
|
id, err := store.Set(tc.input)
|
|
assert.Check(t, err)
|
|
assert.Check(t, is.Equal(tc.expected, id))
|
|
}
|
|
|
|
for _, tc := range tcases {
|
|
data, err := store.Get(tc.expected)
|
|
assert.Check(t, err)
|
|
assert.Check(t, is.DeepEqual(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"} {
|
|
_, err := store.Get(key)
|
|
assert.Check(t, is.ErrorContains(err, "failed to get digest"))
|
|
}
|
|
}
|
|
|
|
func TestFSGetEmptyData(t *testing.T) {
|
|
store, cleanup := defaultFSStoreBackend(t)
|
|
defer cleanup()
|
|
|
|
for _, emptyData := range [][]byte{nil, {}} {
|
|
_, err := store.Set(emptyData)
|
|
assert.Check(t, is.ErrorContains(err, "invalid empty data"))
|
|
}
|
|
}
|
|
|
|
func TestFSDelete(t *testing.T) {
|
|
store, cleanup := defaultFSStoreBackend(t)
|
|
defer cleanup()
|
|
|
|
id, err := store.Set([]byte("foo"))
|
|
assert.Check(t, err)
|
|
|
|
id2, err := store.Set([]byte("bar"))
|
|
assert.Check(t, err)
|
|
|
|
err = store.Delete(id)
|
|
assert.Check(t, err)
|
|
|
|
_, err = store.Get(id)
|
|
assert.Check(t, is.ErrorContains(err, "failed to get digest"))
|
|
|
|
_, err = store.Get(id2)
|
|
assert.Check(t, err)
|
|
|
|
err = store.Delete(id2)
|
|
assert.Check(t, err)
|
|
|
|
_, err = store.Get(id2)
|
|
assert.Check(t, is.ErrorContains(err, "failed to get digest"))
|
|
}
|
|
|
|
func TestFSWalker(t *testing.T) {
|
|
store, cleanup := defaultFSStoreBackend(t)
|
|
defer cleanup()
|
|
|
|
id, err := store.Set([]byte("foo"))
|
|
assert.Check(t, err)
|
|
|
|
id2, err := store.Set([]byte("bar"))
|
|
assert.Check(t, err)
|
|
|
|
tcases := make(map[digest.Digest]struct{})
|
|
tcases[id] = struct{}{}
|
|
tcases[id2] = struct{}{}
|
|
n := 0
|
|
err = store.Walk(func(id digest.Digest) error {
|
|
delete(tcases, id)
|
|
n++
|
|
return nil
|
|
})
|
|
assert.Check(t, err)
|
|
assert.Check(t, is.Equal(2, n))
|
|
assert.Check(t, is.Len(tcases, 0))
|
|
}
|
|
|
|
func TestFSWalkerStopOnError(t *testing.T) {
|
|
store, cleanup := defaultFSStoreBackend(t)
|
|
defer cleanup()
|
|
|
|
id, err := store.Set([]byte("foo"))
|
|
assert.Check(t, err)
|
|
|
|
tcases := make(map[digest.Digest]struct{})
|
|
tcases[id] = struct{}{}
|
|
err = store.Walk(func(id digest.Digest) error {
|
|
return errors.New("what")
|
|
})
|
|
assert.Check(t, is.ErrorContains(err, "what"))
|
|
}
|