123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- package container // import "github.com/docker/docker/container"
- import (
- "os"
- "path/filepath"
- "testing"
- "github.com/docker/docker/api/types"
- containertypes "github.com/docker/docker/api/types/container"
- "github.com/google/uuid"
- "gotest.tools/v3/assert"
- is "gotest.tools/v3/assert/cmp"
- )
- var root string
- func TestMain(m *testing.M) {
- var err error
- root, err = os.MkdirTemp("", "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().String()
- 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.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()))
- // Releasing a name allows the name to point to something else later.
- assert.Check(t, db.ReleaseName("name2"))
- assert.Check(t, db.ReserveName("name2", "containerid3"))
- view := db.Snapshot()
- id, err := view.GetID("name1")
- assert.Check(t, err)
- assert.Check(t, is.Equal("containerid1", id))
- id, err = view.GetID("name2")
- assert.Check(t, err)
- assert.Check(t, is.Equal("containerid3", id))
- _, err = view.GetID("notreserved")
- assert.Check(t, is.Error(err, ErrNameNotReserved.Error()))
- // Releasing and re-reserving a name doesn't affect the snapshot.
- assert.Check(t, db.ReleaseName("name2"))
- assert.Check(t, db.ReserveName("name2", "containerid4"))
- id, err = view.GetID("name1")
- assert.Check(t, err)
- assert.Check(t, is.Equal("containerid1", id))
- id, err = view.GetID("name2")
- assert.Check(t, err)
- assert.Check(t, is.Equal("containerid3", id))
- // GetAllNames
- assert.Check(t, is.DeepEqual(map[string][]string{"containerid1": {"name1"}, "containerid3": {"name2"}}, view.GetAllNames()))
- assert.Check(t, db.ReserveName("name3", "containerid1"))
- assert.Check(t, db.ReserveName("name4", "containerid1"))
- view = db.Snapshot()
- assert.Check(t, is.DeepEqual(map[string][]string{"containerid1": {"name1", "name3", "name4"}, "containerid4": {"name2"}}, view.GetAllNames()))
- // Release containerid1's names with Delete even though no container exists
- assert.Check(t, db.Delete(&Container{ID: "containerid1"}))
- // Reusing one of those names should work
- assert.Check(t, db.ReserveName("name1", "containerid4"))
- view = db.Snapshot()
- assert.Check(t, is.DeepEqual(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)
- }
- }
|