list_test.go 5.4 KB

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