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  }