container/view_test.go
4f0d95fa
 package container // import "github.com/docker/docker/container"
054728b1
 
edad5270
 import (
 	"io/ioutil"
 	"os"
 	"path/filepath"
 	"testing"
054728b1
 
f509a54b
 	"github.com/docker/docker/api/types"
edad5270
 	containertypes "github.com/docker/docker/api/types/container"
c435551c
 	"github.com/google/uuid"
38457285
 	"gotest.tools/assert"
 	is "gotest.tools/assert/cmp"
edad5270
 )
 
 var root string
 
 func TestMain(m *testing.M) {
 	var err error
 	root, err = ioutil.TempDir("", "docker-container-test-")
 	if err != nil {
 		panic(err)
 	}
 	defer os.RemoveAll(root)
 
 	os.Exit(m.Run())
 }
 
 func newContainer(t *testing.T) *Container {
 	var (
c435551c
 		id    = uuid.New().String()
edad5270
 		cRoot = filepath.Join(root, id)
 	)
 	if err := os.MkdirAll(cRoot, 0755); err != nil {
 		t.Fatal(err)
 	}
 	c := NewBaseContainer(id, cRoot)
 	c.HostConfig = &containertypes.HostConfig{}
 	return c
 }
 
 func TestViewSaveDelete(t *testing.T) {
aacddda8
 	db, err := NewViewDB()
054728b1
 	if err != nil {
 		t.Fatal(err)
 	}
edad5270
 	c := newContainer(t)
aacddda8
 	if err := c.CheckpointTo(db); err != nil {
054728b1
 		t.Fatal(err)
 	}
edad5270
 	if err := db.Delete(c); err != nil {
 		t.Fatal(err)
 	}
054728b1
 }
 
 func TestViewAll(t *testing.T) {
 	var (
aacddda8
 		db, _ = NewViewDB()
edad5270
 		one   = newContainer(t)
 		two   = newContainer(t)
054728b1
 	)
 	one.Pid = 10
edad5270
 	if err := one.CheckpointTo(db); err != nil {
 		t.Fatal(err)
 	}
054728b1
 	two.Pid = 20
edad5270
 	if err := two.CheckpointTo(db); err != nil {
 		t.Fatal(err)
 	}
 
1128fc1a
 	all, err := db.Snapshot().All()
054728b1
 	if err != nil {
 		t.Fatal(err)
 	}
 	if l := len(all); l != 2 {
 		t.Fatalf("expected 2 items, got %d", l)
 	}
 	byID := make(map[string]Snapshot)
 	for i := range all {
 		byID[all[i].ID] = all[i]
 	}
edad5270
 	if s, ok := byID[one.ID]; !ok || s.Pid != 10 {
 		t.Fatalf("expected something different with for id=%s: %v", one.ID, s)
054728b1
 	}
edad5270
 	if s, ok := byID[two.ID]; !ok || s.Pid != 20 {
 		t.Fatalf("expected something different with for id=%s: %v", two.ID, s)
054728b1
 	}
 }
 
 func TestViewGet(t *testing.T) {
edad5270
 	var (
 		db, _ = NewViewDB()
 		one   = newContainer(t)
 	)
054728b1
 	one.ImageID = "some-image-123"
edad5270
 	if err := one.CheckpointTo(db); err != nil {
 		t.Fatal(err)
 	}
1128fc1a
 	s, err := db.Snapshot().Get(one.ID)
054728b1
 	if err != nil {
 		t.Fatal(err)
 	}
 	if s == nil || s.ImageID != "some-image-123" {
edad5270
 		t.Fatalf("expected ImageID=some-image-123. Got: %v", s)
054728b1
 	}
 }
1128fc1a
 
 func TestNames(t *testing.T) {
 	db, err := NewViewDB()
 	if err != nil {
 		t.Fatal(err)
 	}
6be0f709
 	assert.Check(t, db.ReserveName("name1", "containerid1"))
 	assert.Check(t, db.ReserveName("name1", "containerid1")) // idempotent
 	assert.Check(t, db.ReserveName("name2", "containerid2"))
 	assert.Check(t, is.Error(db.ReserveName("name2", "containerid3"), ErrNameReserved.Error()))
1128fc1a
 
 	// Releasing a name allows the name to point to something else later.
6be0f709
 	assert.Check(t, db.ReleaseName("name2"))
 	assert.Check(t, db.ReserveName("name2", "containerid3"))
1128fc1a
 
 	view := db.Snapshot()
 
 	id, err := view.GetID("name1")
6be0f709
 	assert.Check(t, err)
 	assert.Check(t, is.Equal("containerid1", id))
1128fc1a
 
 	id, err = view.GetID("name2")
6be0f709
 	assert.Check(t, err)
 	assert.Check(t, is.Equal("containerid3", id))
1128fc1a
 
 	_, err = view.GetID("notreserved")
6be0f709
 	assert.Check(t, is.Error(err, ErrNameNotReserved.Error()))
1128fc1a
 
 	// Releasing and re-reserving a name doesn't affect the snapshot.
6be0f709
 	assert.Check(t, db.ReleaseName("name2"))
 	assert.Check(t, db.ReserveName("name2", "containerid4"))
1128fc1a
 
 	id, err = view.GetID("name1")
6be0f709
 	assert.Check(t, err)
 	assert.Check(t, is.Equal("containerid1", id))
1128fc1a
 
 	id, err = view.GetID("name2")
6be0f709
 	assert.Check(t, err)
 	assert.Check(t, is.Equal("containerid3", id))
1128fc1a
 
 	// GetAllNames
6be0f709
 	assert.Check(t, is.DeepEqual(map[string][]string{"containerid1": {"name1"}, "containerid3": {"name2"}}, view.GetAllNames()))
1128fc1a
 
6be0f709
 	assert.Check(t, db.ReserveName("name3", "containerid1"))
 	assert.Check(t, db.ReserveName("name4", "containerid1"))
1128fc1a
 
 	view = db.Snapshot()
6be0f709
 	assert.Check(t, is.DeepEqual(map[string][]string{"containerid1": {"name1", "name3", "name4"}, "containerid4": {"name2"}}, view.GetAllNames()))
1d9546fc
 
 	// Release containerid1's names with Delete even though no container exists
6be0f709
 	assert.Check(t, db.Delete(&Container{ID: "containerid1"}))
1d9546fc
 
 	// Reusing one of those names should work
6be0f709
 	assert.Check(t, db.ReserveName("name1", "containerid4"))
1d9546fc
 	view = db.Snapshot()
6be0f709
 	assert.Check(t, is.DeepEqual(map[string][]string{"containerid4": {"name1", "name2"}}, view.GetAllNames()))
1128fc1a
 }
f509a54b
 
 // Test case for GitHub issue 35920
 func TestViewWithHealthCheck(t *testing.T) {
 	var (
 		db, _ = NewViewDB()
 		one   = newContainer(t)
 	)
 	one.Health = &Health{
 		Health: types.Health{
 			Status: "starting",
 		},
 	}
 	if err := one.CheckpointTo(db); err != nil {
 		t.Fatal(err)
 	}
 	s, err := db.Snapshot().Get(one.ID)
 	if err != nil {
 		t.Fatal(err)
 	}
 	if s == nil || s.Health != "starting" {
 		t.Fatalf("expected Health=starting. Got: %+v", s)
 	}
 }