github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/pkg/client/docker_context_test.go (about)

     1  package client_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  
    14  	"github.com/buildpacks/pack/pkg/client"
    15  	"github.com/buildpacks/pack/pkg/logging"
    16  	h "github.com/buildpacks/pack/testhelpers"
    17  )
    18  
    19  func TestProcessDockerContext(t *testing.T) {
    20  	color.Disable(true)
    21  	defer color.Disable(false)
    22  	spec.Run(t, "processDockerContext", testProcessDockerContext, spec.Report(report.Terminal{}))
    23  }
    24  
    25  const (
    26  	rootFolder = "docker-context"
    27  	happyCase  = "happy-cases"
    28  	errorCase  = "error-cases"
    29  )
    30  
    31  func testProcessDockerContext(t *testing.T, when spec.G, it spec.S) {
    32  	var (
    33  		outBuf bytes.Buffer
    34  		logger logging.Logger
    35  	)
    36  
    37  	it.Before(func() {
    38  		logger = logging.NewLogWithWriters(&outBuf, &outBuf, logging.WithVerbose())
    39  	})
    40  
    41  	when("env DOCKER_HOST is set", func() {
    42  		it.Before(func() {
    43  			os.Setenv("DOCKER_HOST", "some-value")
    44  		})
    45  
    46  		it("docker context process is skipped", func() {
    47  			err := client.ProcessDockerContext(logger)
    48  			h.AssertNil(t, err)
    49  			h.AssertContains(t, strings.TrimSpace(outBuf.String()), "'DOCKER_HOST=some-value' environment variable is being used")
    50  		})
    51  	})
    52  
    53  	when("env DOCKER_HOST is empty", func() {
    54  		it.Before(func() {
    55  			os.Setenv("DOCKER_HOST", "")
    56  		})
    57  
    58  		when("config.json has currentContext", func() {
    59  			when("currentContext is default", func() {
    60  				it.Before(func() {
    61  					setDockerConfig(t, happyCase, "default-context")
    62  				})
    63  
    64  				it("docker context process is skip", func() {
    65  					err := client.ProcessDockerContext(logger)
    66  					h.AssertNil(t, err)
    67  					h.AssertContains(t, strings.TrimSpace(outBuf.String()), "docker context is default or empty, skipping it")
    68  				})
    69  			})
    70  
    71  			when("currentContext is default but config doesn't exist", func() {
    72  				it.Before(func() {
    73  					setDockerConfig(t, errorCase, "empty-context")
    74  				})
    75  
    76  				it("throw an error", func() {
    77  					err := client.ProcessDockerContext(logger)
    78  					h.AssertNotNil(t, err)
    79  					h.AssertError(t, err, "docker context 'some-bad-context' not found")
    80  				})
    81  			})
    82  
    83  			when("currentContext is not default", func() {
    84  				when("metadata has one endpoint", func() {
    85  					it.Before(func() {
    86  						setDockerConfig(t, happyCase, "custom-context")
    87  					})
    88  
    89  					it("docker endpoint host is being used", func() {
    90  						err := client.ProcessDockerContext(logger)
    91  						h.AssertNil(t, err)
    92  						h.AssertContains(t, outBuf.String(), "using docker context 'desktop-linux' with endpoint = 'unix:///Users/user/.docker/run/docker.sock'")
    93  					})
    94  				})
    95  
    96  				when("metadata has more than one endpoint", func() {
    97  					it.Before(func() {
    98  						setDockerConfig(t, happyCase, "two-endpoints-context")
    99  					})
   100  
   101  					it("docker endpoint host is being used", func() {
   102  						err := client.ProcessDockerContext(logger)
   103  						h.AssertNil(t, err)
   104  						h.AssertContains(t, outBuf.String(), "using docker context 'desktop-linux' with endpoint = 'unix:///Users/user/.docker/run/docker.sock'")
   105  					})
   106  				})
   107  
   108  				when("currentContext doesn't match metadata name", func() {
   109  					it.Before(func() {
   110  						setDockerConfig(t, errorCase, "current-context-does-not-match")
   111  					})
   112  
   113  					it("throw an error", func() {
   114  						err := client.ProcessDockerContext(logger)
   115  						h.AssertNotNil(t, err)
   116  						h.AssertError(t, err, "context 'desktop-linux' doesn't match metadata name 'bad-name'")
   117  					})
   118  				})
   119  
   120  				when("metadata doesn't contain a docker endpoint", func() {
   121  					it.Before(func() {
   122  						setDockerConfig(t, errorCase, "docker-endpoint-does-not-exist")
   123  					})
   124  
   125  					it("writes a warn message into the log", func() {
   126  						err := client.ProcessDockerContext(logger)
   127  						h.AssertNil(t, err)
   128  						h.AssertContains(t, outBuf.String(), "docker endpoint doesn't exist for context 'desktop-linux'")
   129  					})
   130  				})
   131  
   132  				when("metadata is invalid", func() {
   133  					it.Before(func() {
   134  						setDockerConfig(t, errorCase, "invalid-metadata")
   135  					})
   136  
   137  					it("throw an error", func() {
   138  						err := client.ProcessDockerContext(logger)
   139  						h.AssertNotNil(t, err)
   140  						h.AssertError(t, err, "reading metadata for current context 'desktop-linux'")
   141  					})
   142  				})
   143  			})
   144  		})
   145  
   146  		when("config.json is invalid", func() {
   147  			it.Before(func() {
   148  				setDockerConfig(t, errorCase, "invalid-config")
   149  			})
   150  
   151  			it("throw an error", func() {
   152  				err := client.ProcessDockerContext(logger)
   153  				h.AssertNotNil(t, err)
   154  				h.AssertError(t, err, "reading configuration file")
   155  			})
   156  		})
   157  
   158  		when("config.json doesn't have current context", func() {
   159  			it.Before(func() {
   160  				setDockerConfig(t, happyCase, "current-context-not-defined")
   161  			})
   162  
   163  			it("docker context process is skip", func() {
   164  				err := client.ProcessDockerContext(logger)
   165  				h.AssertNil(t, err)
   166  				h.AssertContains(t, strings.TrimSpace(outBuf.String()), "docker context is default or empty, skipping it")
   167  			})
   168  		})
   169  
   170  		when("docker config folder doesn't exists", func() {
   171  			it.Before(func() {
   172  				setDockerConfig(t, errorCase, "no-docker-folder")
   173  			})
   174  
   175  			it("docker context process is skip", func() {
   176  				err := client.ProcessDockerContext(logger)
   177  				h.AssertNil(t, err)
   178  				h.AssertContains(t, strings.TrimSpace(outBuf.String()), "docker context is default or empty, skipping it")
   179  			})
   180  		})
   181  
   182  		when("config.json config doesn't exists", func() {
   183  			it.Before(func() {
   184  				setDockerConfig(t, errorCase, "config-does-not-exist")
   185  			})
   186  
   187  			it("docker context process is skip", func() {
   188  				err := client.ProcessDockerContext(logger)
   189  				h.AssertNil(t, err)
   190  				h.AssertContains(t, strings.TrimSpace(outBuf.String()), "docker context is default or empty, skipping it")
   191  			})
   192  		})
   193  	})
   194  }
   195  
   196  func setDockerConfig(t *testing.T, test, context string) {
   197  	t.Helper()
   198  	contextDir, err := filepath.Abs(filepath.Join("testdata", rootFolder, test, context))
   199  	h.AssertNil(t, err)
   200  	err = os.Setenv("DOCKER_CONFIG", contextDir)
   201  	h.AssertNil(t, err)
   202  }