| package service | |
| import ( | |
| "context" | |
| "os" | |
| "testing" | |
| "github.com/docker/docker/api/types/events" | |
| "github.com/docker/docker/api/types/filters" | |
| "github.com/docker/docker/errdefs" | |
| "github.com/docker/docker/volume" | |
| volumedrivers "github.com/docker/docker/volume/drivers" | |
| "github.com/docker/docker/volume/service/opts" | |
| "github.com/docker/docker/volume/testutils" | |
| "gotest.tools/v3/assert" | |
| is "gotest.tools/v3/assert/cmp" | |
| ) | |
| func TestServiceCreate(t *testing.T) { | |
| t.Parallel() | |
| ds := volumedrivers.NewStore(nil) | |
| assert.Assert(t, ds.Register(testutils.NewFakeDriver("d1"), "d1")) | |
| assert.Assert(t, ds.Register(testutils.NewFakeDriver("d2"), "d2")) | |
| ctx := context.Background() | |
| service, cleanup := newTestService(t, ds) | |
| defer cleanup() | |
| _, err := service.Create(ctx, "v1", "notexist") | |
| assert.Assert(t, errdefs.IsNotFound(err), err) | |
| v, err := service.Create(ctx, "v1", "d1") | |
| assert.NilError(t, err) | |
| vCopy, err := service.Create(ctx, "v1", "d1") | |
| assert.NilError(t, err) | |
| assert.Assert(t, is.DeepEqual(v, vCopy)) | |
| _, err = service.Create(ctx, "v1", "d2") | |
| assert.Check(t, IsNameConflict(err), err) | |
| assert.Check(t, errdefs.IsConflict(err), err) | |
| assert.Assert(t, service.Remove(ctx, "v1")) | |
| _, err = service.Create(ctx, "v1", "d2") | |
| assert.NilError(t, err) | |
| _, err = service.Create(ctx, "v1", "d2") | |
| assert.NilError(t, err) | |
| } | |
| func TestServiceList(t *testing.T) { | |
| t.Parallel() | |
| ds := volumedrivers.NewStore(nil) | |
| assert.Assert(t, ds.Register(testutils.NewFakeDriver("d1"), "d1")) | |
| assert.Assert(t, ds.Register(testutils.NewFakeDriver("d2"), "d2")) | |
| service, cleanup := newTestService(t, ds) | |
| defer cleanup() | |
| ctx := context.Background() | |
| _, err := service.Create(ctx, "v1", "d1") | |
| assert.NilError(t, err) | |
| _, err = service.Create(ctx, "v2", "d1") | |
| assert.NilError(t, err) | |
| _, err = service.Create(ctx, "v3", "d2") | |
| assert.NilError(t, err) | |
| ls, _, err := service.List(ctx, filters.NewArgs(filters.Arg("driver", "d1"))) | |
| assert.NilError(t, err) | |
| assert.Check(t, is.Len(ls, 2)) | |
| ls, _, err = service.List(ctx, filters.NewArgs(filters.Arg("driver", "d2"))) | |
| assert.NilError(t, err) | |
| assert.Check(t, is.Len(ls, 1)) | |
| ls, _, err = service.List(ctx, filters.NewArgs(filters.Arg("driver", "notexist"))) | |
| assert.NilError(t, err) | |
| assert.Check(t, is.Len(ls, 0)) | |
| ls, _, err = service.List(ctx, filters.NewArgs(filters.Arg("dangling", "true"))) | |
| assert.NilError(t, err) | |
| assert.Check(t, is.Len(ls, 3)) | |
| ls, _, err = service.List(ctx, filters.NewArgs(filters.Arg("dangling", "false"))) | |
| assert.NilError(t, err) | |
| assert.Check(t, is.Len(ls, 0)) | |
| _, err = service.Get(ctx, "v1", opts.WithGetReference("foo")) | |
| assert.NilError(t, err) | |
| ls, _, err = service.List(ctx, filters.NewArgs(filters.Arg("dangling", "true"))) | |
| assert.NilError(t, err) | |
| assert.Check(t, is.Len(ls, 2)) | |
| ls, _, err = service.List(ctx, filters.NewArgs(filters.Arg("dangling", "false"))) | |
| assert.NilError(t, err) | |
| assert.Check(t, is.Len(ls, 1)) | |
| ls, _, err = service.List(ctx, filters.NewArgs(filters.Arg("dangling", "false"), filters.Arg("driver", "d2"))) | |
| assert.NilError(t, err) | |
| assert.Check(t, is.Len(ls, 0)) | |
| ls, _, err = service.List(ctx, filters.NewArgs(filters.Arg("dangling", "true"), filters.Arg("driver", "d2"))) | |
| assert.NilError(t, err) | |
| assert.Check(t, is.Len(ls, 1)) | |
| } | |
| func TestServiceRemove(t *testing.T) { | |
| t.Parallel() | |
| ds := volumedrivers.NewStore(nil) | |
| assert.Assert(t, ds.Register(testutils.NewFakeDriver("d1"), "d1")) | |
| service, cleanup := newTestService(t, ds) | |
| defer cleanup() | |
| ctx := context.Background() | |
| _, err := service.Create(ctx, "test", "d1") | |
| assert.NilError(t, err) | |
| assert.Assert(t, service.Remove(ctx, "test")) | |
| assert.Assert(t, service.Remove(ctx, "test", opts.WithPurgeOnError(true))) | |
| } | |
| func TestServiceGet(t *testing.T) { | |
| t.Parallel() | |
| ds := volumedrivers.NewStore(nil) | |
| assert.Assert(t, ds.Register(testutils.NewFakeDriver("d1"), "d1")) | |
| service, cleanup := newTestService(t, ds) | |
| defer cleanup() | |
| ctx := context.Background() | |
| v, err := service.Get(ctx, "notexist") | |
| assert.Assert(t, IsNotExist(err)) | |
| assert.Check(t, v == nil) | |
| created, err := service.Create(ctx, "test", "d1") | |
| assert.NilError(t, err) | |
| assert.Assert(t, created != nil) | |
| v, err = service.Get(ctx, "test") | |
| assert.NilError(t, err) | |
| assert.Assert(t, is.DeepEqual(created, v)) | |
| v, err = service.Get(ctx, "test", opts.WithGetResolveStatus) | |
| assert.NilError(t, err) | |
| assert.Assert(t, is.Len(v.Status, 1), v.Status) | |
| _, err = service.Get(ctx, "test", opts.WithGetDriver("notarealdriver")) | |
| assert.Assert(t, errdefs.IsConflict(err), err) | |
| v, err = service.Get(ctx, "test", opts.WithGetDriver("d1")) | |
| assert.Assert(t, err == nil) | |
| assert.Assert(t, is.DeepEqual(created, v)) | |
| assert.Assert(t, ds.Register(testutils.NewFakeDriver("d2"), "d2")) | |
| _, err = service.Get(ctx, "test", opts.WithGetDriver("d2")) | |
| assert.Assert(t, errdefs.IsConflict(err), err) | |
| } | |
| func TestServicePrune(t *testing.T) { | |
| t.Parallel() | |
| ds := volumedrivers.NewStore(nil) | |
| assert.Assert(t, ds.Register(testutils.NewFakeDriver(volume.DefaultDriverName), volume.DefaultDriverName)) | |
| assert.Assert(t, ds.Register(testutils.NewFakeDriver("other"), "other")) | |
| service, cleanup := newTestService(t, ds) | |
| defer cleanup() | |
| ctx := context.Background() | |
| _, err := service.Create(ctx, "test", volume.DefaultDriverName) | |
| assert.NilError(t, err) | |
| _, err = service.Create(ctx, "test2", "other") | |
| assert.NilError(t, err) | |
| pr, err := service.Prune(ctx, filters.NewArgs(filters.Arg("label", "banana"), filters.Arg("all", "true"))) | |
| assert.NilError(t, err) | |
| assert.Assert(t, is.Len(pr.VolumesDeleted, 0)) | |
| pr, err = service.Prune(ctx, filters.NewArgs(filters.Arg("all", "true"))) | |
| assert.NilError(t, err) | |
| assert.Assert(t, is.Len(pr.VolumesDeleted, 1)) | |
| assert.Assert(t, is.Equal(pr.VolumesDeleted[0], "test")) | |
| _, err = service.Get(ctx, "test") | |
| assert.Assert(t, IsNotExist(err), err) | |
| v, err := service.Get(ctx, "test2") | |
| assert.NilError(t, err) | |
| assert.Assert(t, is.Equal(v.Driver, "other")) | |
| _, err = service.Create(ctx, "test", volume.DefaultDriverName) | |
| assert.NilError(t, err) | |
| pr, err = service.Prune(ctx, filters.NewArgs(filters.Arg("label!", "banana"), filters.Arg("all", "true"))) | |
| assert.NilError(t, err) | |
| assert.Assert(t, is.Len(pr.VolumesDeleted, 1)) | |
| assert.Assert(t, is.Equal(pr.VolumesDeleted[0], "test")) | |
| v, err = service.Get(ctx, "test2") | |
| assert.NilError(t, err) | |
| assert.Assert(t, is.Equal(v.Driver, "other")) | |
| _, err = service.Create(ctx, "test", volume.DefaultDriverName, opts.WithCreateLabels(map[string]string{"banana": ""})) | |
| assert.NilError(t, err) | |
| pr, err = service.Prune(ctx, filters.NewArgs(filters.Arg("label!", "banana"))) | |
| assert.NilError(t, err) | |
| assert.Assert(t, is.Len(pr.VolumesDeleted, 0)) | |
| _, err = service.Create(ctx, "test3", volume.DefaultDriverName, opts.WithCreateLabels(map[string]string{"banana": "split"})) | |
| assert.NilError(t, err) | |
| pr, err = service.Prune(ctx, filters.NewArgs(filters.Arg("label!", "banana=split"), filters.Arg("all", "true"))) | |
| assert.NilError(t, err) | |
| assert.Assert(t, is.Len(pr.VolumesDeleted, 1)) | |
| assert.Assert(t, is.Equal(pr.VolumesDeleted[0], "test")) | |
| pr, err = service.Prune(ctx, filters.NewArgs(filters.Arg("label", "banana=split"), filters.Arg("all", "true"))) | |
| assert.NilError(t, err) | |
| assert.Assert(t, is.Len(pr.VolumesDeleted, 1)) | |
| assert.Assert(t, is.Equal(pr.VolumesDeleted[0], "test3")) | |
| v, err = service.Create(ctx, "test", volume.DefaultDriverName, opts.WithCreateReference(t.Name())) | |
| assert.NilError(t, err) | |
| pr, err = service.Prune(ctx, filters.NewArgs()) | |
| assert.NilError(t, err) | |
| assert.Assert(t, is.Len(pr.VolumesDeleted, 0)) | |
| assert.Assert(t, service.Release(ctx, v.Name, t.Name())) | |
| pr, err = service.Prune(ctx, filters.NewArgs(filters.Arg("all", "true"))) | |
| assert.NilError(t, err) | |
| assert.Assert(t, is.Len(pr.VolumesDeleted, 1)) | |
| assert.Assert(t, is.Equal(pr.VolumesDeleted[0], "test")) | |
| } | |
| func newTestService(t *testing.T, ds *volumedrivers.Store) (*VolumesService, func()) { | |
| t.Helper() | |
| dir, err := os.MkdirTemp("", t.Name()) | |
| assert.NilError(t, err) | |
| store, err := NewStore(dir, ds) | |
| assert.NilError(t, err) | |
| s := &VolumesService{vs: store, eventLogger: dummyEventLogger{}} | |
| return s, func() { | |
| assert.Check(t, s.Shutdown()) | |
| assert.Check(t, os.RemoveAll(dir)) | |
| } | |
| } | |
| type dummyEventLogger struct{} | |
| func (dummyEventLogger) LogVolumeEvent(_ string, _ events.Action, _ map[string]string) {} |