diff --git a/cmd/minikube/cmd/root.go b/cmd/minikube/cmd/root.go index 4c5c00b90c..3e2dab8d38 100644 --- a/cmd/minikube/cmd/root.go +++ b/cmd/minikube/cmd/root.go @@ -21,6 +21,7 @@ import ( "fmt" "io/ioutil" "os" + "runtime" "strings" "github.com/docker/machine/libmachine/log" @@ -102,7 +103,7 @@ Please use --v=3 to show libmachine logs, and --v=7 for debug level libmachine l notify.MaybePrintUpdateTextFromGithub(os.Stderr) } if enableKubectlDownloadMsg { - util.MaybePrintKubectlDownloadMsg() + util.MaybePrintKubectlDownloadMsg(runtime.GOOS, os.Stderr) } }, } diff --git a/cmd/util/util.go b/cmd/util/util.go index 722fb11120..00de092a10 100644 --- a/cmd/util/util.go +++ b/cmd/util/util.go @@ -49,6 +49,14 @@ type Message struct { ServiceContext `json:"serviceContext"` } +type LookPath func(filename string) (string, error) + +var lookPath LookPath + +func init() { + lookPath = exec.LookPath +} + func ReportError(err error, url string) error { errMsg, err := FormatError(err) if err != nil { @@ -168,13 +176,10 @@ func PromptUserForAccept(r io.Reader) bool { } } -func MaybePrintKubectlDownloadMsg() { - if !viper.GetBool(config.WantKubectlDownloadMsg) { - return - } +func MaybePrintKubectlDownloadMsg(goos string, out io.Writer) { verb := "run" installInstructions := "curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/%s/bin/%s/%s/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/" - if runtime.GOOS == "windows" { + if goos == "windows" { verb = "do" installInstructions = `download kubectl from: https://storage.googleapis.com/kubernetes-release/release/%s/bin/%s/%s/kubectl.exe @@ -182,13 +187,13 @@ Add kubectl to your system PATH` } var err error - if runtime.GOOS == "windows" { - _, err = exec.LookPath("kubectl.exe") + if goos == "windows" { + _, err = lookPath("kubectl.exe") } else { - _, err = exec.LookPath("kubectl") + _, err = lookPath("kubectl") } if err != nil { - fmt.Fprintf(os.Stderr, + fmt.Fprintf(out, `======================================== kubectl could not be found on your path. kubectl is a requirement for using minikube To install kubectl, please %s the following: @@ -200,6 +205,6 @@ To disable this message, run the following: minikube config set WantKubectlDownloadMsg false ======================================== `, - verb, fmt.Sprintf(installInstructions, constants.DefaultKubernetesVersion, runtime.GOOS, runtime.GOARCH)) + verb, fmt.Sprintf(installInstructions, constants.DefaultKubernetesVersion, goos, runtime.GOARCH)) } } diff --git a/cmd/util/util_test.go b/cmd/util/util_test.go index ff03611581..856df0d0cf 100644 --- a/cmd/util/util_test.go +++ b/cmd/util/util_test.go @@ -17,9 +17,11 @@ limitations under the License. package util import ( + "bytes" "fmt" "net/http" "net/http/httptest" + "strings" "testing" "k8s.io/minikube/pkg/version" @@ -81,3 +83,62 @@ func TestUploadError(t *testing.T) { t.Fatalf("UploadError should have errored from a 400 response") } } + +func revertLookPath(l LookPath) { + lookPath = l +} + +func fakeLookPathFound(string) (string, error) { return "/usr/local/bin/kubectl", nil } +func fakeLookPathError(string) (string, error) { return "", errors.New("") } + +func TestKubectlDownloadMsg(t *testing.T) { + var tests = []struct { + description string + lp LookPath + goos string + matches string + noOutput bool + }{ + { + description: "No output when binary is found windows", + goos: "windows", + lp: fakeLookPathFound, + noOutput: true, + }, + { + description: "No output when binary is found darwin", + goos: "darwin", + lp: fakeLookPathFound, + noOutput: true, + }, + { + description: "windows kubectl not found, has .exe in output", + goos: "windows", + lp: fakeLookPathError, + matches: ".exe", + }, + { + description: "linux kubectl not found", + goos: "linux", + lp: fakeLookPathError, + matches: "WantKubectlDownloadMsg", + }, + } + + for _, test := range tests { + test := test + t.Run(test.description, func(t *testing.T) { + defer revertLookPath(lookPath) + lookPath = test.lp + var b bytes.Buffer + MaybePrintKubectlDownloadMsg(test.goos, &b) + actual := b.String() + if actual != "" && test.noOutput { + t.Errorf("Got output, but kubectl binary was found") + } + if !strings.Contains(actual, test.matches) { + t.Errorf("Output did not contain substring expected got output %s") + } + }) + } +}