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

     1  package commands_test
     2  
     3  import (
     4  	"bytes"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     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/pkg/logging"
    18  	h "github.com/buildpacks/pack/testhelpers"
    19  )
    20  
    21  func TestConfigLifecyleImage(t *testing.T) {
    22  	color.Disable(true)
    23  	defer color.Disable(false)
    24  	spec.Run(t, "ConfigLifecycleImage", testConfigLifecycleImageCommand, spec.Random(), spec.Report(report.Terminal{}))
    25  }
    26  
    27  func testConfigLifecycleImageCommand(t *testing.T, when spec.G, it spec.S) {
    28  	var (
    29  		command      *cobra.Command
    30  		logger       logging.Logger
    31  		outBuf       bytes.Buffer
    32  		tempPackHome string
    33  		configFile   string
    34  		assert       = h.NewAssertionManager(t)
    35  		cfg          = config.Config{}
    36  	)
    37  
    38  	it.Before(func() {
    39  		var err error
    40  		logger = logging.NewLogWithWriters(&outBuf, &outBuf)
    41  		tempPackHome, err = os.MkdirTemp("", "pack-home")
    42  		h.AssertNil(t, err)
    43  		configFile = filepath.Join(tempPackHome, "config.toml")
    44  
    45  		command = commands.ConfigLifecycleImage(logger, cfg, configFile)
    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("#ConfigLifecycleImage", func() {
    54  		when("list", func() {
    55  			when("no custom lifecycle image was set", func() {
    56  				it("lists the default", func() {
    57  					command.SetArgs([]string{})
    58  
    59  					h.AssertNil(t, command.Execute())
    60  
    61  					assert.Contains(outBuf.String(), config.DefaultLifecycleImageRepo)
    62  				})
    63  			})
    64  			when("custom lifecycle-image was set", func() {
    65  				it("lists the custom image", func() {
    66  					cfg.LifecycleImage = "custom-lifecycle/image:v1"
    67  					command = commands.ConfigLifecycleImage(logger, cfg, configFile)
    68  					command.SetArgs([]string{})
    69  
    70  					h.AssertNil(t, command.Execute())
    71  
    72  					assert.Contains(outBuf.String(), "custom-lifecycle/image:v1")
    73  				})
    74  			})
    75  		})
    76  		when("set", func() {
    77  			when("custom lifecycle-image provided is the same as configured lifecycle-image", func() {
    78  				it("provides a helpful message", func() {
    79  					cfg.LifecycleImage = "custom-lifecycle/image:v1"
    80  					command = commands.ConfigLifecycleImage(logger, cfg, configFile)
    81  					command.SetArgs([]string{"custom-lifecycle/image:v1"})
    82  
    83  					h.AssertNil(t, command.Execute())
    84  
    85  					output := outBuf.String()
    86  					h.AssertEq(t, strings.TrimSpace(output), `Custom lifecycle image is already set to 'custom-lifecycle/image:v1'`)
    87  				})
    88  				it("it does not change the configured", func() {
    89  					command = commands.ConfigLifecycleImage(logger, cfg, configFile)
    90  					command.SetArgs([]string{"custom-lifecycle/image:v1"})
    91  					assert.Succeeds(command.Execute())
    92  
    93  					readCfg, err := config.Read(configFile)
    94  					assert.Nil(err)
    95  					assert.Equal(readCfg.LifecycleImage, "custom-lifecycle/image:v1")
    96  
    97  					command = commands.ConfigLifecycleImage(logger, readCfg, configFile)
    98  					command.SetArgs([]string{"custom-lifecycle/image:v1"})
    99  					assert.Succeeds(command.Execute())
   100  
   101  					readCfg, err = config.Read(configFile)
   102  					assert.Nil(err)
   103  					assert.Equal(readCfg.LifecycleImage, "custom-lifecycle/image:v1")
   104  				})
   105  			})
   106  
   107  			when("valid lifecycle-image is specified", func() {
   108  				it("sets the lifecycle-image in config", func() {
   109  					command.SetArgs([]string{"custom-lifecycle/image:v1"})
   110  					assert.Succeeds(command.Execute())
   111  
   112  					readCfg, err := config.Read(configFile)
   113  					assert.Nil(err)
   114  					assert.Equal(readCfg.LifecycleImage, "custom-lifecycle/image:v1")
   115  				})
   116  				it("returns clear error if fails to write", func() {
   117  					assert.Nil(os.WriteFile(configFile, []byte("something"), 0001))
   118  					command := commands.ConfigLifecycleImage(logger, cfg, configFile)
   119  					command.SetArgs([]string{"custom-lifecycle/image:v1"})
   120  					assert.ErrorContains(command.Execute(), "failed to write to config at")
   121  				})
   122  			})
   123  			when("invalid lifecycle-image is specified", func() {
   124  				it("returns an error", func() {
   125  					command.SetArgs([]string{"custom$1#-lifecycle/image-repo"})
   126  					err := command.Execute()
   127  					h.AssertError(t, err, `Invalid image name`)
   128  				})
   129  				it("returns clear error if fails to write", func() {
   130  					assert.Nil(os.WriteFile(configFile, []byte("something"), 0001))
   131  					command := commands.ConfigLifecycleImage(logger, cfg, configFile)
   132  					command.SetArgs([]string{"custom-lifecycle/image:v1"})
   133  					assert.ErrorContains(command.Execute(), "failed to write to config at")
   134  				})
   135  			})
   136  		})
   137  		when("unset", func() {
   138  			when("the custom lifecycle image is set", func() {
   139  				it("removes set lifecycle image and resets to default lifecycle image", func() {
   140  					command = commands.ConfigLifecycleImage(logger, cfg, configFile)
   141  					command.SetArgs([]string{"custom-lifecycle/image:v1"})
   142  					assert.Succeeds(command.Execute())
   143  
   144  					readCfg, err := config.Read(configFile)
   145  					assert.Nil(err)
   146  					assert.Equal(readCfg.LifecycleImage, "custom-lifecycle/image:v1")
   147  
   148  					command = commands.ConfigLifecycleImage(logger, readCfg, configFile)
   149  					command.SetArgs([]string{"--unset"})
   150  					assert.Succeeds(command.Execute())
   151  
   152  					readCfg, err = config.Read(configFile)
   153  					assert.Nil(err)
   154  					assert.Equal(readCfg.LifecycleImage, "")
   155  				})
   156  				it("returns clear error if fails to write", func() {
   157  					assert.Nil(os.WriteFile(configFile, []byte("something"), 0001))
   158  					command := commands.ConfigLifecycleImage(logger, config.Config{LifecycleImage: "custom-lifecycle/image:v1"}, configFile)
   159  					command.SetArgs([]string{"--unset"})
   160  					assert.ErrorContains(command.Execute(), "failed to write to config at")
   161  				})
   162  			})
   163  			when("the custom lifecycle image is not set", func() {
   164  				it("returns clear message that no custom lifecycle image is set", func() {
   165  					command.SetArgs([]string{"--unset"})
   166  					assert.Succeeds(command.Execute())
   167  					output := outBuf.String()
   168  					h.AssertEq(t, strings.TrimSpace(output), `No custom lifecycle image was set.`)
   169  				})
   170  			})
   171  		})
   172  		when("--unset and lifecycle image to set is provided", func() {
   173  			it("errors", func() {
   174  				command.SetArgs([]string{
   175  					"custom-lifecycle/image:v1",
   176  					"--unset",
   177  				})
   178  				err := command.Execute()
   179  				h.AssertError(t, err, `lifecycle image and --unset cannot be specified simultaneously`)
   180  			})
   181  		})
   182  	})
   183  }