@@ -20,6 +20,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/docker/docker/pkg/truncindex"
|
||||
|
||||
cio "github.com/kubernetes-incubator/cri-containerd/pkg/server/io"
|
||||
"github.com/kubernetes-incubator/cri-containerd/pkg/store"
|
||||
@@ -92,7 +93,7 @@ func (c *Container) Delete() error {
|
||||
type Store struct {
|
||||
lock sync.RWMutex
|
||||
containers map[string]Container
|
||||
// TODO(random-liu): Add trunc index.
|
||||
idIndex *truncindex.TruncIndex
|
||||
}
|
||||
|
||||
// LoadStore loads containers from runtime.
|
||||
@@ -101,7 +102,10 @@ func LoadStore() *Store { return nil }
|
||||
|
||||
// NewStore creates a container store.
|
||||
func NewStore() *Store {
|
||||
return &Store{containers: make(map[string]Container)}
|
||||
return &Store{
|
||||
containers: make(map[string]Container),
|
||||
idIndex: truncindex.NewTruncIndex([]string{}),
|
||||
}
|
||||
}
|
||||
|
||||
// Add a container into the store. Returns store.ErrAlreadyExist if the
|
||||
@@ -112,6 +116,9 @@ func (s *Store) Add(c Container) error {
|
||||
if _, ok := s.containers[c.ID]; ok {
|
||||
return store.ErrAlreadyExist
|
||||
}
|
||||
if err := s.idIndex.Add(c.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
s.containers[c.ID] = c
|
||||
return nil
|
||||
}
|
||||
@@ -121,6 +128,13 @@ func (s *Store) Add(c Container) error {
|
||||
func (s *Store) Get(id string) (Container, error) {
|
||||
s.lock.RLock()
|
||||
defer s.lock.RUnlock()
|
||||
id, err := s.idIndex.Get(id)
|
||||
if err != nil {
|
||||
if err == truncindex.ErrNotExist {
|
||||
err = store.ErrNotExist
|
||||
}
|
||||
return Container{}, err
|
||||
}
|
||||
if c, ok := s.containers[id]; ok {
|
||||
return c, nil
|
||||
}
|
||||
@@ -142,5 +156,12 @@ func (s *Store) List() []Container {
|
||||
func (s *Store) Delete(id string) {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
id, err := s.idIndex.Get(id)
|
||||
if err != nil {
|
||||
// Note: The idIndex.Delete and delete doesn't handle truncated index.
|
||||
// So we need to return if there are error.
|
||||
return
|
||||
}
|
||||
s.idIndex.Delete(id) // nolint: errcheck
|
||||
delete(s.containers, id)
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import (
|
||||
)
|
||||
|
||||
func TestContainerStore(t *testing.T) {
|
||||
ids := []string{"1", "2", "3"}
|
||||
metadatas := map[string]Metadata{
|
||||
"1": {
|
||||
ID: "1",
|
||||
@@ -43,32 +42,44 @@ func TestContainerStore(t *testing.T) {
|
||||
ImageRef: "TestImage-1",
|
||||
LogPath: "/test/log/path/1",
|
||||
},
|
||||
"2": {
|
||||
ID: "2",
|
||||
Name: "Container-2",
|
||||
SandboxID: "Sandbox-2",
|
||||
"2abcd": {
|
||||
ID: "2abcd",
|
||||
Name: "Container-2abcd",
|
||||
SandboxID: "Sandbox-2abcd",
|
||||
Config: &runtime.ContainerConfig{
|
||||
Metadata: &runtime.ContainerMetadata{
|
||||
Name: "TestPod-2",
|
||||
Name: "TestPod-2abcd",
|
||||
Attempt: 2,
|
||||
},
|
||||
},
|
||||
ImageRef: "TestImage-2",
|
||||
LogPath: "/test/log/path/2",
|
||||
},
|
||||
"3": {
|
||||
ID: "3",
|
||||
Name: "Container-3",
|
||||
SandboxID: "Sandbox-3",
|
||||
"4a333": {
|
||||
ID: "4a333",
|
||||
Name: "Container-4a333",
|
||||
SandboxID: "Sandbox-4a333",
|
||||
Config: &runtime.ContainerConfig{
|
||||
Metadata: &runtime.ContainerMetadata{
|
||||
Name: "TestPod-3",
|
||||
Name: "TestPod-4a333",
|
||||
Attempt: 3,
|
||||
},
|
||||
},
|
||||
ImageRef: "TestImage-3",
|
||||
LogPath: "/test/log/path/3",
|
||||
},
|
||||
"4abcd": {
|
||||
ID: "4abcd",
|
||||
Name: "Container-4abcd",
|
||||
SandboxID: "Sandbox-4abcd",
|
||||
Config: &runtime.ContainerConfig{
|
||||
Metadata: &runtime.ContainerMetadata{
|
||||
Name: "TestPod-4abcd",
|
||||
Attempt: 1,
|
||||
},
|
||||
},
|
||||
ImageRef: "TestImage-4abcd",
|
||||
},
|
||||
}
|
||||
statuses := map[string]Status{
|
||||
"1": {
|
||||
@@ -80,29 +91,39 @@ func TestContainerStore(t *testing.T) {
|
||||
Reason: "TestReason-1",
|
||||
Message: "TestMessage-1",
|
||||
},
|
||||
"2": {
|
||||
"2abcd": {
|
||||
Pid: 2,
|
||||
CreatedAt: time.Now().UnixNano(),
|
||||
StartedAt: time.Now().UnixNano(),
|
||||
FinishedAt: time.Now().UnixNano(),
|
||||
ExitCode: 2,
|
||||
Reason: "TestReason-2",
|
||||
Message: "TestMessage-2",
|
||||
Reason: "TestReason-2abcd",
|
||||
Message: "TestMessage-2abcd",
|
||||
},
|
||||
"3": {
|
||||
"4a333": {
|
||||
Pid: 3,
|
||||
CreatedAt: time.Now().UnixNano(),
|
||||
StartedAt: time.Now().UnixNano(),
|
||||
FinishedAt: time.Now().UnixNano(),
|
||||
ExitCode: 3,
|
||||
Reason: "TestReason-3",
|
||||
Message: "TestMessage-3",
|
||||
Reason: "TestReason-4a333",
|
||||
Message: "TestMessage-4a333",
|
||||
Removing: true,
|
||||
},
|
||||
"4abcd": {
|
||||
Pid: 4,
|
||||
CreatedAt: time.Now().UnixNano(),
|
||||
StartedAt: time.Now().UnixNano(),
|
||||
FinishedAt: time.Now().UnixNano(),
|
||||
ExitCode: 4,
|
||||
Reason: "TestReason-4abcd",
|
||||
Message: "TestMessage-4abcd",
|
||||
Removing: true,
|
||||
},
|
||||
}
|
||||
assert := assertlib.New(t)
|
||||
containers := map[string]Container{}
|
||||
for _, id := range ids {
|
||||
for id := range metadatas {
|
||||
container, err := NewContainer(
|
||||
metadatas[id],
|
||||
WithFakeStatus(statuses[id]),
|
||||
@@ -119,29 +140,35 @@ func TestContainerStore(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Logf("should be able to get container")
|
||||
genTruncIndex := func(normalName string) string { return normalName[:(len(normalName)+1)/2] }
|
||||
for id, c := range containers {
|
||||
got, err := s.Get(id)
|
||||
got, err := s.Get(genTruncIndex(id))
|
||||
assert.NoError(err)
|
||||
assert.Equal(c, got)
|
||||
}
|
||||
|
||||
t.Logf("should be able to list containers")
|
||||
cs := s.List()
|
||||
assert.Len(cs, 3)
|
||||
assert.Len(cs, len(containers))
|
||||
|
||||
testID := "2"
|
||||
t.Logf("add should return already exists error for duplicated container")
|
||||
assert.Equal(store.ErrAlreadyExist, s.Add(containers[testID]))
|
||||
cntrNum := len(containers)
|
||||
for testID, v := range containers {
|
||||
truncID := genTruncIndex(testID)
|
||||
|
||||
t.Logf("should be able to delete container")
|
||||
s.Delete(testID)
|
||||
cs = s.List()
|
||||
assert.Len(cs, 2)
|
||||
t.Logf("add should return already exists error for duplicated container")
|
||||
assert.Equal(store.ErrAlreadyExist, s.Add(v))
|
||||
|
||||
t.Logf("get should return not exist error after deletion")
|
||||
c, err := s.Get(testID)
|
||||
assert.Equal(Container{}, c)
|
||||
assert.Equal(store.ErrNotExist, err)
|
||||
t.Logf("should be able to delete container")
|
||||
s.Delete(truncID)
|
||||
cntrNum--
|
||||
cs = s.List()
|
||||
assert.Len(cs, cntrNum)
|
||||
|
||||
t.Logf("get should return not exist error after deletion")
|
||||
c, err := s.Get(truncID)
|
||||
assert.Equal(Container{}, c)
|
||||
assert.Equal(store.ErrNotExist, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithContainerIO(t *testing.T) {
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/docker/docker/pkg/truncindex"
|
||||
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
"github.com/kubernetes-incubator/cri-containerd/pkg/store"
|
||||
@@ -46,9 +47,9 @@ type Image struct {
|
||||
|
||||
// Store stores all images.
|
||||
type Store struct {
|
||||
lock sync.RWMutex
|
||||
images map[string]Image
|
||||
// TODO(random-liu): Add trunc index.
|
||||
lock sync.RWMutex
|
||||
images map[string]Image
|
||||
idIndex *truncindex.TruncIndex
|
||||
}
|
||||
|
||||
// LoadStore loads images from runtime.
|
||||
@@ -57,23 +58,36 @@ func LoadStore() *Store { return nil }
|
||||
|
||||
// NewStore creates an image store.
|
||||
func NewStore() *Store {
|
||||
return &Store{images: make(map[string]Image)}
|
||||
return &Store{
|
||||
images: make(map[string]Image),
|
||||
idIndex: truncindex.NewTruncIndex([]string{}),
|
||||
}
|
||||
}
|
||||
|
||||
// Add an image into the store.
|
||||
func (s *Store) Add(img Image) {
|
||||
func (s *Store) Add(img Image) error {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
if _, err := s.idIndex.Get(img.ID); err != nil {
|
||||
if err != truncindex.ErrNotExist {
|
||||
return err
|
||||
}
|
||||
if err := s.idIndex.Add(img.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
i, ok := s.images[img.ID]
|
||||
if !ok {
|
||||
// If the image doesn't exist, add it.
|
||||
s.images[img.ID] = img
|
||||
return
|
||||
return nil
|
||||
}
|
||||
// Or else, merge the repo tags/digests.
|
||||
i.RepoTags = mergeStringSlices(i.RepoTags, img.RepoTags)
|
||||
i.RepoDigests = mergeStringSlices(i.RepoDigests, img.RepoDigests)
|
||||
s.images[img.ID] = i
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the image with specified id. Returns store.ErrNotExist if the
|
||||
@@ -81,6 +95,13 @@ func (s *Store) Add(img Image) {
|
||||
func (s *Store) Get(id string) (Image, error) {
|
||||
s.lock.RLock()
|
||||
defer s.lock.RUnlock()
|
||||
id, err := s.idIndex.Get(id)
|
||||
if err != nil {
|
||||
if err == truncindex.ErrNotExist {
|
||||
err = store.ErrNotExist
|
||||
}
|
||||
return Image{}, err
|
||||
}
|
||||
if i, ok := s.images[id]; ok {
|
||||
return i, nil
|
||||
}
|
||||
@@ -102,6 +123,13 @@ func (s *Store) List() []Image {
|
||||
func (s *Store) Delete(id string) {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
id, err := s.idIndex.Get(id)
|
||||
if err != nil {
|
||||
// Note: The idIndex.Delete and delete doesn't handle truncated index.
|
||||
// So we need to return if there are error.
|
||||
return
|
||||
}
|
||||
s.idIndex.Delete(id) // nolint: errcheck
|
||||
delete(s.images, id)
|
||||
}
|
||||
|
||||
|
||||
@@ -35,22 +35,30 @@ func TestImageStore(t *testing.T) {
|
||||
Size: 10,
|
||||
Config: &imagespec.ImageConfig{},
|
||||
},
|
||||
"2": {
|
||||
ID: "2",
|
||||
ChainID: "test-chain-id-2",
|
||||
RepoTags: []string{"tag-2"},
|
||||
RepoDigests: []string{"digest-2"},
|
||||
"2abcd": {
|
||||
ID: "2abcd",
|
||||
ChainID: "test-chain-id-2abcd",
|
||||
RepoTags: []string{"tag-2abcd"},
|
||||
RepoDigests: []string{"digest-2abcd"},
|
||||
Size: 20,
|
||||
Config: &imagespec.ImageConfig{},
|
||||
},
|
||||
"3": {
|
||||
ID: "3",
|
||||
RepoTags: []string{"tag-3"},
|
||||
RepoDigests: []string{"digest-3"},
|
||||
ChainID: "test-chain-id-3",
|
||||
"4a333": {
|
||||
ID: "4a333",
|
||||
RepoTags: []string{"tag-4a333"},
|
||||
RepoDigests: []string{"digest-4a333"},
|
||||
ChainID: "test-chain-id-4a333",
|
||||
Size: 30,
|
||||
Config: &imagespec.ImageConfig{},
|
||||
},
|
||||
"4abcd": {
|
||||
ID: "4abcd",
|
||||
RepoTags: []string{"tag-4abcd"},
|
||||
RepoDigests: []string{"digest-4abcd"},
|
||||
ChainID: "test-chain-id-4abcd",
|
||||
Size: 40,
|
||||
Config: &imagespec.ImageConfig{},
|
||||
},
|
||||
}
|
||||
assert := assertlib.New(t)
|
||||
|
||||
@@ -58,49 +66,62 @@ func TestImageStore(t *testing.T) {
|
||||
|
||||
t.Logf("should be able to add image")
|
||||
for _, img := range images {
|
||||
s.Add(img)
|
||||
err := s.Add(img)
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
t.Logf("should be able to get image")
|
||||
genTruncIndex := func(normalName string) string { return normalName[:(len(normalName)+1)/2] }
|
||||
for id, img := range images {
|
||||
got, err := s.Get(id)
|
||||
got, err := s.Get(genTruncIndex(id))
|
||||
assert.NoError(err)
|
||||
assert.Equal(img, got)
|
||||
}
|
||||
|
||||
t.Logf("should be able to list images")
|
||||
imgs := s.List()
|
||||
assert.Len(imgs, 3)
|
||||
assert.Len(imgs, len(images))
|
||||
|
||||
testID := "2"
|
||||
t.Logf("should be able to add new repo tags/digests")
|
||||
newImg := images[testID]
|
||||
newImg.RepoTags = []string{"tag-new"}
|
||||
newImg.RepoDigests = []string{"digest-new"}
|
||||
s.Add(newImg)
|
||||
got, err := s.Get(testID)
|
||||
assert.NoError(err)
|
||||
assert.Len(got.RepoTags, 2)
|
||||
assert.Contains(got.RepoTags, "tag-2", "tag-new")
|
||||
assert.Len(got.RepoDigests, 2)
|
||||
assert.Contains(got.RepoDigests, "digest-2", "digest-new")
|
||||
imageNum := len(images)
|
||||
for testID, v := range images {
|
||||
truncID := genTruncIndex(testID)
|
||||
oldRepoTag := v.RepoTags[0]
|
||||
oldRepoDigest := v.RepoDigests[0]
|
||||
newRepoTag := oldRepoTag + "new"
|
||||
newRepoDigest := oldRepoDigest + "new"
|
||||
|
||||
t.Logf("should not be able to add duplicated repo tags/digests")
|
||||
s.Add(newImg)
|
||||
got, err = s.Get(testID)
|
||||
assert.NoError(err)
|
||||
assert.Len(got.RepoTags, 2)
|
||||
assert.Contains(got.RepoTags, "tag-2", "tag-new")
|
||||
assert.Len(got.RepoDigests, 2)
|
||||
assert.Contains(got.RepoDigests, "digest-2", "digest-new")
|
||||
t.Logf("should be able to add new repo tags/digests")
|
||||
newImg := v
|
||||
newImg.RepoTags = []string{newRepoTag}
|
||||
newImg.RepoDigests = []string{newRepoDigest}
|
||||
err := s.Add(newImg)
|
||||
assert.NoError(err)
|
||||
got, err := s.Get(truncID)
|
||||
assert.NoError(err)
|
||||
assert.Len(got.RepoTags, 2)
|
||||
assert.Contains(got.RepoTags, oldRepoTag, newRepoTag)
|
||||
assert.Len(got.RepoDigests, 2)
|
||||
assert.Contains(got.RepoDigests, oldRepoDigest, newRepoDigest)
|
||||
|
||||
t.Logf("should be able to delete image")
|
||||
s.Delete(testID)
|
||||
imgs = s.List()
|
||||
assert.Len(imgs, 2)
|
||||
t.Logf("should not be able to add duplicated repo tags/digests")
|
||||
err = s.Add(newImg)
|
||||
assert.NoError(err)
|
||||
got, err = s.Get(truncID)
|
||||
assert.NoError(err)
|
||||
assert.Len(got.RepoTags, 2)
|
||||
assert.Contains(got.RepoTags, oldRepoTag, newRepoTag)
|
||||
assert.Len(got.RepoDigests, 2)
|
||||
assert.Contains(got.RepoDigests, oldRepoDigest, newRepoDigest)
|
||||
|
||||
t.Logf("get should return empty struct and ErrNotExist after deletion")
|
||||
img, err := s.Get(testID)
|
||||
assert.Equal(Image{}, img)
|
||||
assert.Equal(store.ErrNotExist, err)
|
||||
t.Logf("should be able to delete image")
|
||||
s.Delete(truncID)
|
||||
imageNum--
|
||||
imgs = s.List()
|
||||
assert.Len(imgs, imageNum)
|
||||
|
||||
t.Logf("get should return empty struct and ErrNotExist after deletion")
|
||||
img, err := s.Get(truncID)
|
||||
assert.Equal(Image{}, img)
|
||||
assert.Equal(store.ErrNotExist, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/docker/docker/pkg/truncindex"
|
||||
|
||||
"github.com/kubernetes-incubator/cri-containerd/pkg/store"
|
||||
)
|
||||
@@ -39,7 +40,7 @@ type Sandbox struct {
|
||||
type Store struct {
|
||||
lock sync.RWMutex
|
||||
sandboxes map[string]Sandbox
|
||||
// TODO(random-liu): Add trunc index.
|
||||
idIndex *truncindex.TruncIndex
|
||||
}
|
||||
|
||||
// LoadStore loads sandboxes from runtime.
|
||||
@@ -48,7 +49,10 @@ func LoadStore() *Store { return nil }
|
||||
|
||||
// NewStore creates a sandbox store.
|
||||
func NewStore() *Store {
|
||||
return &Store{sandboxes: make(map[string]Sandbox)}
|
||||
return &Store{
|
||||
sandboxes: make(map[string]Sandbox),
|
||||
idIndex: truncindex.NewTruncIndex([]string{}),
|
||||
}
|
||||
}
|
||||
|
||||
// Add a sandbox into the store.
|
||||
@@ -58,6 +62,9 @@ func (s *Store) Add(sb Sandbox) error {
|
||||
if _, ok := s.sandboxes[sb.ID]; ok {
|
||||
return store.ErrAlreadyExist
|
||||
}
|
||||
if err := s.idIndex.Add(sb.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
s.sandboxes[sb.ID] = sb
|
||||
return nil
|
||||
}
|
||||
@@ -67,6 +74,13 @@ func (s *Store) Add(sb Sandbox) error {
|
||||
func (s *Store) Get(id string) (Sandbox, error) {
|
||||
s.lock.RLock()
|
||||
defer s.lock.RUnlock()
|
||||
id, err := s.idIndex.Get(id)
|
||||
if err != nil {
|
||||
if err == truncindex.ErrNotExist {
|
||||
err = store.ErrNotExist
|
||||
}
|
||||
return Sandbox{}, err
|
||||
}
|
||||
if sb, ok := s.sandboxes[id]; ok {
|
||||
return sb, nil
|
||||
}
|
||||
@@ -88,5 +102,12 @@ func (s *Store) List() []Sandbox {
|
||||
func (s *Store) Delete(id string) {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
id, err := s.idIndex.Get(id)
|
||||
if err != nil {
|
||||
// Note: The idIndex.Delete and delete doesn't handle truncated index.
|
||||
// So we need to return if there are error.
|
||||
return
|
||||
}
|
||||
s.idIndex.Delete(id) // nolint: errcheck
|
||||
delete(s.sandboxes, id)
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import (
|
||||
)
|
||||
|
||||
func TestSandboxStore(t *testing.T) {
|
||||
ids := []string{"1", "2", "3"}
|
||||
metadatas := map[string]Metadata{
|
||||
"1": {
|
||||
ID: "1",
|
||||
@@ -41,36 +40,49 @@ func TestSandboxStore(t *testing.T) {
|
||||
},
|
||||
NetNSPath: "TestNetNS-1",
|
||||
},
|
||||
"2": {
|
||||
ID: "2",
|
||||
Name: "Sandbox-2",
|
||||
"2abcd": {
|
||||
ID: "2abcd",
|
||||
Name: "Sandbox-2abcd",
|
||||
Config: &runtime.PodSandboxConfig{
|
||||
Metadata: &runtime.PodSandboxMetadata{
|
||||
Name: "TestPod-2",
|
||||
Uid: "TestUid-2",
|
||||
Namespace: "TestNamespace-2",
|
||||
Name: "TestPod-2abcd",
|
||||
Uid: "TestUid-2abcd",
|
||||
Namespace: "TestNamespace-2abcd",
|
||||
Attempt: 2,
|
||||
},
|
||||
},
|
||||
NetNSPath: "TestNetNS-2",
|
||||
},
|
||||
"3": {
|
||||
ID: "3",
|
||||
Name: "Sandbox-3",
|
||||
"4a333": {
|
||||
ID: "4a333",
|
||||
Name: "Sandbox-4a333",
|
||||
Config: &runtime.PodSandboxConfig{
|
||||
Metadata: &runtime.PodSandboxMetadata{
|
||||
Name: "TestPod-3",
|
||||
Uid: "TestUid-3",
|
||||
Namespace: "TestNamespace-3",
|
||||
Name: "TestPod-4a333",
|
||||
Uid: "TestUid-4a333",
|
||||
Namespace: "TestNamespace-4a333",
|
||||
Attempt: 3,
|
||||
},
|
||||
},
|
||||
NetNSPath: "TestNetNS-3",
|
||||
},
|
||||
"4abcd": {
|
||||
ID: "4abcd",
|
||||
Name: "Sandbox-4abcd",
|
||||
Config: &runtime.PodSandboxConfig{
|
||||
Metadata: &runtime.PodSandboxMetadata{
|
||||
Name: "TestPod-4abcd",
|
||||
Uid: "TestUid-4abcd",
|
||||
Namespace: "TestNamespace-4abcd",
|
||||
Attempt: 1,
|
||||
},
|
||||
},
|
||||
NetNSPath: "TestNetNS-4abcd",
|
||||
},
|
||||
}
|
||||
assert := assertlib.New(t)
|
||||
sandboxes := map[string]Sandbox{}
|
||||
for _, id := range ids {
|
||||
for id := range metadatas {
|
||||
sandboxes[id] = Sandbox{Metadata: metadatas[id]}
|
||||
}
|
||||
|
||||
@@ -82,27 +94,33 @@ func TestSandboxStore(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Logf("should be able to get sandbox")
|
||||
genTruncIndex := func(normalName string) string { return normalName[:(len(normalName)+1)/2] }
|
||||
for id, sb := range sandboxes {
|
||||
got, err := s.Get(id)
|
||||
got, err := s.Get(genTruncIndex(id))
|
||||
assert.NoError(err)
|
||||
assert.Equal(sb, got)
|
||||
}
|
||||
|
||||
t.Logf("should be able to list sandboxes")
|
||||
sbs := s.List()
|
||||
assert.Len(sbs, 3)
|
||||
assert.Len(sbs, len(sandboxes))
|
||||
|
||||
testID := "2"
|
||||
t.Logf("add should return already exists error for duplicated sandbox")
|
||||
assert.Equal(store.ErrAlreadyExist, s.Add(sandboxes[testID]))
|
||||
sbNum := len(sandboxes)
|
||||
for testID, v := range sandboxes {
|
||||
truncID := genTruncIndex(testID)
|
||||
|
||||
t.Logf("should be able to delete sandbox")
|
||||
s.Delete(testID)
|
||||
sbs = s.List()
|
||||
assert.Len(sbs, 2)
|
||||
t.Logf("add should return already exists error for duplicated sandbox")
|
||||
assert.Equal(store.ErrAlreadyExist, s.Add(v))
|
||||
|
||||
t.Logf("get should return not exist error after deletion")
|
||||
sb, err := s.Get(testID)
|
||||
assert.Equal(Sandbox{}, sb)
|
||||
assert.Equal(store.ErrNotExist, err)
|
||||
t.Logf("should be able to delete sandbox")
|
||||
s.Delete(truncID)
|
||||
sbNum--
|
||||
sbs = s.List()
|
||||
assert.Len(sbs, sbNum)
|
||||
|
||||
t.Logf("get should return not exist error after deletion")
|
||||
sb, err := s.Get(truncID)
|
||||
assert.Equal(Sandbox{}, sb)
|
||||
assert.Equal(store.ErrNotExist, err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user