GitOps for k8s
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

images_test.go 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package update
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/stretchr/testify/assert"
  6. "github.com/fluxcd/flux/image"
  7. "github.com/fluxcd/flux/policy"
  8. "github.com/fluxcd/flux/registry/mock"
  9. )
  10. var (
  11. name = mustParseName("index.docker.io/weaveworks/helloworld").CanonicalName()
  12. infos = []image.Info{
  13. {ID: name.ToRef("v1"), CreatedAt: time.Now().Add(-time.Hour)},
  14. {ID: name.ToRef("v2"), CreatedAt: time.Now()},
  15. }
  16. )
  17. func buildImageRepos(t *testing.T) ImageRepos {
  18. registry := mock.Registry{Images: infos}
  19. repoMetadata, err := registry.GetImageRepositoryMetadata(name.Name)
  20. assert.NoError(t, err)
  21. return ImageRepos{
  22. imageRepos: imageReposMap{name.Name.CanonicalName(): repoMetadata},
  23. }
  24. }
  25. func getFilteredAndSortedImagesFromRepos(t *testing.T, imageName string, repos ImageRepos) SortedImageInfos {
  26. metadata := repos.GetRepositoryMetadata(mustParseName(imageName))
  27. images, err := FilterAndSortRepositoryMetadata(metadata, policy.PatternAll)
  28. assert.NoError(t, err)
  29. return images
  30. }
  31. // TestDecanon checks that we return appropriate image names when
  32. // asked for images. The registry (cache) stores things with canonical
  33. // names (e.g., `index.docker.io/library/alpine`), but we ask
  34. // questions in terms of everyday names (e.g., `alpine`).
  35. func TestDecanon(t *testing.T) {
  36. imageRepos := buildImageRepos(t)
  37. images := getFilteredAndSortedImagesFromRepos(t, "weaveworks/helloworld", imageRepos)
  38. latest, ok := images.Latest()
  39. if !ok {
  40. t.Error("did not find latest image")
  41. } else if latest.ID.Name != mustParseName("weaveworks/helloworld") {
  42. t.Error("name did not match what was asked")
  43. }
  44. images = getFilteredAndSortedImagesFromRepos(t, "index.docker.io/weaveworks/helloworld", imageRepos)
  45. latest, ok = images.Latest()
  46. if !ok {
  47. t.Error("did not find latest image")
  48. } else if latest.ID.Name != mustParseName("index.docker.io/weaveworks/helloworld") {
  49. t.Error("name did not match what was asked")
  50. }
  51. avail := getFilteredAndSortedImagesFromRepos(t, "weaveworks/helloworld", imageRepos)
  52. if len(avail) != len(infos) {
  53. t.Errorf("expected %d available images, got %d", len(infos), len(avail))
  54. }
  55. for _, im := range avail {
  56. if im.ID.Name != mustParseName("weaveworks/helloworld") {
  57. t.Errorf("got image with name %q", im.ID.String())
  58. }
  59. }
  60. }
  61. func TestMetadataInConsistencyTolerance(t *testing.T) {
  62. imageRepos := buildImageRepos(t)
  63. metadata := imageRepos.GetRepositoryMetadata(mustParseName("weaveworks/helloworld"))
  64. images, err := FilterAndSortRepositoryMetadata(metadata, policy.NewPattern("semver:*"))
  65. assert.NoError(t, err)
  66. // Let's make the metadata inconsistent by adding a non-semver tag
  67. metadata.Tags = append(metadata.Tags, "latest")
  68. // Filtering and sorting should still work
  69. images2, err := FilterAndSortRepositoryMetadata(metadata, policy.NewPattern("semver:*"))
  70. assert.NoError(t, err)
  71. assert.Equal(t, images, images2)
  72. // However, an inconsistency in a semver tag should make filtering and sorting fail
  73. metadata.Tags = append(metadata.Tags, "v9")
  74. _, err = FilterAndSortRepositoryMetadata(metadata, policy.NewPattern("semver:*"))
  75. assert.Error(t, err)
  76. }
  77. func TestImageInfos_Filter_latest(t *testing.T) {
  78. latest := image.Info{
  79. ID: image.Ref{Name: image.Name{Image: "flux"}, Tag: "latest"},
  80. }
  81. other := image.Info{
  82. ID: image.Ref{Name: image.Name{Image: "moon"}, Tag: "v0"},
  83. }
  84. images := []image.Info{latest, other}
  85. assert.Equal(t, []image.Info{latest}, filterImages(images, policy.PatternLatest))
  86. assert.Equal(t, []image.Info{latest}, filterImages(images, policy.NewPattern("latest")))
  87. assert.Equal(t, []image.Info{other}, filterImages(images, policy.PatternAll))
  88. assert.Equal(t, []image.Info{other}, filterImages(images, policy.NewPattern("*")))
  89. }
  90. func TestImageInfos_Filter_semver(t *testing.T) {
  91. latest := image.Info{ID: image.Ref{Name: image.Name{Image: "flux"}, Tag: "latest"}}
  92. semver0 := image.Info{ID: image.Ref{Name: image.Name{Image: "moon"}, Tag: "v0.0.1"}}
  93. semver1 := image.Info{ID: image.Ref{Name: image.Name{Image: "earth"}, Tag: "1.0.0"}}
  94. filterAndSort := func(images []image.Info, pattern policy.Pattern) SortedImageInfos {
  95. filtered := FilterImages(images, pattern)
  96. return SortImages(filtered, pattern)
  97. }
  98. images := []image.Info{latest, semver0, semver1}
  99. assert.Equal(t, SortedImageInfos{semver1, semver0}, filterAndSort(images, policy.NewPattern("semver:*")))
  100. assert.Equal(t, SortedImageInfos{semver1}, filterAndSort(images, policy.NewPattern("semver:~1")))
  101. }
  102. func TestAvail(t *testing.T) {
  103. imageRepos := buildImageRepos(t)
  104. avail := getFilteredAndSortedImagesFromRepos(t, "weaveworks/goodbyeworld", imageRepos)
  105. if len(avail) > 0 {
  106. t.Errorf("did not expect available images, but got %#v", avail)
  107. }
  108. }
  109. func mustParseName(im string) image.Name {
  110. ref, err := image.ParseRef(im)
  111. if err != nil {
  112. panic(err)
  113. }
  114. return ref.Name
  115. }