github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/pkg/index/index_factory_test.go (about) 1 package index_test 2 3 import ( 4 "fmt" 5 "os" 6 "testing" 7 8 "github.com/buildpacks/imgutil" 9 "github.com/google/go-containerregistry/pkg/authn" 10 "github.com/google/go-containerregistry/pkg/name" 11 v1 "github.com/google/go-containerregistry/pkg/v1" 12 "github.com/google/go-containerregistry/pkg/v1/random" 13 "github.com/google/go-containerregistry/pkg/v1/remote" 14 "github.com/heroku/color" 15 "github.com/sclevine/spec" 16 "github.com/sclevine/spec/report" 17 18 "github.com/buildpacks/pack/pkg/index" 19 h "github.com/buildpacks/pack/testhelpers" 20 ) 21 22 var dockerRegistry *h.TestRegistryConfig 23 24 func TestIndexFactory(t *testing.T) { 25 color.Disable(true) 26 defer color.Disable(false) 27 28 h.RequireDocker(t) 29 30 dockerRegistry = h.RunRegistry(t) 31 defer dockerRegistry.StopRegistry(t) 32 33 os.Setenv("DOCKER_CONFIG", dockerRegistry.DockerConfigDir) 34 spec.Run(t, "Fetcher", testIndexFactory, spec.Parallel(), spec.Report(report.Terminal{})) 35 } 36 37 func testIndexFactory(t *testing.T, when spec.G, it spec.S) { 38 var ( 39 indexFactory *index.IndexFactory 40 imageIndex imgutil.ImageIndex 41 indexRepoName string 42 err error 43 tmpDir string 44 ) 45 46 it.Before(func() { 47 tmpDir, err = os.MkdirTemp("", "index-factory-test") 48 h.AssertNil(t, err) 49 indexFactory = index.NewIndexFactory(authn.DefaultKeychain, tmpDir) 50 }) 51 52 it.After(func() { 53 os.RemoveAll(tmpDir) 54 }) 55 56 when("#CreateIndex", func() { 57 it.Before(func() { 58 indexRepoName = h.NewRandomIndexRepoName() 59 }) 60 61 when("no options are provided", func() { 62 it("creates an image index", func() { 63 imageIndex, err = indexFactory.CreateIndex(indexRepoName) 64 h.AssertNil(t, err) 65 h.AssertNotNil(t, imageIndex) 66 }) 67 }) 68 }) 69 70 when("#Exists", func() { 71 when("index exists on disk", func() { 72 it.Before(func() { 73 indexRepoName = h.NewRandomIndexRepoName() 74 setUpLocalIndex(t, indexFactory, indexRepoName) 75 }) 76 77 it("returns true", func() { 78 h.AssertTrue(t, indexFactory.Exists(indexRepoName)) 79 }) 80 }) 81 82 when("index does not exist on disk", func() { 83 it.Before(func() { 84 indexRepoName = h.NewRandomIndexRepoName() 85 }) 86 87 it("returns false", func() { 88 h.AssertFalse(t, indexFactory.Exists(indexRepoName)) 89 }) 90 }) 91 }) 92 93 when("#LoadIndex", func() { 94 when("index exists on disk", func() { 95 it.Before(func() { 96 indexRepoName = h.NewRandomIndexRepoName() 97 setUpLocalIndex(t, indexFactory, indexRepoName) 98 }) 99 100 it("loads the index from disk", func() { 101 imageIndex, err = indexFactory.LoadIndex(indexRepoName) 102 h.AssertNil(t, err) 103 h.AssertNotNil(t, imageIndex) 104 }) 105 }) 106 107 when("index does not exist on disk", func() { 108 it.Before(func() { 109 indexRepoName = h.NewRandomIndexRepoName() 110 }) 111 112 it("errors with a message", func() { 113 _, err = indexFactory.LoadIndex(indexRepoName) 114 h.AssertError(t, err, fmt.Sprintf("Image: '%s' not found", indexRepoName)) 115 }) 116 }) 117 }) 118 119 when("#FetchIndex", func() { 120 when("index exists in a remote registry", func() { 121 var remoteIndexRepoName string 122 123 it.Before(func() { 124 indexRepoName = h.NewRandomIndexRepoName() 125 remoteIndexRepoName = newTestImageIndexName("fetch-remote") 126 setUpRandomRemoteIndex(t, remoteIndexRepoName, 1, 1) 127 }) 128 129 it("creates an index with the underlying remote index", func() { 130 _, err = indexFactory.FetchIndex(indexRepoName, imgutil.FromBaseIndex(remoteIndexRepoName)) 131 h.AssertNil(t, err) 132 }) 133 }) 134 135 when("index does not exist in a remote registry", func() { 136 it.Before(func() { 137 indexRepoName = h.NewRandomIndexRepoName() 138 }) 139 140 it("errors with a message", func() { 141 _, err = indexFactory.FetchIndex(indexRepoName, imgutil.FromBaseIndex(indexRepoName)) 142 h.AssertNotNil(t, err) 143 }) 144 }) 145 }) 146 147 when("#FindIndex", func() { 148 when("index exists on disk", func() { 149 it.Before(func() { 150 indexRepoName = h.NewRandomIndexRepoName() 151 setUpLocalIndex(t, indexFactory, indexRepoName) 152 }) 153 154 it("finds the index on disk", func() { 155 imageIndex, err = indexFactory.FindIndex(indexRepoName) 156 h.AssertNil(t, err) 157 h.AssertNotNil(t, imageIndex) 158 }) 159 }) 160 161 when("index exists in a remote registry", func() { 162 it.Before(func() { 163 indexRepoName = newTestImageIndexName("find-remote") 164 setUpRandomRemoteIndex(t, indexRepoName, 1, 1) 165 }) 166 167 it("finds the index in the remote registry", func() { 168 imageIndex, err = indexFactory.FindIndex(indexRepoName) 169 h.AssertNil(t, err) 170 h.AssertNotNil(t, imageIndex) 171 }) 172 }) 173 }) 174 } 175 176 func setUpLocalIndex(t *testing.T, indexFactory *index.IndexFactory, indexRepoName string) { 177 imageIndex, err := indexFactory.CreateIndex(indexRepoName) 178 h.AssertNil(t, err) 179 h.AssertNil(t, imageIndex.SaveDir()) 180 } 181 182 func newTestImageIndexName(name string) string { 183 return dockerRegistry.RepoName(name + "-" + h.RandString(10)) 184 } 185 186 // setUpRandomRemoteIndex creates a random image index with the provided (count) number of manifest 187 // each manifest will have the provided number of layers 188 func setUpRandomRemoteIndex(t *testing.T, repoName string, layers, count int64) v1.ImageIndex { 189 ref, err := name.ParseReference(repoName, name.WeakValidation) 190 h.AssertNil(t, err) 191 192 randomIndex, err := random.Index(1024, layers, count) 193 h.AssertNil(t, err) 194 195 err = remote.WriteIndex(ref, randomIndex, remote.WithAuthFromKeychain(authn.DefaultKeychain)) 196 h.AssertNil(t, err) 197 198 return randomIndex 199 }