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  }