github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/pkg/client/inspect_extension_test.go (about) 1 package client_test 2 3 import ( 4 "bytes" 5 "fmt" 6 "testing" 7 8 "github.com/buildpacks/imgutil/fakes" 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 15 "github.com/buildpacks/pack/pkg/buildpack" 16 "github.com/buildpacks/pack/pkg/client" 17 "github.com/buildpacks/pack/pkg/dist" 18 "github.com/buildpacks/pack/pkg/image" 19 "github.com/buildpacks/pack/pkg/logging" 20 "github.com/buildpacks/pack/pkg/testmocks" 21 h "github.com/buildpacks/pack/testhelpers" 22 ) 23 24 const extensionMetadataTag = `{ 25 "id": "some/top-extension", 26 "version": "0.0.1", 27 "name": "top", 28 "homepage": "top-extension-homepage" 29 }` 30 31 const extensionLayersTag = `{ 32 "some/top-extension":{ 33 "0.0.1":{ 34 "api":"0.2", 35 "homepage":"top-extension-homepage", 36 "name": "top" 37 } 38 } 39 }` 40 41 func TestInspectExtension(t *testing.T) { 42 color.Disable(true) 43 defer color.Disable(false) 44 spec.Run(t, "InspectExtension", testInspectExtension, spec.Sequential(), spec.Report(report.Terminal{})) 45 } 46 func testInspectExtension(t *testing.T, when spec.G, it spec.S) { 47 var ( 48 subject *client.Client 49 mockImageFetcher *testmocks.MockImageFetcher 50 mockController *gomock.Controller 51 out bytes.Buffer 52 extensionImage *fakes.Image 53 expectedInfo *client.ExtensionInfo 54 ) 55 56 it.Before(func() { 57 mockController = gomock.NewController(t) 58 mockImageFetcher = testmocks.NewMockImageFetcher(mockController) 59 60 subject = &client.Client{} 61 client.WithLogger(logging.NewLogWithWriters(&out, &out))(subject) 62 client.WithFetcher(mockImageFetcher)(subject) 63 64 extensionImage = fakes.NewImage("some/extension", "", nil) 65 h.AssertNil(t, extensionImage.SetLabel(dist.ExtensionMetadataLabel, extensionMetadataTag)) 66 h.AssertNil(t, extensionImage.SetLabel(dist.ExtensionLayersLabel, extensionLayersTag)) 67 68 expectedInfo = &client.ExtensionInfo{ 69 Extension: dist.ModuleInfo{ 70 ID: "some/top-extension", 71 Version: "0.0.1", 72 Name: "top", 73 Homepage: "top-extension-homepage", 74 }, 75 } 76 }) 77 78 it.After(func() { 79 mockController.Finish() 80 }) 81 82 when("inspect-extension", func() { 83 when("inspecting an image", func() { 84 for _, useDaemon := range []bool{true, false} { 85 useDaemon := useDaemon 86 when(fmt.Sprintf("daemon is %t", useDaemon), func() { 87 it.Before(func() { 88 expectedInfo.Location = buildpack.PackageLocator 89 if useDaemon { 90 mockImageFetcher.EXPECT().Fetch(gomock.Any(), "some/extension", image.FetchOptions{Daemon: true, PullPolicy: image.PullNever}).Return(extensionImage, nil) 91 } else { 92 mockImageFetcher.EXPECT().Fetch(gomock.Any(), "some/extension", image.FetchOptions{Daemon: false, PullPolicy: image.PullNever}).Return(extensionImage, nil) 93 } 94 }) 95 96 it("succeeds", func() { 97 inspectOptions := client.InspectExtensionOptions{ 98 ExtensionName: "docker://some/extension", 99 Daemon: useDaemon, 100 } 101 info, err := subject.InspectExtension(inspectOptions) 102 h.AssertNil(t, err) 103 104 h.AssertEq(t, info, expectedInfo) 105 }) 106 }) 107 } 108 }) 109 }) 110 when("failure cases", func() { 111 when("invalid extension name", func() { 112 it.Before(func() { 113 mockImageFetcher.EXPECT().Fetch(gomock.Any(), "", image.FetchOptions{Daemon: false, PullPolicy: image.PullNever}).Return(nil, errors.Wrapf(image.ErrNotFound, "unable to handle locator")) 114 }) 115 it("returns an error", func() { 116 invalidExtensionName := "" 117 inspectOptions := client.InspectExtensionOptions{ 118 ExtensionName: invalidExtensionName, 119 } 120 _, err := subject.InspectExtension(inspectOptions) 121 122 h.AssertError(t, err, "unable to handle locator") 123 h.AssertTrue(t, errors.Is(err, image.ErrNotFound)) 124 }) 125 }) 126 when("extension image", func() { 127 when("unable to fetch extension image", func() { 128 it.Before(func() { 129 mockImageFetcher.EXPECT().Fetch(gomock.Any(), "missing/extension", image.FetchOptions{Daemon: true, PullPolicy: image.PullNever}).Return(nil, errors.Wrapf(image.ErrNotFound, "big bad error")) 130 }) 131 it("returns an ErrNotFound error", func() { 132 inspectOptions := client.InspectExtensionOptions{ 133 ExtensionName: "docker://missing/extension", 134 Daemon: true, 135 } 136 _, err := subject.InspectExtension(inspectOptions) 137 h.AssertTrue(t, errors.Is(err, image.ErrNotFound)) 138 }) 139 }) 140 141 when("image does not have extension metadata", func() { 142 it.Before(func() { 143 fakeImage := fakes.NewImage("empty", "", nil) 144 h.AssertNil(t, fakeImage.SetLabel(dist.ExtensionLayersLabel, ":::")) 145 mockImageFetcher.EXPECT().Fetch(gomock.Any(), "missing-metadata/extension", image.FetchOptions{Daemon: true, PullPolicy: image.PullNever}).Return(fakeImage, nil) 146 }) 147 it("returns an error", func() { 148 inspectOptions := client.InspectExtensionOptions{ 149 ExtensionName: "docker://missing-metadata/extension", 150 Daemon: true, 151 } 152 _, err := subject.InspectExtension(inspectOptions) 153 154 h.AssertError(t, err, fmt.Sprintf("unable to get image label %s", dist.ExtensionLayersLabel)) 155 h.AssertFalse(t, errors.Is(err, image.ErrNotFound)) 156 }) 157 }) 158 }) 159 }) 160 }