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

     1  package commands_test
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"testing"
     9  
    10  	"github.com/golang/mock/gomock"
    11  	"github.com/heroku/color"
    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/internal/style"
    20  	"github.com/buildpacks/pack/pkg/client"
    21  	"github.com/buildpacks/pack/pkg/logging"
    22  	h "github.com/buildpacks/pack/testhelpers"
    23  )
    24  
    25  func TestConfigDefaultBuilder(t *testing.T) {
    26  	color.Disable(true)
    27  	defer color.Disable(false)
    28  	spec.Run(t, "ConfigDefaultBuilderCommand", testConfigDefaultBuilder, spec.Random(), spec.Report(report.Terminal{}))
    29  }
    30  
    31  func testConfigDefaultBuilder(t *testing.T, when spec.G, it spec.S) {
    32  	var (
    33  		cmd            *cobra.Command
    34  		logger         logging.Logger
    35  		outBuf         bytes.Buffer
    36  		mockController *gomock.Controller
    37  		mockClient     *testmocks.MockPackClient
    38  		tempPackHome   string
    39  		configPath     string
    40  	)
    41  
    42  	it.Before(func() {
    43  		var err error
    44  
    45  		mockController = gomock.NewController(t)
    46  		mockClient = testmocks.NewMockPackClient(mockController)
    47  		logger = logging.NewLogWithWriters(&outBuf, &outBuf)
    48  		tempPackHome, err = os.MkdirTemp("", "pack-home")
    49  		h.AssertNil(t, err)
    50  		configPath = filepath.Join(tempPackHome, "config.toml")
    51  		cmd = commands.ConfigDefaultBuilder(logger, config.Config{}, configPath, mockClient)
    52  	})
    53  
    54  	it.After(func() {
    55  		mockController.Finish()
    56  		h.AssertNil(t, os.RemoveAll(tempPackHome))
    57  	})
    58  
    59  	when("#ConfigDefaultBuilder", func() {
    60  		when("no args", func() {
    61  			it("lists current default builder if one is set", func() {
    62  				cmd = commands.ConfigDefaultBuilder(logger, config.Config{DefaultBuilder: "some/builder"}, configPath, mockClient)
    63  				cmd.SetArgs([]string{})
    64  				h.AssertNil(t, cmd.Execute())
    65  				h.AssertContains(t, outBuf.String(), "some/builder")
    66  			})
    67  
    68  			it("suggests setting a builder if none is set", func() {
    69  				cmd.SetArgs([]string{})
    70  				h.AssertNil(t, cmd.Execute())
    71  				h.AssertContains(t, outBuf.String(), "No default builder is set.")
    72  				h.AssertContains(t, outBuf.String(), "run `pack builder suggest`")
    73  			})
    74  		})
    75  
    76  		when("unset", func() {
    77  			it("unsets current default builder", func() {
    78  				cfg := config.Config{DefaultBuilder: "some/builder"}
    79  				h.AssertNil(t, config.Write(cfg, configPath))
    80  				cmd = commands.ConfigDefaultBuilder(logger, cfg, configPath, mockClient)
    81  				cmd.SetArgs([]string{"--unset"})
    82  				err := cmd.Execute()
    83  				h.AssertNil(t, err)
    84  				cfg, err = config.Read(configPath)
    85  				h.AssertNil(t, err)
    86  				h.AssertEq(t, cfg.DefaultBuilder, "")
    87  				h.AssertContains(t, outBuf.String(), fmt.Sprintf("Successfully unset default builder %s", style.Symbol("some/builder")))
    88  			})
    89  
    90  			it("clarifies if no builder was set", func() {
    91  				cmd.SetArgs([]string{"--unset"})
    92  				h.AssertNil(t, cmd.Execute())
    93  				h.AssertContains(t, outBuf.String(), "No default builder was set")
    94  			})
    95  
    96  			it("gives clear error if unable to write to config", func() {
    97  				h.AssertNil(t, os.WriteFile(configPath, []byte("some-data"), 0001))
    98  				cmd = commands.ConfigDefaultBuilder(logger, config.Config{DefaultBuilder: "some/builder"}, configPath, mockClient)
    99  				cmd.SetArgs([]string{"--unset"})
   100  				err := cmd.Execute()
   101  				h.AssertError(t, err, "failed to write to config at "+configPath)
   102  			})
   103  		})
   104  
   105  		when("set", func() {
   106  			when("valid builder is provider", func() {
   107  				when("in local", func() {
   108  					var imageName = "some/image"
   109  
   110  					it("sets default builder", func() {
   111  						mockClient.EXPECT().InspectBuilder(imageName, true).Return(&client.BuilderInfo{
   112  							Stack: "test.stack.id",
   113  						}, nil)
   114  
   115  						cmd.SetArgs([]string{imageName})
   116  						h.AssertNil(t, cmd.Execute())
   117  						h.AssertContains(t, outBuf.String(), fmt.Sprintf("Builder '%s' is now the default builder", imageName))
   118  
   119  						cfg, err := config.Read(configPath)
   120  						h.AssertNil(t, err)
   121  						h.AssertEq(t, cfg.DefaultBuilder, "some/image")
   122  					})
   123  
   124  					it("gives clear error if unable to write to config", func() {
   125  						h.AssertNil(t, os.WriteFile(configPath, []byte("some-data"), 0001))
   126  						mockClient.EXPECT().InspectBuilder(imageName, true).Return(&client.BuilderInfo{
   127  							Stack: "test.stack.id",
   128  						}, nil)
   129  						cmd = commands.ConfigDefaultBuilder(logger, config.Config{}, configPath, mockClient)
   130  						cmd.SetArgs([]string{imageName})
   131  						err := cmd.Execute()
   132  						h.AssertError(t, err, "failed to write to config at "+configPath)
   133  					})
   134  				})
   135  
   136  				when("in remote", func() {
   137  					it("sets default builder", func() {
   138  						imageName := "some/image"
   139  
   140  						localCall := mockClient.EXPECT().InspectBuilder(imageName, true).Return(nil, nil)
   141  
   142  						mockClient.EXPECT().InspectBuilder(imageName, false).Return(&client.BuilderInfo{
   143  							Stack: "test.stack.id",
   144  						}, nil).After(localCall)
   145  
   146  						cmd.SetArgs([]string{imageName})
   147  						h.AssertNil(t, cmd.Execute())
   148  						h.AssertContains(t, outBuf.String(), fmt.Sprintf("Builder '%s' is now the default builder", imageName))
   149  					})
   150  
   151  					it("gives clear error if unable to inspect remote image", func() {
   152  						imageName := "some/image"
   153  
   154  						localCall := mockClient.EXPECT().InspectBuilder(imageName, true).Return(nil, nil)
   155  
   156  						mockClient.EXPECT().InspectBuilder(imageName, false).Return(&client.BuilderInfo{
   157  							Stack: "test.stack.id",
   158  						}, client.SoftError{}).After(localCall)
   159  
   160  						cmd.SetArgs([]string{imageName})
   161  						err := cmd.Execute()
   162  						h.AssertError(t, err, fmt.Sprintf("failed to inspect remote image %s", style.Symbol(imageName)))
   163  					})
   164  				})
   165  			})
   166  
   167  			when("invalid builder is provided", func() {
   168  				it("error is presented", func() {
   169  					imageName := "nonbuilder/image"
   170  
   171  					mockClient.EXPECT().InspectBuilder(imageName, true).Return(
   172  						nil,
   173  						fmt.Errorf("failed to inspect image %s", imageName))
   174  
   175  					cmd.SetArgs([]string{imageName})
   176  
   177  					h.AssertNotNil(t, cmd.Execute())
   178  					h.AssertContains(t, outBuf.String(), fmt.Sprintf("validating that builder %s exists", style.Symbol("nonbuilder/image")))
   179  				})
   180  			})
   181  
   182  			when("non-existent builder is provided", func() {
   183  				it("error is present", func() {
   184  					imageName := "nonexisting/image"
   185  
   186  					localCall := mockClient.EXPECT().InspectBuilder(imageName, true).Return(
   187  						nil,
   188  						nil)
   189  
   190  					mockClient.EXPECT().InspectBuilder(imageName, false).Return(
   191  						nil,
   192  						nil).After(localCall)
   193  
   194  					cmd.SetArgs([]string{imageName})
   195  
   196  					h.AssertNotNil(t, cmd.Execute())
   197  					h.AssertContains(t, outBuf.String(), "builder 'nonexisting/image' not found")
   198  				})
   199  			})
   200  		})
   201  	})
   202  }