github.com/rish1988/moby@v25.0.2+incompatible/integration/image/list_test.go (about) 1 package image // import "github.com/docker/docker/integration/image" 2 3 import ( 4 "fmt" 5 "strings" 6 "testing" 7 "time" 8 9 containertypes "github.com/docker/docker/api/types/container" 10 "github.com/docker/docker/api/types/filters" 11 "github.com/docker/docker/api/types/image" 12 "github.com/docker/docker/integration/internal/container" 13 "github.com/docker/docker/testutil" 14 "github.com/google/go-cmp/cmp/cmpopts" 15 "gotest.tools/v3/assert" 16 is "gotest.tools/v3/assert/cmp" 17 ) 18 19 // Regression : #38171 20 func TestImagesFilterMultiReference(t *testing.T) { 21 ctx := setupTest(t) 22 23 client := testEnv.APIClient() 24 25 name := strings.ToLower(t.Name()) 26 repoTags := []string{ 27 name + ":v1", 28 name + ":v2", 29 name + ":v3", 30 name + ":v4", 31 } 32 33 for _, repoTag := range repoTags { 34 err := client.ImageTag(ctx, "busybox:latest", repoTag) 35 assert.NilError(t, err) 36 } 37 38 filter := filters.NewArgs() 39 filter.Add("reference", repoTags[0]) 40 filter.Add("reference", repoTags[1]) 41 filter.Add("reference", repoTags[2]) 42 options := image.ListOptions{ 43 Filters: filter, 44 } 45 images, err := client.ImageList(ctx, options) 46 assert.NilError(t, err) 47 48 assert.Assert(t, is.Len(images, 1)) 49 assert.Check(t, is.Len(images[0].RepoTags, 3)) 50 for _, repoTag := range images[0].RepoTags { 51 if repoTag != repoTags[0] && repoTag != repoTags[1] && repoTag != repoTags[2] { 52 t.Errorf("list images doesn't match any repoTag we expected, repoTag: %s", repoTag) 53 } 54 } 55 } 56 57 func TestImagesFilterUntil(t *testing.T) { 58 ctx := setupTest(t) 59 60 client := testEnv.APIClient() 61 62 name := strings.ToLower(t.Name()) 63 ctr := container.Create(ctx, t, client, container.WithName(name)) 64 65 imgs := make([]string, 5) 66 for i := range imgs { 67 if i > 0 { 68 // Make really really sure each image has a distinct timestamp. 69 time.Sleep(time.Millisecond) 70 } 71 id, err := client.ContainerCommit(ctx, ctr, containertypes.CommitOptions{Reference: fmt.Sprintf("%s:v%d", name, i)}) 72 assert.NilError(t, err) 73 imgs[i] = id.ID 74 } 75 76 olderImage, _, err := client.ImageInspectWithRaw(ctx, imgs[2]) 77 assert.NilError(t, err) 78 olderUntil := olderImage.Created 79 80 laterImage, _, err := client.ImageInspectWithRaw(ctx, imgs[3]) 81 assert.NilError(t, err) 82 laterUntil := laterImage.Created 83 84 filter := filters.NewArgs( 85 filters.Arg("since", imgs[0]), 86 filters.Arg("until", olderUntil), 87 filters.Arg("until", laterUntil), 88 filters.Arg("before", imgs[len(imgs)-1]), 89 ) 90 list, err := client.ImageList(ctx, image.ListOptions{Filters: filter}) 91 assert.NilError(t, err) 92 93 var listedIDs []string 94 for _, i := range list { 95 t.Logf("ImageList: ID=%v RepoTags=%v", i.ID, i.RepoTags) 96 listedIDs = append(listedIDs, i.ID) 97 } 98 assert.DeepEqual(t, listedIDs, imgs[1:2], cmpopts.SortSlices(func(a, b string) bool { return a < b })) 99 } 100 101 func TestImagesFilterBeforeSince(t *testing.T) { 102 ctx := setupTest(t) 103 104 client := testEnv.APIClient() 105 106 name := strings.ToLower(t.Name()) 107 ctr := container.Create(ctx, t, client, container.WithName(name)) 108 109 imgs := make([]string, 5) 110 for i := range imgs { 111 if i > 0 { 112 // Make really really sure each image has a distinct timestamp. 113 time.Sleep(time.Millisecond) 114 } 115 id, err := client.ContainerCommit(ctx, ctr, containertypes.CommitOptions{Reference: fmt.Sprintf("%s:v%d", name, i)}) 116 assert.NilError(t, err) 117 imgs[i] = id.ID 118 } 119 120 filter := filters.NewArgs( 121 filters.Arg("since", imgs[0]), 122 filters.Arg("before", imgs[len(imgs)-1]), 123 ) 124 list, err := client.ImageList(ctx, image.ListOptions{Filters: filter}) 125 assert.NilError(t, err) 126 127 var listedIDs []string 128 for _, i := range list { 129 t.Logf("ImageList: ID=%v RepoTags=%v", i.ID, i.RepoTags) 130 listedIDs = append(listedIDs, i.ID) 131 } 132 // The ImageList API sorts the list by created timestamp... truncated to 133 // 1-second precision. Since all the images were created within 134 // milliseconds of each other, listedIDs is effectively unordered and 135 // the assertion must therefore be order-independent. 136 assert.DeepEqual(t, listedIDs, imgs[1:len(imgs)-1], cmpopts.SortSlices(func(a, b string) bool { return a < b })) 137 } 138 139 func TestAPIImagesFilters(t *testing.T) { 140 ctx := setupTest(t) 141 client := testEnv.APIClient() 142 143 for _, n := range []string{"utest:tag1", "utest/docker:tag2", "utest:5000/docker:tag3"} { 144 err := client.ImageTag(ctx, "busybox:latest", n) 145 assert.NilError(t, err) 146 } 147 148 testcases := []struct { 149 name string 150 filters []filters.KeyValuePair 151 expectedImages int 152 expectedRepoTags int 153 }{ 154 { 155 name: "repository regex", 156 filters: []filters.KeyValuePair{filters.Arg("reference", "utest*/*")}, 157 expectedImages: 1, 158 expectedRepoTags: 2, 159 }, 160 { 161 name: "image name regex", 162 filters: []filters.KeyValuePair{filters.Arg("reference", "utest*")}, 163 expectedImages: 1, 164 expectedRepoTags: 1, 165 }, 166 { 167 name: "image name without a tag", 168 filters: []filters.KeyValuePair{filters.Arg("reference", "utest")}, 169 expectedImages: 1, 170 expectedRepoTags: 1, 171 }, 172 { 173 name: "registry port regex", 174 filters: []filters.KeyValuePair{filters.Arg("reference", "*5000*/*")}, 175 expectedImages: 1, 176 expectedRepoTags: 1, 177 }, 178 } 179 180 for _, tc := range testcases { 181 tc := tc 182 t.Run(tc.name, func(t *testing.T) { 183 t.Parallel() 184 185 ctx := testutil.StartSpan(ctx, t) 186 images, err := client.ImageList(ctx, image.ListOptions{ 187 Filters: filters.NewArgs(tc.filters...), 188 }) 189 assert.Check(t, err) 190 assert.Assert(t, is.Len(images, tc.expectedImages)) 191 assert.Check(t, is.Len(images[0].RepoTags, tc.expectedRepoTags)) 192 }) 193 } 194 }