| package container // import "github.com/docker/docker/container" |
| |
| import ( |
| "io/ioutil" |
| "os" |
| "path/filepath" |
| "testing" |
| |
| "github.com/docker/docker/api/types" |
| containertypes "github.com/docker/docker/api/types/container" |
| "github.com/pborman/uuid" |
| "github.com/stretchr/testify/assert" |
| ) |
| |
| 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 ( |
| id = uuid.New() |
| 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) { |
| db, err := NewViewDB() |
| if err != nil { |
| t.Fatal(err) |
| } |
| c := newContainer(t) |
| if err := c.CheckpointTo(db); err != nil { |
| t.Fatal(err) |
| } |
| if err := db.Delete(c); err != nil { |
| t.Fatal(err) |
| } |
| } |
| |
| func TestViewAll(t *testing.T) { |
| var ( |
| db, _ = NewViewDB() |
| one = newContainer(t) |
| two = newContainer(t) |
| ) |
| one.Pid = 10 |
| if err := one.CheckpointTo(db); err != nil { |
| t.Fatal(err) |
| } |
| two.Pid = 20 |
| if err := two.CheckpointTo(db); err != nil { |
| t.Fatal(err) |
| } |
| |
| all, err := db.Snapshot().All() |
| 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] |
| } |
| if s, ok := byID[one.ID]; !ok || s.Pid != 10 { |
| t.Fatalf("expected something different with for id=%s: %v", one.ID, s) |
| } |
| if s, ok := byID[two.ID]; !ok || s.Pid != 20 { |
| t.Fatalf("expected something different with for id=%s: %v", two.ID, s) |
| } |
| } |
| |
| func TestViewGet(t *testing.T) { |
| var ( |
| db, _ = NewViewDB() |
| one = newContainer(t) |
| ) |
| one.ImageID = "some-image-123" |
| 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.ImageID != "some-image-123" { |
| t.Fatalf("expected ImageID=some-image-123. Got: %v", s) |
| } |
| } |
| |
| func TestNames(t *testing.T) { |
| db, err := NewViewDB() |
| if err != nil { |
| t.Fatal(err) |
| } |
| assert.NoError(t, db.ReserveName("name1", "containerid1")) |
| assert.NoError(t, db.ReserveName("name1", "containerid1")) // idempotent |
| assert.NoError(t, db.ReserveName("name2", "containerid2")) |
| assert.EqualError(t, db.ReserveName("name2", "containerid3"), ErrNameReserved.Error()) |
| |
| // Releasing a name allows the name to point to something else later. |
| assert.NoError(t, db.ReleaseName("name2")) |
| assert.NoError(t, db.ReserveName("name2", "containerid3")) |
| |
| view := db.Snapshot() |
| |
| id, err := view.GetID("name1") |
| assert.NoError(t, err) |
| assert.Equal(t, "containerid1", id) |
| |
| id, err = view.GetID("name2") |
| assert.NoError(t, err) |
| assert.Equal(t, "containerid3", id) |
| |
| _, err = view.GetID("notreserved") |
| assert.EqualError(t, err, ErrNameNotReserved.Error()) |
| |
| // Releasing and re-reserving a name doesn't affect the snapshot. |
| assert.NoError(t, db.ReleaseName("name2")) |
| assert.NoError(t, db.ReserveName("name2", "containerid4")) |
| |
| id, err = view.GetID("name1") |
| assert.NoError(t, err) |
| assert.Equal(t, "containerid1", id) |
| |
| id, err = view.GetID("name2") |
| assert.NoError(t, err) |
| assert.Equal(t, "containerid3", id) |
| |
| // GetAllNames |
| assert.Equal(t, map[string][]string{"containerid1": {"name1"}, "containerid3": {"name2"}}, view.GetAllNames()) |
| |
| assert.NoError(t, db.ReserveName("name3", "containerid1")) |
| assert.NoError(t, db.ReserveName("name4", "containerid1")) |
| |
| view = db.Snapshot() |
| assert.Equal(t, map[string][]string{"containerid1": {"name1", "name3", "name4"}, "containerid4": {"name2"}}, view.GetAllNames()) |
| |
| // Release containerid1's names with Delete even though no container exists |
| assert.NoError(t, db.Delete(&Container{ID: "containerid1"})) |
| |
| // Reusing one of those names should work |
| assert.NoError(t, db.ReserveName("name1", "containerid4")) |
| view = db.Snapshot() |
| assert.Equal(t, map[string][]string{"containerid4": {"name1", "name2"}}, view.GetAllNames()) |
| } |
| |
| // 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) |
| } |
| } |