github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/internal/commands/config_trusted_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/heroku/color" 11 "github.com/sclevine/spec" 12 "github.com/sclevine/spec/report" 13 "github.com/spf13/cobra" 14 15 "github.com/buildpacks/pack/internal/commands" 16 "github.com/buildpacks/pack/internal/config" 17 "github.com/buildpacks/pack/internal/style" 18 "github.com/buildpacks/pack/pkg/logging" 19 h "github.com/buildpacks/pack/testhelpers" 20 ) 21 22 func TestTrustedBuilderCommand(t *testing.T) { 23 color.Disable(true) 24 defer color.Disable(false) 25 spec.Run(t, "TrustedBuilderCommands", testTrustedBuilderCommand, spec.Random(), spec.Report(report.Terminal{})) 26 } 27 28 func testTrustedBuilderCommand(t *testing.T, when spec.G, it spec.S) { 29 var ( 30 command *cobra.Command 31 logger logging.Logger 32 outBuf bytes.Buffer 33 tempPackHome string 34 configPath string 35 ) 36 37 it.Before(func() { 38 var err error 39 40 logger = logging.NewLogWithWriters(&outBuf, &outBuf) 41 tempPackHome, err = os.MkdirTemp("", "pack-home") 42 h.AssertNil(t, err) 43 configPath = filepath.Join(tempPackHome, "config.toml") 44 45 command = commands.ConfigTrustedBuilder(logger, config.Config{}, configPath) 46 command.SetOut(logging.GetWriterForLevel(logger, logging.InfoLevel)) 47 }) 48 49 it.After(func() { 50 h.AssertNil(t, os.RemoveAll(tempPackHome)) 51 }) 52 53 when("no args", func() { 54 it("prints list of trusted builders", func() { 55 command.SetArgs([]string{}) 56 h.AssertNil(t, command.Execute()) 57 h.AssertContainsAllInOrder(t, 58 outBuf, 59 "gcr.io/buildpacks/builder:v1", 60 "heroku/builder:20", 61 "heroku/builder:22", 62 "paketobuildpacks/builder-jammy-base", 63 "paketobuildpacks/builder-jammy-full", 64 "paketobuildpacks/builder-jammy-tiny", 65 ) 66 }) 67 68 it("works with alias of trusted-builders", func() { 69 command.SetArgs([]string{}) 70 h.AssertNil(t, command.Execute()) 71 h.AssertContainsAllInOrder(t, 72 outBuf, 73 "gcr.io/buildpacks/builder:v1", 74 "heroku/builder:20", 75 "heroku/builder:22", 76 "paketobuildpacks/builder-jammy-base", 77 "paketobuildpacks/builder-jammy-full", 78 "paketobuildpacks/builder-jammy-tiny", 79 ) 80 }) 81 }) 82 83 when("list", func() { 84 var args = []string{"list"} 85 86 it("shows suggested builders and locally trusted builder in alphabetical order", func() { 87 builderName := "great-builder-" + h.RandString(8) 88 89 command.SetArgs(args) 90 h.AssertNil(t, command.Execute()) 91 h.AssertNotContains(t, outBuf.String(), builderName) 92 h.AssertContainsAllInOrder(t, 93 outBuf, 94 "gcr.io/buildpacks/builder:v1", 95 "heroku/builder:20", 96 "heroku/builder:22", 97 "paketobuildpacks/builder-jammy-base", 98 "paketobuildpacks/builder-jammy-full", 99 "paketobuildpacks/builder-jammy-tiny", 100 ) 101 outBuf.Reset() 102 103 configManager := newConfigManager(t, configPath) 104 command = commands.ConfigTrustedBuilder(logger, configManager.configWithTrustedBuilders(builderName), configPath) 105 command.SetArgs(args) 106 h.AssertNil(t, command.Execute()) 107 108 h.AssertContainsAllInOrder(t, 109 outBuf, 110 "gcr.io/buildpacks/builder:v1", 111 builderName, 112 "heroku/builder:20", 113 "heroku/builder:22", 114 "paketobuildpacks/builder-jammy-base", 115 "paketobuildpacks/builder-jammy-full", 116 "paketobuildpacks/builder-jammy-tiny", 117 ) 118 }) 119 }) 120 121 when("add", func() { 122 var args = []string{"add"} 123 when("no builder is provided", func() { 124 it("prints usage", func() { 125 command.SetArgs(args) 126 h.AssertError(t, command.Execute(), "accepts 1 arg(s)") 127 }) 128 }) 129 130 when("can't write to config path", func() { 131 it("fails", func() { 132 tempPath := filepath.Join(tempPackHome, "non-existent-file.toml") 133 h.AssertNil(t, os.WriteFile(tempPath, []byte("something"), 0111)) 134 command = commands.ConfigTrustedBuilder(logger, config.Config{}, tempPath) 135 command.SetOut(logging.GetWriterForLevel(logger, logging.InfoLevel)) 136 command.SetArgs(append(args, "some-builder")) 137 h.AssertError(t, command.Execute(), "writing config") 138 }) 139 }) 140 141 when("builder is provided", func() { 142 when("builder is not already trusted", func() { 143 it("updates the config", func() { 144 command.SetArgs(append(args, "some-builder")) 145 h.AssertNil(t, command.Execute()) 146 147 b, err := os.ReadFile(configPath) 148 h.AssertNil(t, err) 149 h.AssertContains(t, string(b), `[[trusted-builders]] 150 name = "some-builder"`) 151 }) 152 }) 153 154 when("builder is already trusted", func() { 155 it("does nothing", func() { 156 command.SetArgs(append(args, "some-already-trusted-builder")) 157 h.AssertNil(t, command.Execute()) 158 oldContents, err := os.ReadFile(configPath) 159 h.AssertNil(t, err) 160 161 command.SetArgs(append(args, "some-already-trusted-builder")) 162 h.AssertNil(t, command.Execute()) 163 164 newContents, err := os.ReadFile(configPath) 165 h.AssertNil(t, err) 166 h.AssertEq(t, newContents, oldContents) 167 }) 168 }) 169 170 when("builder is a suggested builder", func() { 171 it("does nothing", func() { 172 h.AssertNil(t, os.WriteFile(configPath, []byte(""), os.ModePerm)) 173 174 command.SetArgs(append(args, "paketobuildpacks/builder-jammy-base")) 175 h.AssertNil(t, command.Execute()) 176 oldContents, err := os.ReadFile(configPath) 177 h.AssertNil(t, err) 178 h.AssertEq(t, string(oldContents), "") 179 }) 180 }) 181 }) 182 }) 183 184 when("remove", func() { 185 var ( 186 args = []string{"remove"} 187 configManager configManager 188 ) 189 190 it.Before(func() { 191 configManager = newConfigManager(t, configPath) 192 }) 193 194 when("no builder is provided", func() { 195 it("prints usage", func() { 196 cfg := configManager.configWithTrustedBuilders() 197 command := commands.ConfigTrustedBuilder(logger, cfg, configPath) 198 command.SetArgs(args) 199 command.SetOut(&outBuf) 200 201 err := command.Execute() 202 h.AssertError(t, err, "accepts 1 arg(s), received 0") 203 h.AssertContains(t, outBuf.String(), "Usage:") 204 }) 205 }) 206 207 when("builder is already trusted", func() { 208 it("removes builder from the config", func() { 209 builderName := "some-builder" 210 211 cfg := configManager.configWithTrustedBuilders(builderName) 212 command := commands.ConfigTrustedBuilder(logger, cfg, configPath) 213 command.SetArgs(append(args, builderName)) 214 215 h.AssertNil(t, command.Execute()) 216 217 b, err := os.ReadFile(configPath) 218 h.AssertNil(t, err) 219 h.AssertNotContains(t, string(b), builderName) 220 221 h.AssertContains(t, 222 outBuf.String(), 223 fmt.Sprintf("Builder %s is no longer trusted", style.Symbol(builderName)), 224 ) 225 }) 226 227 it("removes only the named builder when multiple builders are trusted", func() { 228 untrustBuilder := "stop/trusting:me" 229 stillTrustedBuilder := "very/safe/builder" 230 231 cfg := configManager.configWithTrustedBuilders(untrustBuilder, stillTrustedBuilder) 232 command := commands.ConfigTrustedBuilder(logger, cfg, configPath) 233 command.SetArgs(append(args, untrustBuilder)) 234 235 h.AssertNil(t, command.Execute()) 236 237 b, err := os.ReadFile(configPath) 238 h.AssertNil(t, err) 239 h.AssertContains(t, string(b), stillTrustedBuilder) 240 h.AssertNotContains(t, string(b), untrustBuilder) 241 }) 242 }) 243 244 when("builder wasn't already trusted", func() { 245 it("does nothing and reports builder wasn't trusted", func() { 246 neverTrustedBuilder := "never/trusted-builder" 247 stillTrustedBuilder := "very/safe/builder" 248 249 cfg := configManager.configWithTrustedBuilders(stillTrustedBuilder) 250 command := commands.ConfigTrustedBuilder(logger, cfg, configPath) 251 command.SetArgs(append(args, neverTrustedBuilder)) 252 253 h.AssertNil(t, command.Execute()) 254 255 b, err := os.ReadFile(configPath) 256 h.AssertNil(t, err) 257 h.AssertContains(t, string(b), stillTrustedBuilder) 258 h.AssertNotContains(t, string(b), neverTrustedBuilder) 259 260 h.AssertContains(t, 261 outBuf.String(), 262 fmt.Sprintf("Builder %s wasn't trusted", style.Symbol(neverTrustedBuilder)), 263 ) 264 }) 265 }) 266 267 when("builder is a suggested builder", func() { 268 it("does nothing and reports that ", func() { 269 builder := "paketobuildpacks/builder-jammy-base" 270 command := commands.ConfigTrustedBuilder(logger, config.Config{}, configPath) 271 command.SetArgs(append(args, builder)) 272 273 err := command.Execute() 274 h.AssertError(t, err, fmt.Sprintf("Builder %s is a suggested builder, and is trusted by default", style.Symbol(builder))) 275 }) 276 }) 277 }) 278 }