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 }