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  }