github.com/moby/docker@v26.1.3+incompatible/integration/system/disk_usage_test.go (about)

     1  package system // import "github.com/docker/docker/integration/system"
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/docker/docker/api/types"
     8  	"github.com/docker/docker/api/types/image"
     9  	"github.com/docker/docker/api/types/volume"
    10  	"github.com/docker/docker/integration/internal/container"
    11  	"github.com/docker/docker/testutil"
    12  	"github.com/docker/docker/testutil/daemon"
    13  	"gotest.tools/v3/assert"
    14  	is "gotest.tools/v3/assert/cmp"
    15  	"gotest.tools/v3/skip"
    16  )
    17  
    18  func TestDiskUsage(t *testing.T) {
    19  	skip.If(t, testEnv.DaemonInfo.OSType == "windows") // d.Start fails on Windows with `protocol not available`
    20  
    21  	// TODO: If this helps, then fix the root cause.
    22  	// See: https://github.com/moby/moby/issues/47119
    23  	// t.Parallel()
    24  
    25  	ctx := testutil.StartSpan(baseContext, t)
    26  
    27  	d := daemon.New(t)
    28  	defer d.Cleanup(t)
    29  	d.Start(t, "--iptables=false")
    30  	defer d.Stop(t)
    31  	client := d.NewClientT(t)
    32  
    33  	var stepDU types.DiskUsage
    34  	for _, step := range []struct {
    35  		doc  string
    36  		next func(t *testing.T, prev types.DiskUsage) types.DiskUsage
    37  	}{
    38  		{
    39  			doc: "empty",
    40  			next: func(t *testing.T, _ types.DiskUsage) types.DiskUsage {
    41  				du, err := client.DiskUsage(ctx, types.DiskUsageOptions{})
    42  				assert.NilError(t, err)
    43  				assert.DeepEqual(t, du, types.DiskUsage{
    44  					Images:     []*image.Summary{},
    45  					Containers: []*types.Container{},
    46  					Volumes:    []*volume.Volume{},
    47  					BuildCache: []*types.BuildCache{},
    48  				})
    49  				return du
    50  			},
    51  		},
    52  		{
    53  			doc: "after LoadBusybox",
    54  			next: func(t *testing.T, _ types.DiskUsage) types.DiskUsage {
    55  				d.LoadBusybox(ctx, t)
    56  
    57  				du, err := client.DiskUsage(ctx, types.DiskUsageOptions{})
    58  				assert.NilError(t, err)
    59  				assert.Assert(t, du.LayersSize > 0)
    60  				assert.Equal(t, len(du.Images), 1)
    61  				assert.Equal(t, len(du.Images[0].RepoTags), 1)
    62  				assert.Check(t, is.Equal(du.Images[0].RepoTags[0], "busybox:latest"))
    63  
    64  				// Image size is layer size + content size, should be greater than total layer size
    65  				assert.Assert(t, du.Images[0].Size >= du.LayersSize)
    66  
    67  				// If size is greater, than content exists and should have a repodigest
    68  				if du.Images[0].Size > du.LayersSize {
    69  					assert.Equal(t, len(du.Images[0].RepoDigests), 1)
    70  					assert.Check(t, strings.HasPrefix(du.Images[0].RepoDigests[0], "busybox@"))
    71  				}
    72  
    73  				return du
    74  			},
    75  		},
    76  		{
    77  			doc: "after container.Run",
    78  			next: func(t *testing.T, prev types.DiskUsage) types.DiskUsage {
    79  				cID := container.Run(ctx, t, client)
    80  
    81  				du, err := client.DiskUsage(ctx, types.DiskUsageOptions{})
    82  				assert.NilError(t, err)
    83  				assert.Equal(t, len(du.Containers), 1)
    84  				assert.Equal(t, len(du.Containers[0].Names), 1)
    85  				assert.Assert(t, len(prev.Images) > 0)
    86  				assert.Check(t, du.Containers[0].Created >= prev.Images[0].Created)
    87  
    88  				// Additional container layer could add to the size
    89  				assert.Check(t, du.LayersSize >= prev.LayersSize)
    90  
    91  				assert.Equal(t, len(du.Images), 1)
    92  				assert.Equal(t, du.Images[0].Containers, prev.Images[0].Containers+1)
    93  
    94  				assert.Check(t, is.Equal(du.Containers[0].ID, cID))
    95  				assert.Check(t, is.Equal(du.Containers[0].Image, "busybox"))
    96  				assert.Check(t, is.Equal(du.Containers[0].ImageID, prev.Images[0].ID))
    97  
    98  				// The rootfs size should be equivalent to all the layers,
    99  				// previously used prev.Images[0].Size, which may differ from content data
   100  				assert.Check(t, is.Equal(du.Containers[0].SizeRootFs, du.LayersSize))
   101  
   102  				return du
   103  			},
   104  		},
   105  	} {
   106  		t.Run(step.doc, func(t *testing.T) {
   107  			ctx := testutil.StartSpan(ctx, t)
   108  			stepDU = step.next(t, stepDU)
   109  
   110  			for _, tc := range []struct {
   111  				doc      string
   112  				options  types.DiskUsageOptions
   113  				expected types.DiskUsage
   114  			}{
   115  				{
   116  					doc: "container types",
   117  					options: types.DiskUsageOptions{
   118  						Types: []types.DiskUsageObject{
   119  							types.ContainerObject,
   120  						},
   121  					},
   122  					expected: types.DiskUsage{
   123  						Containers: stepDU.Containers,
   124  					},
   125  				},
   126  				{
   127  					doc: "image types",
   128  					options: types.DiskUsageOptions{
   129  						Types: []types.DiskUsageObject{
   130  							types.ImageObject,
   131  						},
   132  					},
   133  					expected: types.DiskUsage{
   134  						LayersSize: stepDU.LayersSize,
   135  						Images:     stepDU.Images,
   136  					},
   137  				},
   138  				{
   139  					doc: "volume types",
   140  					options: types.DiskUsageOptions{
   141  						Types: []types.DiskUsageObject{
   142  							types.VolumeObject,
   143  						},
   144  					},
   145  					expected: types.DiskUsage{
   146  						Volumes: stepDU.Volumes,
   147  					},
   148  				},
   149  				{
   150  					doc: "build-cache types",
   151  					options: types.DiskUsageOptions{
   152  						Types: []types.DiskUsageObject{
   153  							types.BuildCacheObject,
   154  						},
   155  					},
   156  					expected: types.DiskUsage{
   157  						BuildCache: stepDU.BuildCache,
   158  					},
   159  				},
   160  				{
   161  					doc: "container, volume types",
   162  					options: types.DiskUsageOptions{
   163  						Types: []types.DiskUsageObject{
   164  							types.ContainerObject,
   165  							types.VolumeObject,
   166  						},
   167  					},
   168  					expected: types.DiskUsage{
   169  						Containers: stepDU.Containers,
   170  						Volumes:    stepDU.Volumes,
   171  					},
   172  				},
   173  				{
   174  					doc: "image, build-cache types",
   175  					options: types.DiskUsageOptions{
   176  						Types: []types.DiskUsageObject{
   177  							types.ImageObject,
   178  							types.BuildCacheObject,
   179  						},
   180  					},
   181  					expected: types.DiskUsage{
   182  						LayersSize: stepDU.LayersSize,
   183  						Images:     stepDU.Images,
   184  						BuildCache: stepDU.BuildCache,
   185  					},
   186  				},
   187  				{
   188  					doc: "container, volume, build-cache types",
   189  					options: types.DiskUsageOptions{
   190  						Types: []types.DiskUsageObject{
   191  							types.ContainerObject,
   192  							types.VolumeObject,
   193  							types.BuildCacheObject,
   194  						},
   195  					},
   196  					expected: types.DiskUsage{
   197  						Containers: stepDU.Containers,
   198  						Volumes:    stepDU.Volumes,
   199  						BuildCache: stepDU.BuildCache,
   200  					},
   201  				},
   202  				{
   203  					doc: "image, volume, build-cache types",
   204  					options: types.DiskUsageOptions{
   205  						Types: []types.DiskUsageObject{
   206  							types.ImageObject,
   207  							types.VolumeObject,
   208  							types.BuildCacheObject,
   209  						},
   210  					},
   211  					expected: types.DiskUsage{
   212  						LayersSize: stepDU.LayersSize,
   213  						Images:     stepDU.Images,
   214  						Volumes:    stepDU.Volumes,
   215  						BuildCache: stepDU.BuildCache,
   216  					},
   217  				},
   218  				{
   219  					doc: "container, image, volume types",
   220  					options: types.DiskUsageOptions{
   221  						Types: []types.DiskUsageObject{
   222  							types.ContainerObject,
   223  							types.ImageObject,
   224  							types.VolumeObject,
   225  						},
   226  					},
   227  					expected: types.DiskUsage{
   228  						LayersSize: stepDU.LayersSize,
   229  						Containers: stepDU.Containers,
   230  						Images:     stepDU.Images,
   231  						Volumes:    stepDU.Volumes,
   232  					},
   233  				},
   234  				{
   235  					doc: "container, image, volume, build-cache types",
   236  					options: types.DiskUsageOptions{
   237  						Types: []types.DiskUsageObject{
   238  							types.ContainerObject,
   239  							types.ImageObject,
   240  							types.VolumeObject,
   241  							types.BuildCacheObject,
   242  						},
   243  					},
   244  					expected: types.DiskUsage{
   245  						LayersSize: stepDU.LayersSize,
   246  						Containers: stepDU.Containers,
   247  						Images:     stepDU.Images,
   248  						Volumes:    stepDU.Volumes,
   249  						BuildCache: stepDU.BuildCache,
   250  					},
   251  				},
   252  			} {
   253  				tc := tc
   254  				t.Run(tc.doc, func(t *testing.T) {
   255  					ctx := testutil.StartSpan(ctx, t)
   256  					// TODO: Run in parallel once https://github.com/moby/moby/pull/42560 is merged.
   257  
   258  					du, err := client.DiskUsage(ctx, tc.options)
   259  					assert.NilError(t, err)
   260  					assert.DeepEqual(t, du, tc.expected)
   261  				})
   262  			}
   263  		})
   264  	}
   265  }