github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/internal/commands/inspect_buildpack_test.go (about)

     1  package commands_test
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/buildpacks/lifecycle/api"
     9  	"github.com/golang/mock/gomock"
    10  	"github.com/heroku/color"
    11  	"github.com/pkg/errors"
    12  	"github.com/sclevine/spec"
    13  	"github.com/sclevine/spec/report"
    14  	"github.com/spf13/cobra"
    15  
    16  	"github.com/buildpacks/pack/internal/commands"
    17  	"github.com/buildpacks/pack/internal/commands/testmocks"
    18  	"github.com/buildpacks/pack/internal/config"
    19  	"github.com/buildpacks/pack/pkg/buildpack"
    20  	"github.com/buildpacks/pack/pkg/client"
    21  	"github.com/buildpacks/pack/pkg/dist"
    22  	"github.com/buildpacks/pack/pkg/image"
    23  	"github.com/buildpacks/pack/pkg/logging"
    24  	h "github.com/buildpacks/pack/testhelpers"
    25  )
    26  
    27  func TestInspectBuildpackCommand(t *testing.T) {
    28  	color.Disable(true)
    29  	defer color.Disable(false)
    30  	spec.Run(t, "InspectBuildpackCommand", testInspectBuildpackCommand, spec.Sequential(), spec.Report(report.Terminal{}))
    31  }
    32  
    33  func testInspectBuildpackCommand(t *testing.T, when spec.G, it spec.S) {
    34  	apiVersion, err := api.NewVersion("0.2")
    35  	if err != nil {
    36  		t.Fail()
    37  	}
    38  
    39  	var (
    40  		command        *cobra.Command
    41  		logger         logging.Logger
    42  		outBuf         bytes.Buffer
    43  		mockController *gomock.Controller
    44  		mockClient     *testmocks.MockPackClient
    45  		cfg            config.Config
    46  		complexInfo    *client.BuildpackInfo
    47  		simpleInfo     *client.BuildpackInfo
    48  		assert         = h.NewAssertionManager(t)
    49  	)
    50  
    51  	it.Before(func() {
    52  		mockController = gomock.NewController(t)
    53  		mockClient = testmocks.NewMockPackClient(mockController)
    54  		logger = logging.NewLogWithWriters(&outBuf, &outBuf)
    55  
    56  		cfg = config.Config{
    57  			DefaultRegistry: "default-registry",
    58  		}
    59  
    60  		complexInfo = &client.BuildpackInfo{
    61  			BuildpackMetadata: buildpack.Metadata{
    62  				ModuleInfo: dist.ModuleInfo{
    63  					ID:       "some/top-buildpack",
    64  					Version:  "0.0.1",
    65  					Homepage: "top-buildpack-homepage",
    66  				},
    67  				Stacks: []dist.Stack{
    68  					{ID: "io.buildpacks.stacks.first-stack", Mixins: []string{"mixin1", "mixin2", "build:mixin3", "build:mixin4"}},
    69  					{ID: "io.buildpacks.stacks.second-stack", Mixins: []string{"mixin1", "mixin2"}},
    70  				},
    71  			},
    72  			Buildpacks: []dist.ModuleInfo{
    73  				{
    74  					ID:       "some/first-inner-buildpack",
    75  					Version:  "1.0.0",
    76  					Homepage: "first-inner-buildpack-homepage",
    77  				},
    78  				{
    79  					ID:       "some/second-inner-buildpack",
    80  					Version:  "2.0.0",
    81  					Homepage: "second-inner-buildpack-homepage",
    82  				},
    83  				{
    84  					ID:       "some/third-inner-buildpack",
    85  					Version:  "3.0.0",
    86  					Homepage: "third-inner-buildpack-homepage",
    87  				},
    88  				{
    89  					ID:       "some/top-buildpack",
    90  					Version:  "0.0.1",
    91  					Homepage: "top-buildpack-homepage",
    92  					Name:     "top",
    93  				},
    94  			},
    95  			Order: dist.Order{
    96  				{
    97  					Group: []dist.ModuleRef{
    98  						{
    99  							ModuleInfo: dist.ModuleInfo{
   100  								ID:       "some/top-buildpack",
   101  								Version:  "0.0.1",
   102  								Homepage: "top-buildpack-homepage",
   103  							},
   104  							Optional: false,
   105  						},
   106  					},
   107  				},
   108  			},
   109  			BuildpackLayers: dist.ModuleLayers{
   110  				"some/first-inner-buildpack": {
   111  					"1.0.0": {
   112  						API: apiVersion,
   113  						Stacks: []dist.Stack{
   114  							{ID: "io.buildpacks.stacks.first-stack", Mixins: []string{"mixin1", "mixin2", "build:mixin3", "build:mixin4"}},
   115  							{ID: "io.buildpacks.stacks.second-stack", Mixins: []string{"mixin1", "mixin2"}},
   116  						},
   117  						Order: dist.Order{
   118  							{
   119  								Group: []dist.ModuleRef{
   120  									{
   121  										ModuleInfo: dist.ModuleInfo{
   122  											ID:      "some/first-inner-buildpack",
   123  											Version: "1.0.0",
   124  										},
   125  										Optional: false,
   126  									},
   127  									{
   128  										ModuleInfo: dist.ModuleInfo{
   129  											ID:      "some/third-inner-buildpack",
   130  											Version: "3.0.0",
   131  										},
   132  										Optional: false,
   133  									},
   134  								},
   135  							},
   136  							{
   137  								Group: []dist.ModuleRef{
   138  									{
   139  										ModuleInfo: dist.ModuleInfo{
   140  											ID:      "some/third-inner-buildpack",
   141  											Version: "3.0.0",
   142  										},
   143  										Optional: false,
   144  									},
   145  								},
   146  							},
   147  						},
   148  						LayerDiffID: "sha256:first-inner-buildpack-diff-id",
   149  						Homepage:    "first-inner-buildpack-homepage",
   150  					},
   151  				},
   152  				"some/second-inner-buildpack": {
   153  					"2.0.0": {
   154  						API: apiVersion,
   155  						Stacks: []dist.Stack{
   156  							{ID: "io.buildpacks.stacks.first-stack", Mixins: []string{"mixin1", "mixin2", "build:mixin3", "build:mixin4"}},
   157  							{ID: "io.buildpacks.stacks.second-stack", Mixins: []string{"mixin1", "mixin2"}},
   158  						},
   159  						LayerDiffID: "sha256:second-inner-buildpack-diff-id",
   160  						Homepage:    "second-inner-buildpack-homepage",
   161  					},
   162  				},
   163  				"some/third-inner-buildpack": {
   164  					"3.0.0": {
   165  						API: apiVersion,
   166  						Stacks: []dist.Stack{
   167  							{ID: "io.buildpacks.stacks.first-stack", Mixins: []string{"mixin1", "mixin2", "build:mixin3", "build:mixin4"}},
   168  							{ID: "io.buildpacks.stacks.second-stack", Mixins: []string{"mixin1", "mixin2"}},
   169  						},
   170  						LayerDiffID: "sha256:third-inner-buildpack-diff-id",
   171  						Homepage:    "third-inner-buildpack-homepage",
   172  					},
   173  				},
   174  				"some/top-buildpack": {
   175  					"0.0.1": {
   176  						API: apiVersion,
   177  						Order: dist.Order{
   178  							{
   179  								Group: []dist.ModuleRef{
   180  									{
   181  										ModuleInfo: dist.ModuleInfo{
   182  											ID:      "some/first-inner-buildpack",
   183  											Version: "1.0.0",
   184  										},
   185  										Optional: false,
   186  									},
   187  									{
   188  										ModuleInfo: dist.ModuleInfo{
   189  											ID:      "some/second-inner-buildpack",
   190  											Version: "2.0.0",
   191  										},
   192  										Optional: false,
   193  									},
   194  								},
   195  							},
   196  							{
   197  								Group: []dist.ModuleRef{
   198  									{
   199  										ModuleInfo: dist.ModuleInfo{
   200  											ID:      "some/first-inner-buildpack",
   201  											Version: "1.0.0",
   202  										},
   203  										Optional: false,
   204  									},
   205  								},
   206  							},
   207  						},
   208  						LayerDiffID: "sha256:top-buildpack-diff-id",
   209  						Homepage:    "top-buildpack-homepage",
   210  					},
   211  				},
   212  			},
   213  		}
   214  
   215  		simpleInfo = &client.BuildpackInfo{
   216  			BuildpackMetadata: buildpack.Metadata{
   217  				ModuleInfo: dist.ModuleInfo{
   218  					ID:       "some/single-buildpack",
   219  					Version:  "0.0.1",
   220  					Homepage: "single-homepage-homepace",
   221  				},
   222  				Stacks: []dist.Stack{
   223  					{ID: "io.buildpacks.stacks.first-stack", Mixins: []string{"mixin1", "mixin2", "build:mixin3", "build:mixin4"}},
   224  					{ID: "io.buildpacks.stacks.second-stack", Mixins: []string{"mixin1", "mixin2"}},
   225  				},
   226  			},
   227  			Buildpacks: []dist.ModuleInfo{
   228  				{
   229  					ID:       "some/single-buildpack",
   230  					Version:  "0.0.1",
   231  					Homepage: "single-buildpack-homepage",
   232  					Name:     "some",
   233  				},
   234  				{
   235  					ID:      "some/buildpack-no-homepage",
   236  					Version: "0.0.2",
   237  				},
   238  			},
   239  			Order: dist.Order{
   240  				{
   241  					Group: []dist.ModuleRef{
   242  						{
   243  							ModuleInfo: dist.ModuleInfo{
   244  								ID:       "some/single-buildpack",
   245  								Version:  "0.0.1",
   246  								Homepage: "single-buildpack-homepage",
   247  							},
   248  							Optional: false,
   249  						},
   250  					},
   251  				},
   252  			},
   253  			BuildpackLayers: dist.ModuleLayers{
   254  				"some/single-buildpack": {
   255  					"0.0.1": {
   256  						API: apiVersion,
   257  						Stacks: []dist.Stack{
   258  							{ID: "io.buildpacks.stacks.first-stack", Mixins: []string{"mixin1", "mixin2", "build:mixin3", "build:mixin4"}},
   259  							{ID: "io.buildpacks.stacks.second-stack", Mixins: []string{"mixin1", "mixin2"}},
   260  						},
   261  						LayerDiffID: "sha256:single-buildpack-diff-id",
   262  						Homepage:    "single-buildpack-homepage",
   263  					},
   264  				},
   265  			},
   266  		}
   267  
   268  		command = commands.InspectBuildpack(logger, cfg, mockClient)
   269  	})
   270  
   271  	when("InspectBuildpack", func() {
   272  		when("inspecting an image", func() {
   273  			when("both remote and local image are present", func() {
   274  				it.Before(func() {
   275  					complexInfo.Location = buildpack.PackageLocator
   276  					simpleInfo.Location = buildpack.PackageLocator
   277  
   278  					mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   279  						BuildpackName: "test/buildpack",
   280  						Daemon:        true,
   281  						Registry:      "default-registry",
   282  					}).Return(complexInfo, nil)
   283  
   284  					mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   285  						BuildpackName: "test/buildpack",
   286  						Daemon:        false,
   287  						Registry:      "default-registry",
   288  					}).Return(simpleInfo, nil)
   289  				})
   290  
   291  				it("succeeds", func() {
   292  					command.SetArgs([]string{"test/buildpack"})
   293  					assert.Nil(command.Execute())
   294  
   295  					localOutputSection := fmt.Sprintf(inspectOutputTemplate,
   296  						"test/buildpack",
   297  						"LOCAL IMAGE:",
   298  						complexOutputSection)
   299  
   300  					remoteOutputSection := fmt.Sprintf("%s\n\n%s",
   301  						"REMOTE IMAGE:",
   302  						simpleOutputSection)
   303  
   304  					assert.AssertTrimmedContains(outBuf.String(), localOutputSection)
   305  					assert.AssertTrimmedContains(outBuf.String(), remoteOutputSection)
   306  				})
   307  			})
   308  			when("only a local image is present", func() {
   309  				it.Before(func() {
   310  					complexInfo.Location = buildpack.PackageLocator
   311  					simpleInfo.Location = buildpack.PackageLocator
   312  
   313  					mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   314  						BuildpackName: "only-local-test/buildpack",
   315  						Daemon:        true,
   316  						Registry:      "default-registry",
   317  					}).Return(complexInfo, nil)
   318  
   319  					mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   320  						BuildpackName: "only-local-test/buildpack",
   321  						Daemon:        false,
   322  						Registry:      "default-registry",
   323  					}).Return(nil, errors.Wrap(image.ErrNotFound, "remote image not found!"))
   324  				})
   325  
   326  				it("displays output for local image", func() {
   327  					command.SetArgs([]string{"only-local-test/buildpack"})
   328  					assert.Nil(command.Execute())
   329  
   330  					expectedOutput := fmt.Sprintf(inspectOutputTemplate,
   331  						"only-local-test/buildpack",
   332  						"LOCAL IMAGE:",
   333  						complexOutputSection)
   334  
   335  					assert.AssertTrimmedContains(outBuf.String(), expectedOutput)
   336  				})
   337  			})
   338  			when("only a remote image is present", func() {
   339  				it.Before(func() {
   340  					complexInfo.Location = buildpack.PackageLocator
   341  					simpleInfo.Location = buildpack.PackageLocator
   342  
   343  					mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   344  						BuildpackName: "only-remote-test/buildpack",
   345  						Daemon:        false,
   346  						Registry:      "default-registry",
   347  					}).Return(complexInfo, nil)
   348  
   349  					mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   350  						BuildpackName: "only-remote-test/buildpack",
   351  						Daemon:        true,
   352  						Registry:      "default-registry",
   353  					}).Return(nil, errors.Wrap(image.ErrNotFound, "remote image not found!"))
   354  				})
   355  
   356  				it("displays output for remote image", func() {
   357  					command.SetArgs([]string{"only-remote-test/buildpack"})
   358  					assert.Nil(command.Execute())
   359  
   360  					expectedOutput := fmt.Sprintf(inspectOutputTemplate,
   361  						"only-remote-test/buildpack",
   362  						"REMOTE IMAGE:",
   363  						complexOutputSection)
   364  
   365  					assert.AssertTrimmedContains(outBuf.String(), expectedOutput)
   366  				})
   367  			})
   368  			when("local docker daemon is not running", func() {
   369  				it.Before(func() {
   370  					complexInfo.Location = buildpack.PackageLocator
   371  					simpleInfo.Location = buildpack.PackageLocator
   372  
   373  					mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   374  						BuildpackName: "only-remote-test/buildpack",
   375  						Daemon:        false,
   376  						Registry:      "default-registry",
   377  					}).Return(complexInfo, nil)
   378  
   379  					mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   380  						BuildpackName: "only-remote-test/buildpack",
   381  						Daemon:        true,
   382  						Registry:      "default-registry",
   383  					}).Return(nil, errors.New("the docker daemon is not running"))
   384  				})
   385  
   386  				it("displays output for remote image", func() {
   387  					command.SetArgs([]string{"only-remote-test/buildpack"})
   388  					assert.Nil(command.Execute())
   389  
   390  					expectedOutput := fmt.Sprintf(inspectOutputTemplate,
   391  						"only-remote-test/buildpack",
   392  						"REMOTE IMAGE:",
   393  						complexOutputSection)
   394  
   395  					assert.AssertTrimmedContains(outBuf.String(), expectedOutput)
   396  				})
   397  			})
   398  		})
   399  
   400  		when("inspecting a buildpack uri", func() {
   401  			it.Before(func() {
   402  				simpleInfo.Location = buildpack.URILocator
   403  			})
   404  			when("uri is a local path", func() {
   405  				it.Before(func() {
   406  					mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   407  						BuildpackName: "/path/to/test/buildpack",
   408  						Daemon:        true,
   409  						Registry:      "default-registry",
   410  					}).Return(simpleInfo, nil)
   411  				})
   412  				it("succeeds", func() {
   413  					command.SetArgs([]string{"/path/to/test/buildpack"})
   414  					assert.Nil(command.Execute())
   415  
   416  					expectedOutput := fmt.Sprintf(inspectOutputTemplate,
   417  						"/path/to/test/buildpack",
   418  						"LOCAL ARCHIVE:",
   419  						simpleOutputSection)
   420  
   421  					assert.TrimmedEq(outBuf.String(), expectedOutput)
   422  				})
   423  			})
   424  			when("uri is an http or https location", func() {
   425  				it.Before(func() {
   426  					simpleInfo.Location = buildpack.URILocator
   427  				})
   428  				when("uri is a local path", func() {
   429  					it.Before(func() {
   430  						mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   431  							BuildpackName: "https://path/to/test/buildpack",
   432  							Daemon:        true,
   433  							Registry:      "default-registry",
   434  						}).Return(simpleInfo, nil)
   435  					})
   436  
   437  					it("succeeds", func() {
   438  						command.SetArgs([]string{"https://path/to/test/buildpack"})
   439  						assert.Nil(command.Execute())
   440  
   441  						expectedOutput := fmt.Sprintf(inspectOutputTemplate,
   442  							"https://path/to/test/buildpack",
   443  							"REMOTE ARCHIVE:",
   444  							simpleOutputSection)
   445  
   446  						assert.TrimmedEq(outBuf.String(), expectedOutput)
   447  					})
   448  				})
   449  			})
   450  		})
   451  
   452  		when("inspecting a buildpack on the registry", func() {
   453  			it.Before(func() {
   454  				simpleInfo.Location = buildpack.RegistryLocator
   455  			})
   456  			when("using the default registry", func() {
   457  				it.Before(func() {
   458  					mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   459  						BuildpackName: "urn:cnb:registry:test/buildpack",
   460  						Daemon:        true,
   461  						Registry:      "default-registry",
   462  					}).Return(simpleInfo, nil)
   463  				})
   464  				it("succeeds", func() {
   465  					command.SetArgs([]string{"urn:cnb:registry:test/buildpack"})
   466  					assert.Nil(command.Execute())
   467  
   468  					expectedOutput := fmt.Sprintf(inspectOutputTemplate,
   469  						"urn:cnb:registry:test/buildpack",
   470  						"REGISTRY IMAGE:",
   471  						simpleOutputSection)
   472  
   473  					assert.TrimmedEq(outBuf.String(), expectedOutput)
   474  				})
   475  			})
   476  			when("using a user provided registry", func() {
   477  				it.Before(func() {
   478  					mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   479  						BuildpackName: "urn:cnb:registry:test/buildpack",
   480  						Daemon:        true,
   481  						Registry:      "some-registry",
   482  					}).Return(simpleInfo, nil)
   483  				})
   484  
   485  				it("succeeds", func() {
   486  					command.SetArgs([]string{"urn:cnb:registry:test/buildpack", "-r", "some-registry"})
   487  					assert.Nil(command.Execute())
   488  
   489  					expectedOutput := fmt.Sprintf(inspectOutputTemplate,
   490  						"urn:cnb:registry:test/buildpack",
   491  						"REGISTRY IMAGE:",
   492  						simpleOutputSection)
   493  
   494  					assert.TrimmedEq(outBuf.String(), expectedOutput)
   495  				})
   496  			})
   497  		})
   498  
   499  		when("a depth flag is passed", func() {
   500  			it.Before(func() {
   501  				complexInfo.Location = buildpack.URILocator
   502  
   503  				mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   504  					BuildpackName: "/other/path/to/test/buildpack",
   505  					Daemon:        true,
   506  					Registry:      "default-registry",
   507  				}).Return(complexInfo, nil)
   508  			})
   509  			it("displays detection order to specified depth", func() {
   510  				command.SetArgs([]string{"/other/path/to/test/buildpack", "-d", "2"})
   511  				assert.Nil(command.Execute())
   512  
   513  				assert.AssertTrimmedContains(outBuf.String(), depthOutputSection)
   514  			})
   515  		})
   516  	})
   517  
   518  	when("verbose flag is passed", func() {
   519  		it.Before(func() {
   520  			simpleInfo.Location = buildpack.URILocator
   521  			mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   522  				BuildpackName: "/another/path/to/test/buildpack",
   523  				Daemon:        true,
   524  				Registry:      "default-registry",
   525  			}).Return(simpleInfo, nil)
   526  		})
   527  		it("displays all mixins", func() {
   528  			command.SetArgs([]string{"/another/path/to/test/buildpack", "-v"})
   529  			assert.Nil(command.Execute())
   530  
   531  			assert.AssertTrimmedContains(outBuf.String(), simpleMixinOutputSection)
   532  		})
   533  	})
   534  
   535  	when("failure cases", func() {
   536  		when("unable to inspect buildpack image", func() {
   537  			it.Before(func() {
   538  				mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   539  					BuildpackName: "failure-case/buildpack",
   540  					Daemon:        true,
   541  					Registry:      "default-registry",
   542  				}).Return(&client.BuildpackInfo{}, errors.Wrap(image.ErrNotFound, "unable to inspect local failure-case/buildpack"))
   543  
   544  				mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   545  					BuildpackName: "failure-case/buildpack",
   546  					Daemon:        false,
   547  					Registry:      "default-registry",
   548  				}).Return(&client.BuildpackInfo{}, errors.Wrap(image.ErrNotFound, "unable to inspect remote failure-case/buildpack"))
   549  			})
   550  			it("errors", func() {
   551  				command.SetArgs([]string{"failure-case/buildpack"})
   552  				err := command.Execute()
   553  				assert.Error(err)
   554  			})
   555  		})
   556  		when("unable to inspect buildpack archive", func() {
   557  			it.Before(func() {
   558  				mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   559  					BuildpackName: "http://path/to/failure-case/buildpack",
   560  					Daemon:        true,
   561  					Registry:      "default-registry",
   562  				}).Return(&client.BuildpackInfo{}, errors.New("error inspecting local archive"))
   563  
   564  				it("errors", func() {
   565  					command.SetArgs([]string{"http://path/to/failure-case/buildpack"})
   566  					err := command.Execute()
   567  
   568  					assert.Error(err)
   569  					assert.Contains(err.Error(), "error inspecting local archive")
   570  				})
   571  			})
   572  		})
   573  		when("unable to inspect both remote and local images", func() {
   574  			it.Before(func() {
   575  				mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   576  					BuildpackName: "image-failure-case/buildpack",
   577  					Daemon:        true,
   578  					Registry:      "default-registry",
   579  				}).Return(&client.BuildpackInfo{}, errors.Wrap(image.ErrNotFound, "error inspecting local archive"))
   580  
   581  				mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   582  					BuildpackName: "image-failure-case/buildpack",
   583  					Daemon:        false,
   584  					Registry:      "default-registry",
   585  				}).Return(&client.BuildpackInfo{}, errors.Wrap(image.ErrNotFound, "error inspecting remote archive"))
   586  			})
   587  			it("errors", func() {
   588  				command.SetArgs([]string{"image-failure-case/buildpack"})
   589  				err := command.Execute()
   590  
   591  				assert.Error(err)
   592  				assert.Contains(err.Error(), "error writing buildpack output: \"error inspecting local archive: not found, error inspecting remote archive: not found\"")
   593  			})
   594  		})
   595  
   596  		when("unable to inspect buildpack on registry", func() {
   597  			it.Before(func() {
   598  				mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   599  					BuildpackName: "urn:cnb:registry:registry-failure/buildpack",
   600  					Daemon:        true,
   601  					Registry:      "some-registry",
   602  				}).Return(&client.BuildpackInfo{}, errors.New("error inspecting registry image"))
   603  
   604  				mockClient.EXPECT().InspectBuildpack(client.InspectBuildpackOptions{
   605  					BuildpackName: "urn:cnb:registry:registry-failure/buildpack",
   606  					Daemon:        false,
   607  					Registry:      "some-registry",
   608  				}).Return(&client.BuildpackInfo{}, errors.New("error inspecting registry image"))
   609  			})
   610  
   611  			it("errors", func() {
   612  				command.SetArgs([]string{"urn:cnb:registry:registry-failure/buildpack", "-r", "some-registry"})
   613  
   614  				err := command.Execute()
   615  				assert.Error(err)
   616  				assert.Contains(err.Error(), "error inspecting registry image")
   617  			})
   618  		})
   619  	})
   620  }