2018-02-05 16:05:59 -05:00
|
|
|
package container // import "github.com/docker/docker/container"
|
2017-02-22 13:00:50 -05:00
|
|
|
|
2017-03-27 13:18:53 -04:00
|
|
|
import (
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"testing"
|
2017-02-22 13:00:50 -05:00
|
|
|
|
2018-01-07 00:10:36 -05:00
|
|
|
"github.com/docker/docker/api/types"
|
2017-03-27 13:18:53 -04:00
|
|
|
containertypes "github.com/docker/docker/api/types/container"
|
2019-03-13 07:34:27 -04:00
|
|
|
"github.com/google/uuid"
|
2020-02-07 08:39:24 -05:00
|
|
|
"gotest.tools/v3/assert"
|
|
|
|
is "gotest.tools/v3/assert/cmp"
|
2017-03-27 13:18:53 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
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 (
|
2019-03-13 07:34:27 -04:00
|
|
|
id = uuid.New().String()
|
2017-03-27 13:18:53 -04:00
|
|
|
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) {
|
2017-02-23 18:12:18 -05:00
|
|
|
db, err := NewViewDB()
|
2017-02-22 13:00:50 -05:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2017-03-27 13:18:53 -04:00
|
|
|
c := newContainer(t)
|
2017-02-23 18:12:18 -05:00
|
|
|
if err := c.CheckpointTo(db); err != nil {
|
2017-02-22 13:00:50 -05:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2017-03-27 13:18:53 -04:00
|
|
|
if err := db.Delete(c); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2017-02-22 13:00:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestViewAll(t *testing.T) {
|
|
|
|
var (
|
2017-02-23 18:12:18 -05:00
|
|
|
db, _ = NewViewDB()
|
2017-03-27 13:18:53 -04:00
|
|
|
one = newContainer(t)
|
|
|
|
two = newContainer(t)
|
2017-02-22 13:00:50 -05:00
|
|
|
)
|
|
|
|
one.Pid = 10
|
2017-03-27 13:18:53 -04:00
|
|
|
if err := one.CheckpointTo(db); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2017-02-22 13:00:50 -05:00
|
|
|
two.Pid = 20
|
2017-03-27 13:18:53 -04:00
|
|
|
if err := two.CheckpointTo(db); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2017-06-29 21:56:22 -04:00
|
|
|
all, err := db.Snapshot().All()
|
2017-02-22 13:00:50 -05:00
|
|
|
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]
|
|
|
|
}
|
2017-03-27 13:18:53 -04:00
|
|
|
if s, ok := byID[one.ID]; !ok || s.Pid != 10 {
|
|
|
|
t.Fatalf("expected something different with for id=%s: %v", one.ID, s)
|
2017-02-22 13:00:50 -05:00
|
|
|
}
|
2017-03-27 13:18:53 -04:00
|
|
|
if s, ok := byID[two.ID]; !ok || s.Pid != 20 {
|
|
|
|
t.Fatalf("expected something different with for id=%s: %v", two.ID, s)
|
2017-02-22 13:00:50 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestViewGet(t *testing.T) {
|
2017-03-27 13:18:53 -04:00
|
|
|
var (
|
|
|
|
db, _ = NewViewDB()
|
|
|
|
one = newContainer(t)
|
|
|
|
)
|
2017-02-22 13:00:50 -05:00
|
|
|
one.ImageID = "some-image-123"
|
2017-03-27 13:18:53 -04:00
|
|
|
if err := one.CheckpointTo(db); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2017-06-29 21:56:22 -04:00
|
|
|
s, err := db.Snapshot().Get(one.ID)
|
2017-02-22 13:00:50 -05:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if s == nil || s.ImageID != "some-image-123" {
|
2017-03-27 13:18:53 -04:00
|
|
|
t.Fatalf("expected ImageID=some-image-123. Got: %v", s)
|
2017-02-22 13:00:50 -05:00
|
|
|
}
|
|
|
|
}
|
2017-06-29 21:56:22 -04:00
|
|
|
|
|
|
|
func TestNames(t *testing.T) {
|
|
|
|
db, err := NewViewDB()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2018-03-13 15:28:34 -04:00
|
|
|
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()))
|
2017-06-29 21:56:22 -04:00
|
|
|
|
|
|
|
// Releasing a name allows the name to point to something else later.
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, db.ReleaseName("name2"))
|
|
|
|
assert.Check(t, db.ReserveName("name2", "containerid3"))
|
2017-06-29 21:56:22 -04:00
|
|
|
|
|
|
|
view := db.Snapshot()
|
|
|
|
|
|
|
|
id, err := view.GetID("name1")
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, is.Equal("containerid1", id))
|
2017-06-29 21:56:22 -04:00
|
|
|
|
|
|
|
id, err = view.GetID("name2")
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, is.Equal("containerid3", id))
|
2017-06-29 21:56:22 -04:00
|
|
|
|
|
|
|
_, err = view.GetID("notreserved")
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, is.Error(err, ErrNameNotReserved.Error()))
|
2017-06-29 21:56:22 -04:00
|
|
|
|
|
|
|
// Releasing and re-reserving a name doesn't affect the snapshot.
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, db.ReleaseName("name2"))
|
|
|
|
assert.Check(t, db.ReserveName("name2", "containerid4"))
|
2017-06-29 21:56:22 -04:00
|
|
|
|
|
|
|
id, err = view.GetID("name1")
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, is.Equal("containerid1", id))
|
2017-06-29 21:56:22 -04:00
|
|
|
|
|
|
|
id, err = view.GetID("name2")
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, err)
|
|
|
|
assert.Check(t, is.Equal("containerid3", id))
|
2017-06-29 21:56:22 -04:00
|
|
|
|
|
|
|
// GetAllNames
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, is.DeepEqual(map[string][]string{"containerid1": {"name1"}, "containerid3": {"name2"}}, view.GetAllNames()))
|
2017-06-29 21:56:22 -04:00
|
|
|
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, db.ReserveName("name3", "containerid1"))
|
|
|
|
assert.Check(t, db.ReserveName("name4", "containerid1"))
|
2017-06-29 21:56:22 -04:00
|
|
|
|
|
|
|
view = db.Snapshot()
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, is.DeepEqual(map[string][]string{"containerid1": {"name1", "name3", "name4"}, "containerid4": {"name2"}}, view.GetAllNames()))
|
2017-07-26 19:43:10 -04:00
|
|
|
|
|
|
|
// Release containerid1's names with Delete even though no container exists
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, db.Delete(&Container{ID: "containerid1"}))
|
2017-07-26 19:43:10 -04:00
|
|
|
|
|
|
|
// Reusing one of those names should work
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, db.ReserveName("name1", "containerid4"))
|
2017-07-26 19:43:10 -04:00
|
|
|
view = db.Snapshot()
|
2018-03-13 15:28:34 -04:00
|
|
|
assert.Check(t, is.DeepEqual(map[string][]string{"containerid4": {"name1", "name2"}}, view.GetAllNames()))
|
2017-06-29 21:56:22 -04:00
|
|
|
}
|
2018-01-07 00:10:36 -05:00
|
|
|
|
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
}
|