| package system // import "github.com/docker/docker/integration/system" | |
| import ( | |
| "context" | |
| "testing" | |
| "github.com/docker/docker/api/types" | |
| "github.com/docker/docker/api/types/volume" | |
| "github.com/docker/docker/integration/internal/container" | |
| "github.com/docker/docker/testutil/daemon" | |
| "gotest.tools/v3/assert" | |
| "gotest.tools/v3/skip" | |
| ) | |
| func TestDiskUsage(t *testing.T) { | |
| skip.If(t, testEnv.OSType == "windows") // d.Start fails on Windows with `protocol not available` | |
| t.Parallel() | |
| d := daemon.New(t) | |
| defer d.Cleanup(t) | |
| d.Start(t, "--iptables=false") | |
| defer d.Stop(t) | |
| client := d.NewClientT(t) | |
| ctx := context.Background() | |
| var stepDU types.DiskUsage | |
| for _, step := range []struct { | |
| doc string | |
| next func(t *testing.T, prev types.DiskUsage) types.DiskUsage | |
| }{ | |
| { | |
| doc: "empty", | |
| next: func(t *testing.T, _ types.DiskUsage) types.DiskUsage { | |
| du, err := client.DiskUsage(ctx, types.DiskUsageOptions{}) | |
| assert.NilError(t, err) | |
| assert.DeepEqual(t, du, types.DiskUsage{ | |
| Images: []*types.ImageSummary{}, | |
| Containers: []*types.Container{}, | |
| Volumes: []*volume.Volume{}, | |
| BuildCache: []*types.BuildCache{}, | |
| }) | |
| return du | |
| }, | |
| }, | |
| { | |
| doc: "after LoadBusybox", | |
| next: func(t *testing.T, _ types.DiskUsage) types.DiskUsage { | |
| d.LoadBusybox(t) | |
| du, err := client.DiskUsage(ctx, types.DiskUsageOptions{}) | |
| assert.NilError(t, err) | |
| assert.Assert(t, du.LayersSize > 0) | |
| assert.Equal(t, len(du.Images), 1) | |
| assert.DeepEqual(t, du, types.DiskUsage{ | |
| LayersSize: du.LayersSize, | |
| Images: []*types.ImageSummary{ | |
| { | |
| Created: du.Images[0].Created, | |
| ID: du.Images[0].ID, | |
| RepoTags: []string{"busybox:latest"}, | |
| Size: du.LayersSize, | |
| VirtualSize: du.LayersSize, //nolint:staticcheck // ignore SA1019: field is deprecated, but still set on API < v1.44. | |
| }, | |
| }, | |
| Containers: []*types.Container{}, | |
| Volumes: []*volume.Volume{}, | |
| BuildCache: []*types.BuildCache{}, | |
| }) | |
| return du | |
| }, | |
| }, | |
| { | |
| doc: "after container.Run", | |
| next: func(t *testing.T, prev types.DiskUsage) types.DiskUsage { | |
| cID := container.Run(ctx, t, client) | |
| du, err := client.DiskUsage(ctx, types.DiskUsageOptions{}) | |
| assert.NilError(t, err) | |
| assert.Equal(t, len(du.Containers), 1) | |
| assert.Equal(t, len(du.Containers[0].Names), 1) | |
| assert.Assert(t, du.Containers[0].Created >= prev.Images[0].Created) | |
| assert.DeepEqual(t, du, types.DiskUsage{ | |
| LayersSize: prev.LayersSize, | |
| Images: []*types.ImageSummary{ | |
| func() *types.ImageSummary { | |
| sum := *prev.Images[0] | |
| sum.Containers++ | |
| return &sum | |
| }(), | |
| }, | |
| Containers: []*types.Container{ | |
| { | |
| ID: cID, | |
| Names: du.Containers[0].Names, | |
| Image: "busybox", | |
| ImageID: prev.Images[0].ID, | |
| Command: du.Containers[0].Command, // not relevant for the test | |
| Created: du.Containers[0].Created, | |
| Ports: du.Containers[0].Ports, // not relevant for the test | |
| SizeRootFs: prev.Images[0].Size, | |
| Labels: du.Containers[0].Labels, // not relevant for the test | |
| State: du.Containers[0].State, // not relevant for the test | |
| Status: du.Containers[0].Status, // not relevant for the test | |
| HostConfig: du.Containers[0].HostConfig, // not relevant for the test | |
| NetworkSettings: du.Containers[0].NetworkSettings, // not relevant for the test | |
| Mounts: du.Containers[0].Mounts, // not relevant for the test | |
| }, | |
| }, | |
| Volumes: []*volume.Volume{}, | |
| BuildCache: []*types.BuildCache{}, | |
| }) | |
| return du | |
| }, | |
| }, | |
| } { | |
| t.Run(step.doc, func(t *testing.T) { | |
| stepDU = step.next(t, stepDU) | |
| for _, tc := range []struct { | |
| doc string | |
| options types.DiskUsageOptions | |
| expected types.DiskUsage | |
| }{ | |
| { | |
| doc: "container types", | |
| options: types.DiskUsageOptions{ | |
| Types: []types.DiskUsageObject{ | |
| types.ContainerObject, | |
| }, | |
| }, | |
| expected: types.DiskUsage{ | |
| Containers: stepDU.Containers, | |
| }, | |
| }, | |
| { | |
| doc: "image types", | |
| options: types.DiskUsageOptions{ | |
| Types: []types.DiskUsageObject{ | |
| types.ImageObject, | |
| }, | |
| }, | |
| expected: types.DiskUsage{ | |
| LayersSize: stepDU.LayersSize, | |
| Images: stepDU.Images, | |
| }, | |
| }, | |
| { | |
| doc: "volume types", | |
| options: types.DiskUsageOptions{ | |
| Types: []types.DiskUsageObject{ | |
| types.VolumeObject, | |
| }, | |
| }, | |
| expected: types.DiskUsage{ | |
| Volumes: stepDU.Volumes, | |
| }, | |
| }, | |
| { | |
| doc: "build-cache types", | |
| options: types.DiskUsageOptions{ | |
| Types: []types.DiskUsageObject{ | |
| types.BuildCacheObject, | |
| }, | |
| }, | |
| expected: types.DiskUsage{ | |
| BuildCache: stepDU.BuildCache, | |
| }, | |
| }, | |
| { | |
| doc: "container, volume types", | |
| options: types.DiskUsageOptions{ | |
| Types: []types.DiskUsageObject{ | |
| types.ContainerObject, | |
| types.VolumeObject, | |
| }, | |
| }, | |
| expected: types.DiskUsage{ | |
| Containers: stepDU.Containers, | |
| Volumes: stepDU.Volumes, | |
| }, | |
| }, | |
| { | |
| doc: "image, build-cache types", | |
| options: types.DiskUsageOptions{ | |
| Types: []types.DiskUsageObject{ | |
| types.ImageObject, | |
| types.BuildCacheObject, | |
| }, | |
| }, | |
| expected: types.DiskUsage{ | |
| LayersSize: stepDU.LayersSize, | |
| Images: stepDU.Images, | |
| BuildCache: stepDU.BuildCache, | |
| }, | |
| }, | |
| { | |
| doc: "container, volume, build-cache types", | |
| options: types.DiskUsageOptions{ | |
| Types: []types.DiskUsageObject{ | |
| types.ContainerObject, | |
| types.VolumeObject, | |
| types.BuildCacheObject, | |
| }, | |
| }, | |
| expected: types.DiskUsage{ | |
| Containers: stepDU.Containers, | |
| Volumes: stepDU.Volumes, | |
| BuildCache: stepDU.BuildCache, | |
| }, | |
| }, | |
| { | |
| doc: "image, volume, build-cache types", | |
| options: types.DiskUsageOptions{ | |
| Types: []types.DiskUsageObject{ | |
| types.ImageObject, | |
| types.VolumeObject, | |
| types.BuildCacheObject, | |
| }, | |
| }, | |
| expected: types.DiskUsage{ | |
| LayersSize: stepDU.LayersSize, | |
| Images: stepDU.Images, | |
| Volumes: stepDU.Volumes, | |
| BuildCache: stepDU.BuildCache, | |
| }, | |
| }, | |
| { | |
| doc: "container, image, volume types", | |
| options: types.DiskUsageOptions{ | |
| Types: []types.DiskUsageObject{ | |
| types.ContainerObject, | |
| types.ImageObject, | |
| types.VolumeObject, | |
| }, | |
| }, | |
| expected: types.DiskUsage{ | |
| LayersSize: stepDU.LayersSize, | |
| Containers: stepDU.Containers, | |
| Images: stepDU.Images, | |
| Volumes: stepDU.Volumes, | |
| }, | |
| }, | |
| { | |
| doc: "container, image, volume, build-cache types", | |
| options: types.DiskUsageOptions{ | |
| Types: []types.DiskUsageObject{ | |
| types.ContainerObject, | |
| types.ImageObject, | |
| types.VolumeObject, | |
| types.BuildCacheObject, | |
| }, | |
| }, | |
| expected: types.DiskUsage{ | |
| LayersSize: stepDU.LayersSize, | |
| Containers: stepDU.Containers, | |
| Images: stepDU.Images, | |
| Volumes: stepDU.Volumes, | |
| BuildCache: stepDU.BuildCache, | |
| }, | |
| }, | |
| } { | |
| tc := tc | |
| t.Run(tc.doc, func(t *testing.T) { | |
| // TODO: Run in parallel once https://github.com/moby/moby/pull/42560 is merged. | |
| du, err := client.DiskUsage(ctx, tc.options) | |
| assert.NilError(t, err) | |
| assert.DeepEqual(t, du, tc.expected) | |
| }) | |
| } | |
| }) | |
| } | |
| } |