list_test.go 4.3 KB

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