github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/pkg/client/pull_buildpack_test.go (about) 1 package client_test 2 3 import ( 4 "bytes" 5 "context" 6 "os" 7 "path/filepath" 8 "runtime" 9 "strings" 10 "testing" 11 12 "github.com/buildpacks/imgutil/fakes" 13 "github.com/golang/mock/gomock" 14 "github.com/heroku/color" 15 "github.com/sclevine/spec" 16 "github.com/sclevine/spec/report" 17 18 cfg "github.com/buildpacks/pack/internal/config" 19 "github.com/buildpacks/pack/internal/registry" 20 "github.com/buildpacks/pack/pkg/client" 21 "github.com/buildpacks/pack/pkg/image" 22 "github.com/buildpacks/pack/pkg/logging" 23 "github.com/buildpacks/pack/pkg/testmocks" 24 h "github.com/buildpacks/pack/testhelpers" 25 ) 26 27 func TestPullBuildpack(t *testing.T) { 28 color.Disable(true) 29 defer color.Disable(false) 30 spec.Run(t, "PackageBuildpack", testPullBuildpack, spec.Parallel(), spec.Report(report.Terminal{})) 31 } 32 33 func testPullBuildpack(t *testing.T, when spec.G, it spec.S) { 34 var ( 35 subject *client.Client 36 mockController *gomock.Controller 37 mockDownloader *testmocks.MockBlobDownloader 38 mockImageFactory *testmocks.MockImageFactory 39 mockImageFetcher *testmocks.MockImageFetcher 40 mockDockerClient *testmocks.MockCommonAPIClient 41 out bytes.Buffer 42 ) 43 44 it.Before(func() { 45 mockController = gomock.NewController(t) 46 mockDownloader = testmocks.NewMockBlobDownloader(mockController) 47 mockImageFactory = testmocks.NewMockImageFactory(mockController) 48 mockImageFetcher = testmocks.NewMockImageFetcher(mockController) 49 mockDockerClient = testmocks.NewMockCommonAPIClient(mockController) 50 51 var err error 52 subject, err = client.NewClient( 53 client.WithLogger(logging.NewLogWithWriters(&out, &out)), 54 client.WithDownloader(mockDownloader), 55 client.WithImageFactory(mockImageFactory), 56 client.WithFetcher(mockImageFetcher), 57 client.WithDockerClient(mockDockerClient), 58 ) 59 h.AssertNil(t, err) 60 }) 61 62 it.After(func() { 63 mockController.Finish() 64 }) 65 66 when("buildpack has issues", func() { 67 it("should fail if not in the registry", func() { 68 err := subject.PullBuildpack(context.TODO(), client.PullBuildpackOptions{ 69 URI: "invalid/image", 70 RegistryName: registry.DefaultRegistryName, 71 }) 72 h.AssertError(t, err, "locating in registry") 73 }) 74 75 it("should fail if it's a URI type", func() { 76 err := subject.PullBuildpack(context.TODO(), client.PullBuildpackOptions{ 77 URI: "file://some-file", 78 }) 79 h.AssertError(t, err, "unsupported buildpack URI type: 'URILocator'") 80 }) 81 82 it("should fail if not a valid URI", func() { 83 err := subject.PullBuildpack(context.TODO(), client.PullBuildpackOptions{ 84 URI: "G@Rb*g3_", 85 }) 86 h.AssertError(t, err, "invalid buildpack URI") 87 }) 88 }) 89 90 when("pulling from a docker registry", func() { 91 it("should fetch the image", func() { 92 packageImage := fakes.NewImage("example.com/some/package:1.0.0", "", nil) 93 h.AssertNil(t, packageImage.SetLabel("io.buildpacks.buildpackage.metadata", `{}`)) 94 h.AssertNil(t, packageImage.SetLabel("io.buildpacks.buildpack.layers", `{}`)) 95 mockImageFetcher.EXPECT().Fetch(gomock.Any(), packageImage.Name(), image.FetchOptions{Daemon: true, PullPolicy: image.PullAlways}).Return(packageImage, nil) 96 97 h.AssertNil(t, subject.PullBuildpack(context.TODO(), client.PullBuildpackOptions{ 98 URI: "example.com/some/package:1.0.0", 99 })) 100 }) 101 }) 102 103 when("pulling from a buildpack registry", func() { 104 var ( 105 tmpDir string 106 registryFixture string 107 packHome string 108 ) 109 110 it.Before(func() { 111 var err error 112 tmpDir, err = os.MkdirTemp("", "registry") 113 h.AssertNil(t, err) 114 115 packHome = filepath.Join(tmpDir, ".pack") 116 err = os.MkdirAll(packHome, 0755) 117 h.AssertNil(t, err) 118 os.Setenv("PACK_HOME", packHome) 119 120 registryFixture = h.CreateRegistryFixture(t, tmpDir, filepath.Join("testdata", "registry")) 121 122 packageImage := fakes.NewImage("example.com/some/package@sha256:74eb48882e835d8767f62940d453eb96ed2737de3a16573881dcea7dea769df7", "", nil) 123 packageImage.SetLabel("io.buildpacks.buildpackage.metadata", `{}`) 124 packageImage.SetLabel("io.buildpacks.buildpack.layers", `{}`) 125 mockImageFetcher.EXPECT().Fetch(gomock.Any(), packageImage.Name(), image.FetchOptions{Daemon: true, PullPolicy: image.PullAlways}).Return(packageImage, nil) 126 127 packHome := filepath.Join(tmpDir, "packHome") 128 h.AssertNil(t, os.Setenv("PACK_HOME", packHome)) 129 configPath := filepath.Join(packHome, "config.toml") 130 h.AssertNil(t, cfg.Write(cfg.Config{ 131 Registries: []cfg.Registry{ 132 { 133 Name: "some-registry", 134 Type: "github", 135 URL: registryFixture, 136 }, 137 }, 138 }, configPath)) 139 }) 140 141 it.After(func() { 142 os.Unsetenv("PACK_HOME") 143 err := os.RemoveAll(tmpDir) 144 if runtime.GOOS != "windows" && err != nil && strings.Contains(err.Error(), "The process cannot access the file because it is being used by another process.") { 145 h.AssertNil(t, err) 146 } 147 }) 148 149 it("should fetch the image", func() { 150 h.AssertNil(t, subject.PullBuildpack(context.TODO(), client.PullBuildpackOptions{ 151 URI: "example/foo@1.1.0", 152 RegistryName: "some-registry", 153 })) 154 }) 155 }) 156 }