From a7c14beed97085c1d8e6c3530a8b5ac2f75ccb50 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Mon, 2 Sep 2019 14:17:29 +0200 Subject: [PATCH] Improve fake commands handling + avoid cases where the parent test would be mark in error instead of the child test. See #2744 + simplify usage + make sure every usage look similar Signed-off-by: David Gageot --- pkg/skaffold/build/bazel/dependencies_test.go | 5 +- .../build/custom/dependencies_test.go | 2 +- pkg/skaffold/build/local/bazel_test.go | 2 +- pkg/skaffold/build/local/docker_test.go | 5 +- pkg/skaffold/build/local/jib_gradle_test.go | 50 ++++++--- pkg/skaffold/build/local/jib_maven_test.go | 58 ++++++---- pkg/skaffold/deploy/helm_test.go | 49 +++++---- pkg/skaffold/deploy/kubectl_test.go | 102 +++++++++--------- pkg/skaffold/deploy/kustomize_test.go | 40 +++---- pkg/skaffold/deploy/status_check_test.go | 49 +++++---- pkg/skaffold/docker/client_test.go | 2 +- pkg/skaffold/jib/jib_gradle_test.go | 2 +- pkg/skaffold/jib/jib_init_test.go | 10 +- pkg/skaffold/jib/jib_maven_test.go | 2 +- pkg/skaffold/jib/jib_test.go | 13 ++- pkg/skaffold/kubectl/cli_test.go | 25 +++-- pkg/skaffold/kubectl/version_test.go | 14 +-- pkg/skaffold/runner/kind_test.go | 34 +++--- pkg/skaffold/test/structure/types_test.go | 7 +- pkg/skaffold/test/test_test.go | 17 ++- testutil/cmd_helper.go | 49 +++++---- testutil/util.go | 21 ++-- 22 files changed, 316 insertions(+), 242 deletions(-) diff --git a/pkg/skaffold/build/bazel/dependencies_test.go b/pkg/skaffold/build/bazel/dependencies_test.go index dc6b38dc074..0240d840460 100644 --- a/pkg/skaffold/build/bazel/dependencies_test.go +++ b/pkg/skaffold/build/bazel/dependencies_test.go @@ -76,7 +76,10 @@ func TestGetDependencies(t *testing.T) { } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, t.FakeRunOut(test.expectedQuery, test.output)) + t.Override(&util.DefaultExecCommand, testutil.CmdRunOut( + test.expectedQuery, + test.output, + )) t.NewTempDir().WriteFiles(test.files).Chdir() deps, err := GetDependencies(context.Background(), test.workspace, &latest.BazelArtifact{ diff --git a/pkg/skaffold/build/custom/dependencies_test.go b/pkg/skaffold/build/custom/dependencies_test.go index 9e41316874a..2af3a301f40 100644 --- a/pkg/skaffold/build/custom/dependencies_test.go +++ b/pkg/skaffold/build/custom/dependencies_test.go @@ -58,7 +58,7 @@ func TestGetDependenciesDockerfile(t *testing.T) { func TestGetDependenciesCommand(t *testing.T) { testutil.Run(t, "", func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, t.FakeRunOut( + t.Override(&util.DefaultExecCommand, testutil.CmdRunOut( "echo [\"file1\",\"file2\",\"file3\"]", "[\"file1\",\"file2\",\"file3\"]", )) diff --git a/pkg/skaffold/build/local/bazel_test.go b/pkg/skaffold/build/local/bazel_test.go index 622c760f4a5..4e2b516e2c0 100644 --- a/pkg/skaffold/build/local/bazel_test.go +++ b/pkg/skaffold/build/local/bazel_test.go @@ -27,7 +27,7 @@ import ( func TestBazelBin(t *testing.T) { testutil.Run(t, "", func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, t.FakeRunOut( + t.Override(&util.DefaultExecCommand, testutil.CmdRunOut( "bazel info bazel-bin --arg1 --arg2", "/absolute/path/bin\n", )) diff --git a/pkg/skaffold/build/local/docker_test.go b/pkg/skaffold/build/local/docker_test.go index ee17db6b116..22c3ccd2e68 100644 --- a/pkg/skaffold/build/local/docker_test.go +++ b/pkg/skaffold/build/local/docker_test.go @@ -71,7 +71,10 @@ func TestDockerCLIBuild(t *testing.T) { testutil.Run(t, test.description, func(t *testutil.T) { t.NewTempDir().Chdir() dockerfilePath, _ := filepath.Abs("Dockerfile") - t.Override(&util.DefaultExecCommand, t.NewFakeCmd().WithRunEnv("docker build . --file "+dockerfilePath+" -t tag --force-rm", test.expectedEnv)) + t.Override(&util.DefaultExecCommand, testutil.CmdRunEnv( + "docker build . --file "+dockerfilePath+" -t tag --force-rm", + test.expectedEnv, + )) t.Override(&util.OSEnviron, func() []string { return []string{"KEY=VALUE"} }) t.Override(&docker.NewAPIClient, func(*runcontext.RunContext) (docker.LocalDaemon, error) { return docker.NewLocalDaemon(&testutil.FakeAPIClient{}, test.extraEnv, false, nil), nil diff --git a/pkg/skaffold/build/local/jib_gradle_test.go b/pkg/skaffold/build/local/jib_gradle_test.go index d8aefc3feed..15dc55850d8 100644 --- a/pkg/skaffold/build/local/jib_gradle_test.go +++ b/pkg/skaffold/build/local/jib_gradle_test.go @@ -34,29 +34,38 @@ func TestBuildJibGradleToDocker(t *testing.T) { tests := []struct { description string artifact *latest.JibGradleArtifact - cmd util.Command + commands util.Command shouldErr bool expectedError string }{ { description: "build", artifact: &latest.JibGradleArtifact{}, - cmd: testutil.FakeRun(t, "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion="+jib.MinimumJibGradleVersion+" :jibDockerBuild --image=img:tag"), + commands: testutil.CmdRun( + "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion=" + jib.MinimumJibGradleVersion + " :jibDockerBuild --image=img:tag", + ), }, { description: "build with additional flags", artifact: &latest.JibGradleArtifact{Flags: []string{"--flag1", "--flag2"}}, - cmd: testutil.FakeRun(t, "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion="+jib.MinimumJibGradleVersion+" :jibDockerBuild --image=img:tag --flag1 --flag2"), + commands: testutil.CmdRun( + "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion=" + jib.MinimumJibGradleVersion + " :jibDockerBuild --image=img:tag --flag1 --flag2", + ), }, { description: "build with project", artifact: &latest.JibGradleArtifact{Project: "project"}, - cmd: testutil.FakeRun(t, "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion="+jib.MinimumJibGradleVersion+" :project:jibDockerBuild --image=img:tag"), + commands: testutil.CmdRun( + "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion=" + jib.MinimumJibGradleVersion + " :project:jibDockerBuild --image=img:tag", + ), }, { - description: "fail build", - artifact: &latest.JibGradleArtifact{}, - cmd: testutil.FakeRunErr(t, "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion="+jib.MinimumJibGradleVersion+" :jibDockerBuild --image=img:tag", errors.New("BUG")), + description: "fail build", + artifact: &latest.JibGradleArtifact{}, + commands: testutil.CmdRunErr( + "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion="+jib.MinimumJibGradleVersion+" :jibDockerBuild --image=img:tag", + errors.New("BUG"), + ), shouldErr: true, expectedError: "gradle build failed", }, @@ -66,7 +75,7 @@ func TestBuildJibGradleToDocker(t *testing.T) { testutil.Run(t, test.description, func(t *testutil.T) { api := (&testutil.FakeAPIClient{}).Add("img:tag", "imageID") - t.Override(&util.DefaultExecCommand, test.cmd) + t.Override(&util.DefaultExecCommand, test.commands) t.Override(&docker.NewAPIClient, func(*runcontext.RunContext) (docker.LocalDaemon, error) { return docker.NewLocalDaemon(api, nil, false, nil), nil }) @@ -92,29 +101,38 @@ func TestBuildJibGradleToRegistry(t *testing.T) { tests := []struct { description string artifact *latest.JibGradleArtifact - cmd util.Command + commands util.Command shouldErr bool expectedError string }{ { description: "remote build", artifact: &latest.JibGradleArtifact{}, - cmd: testutil.FakeRun(t, "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion="+jib.MinimumJibGradleVersion+" :jib --image=img:tag"), + commands: testutil.CmdRun( + "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion=" + jib.MinimumJibGradleVersion + " :jib --image=img:tag", + ), }, { description: "build with additional flags", artifact: &latest.JibGradleArtifact{Flags: []string{"--flag1", "--flag2"}}, - cmd: testutil.FakeRun(t, "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion="+jib.MinimumJibGradleVersion+" :jib --image=img:tag --flag1 --flag2"), + commands: testutil.CmdRun( + "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion=" + jib.MinimumJibGradleVersion + " :jib --image=img:tag --flag1 --flag2", + ), }, { description: "build with project", artifact: &latest.JibGradleArtifact{Project: "project"}, - cmd: testutil.FakeRun(t, "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion="+jib.MinimumJibGradleVersion+" :project:jib --image=img:tag"), + commands: testutil.CmdRun( + "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion=" + jib.MinimumJibGradleVersion + " :project:jib --image=img:tag", + ), }, { - description: "fail build", - artifact: &latest.JibGradleArtifact{}, - cmd: testutil.FakeRunErr(t, "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion="+jib.MinimumJibGradleVersion+" :jib --image=img:tag", errors.New("BUG")), + description: "fail build", + artifact: &latest.JibGradleArtifact{}, + commands: testutil.CmdRunErr( + "gradle -Djib.console=plain _skaffoldFailIfJibOutOfDate -Djib.requiredVersion="+jib.MinimumJibGradleVersion+" :jib --image=img:tag", + errors.New("BUG"), + ), shouldErr: true, expectedError: "gradle build failed", }, @@ -122,7 +140,7 @@ func TestBuildJibGradleToRegistry(t *testing.T) { for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, test.cmd) + t.Override(&util.DefaultExecCommand, test.commands) t.Override(&docker.RemoteDigest, func(identifier string, _ map[string]bool) (string, error) { if identifier == "img:tag" { return "digest", nil diff --git a/pkg/skaffold/build/local/jib_maven_test.go b/pkg/skaffold/build/local/jib_maven_test.go index da4f52eb60e..670328057fd 100644 --- a/pkg/skaffold/build/local/jib_maven_test.go +++ b/pkg/skaffold/build/local/jib_maven_test.go @@ -34,34 +34,45 @@ func TestBuildJibMavenToDocker(t *testing.T) { tests := []struct { description string artifact *latest.JibMavenArtifact - cmd util.Command + commands util.Command shouldErr bool expectedError string }{ { description: "build", artifact: &latest.JibMavenArtifact{}, - cmd: testutil.FakeRun(t, "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion="+jib.MinimumJibMavenVersion+" --non-recursive prepare-package jib:dockerBuild -Dimage=img:tag"), + commands: testutil.CmdRun( + "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion=" + jib.MinimumJibMavenVersion + " --non-recursive prepare-package jib:dockerBuild -Dimage=img:tag", + ), }, { description: "build with additional flags", artifact: &latest.JibMavenArtifact{Flags: []string{"--flag1", "--flag2"}}, - cmd: testutil.FakeRun(t, "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion="+jib.MinimumJibMavenVersion+" --flag1 --flag2 --non-recursive prepare-package jib:dockerBuild -Dimage=img:tag"), + commands: testutil.CmdRun( + "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion=" + jib.MinimumJibMavenVersion + " --flag1 --flag2 --non-recursive prepare-package jib:dockerBuild -Dimage=img:tag", + ), }, { description: "build with module", artifact: &latest.JibMavenArtifact{Module: "module"}, - cmd: testutil.FakeRun(t, "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion="+jib.MinimumJibMavenVersion+" --projects module --also-make package jib:dockerBuild -Djib.containerize=module -Dimage=img:tag"), + commands: testutil.CmdRun( + "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion=" + jib.MinimumJibMavenVersion + " --projects module --also-make package jib:dockerBuild -Djib.containerize=module -Dimage=img:tag", + ), }, { description: "build with module and profile", artifact: &latest.JibMavenArtifact{Module: "module", Profile: "profile"}, - cmd: testutil.FakeRun(t, "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion="+jib.MinimumJibMavenVersion+" --activate-profiles profile --projects module --also-make package jib:dockerBuild -Djib.containerize=module -Dimage=img:tag"), + commands: testutil.CmdRun( + "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion=" + jib.MinimumJibMavenVersion + " --activate-profiles profile --projects module --also-make package jib:dockerBuild -Djib.containerize=module -Dimage=img:tag", + ), }, { - description: "fail build", - artifact: &latest.JibMavenArtifact{}, - cmd: testutil.FakeRunErr(t, "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion="+jib.MinimumJibMavenVersion+" --non-recursive prepare-package jib:dockerBuild -Dimage=img:tag", errors.New("BUG")), + description: "fail build", + artifact: &latest.JibMavenArtifact{}, + commands: testutil.CmdRunErr( + "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion="+jib.MinimumJibMavenVersion+" --non-recursive prepare-package jib:dockerBuild -Dimage=img:tag", + errors.New("BUG"), + ), shouldErr: true, expectedError: "maven build failed", }, @@ -73,7 +84,7 @@ func TestBuildJibMavenToDocker(t *testing.T) { t.Override(&docker.NewAPIClient, func(*runcontext.RunContext) (docker.LocalDaemon, error) { return docker.NewLocalDaemon(api, nil, false, nil), nil }) - t.Override(&util.DefaultExecCommand, test.cmd) + t.Override(&util.DefaultExecCommand, test.commands) builder, err := NewBuilder(stubRunContext(latest.LocalBuild{ Push: util.BoolPtr(false), @@ -96,34 +107,45 @@ func TestBuildJibMavenToRegistry(t *testing.T) { tests := []struct { description string artifact *latest.JibMavenArtifact - cmd util.Command + commands util.Command shouldErr bool expectedError string }{ { description: "build", artifact: &latest.JibMavenArtifact{}, - cmd: testutil.FakeRun(t, "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion="+jib.MinimumJibMavenVersion+" --non-recursive prepare-package jib:build -Dimage=img:tag"), + commands: testutil.CmdRun( + "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion=" + jib.MinimumJibMavenVersion + " --non-recursive prepare-package jib:build -Dimage=img:tag", + ), }, { description: "build with additional flags", artifact: &latest.JibMavenArtifact{Flags: []string{"--flag1", "--flag2"}}, - cmd: testutil.FakeRun(t, "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion="+jib.MinimumJibMavenVersion+" --flag1 --flag2 --non-recursive prepare-package jib:build -Dimage=img:tag"), + commands: testutil.CmdRun( + "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion=" + jib.MinimumJibMavenVersion + " --flag1 --flag2 --non-recursive prepare-package jib:build -Dimage=img:tag", + ), }, { description: "build with module", artifact: &latest.JibMavenArtifact{Module: "module"}, - cmd: testutil.FakeRun(t, "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion="+jib.MinimumJibMavenVersion+" --projects module --also-make package jib:build -Djib.containerize=module -Dimage=img:tag"), + commands: testutil.CmdRun( + "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion=" + jib.MinimumJibMavenVersion + " --projects module --also-make package jib:build -Djib.containerize=module -Dimage=img:tag", + ), }, { description: "build with module and profile", artifact: &latest.JibMavenArtifact{Module: "module", Profile: "profile"}, - cmd: testutil.FakeRun(t, "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion="+jib.MinimumJibMavenVersion+" --activate-profiles profile --projects module --also-make package jib:build -Djib.containerize=module -Dimage=img:tag"), + commands: testutil.CmdRun( + "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion=" + jib.MinimumJibMavenVersion + " --activate-profiles profile --projects module --also-make package jib:build -Djib.containerize=module -Dimage=img:tag", + ), }, { - description: "fail build", - artifact: &latest.JibMavenArtifact{}, - cmd: testutil.FakeRunErr(t, "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion="+jib.MinimumJibMavenVersion+" --non-recursive prepare-package jib:build -Dimage=img:tag", errors.New("BUG")), + description: "fail build", + artifact: &latest.JibMavenArtifact{}, + commands: testutil.CmdRunErr( + "mvn -Djib.console=plain jib:_skaffold-fail-if-jib-out-of-date -Djib.requiredVersion="+jib.MinimumJibMavenVersion+" --non-recursive prepare-package jib:build -Dimage=img:tag", + errors.New("BUG"), + ), shouldErr: true, expectedError: "maven build failed", }, @@ -131,7 +153,7 @@ func TestBuildJibMavenToRegistry(t *testing.T) { for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, test.cmd) + t.Override(&util.DefaultExecCommand, test.commands) t.Override(&docker.RemoteDigest, func(identifier string, _ map[string]bool) (string, error) { if identifier == "img:tag" { return "digest", nil diff --git a/pkg/skaffold/deploy/helm_test.go b/pkg/skaffold/deploy/helm_test.go index 16a59270e16..0506a9de2b6 100644 --- a/pkg/skaffold/deploy/helm_test.go +++ b/pkg/skaffold/deploy/helm_test.go @@ -296,51 +296,51 @@ func TestMain(m *testing.M) { func TestHelmDeploy(t *testing.T) { tests := []struct { description string - cmd *MockHelm + commands *MockHelm runContext *runcontext.RunContext builds []build.Artifact shouldErr bool }{ { description: "deploy success", - cmd: &MockHelm{}, + commands: &MockHelm{}, runContext: makeRunContext(testDeployConfig, false), builds: testBuilds, }, { description: "deploy success with recreatePods", - cmd: &MockHelm{}, + commands: &MockHelm{}, runContext: makeRunContext(testDeployRecreatePodsConfig, false), builds: testBuilds, }, { description: "deploy success with skipBuildDependencies", - cmd: &MockHelm{}, + commands: &MockHelm{}, runContext: makeRunContext(testDeploySkipBuildDependenciesConfig, false), builds: testBuilds, }, { description: "deploy should not error for unmatched parameter when no builds present", - cmd: &MockHelm{}, + commands: &MockHelm{}, runContext: makeRunContext(testDeployConfigParameterUnmatched, false), builds: nil, }, { description: "deploy should error for unmatched parameter when builds present", - cmd: &MockHelm{}, + commands: &MockHelm{}, runContext: makeRunContext(testDeployConfigParameterUnmatched, false), builds: testBuilds, shouldErr: true, }, { description: "deploy success remote chart with skipBuildDependencies", - cmd: &MockHelm{}, + commands: &MockHelm{}, runContext: makeRunContext(testDeploySkipBuildDependencies, false), builds: testBuilds, }, { description: "deploy error remote chart without skipBuildDependencies", - cmd: &MockHelm{ + commands: &MockHelm{ depResult: fmt.Errorf("unexpected error"), }, runContext: makeRunContext(testDeployRemoteChart, false), @@ -349,7 +349,7 @@ func TestHelmDeploy(t *testing.T) { }, { description: "get failure should install not upgrade", - cmd: &MockHelm{ + commands: &MockHelm{ getResult: fmt.Errorf("not found"), installMatcher: func(cmd *exec.Cmd) bool { expected := fmt.Sprintf("image=%s", testBuilds[0].Tag) @@ -362,7 +362,7 @@ func TestHelmDeploy(t *testing.T) { }, { description: "get failure should install not upgrade with helm image strategy", - cmd: &MockHelm{ + commands: &MockHelm{ getResult: fmt.Errorf("not found"), installMatcher: func(cmd *exec.Cmd) bool { dockerRef, err := docker.ParseReference(testBuilds[0].Tag) @@ -380,7 +380,7 @@ func TestHelmDeploy(t *testing.T) { }, { description: "helm image strategy with explicit registry should set the Helm registry value", - cmd: &MockHelm{ + commands: &MockHelm{ getResult: fmt.Errorf("not found"), installMatcher: func(cmd *exec.Cmd) bool { expected := fmt.Sprintf("image.registry=%s,image.repository=%s,image.tag=%s", "docker.io:5000", "skaffold-helm", "3605e7bc17cf46e53f4d81c4cbc24e5b4c495184") @@ -393,7 +393,7 @@ func TestHelmDeploy(t *testing.T) { }, { description: "get success should upgrade by force, not install", - cmd: &MockHelm{ + commands: &MockHelm{ upgradeMatcher: func(cmd *exec.Cmd) bool { return util.StrSliceContains(cmd.Args, "--force") }, @@ -404,7 +404,7 @@ func TestHelmDeploy(t *testing.T) { }, { description: "get success should upgrade without force, not install", - cmd: &MockHelm{ + commands: &MockHelm{ upgradeMatcher: func(cmd *exec.Cmd) bool { return !util.StrSliceContains(cmd.Args, "--force") }, @@ -415,7 +415,7 @@ func TestHelmDeploy(t *testing.T) { }, { description: "deploy error", - cmd: &MockHelm{ + commands: &MockHelm{ upgradeResult: fmt.Errorf("unexpected error"), }, shouldErr: true, @@ -424,7 +424,7 @@ func TestHelmDeploy(t *testing.T) { }, { description: "dep build error", - cmd: &MockHelm{ + commands: &MockHelm{ depResult: fmt.Errorf("unexpected error"), }, shouldErr: true, @@ -433,7 +433,7 @@ func TestHelmDeploy(t *testing.T) { }, { description: "should package chart and deploy", - cmd: &MockHelm{ + commands: &MockHelm{ packageOut: bytes.NewBufferString("Packaged to " + os.TempDir() + "foo-0.1.2.tgz"), }, shouldErr: false, @@ -442,7 +442,7 @@ func TestHelmDeploy(t *testing.T) { }, { description: "should fail to deploy when packaging fails", - cmd: &MockHelm{ + commands: &MockHelm{ packageResult: fmt.Errorf("packaging failed"), }, shouldErr: true, @@ -451,13 +451,13 @@ func TestHelmDeploy(t *testing.T) { }, { description: "deploy and get templated release name", - cmd: &MockHelm{}, + commands: &MockHelm{}, runContext: makeRunContext(testDeployWithTemplatedName, false), builds: testBuilds, }, { description: "deploy with templated values", - cmd: &MockHelm{ + commands: &MockHelm{ upgradeMatcher: func(cmd *exec.Cmd) bool { return util.StrSliceContains(cmd.Args, "other.key=FOOBAR") && util.StrSliceContains(cmd.Args, "missing.key=") && @@ -472,7 +472,7 @@ func TestHelmDeploy(t *testing.T) { for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { t.Override(&util.OSEnviron, func() []string { return []string{"FOO=FOOBAR"} }) - t.Override(&util.DefaultExecCommand, test.cmd.ForTest(t)) + t.Override(&util.DefaultExecCommand, test.commands) event.InitializeState(test.runContext.Cfg.Build) @@ -487,7 +487,7 @@ func TestHelmDeploy(t *testing.T) { type CommandMatcher func(*exec.Cmd) bool type MockHelm struct { - t *testutil.T + t *testing.T getResult error installResult error @@ -500,9 +500,8 @@ type MockHelm struct { packageResult error } -func (m *MockHelm) ForTest(t *testutil.T) *MockHelm { +func (m *MockHelm) ForTest(t *testing.T) { m.t = t - return m } func (m *MockHelm) RunCmdOut(c *exec.Cmd) ([]byte, error) { @@ -530,12 +529,12 @@ func (m *MockHelm) RunCmd(c *exec.Cmd) error { return m.getResult case "install": if m.upgradeMatcher != nil && !m.installMatcher(c) { - m.t.Errorf("install matcher failed to match cmd: %+v", c.Args) + m.t.Errorf("install matcher failed to match commands: %+v", c.Args) } return m.installResult case "upgrade": if m.upgradeMatcher != nil && !m.upgradeMatcher(c) { - m.t.Errorf("upgrade matcher failed to match cmd: %+v", c.Args) + m.t.Errorf("upgrade matcher failed to match commands: %+v", c.Args) } return m.upgradeResult case "dep": diff --git a/pkg/skaffold/deploy/kubectl_test.go b/pkg/skaffold/deploy/kubectl_test.go index 5aa97231593..6609c00e538 100644 --- a/pkg/skaffold/deploy/kubectl_test.go +++ b/pkg/skaffold/deploy/kubectl_test.go @@ -60,24 +60,24 @@ func TestKubectlDeploy(t *testing.T) { description string cfg *latest.KubectlDeploy builds []build.Artifact - command util.Command + commands util.Command shouldErr bool forceDeploy bool }{ { description: "no manifest", cfg: &latest.KubectlDeploy{}, - command: testutil.FakeRunOut(t, "kubectl version --client -ojson", kubectlVersion), + commands: testutil.CmdRunOut("kubectl version --client -ojson", kubectlVersion), }, { description: "deploy success (forced)", cfg: &latest.KubectlDeploy{ Manifests: []string{"deployment.yaml"}, }, - command: testutil.NewFakeCmd(t). - WithRunOut("kubectl version --client -ojson", kubectlVersion). - WithRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f deployment.yaml", deploymentWebYAML). - WithRun("kubectl --context kubecontext --namespace testNamespace apply -f - --force"), + commands: testutil. + CmdRunOut("kubectl version --client -ojson", kubectlVersion). + AndRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f deployment.yaml", deploymentWebYAML). + AndRun("kubectl --context kubecontext --namespace testNamespace apply -f - --force"), builds: []build.Artifact{{ ImageName: "leeroy-web", Tag: "leeroy-web:123", @@ -89,10 +89,10 @@ func TestKubectlDeploy(t *testing.T) { cfg: &latest.KubectlDeploy{ Manifests: []string{"deployment.yaml"}, }, - command: testutil.NewFakeCmd(t). - WithRunOut("kubectl version --client -ojson", kubectlVersion). - WithRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f deployment.yaml", deploymentWebYAML). - WithRun("kubectl --context kubecontext --namespace testNamespace apply -f -"), + commands: testutil. + CmdRunOut("kubectl version --client -ojson", kubectlVersion). + AndRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f deployment.yaml", deploymentWebYAML). + AndRun("kubectl --context kubecontext --namespace testNamespace apply -f -"), builds: []build.Artifact{{ ImageName: "leeroy-web", Tag: "leeroy-web:123", @@ -103,10 +103,10 @@ func TestKubectlDeploy(t *testing.T) { cfg: &latest.KubectlDeploy{ Manifests: []string{"deployment.yaml", "http://remote.yaml"}, }, - command: testutil.NewFakeCmd(t). - WithRunOut("kubectl version --client -ojson", kubectlVersion). - WithRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f deployment.yaml -f http://remote.yaml", deploymentWebYAML). - WithRun("kubectl --context kubecontext --namespace testNamespace apply -f -"), + commands: testutil. + CmdRunOut("kubectl version --client -ojson", kubectlVersion). + AndRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f deployment.yaml -f http://remote.yaml", deploymentWebYAML). + AndRun("kubectl --context kubecontext --namespace testNamespace apply -f -"), builds: []build.Artifact{{ ImageName: "leeroy-web", Tag: "leeroy-web:123", @@ -117,10 +117,10 @@ func TestKubectlDeploy(t *testing.T) { cfg: &latest.KubectlDeploy{ Manifests: []string{"deployment.yaml"}, }, - command: testutil.NewFakeCmd(t). - WithRunOut("kubectl version --client -ojson", kubectlVersion). - WithRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f deployment.yaml", deploymentWebYAML). - WithRunErr("kubectl --context kubecontext --namespace testNamespace apply -f -", fmt.Errorf("")), + commands: testutil. + CmdRunOut("kubectl version --client -ojson", kubectlVersion). + AndRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f deployment.yaml", deploymentWebYAML). + AndRunErr("kubectl --context kubecontext --namespace testNamespace apply -f -", fmt.Errorf("")), builds: []build.Artifact{{ ImageName: "leeroy-web", Tag: "leeroy-web:123", @@ -137,10 +137,10 @@ func TestKubectlDeploy(t *testing.T) { Delete: []string{"ignored"}, }, }, - command: testutil.NewFakeCmd(t). - WithRunOut("kubectl version --client -ojson", kubectlVersion). - WithRunOut("kubectl --context kubecontext --namespace testNamespace create -v=0 --dry-run -oyaml -f deployment.yaml", deploymentWebYAML). - WithRunErr("kubectl --context kubecontext --namespace testNamespace apply -v=0 --overwrite=true -f -", fmt.Errorf("")), + commands: testutil. + CmdRunOut("kubectl version --client -ojson", kubectlVersion). + AndRunOut("kubectl --context kubecontext --namespace testNamespace create -v=0 --dry-run -oyaml -f deployment.yaml", deploymentWebYAML). + AndRunErr("kubectl --context kubecontext --namespace testNamespace apply -v=0 --overwrite=true -f -", fmt.Errorf("")), builds: []build.Artifact{{ ImageName: "leeroy-web", Tag: "leeroy-web:123", @@ -150,7 +150,7 @@ func TestKubectlDeploy(t *testing.T) { } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, test.command) + t.Override(&util.DefaultExecCommand, test.commands) t.NewTempDir(). Write("deployment.yaml", deploymentWebYAML). Touch("empty.ignored"). @@ -183,7 +183,7 @@ func TestKubectlCleanup(t *testing.T) { tests := []struct { description string cfg *latest.KubectlDeploy - command util.Command + commands util.Command shouldErr bool }{ { @@ -191,18 +191,18 @@ func TestKubectlCleanup(t *testing.T) { cfg: &latest.KubectlDeploy{ Manifests: []string{"deployment.yaml"}, }, - command: testutil.NewFakeCmd(t). - WithRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f deployment.yaml", deploymentWebYAML). - WithRun("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true -f -"), + commands: testutil. + CmdRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f deployment.yaml", deploymentWebYAML). + AndRun("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true -f -"), }, { description: "cleanup error", cfg: &latest.KubectlDeploy{ Manifests: []string{"deployment.yaml"}, }, - command: testutil.NewFakeCmd(t). - WithRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f deployment.yaml", deploymentWebYAML). - WithRunErr("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true -f -", errors.New("BUG")), + commands: testutil. + CmdRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f deployment.yaml", deploymentWebYAML). + AndRunErr("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true -f -", errors.New("BUG")), shouldErr: true, }, { @@ -215,14 +215,14 @@ func TestKubectlCleanup(t *testing.T) { Delete: []string{"--grace-period=1"}, }, }, - command: testutil.NewFakeCmd(t). - WithRunOut("kubectl --context kubecontext --namespace testNamespace create -v=0 --dry-run -oyaml -f deployment.yaml", deploymentWebYAML). - WithRun("kubectl --context kubecontext --namespace testNamespace delete -v=0 --grace-period=1 --ignore-not-found=true -f -"), + commands: testutil. + CmdRunOut("kubectl --context kubecontext --namespace testNamespace create -v=0 --dry-run -oyaml -f deployment.yaml", deploymentWebYAML). + AndRun("kubectl --context kubecontext --namespace testNamespace delete -v=0 --grace-period=1 --ignore-not-found=true -f -"), }, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, test.command) + t.Override(&util.DefaultExecCommand, test.commands) t.NewTempDir(). Write("deployment.yaml", deploymentWebYAML). Chdir() @@ -252,32 +252,32 @@ func TestKubectlDeployerRemoteCleanup(t *testing.T) { tests := []struct { description string cfg *latest.KubectlDeploy - command util.Command + commands util.Command }{ { description: "cleanup success", cfg: &latest.KubectlDeploy{ RemoteManifests: []string{"pod/leeroy-web"}, }, - command: testutil.NewFakeCmd(t). - WithRun("kubectl --context kubecontext --namespace testNamespace get pod/leeroy-web -o yaml"). - WithRun("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true -f -"). - WithRunInput("kubectl --context kubecontext --namespace testNamespace apply -f -", deploymentWebYAML), + commands: testutil. + CmdRun("kubectl --context kubecontext --namespace testNamespace get pod/leeroy-web -o yaml"). + AndRun("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true -f -"). + AndRunInput("kubectl --context kubecontext --namespace testNamespace apply -f -", deploymentWebYAML), }, { description: "cleanup error", cfg: &latest.KubectlDeploy{ RemoteManifests: []string{"anotherNamespace:pod/leeroy-web"}, }, - command: testutil.NewFakeCmd(t). - WithRun("kubectl --context kubecontext --namespace anotherNamespace get pod/leeroy-web -o yaml"). - WithRun("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true -f -"). - WithRunInput("kubectl --context kubecontext --namespace anotherNamespace apply -f -", deploymentWebYAML), + commands: testutil. + CmdRun("kubectl --context kubecontext --namespace anotherNamespace get pod/leeroy-web -o yaml"). + AndRun("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true -f -"). + AndRunInput("kubectl --context kubecontext --namespace anotherNamespace apply -f -", deploymentWebYAML), }, } for _, test := range tests { testutil.Run(t, "cleanup remote", func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, test.command) + t.Override(&util.DefaultExecCommand, test.commands) t.NewTempDir(). Write("deployment.yaml", deploymentWebYAML). Chdir() @@ -309,10 +309,10 @@ func TestKubectlRedeploy(t *testing.T) { Write("deployment-web.yaml", deploymentWebYAML). Write("deployment-app.yaml", deploymentAppYAML) - t.Override(&util.DefaultExecCommand, t. - FakeRunOut("kubectl version --client -ojson", kubectlVersion). - WithRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f "+tmpDir.Path("deployment-app.yaml")+" -f "+tmpDir.Path("deployment-web.yaml"), deploymentAppYAML+"\n"+deploymentWebYAML). - WithRunInput("kubectl --context kubecontext --namespace testNamespace apply -f -", `apiVersion: v1 + t.Override(&util.DefaultExecCommand, testutil. + CmdRunOut("kubectl version --client -ojson", kubectlVersion). + AndRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f "+tmpDir.Path("deployment-app.yaml")+" -f "+tmpDir.Path("deployment-web.yaml"), deploymentAppYAML+"\n"+deploymentWebYAML). + AndRunInput("kubectl --context kubecontext --namespace testNamespace apply -f -", `apiVersion: v1 kind: Pod metadata: labels: @@ -333,8 +333,8 @@ spec: containers: - image: leeroy-web:v1 name: leeroy-web`). - WithRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f "+tmpDir.Path("deployment-app.yaml")+" -f "+tmpDir.Path("deployment-web.yaml"), deploymentAppYAML+"\n"+deploymentWebYAML). - WithRunInput("kubectl --context kubecontext --namespace testNamespace apply -f -", `apiVersion: v1 + AndRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f "+tmpDir.Path("deployment-app.yaml")+" -f "+tmpDir.Path("deployment-web.yaml"), deploymentAppYAML+"\n"+deploymentWebYAML). + AndRunInput("kubectl --context kubecontext --namespace testNamespace apply -f -", `apiVersion: v1 kind: Pod metadata: labels: @@ -344,7 +344,7 @@ spec: containers: - image: leeroy-app:v2 name: leeroy-app`). - WithRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f "+tmpDir.Path("deployment-app.yaml")+" -f "+tmpDir.Path("deployment-web.yaml"), deploymentAppYAML+"\n"+deploymentWebYAML), + AndRunOut("kubectl --context kubecontext --namespace testNamespace create --dry-run -oyaml -f "+tmpDir.Path("deployment-app.yaml")+" -f "+tmpDir.Path("deployment-web.yaml"), deploymentAppYAML+"\n"+deploymentWebYAML), ) cfg := &latest.KubectlDeploy{ diff --git a/pkg/skaffold/deploy/kustomize_test.go b/pkg/skaffold/deploy/kustomize_test.go index fcc74eefde2..9282f12f62a 100644 --- a/pkg/skaffold/deploy/kustomize_test.go +++ b/pkg/skaffold/deploy/kustomize_test.go @@ -35,7 +35,7 @@ func TestKustomizeDeploy(t *testing.T) { description string cfg *latest.KustomizeDeploy builds []build.Artifact - command util.Command + commands util.Command shouldErr bool forceDeploy bool }{ @@ -44,19 +44,19 @@ func TestKustomizeDeploy(t *testing.T) { cfg: &latest.KustomizeDeploy{ KustomizePath: ".", }, - command: testutil.NewFakeCmd(t). - WithRunOut("kubectl version --client -ojson", kubectlVersion). - WithRunOut("kustomize build .", ""), + commands: testutil. + CmdRunOut("kubectl version --client -ojson", kubectlVersion). + AndRunOut("kustomize build .", ""), }, { description: "deploy success", cfg: &latest.KustomizeDeploy{ KustomizePath: ".", }, - command: testutil.NewFakeCmd(t). - WithRunOut("kubectl version --client -ojson", kubectlVersion). - WithRunOut("kustomize build .", deploymentWebYAML). - WithRun("kubectl --context kubecontext --namespace testNamespace apply -f - --force"), + commands: testutil. + CmdRunOut("kubectl version --client -ojson", kubectlVersion). + AndRunOut("kustomize build .", deploymentWebYAML). + AndRun("kubectl --context kubecontext --namespace testNamespace apply -f - --force"), builds: []build.Artifact{{ ImageName: "leeroy-web", Tag: "leeroy-web:123", @@ -66,7 +66,7 @@ func TestKustomizeDeploy(t *testing.T) { } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, test.command) + t.Override(&util.DefaultExecCommand, test.commands) t.NewTempDir(). Chdir() @@ -99,7 +99,7 @@ func TestKustomizeCleanup(t *testing.T) { tests := []struct { description string cfg *latest.KustomizeDeploy - command util.Command + commands util.Command shouldErr bool }{ { @@ -107,18 +107,18 @@ func TestKustomizeCleanup(t *testing.T) { cfg: &latest.KustomizeDeploy{ KustomizePath: tmpDir.Root(), }, - command: testutil.NewFakeCmd(t). - WithRunOut("kustomize build "+tmpDir.Root(), deploymentWebYAML). - WithRun("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true -f -"), + commands: testutil. + CmdRunOut("kustomize build "+tmpDir.Root(), deploymentWebYAML). + AndRun("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true -f -"), }, { description: "cleanup error", cfg: &latest.KustomizeDeploy{ KustomizePath: tmpDir.Root(), }, - command: testutil.NewFakeCmd(t). - WithRunOut("kustomize build "+tmpDir.Root(), deploymentWebYAML). - WithRunErr("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true -f -", errors.New("BUG")), + commands: testutil. + CmdRunOut("kustomize build "+tmpDir.Root(), deploymentWebYAML). + AndRunErr("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true -f -", errors.New("BUG")), shouldErr: true, }, { @@ -126,13 +126,17 @@ func TestKustomizeCleanup(t *testing.T) { cfg: &latest.KustomizeDeploy{ KustomizePath: tmpDir.Root(), }, - command: testutil.FakeRunOutErr(t, "kustomize build "+tmpDir.Root(), ``, errors.New("BUG")), + commands: testutil.CmdRunOutErr( + "kustomize build "+tmpDir.Root(), + "", + errors.New("BUG"), + ), shouldErr: true, }, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, test.command) + t.Override(&util.DefaultExecCommand, test.commands) k := NewKustomizeDeployer(&runcontext.RunContext{ WorkingDir: tmpDir.Root(), diff --git a/pkg/skaffold/deploy/status_check_test.go b/pkg/skaffold/deploy/status_check_test.go index 6b63a395a1f..353cb19c24a 100644 --- a/pkg/skaffold/deploy/status_check_test.go +++ b/pkg/skaffold/deploy/status_check_test.go @@ -192,27 +192,31 @@ func TestPollDeploymentRolloutStatus(t *testing.T) { rolloutCmd := "kubectl --context kubecontext --namespace test rollout status deployment dep --watch=false" tests := []struct { description string - command util.Command + commands util.Command duration int shouldErr bool }{ { description: "rollout returns success", - command: testutil.NewFakeCmd(t). - WithRunOut(rolloutCmd, "dep successfully rolled out"), + commands: testutil.CmdRunOut( + rolloutCmd, + "dep successfully rolled out", + ), duration: 50, }, { description: "rollout returns error in the first attempt", - command: testutil.NewFakeCmd(t). - WithRunOutErr(rolloutCmd, "could not find", errors.New("deployment.apps/dep could not be found")), + commands: testutil.CmdRunOutErr( + rolloutCmd, "could not find", + errors.New("deployment.apps/dep could not be found"), + ), shouldErr: true, duration: 50, }, { description: "rollout returns did not stabilize within the given timeout", - command: testutil.NewFakeCmd(t). - WithRunOut(rolloutCmd, "Waiting for rollout to finish: 1 of 3 updated replicas are available..."). - WithRunOut(rolloutCmd, "Waiting for rollout to finish: 1 of 3 updated replicas are available..."). - WithRunOut(rolloutCmd, "Waiting for rollout to finish: 2 of 3 updated replicas are available..."), + commands: testutil. + CmdRunOut(rolloutCmd, "Waiting for rollout to finish: 1 of 3 updated replicas are available..."). + AndRunOut(rolloutCmd, "Waiting for rollout to finish: 1 of 3 updated replicas are available..."). + AndRunOut(rolloutCmd, "Waiting for rollout to finish: 2 of 3 updated replicas are available..."), duration: 20, shouldErr: true, }, @@ -220,7 +224,7 @@ func TestPollDeploymentRolloutStatus(t *testing.T) { for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { t.Override(&defaultPollPeriodInMilliseconds, 10) - t.Override(&util.DefaultExecCommand, test.command) + t.Override(&util.DefaultExecCommand, test.commands) actual := &sync.Map{} cli := &kubectl.CLI{KubeContext: testKubeContext, Namespace: "test"} @@ -289,34 +293,43 @@ func TestGetRollOutStatus(t *testing.T) { rolloutCmd := "kubectl --context kubecontext --namespace test rollout status deployment dep --watch=false" tests := []struct { description string - command util.Command + commands util.Command expected string shouldErr bool }{ { description: "some output", - command: testutil.NewFakeCmd(t). - WithRunOut(rolloutCmd, "Waiting for replicas to be available"), + commands: testutil.CmdRunOut( + rolloutCmd, + "Waiting for replicas to be available", + ), expected: "Waiting for replicas to be available", }, { description: "no output", - command: testutil.NewFakeCmd(t). - WithRunOut(rolloutCmd, ""), + commands: testutil.CmdRunOut( + rolloutCmd, + "", + ), }, { description: "rollout status error", - command: testutil.NewFakeCmd(t). - WithRunOutErr(rolloutCmd, "", fmt.Errorf("error")), + commands: testutil.CmdRunOutErr( + rolloutCmd, + "", + errors.New("error"), + ), shouldErr: true, }, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, test.command) + t.Override(&util.DefaultExecCommand, test.commands) + cli := &kubectl.CLI{KubeContext: testKubeContext, Namespace: "test"} actual, err := getRollOutStatus(context.Background(), cli, "dep") + t.CheckErrorAndDeepEqual(test.shouldErr, err, test.expected, actual) }) } diff --git a/pkg/skaffold/docker/client_test.go b/pkg/skaffold/docker/client_test.go index 150fd8a6d0e..957b3b7af80 100644 --- a/pkg/skaffold/docker/client_test.go +++ b/pkg/skaffold/docker/client_test.go @@ -110,7 +110,7 @@ DOCKER_API_VERSION=1.23`, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, t.FakeRunOut( + t.Override(&util.DefaultExecCommand, testutil.CmdRunOut( "minikube docker-env --shell none", test.env, )) diff --git a/pkg/skaffold/jib/jib_gradle_test.go b/pkg/skaffold/jib/jib_gradle_test.go index 9c7d7445d6b..ac155420073 100644 --- a/pkg/skaffold/jib/jib_gradle_test.go +++ b/pkg/skaffold/jib/jib_gradle_test.go @@ -86,7 +86,7 @@ func TestGetDependenciesGradle(t *testing.T) { } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, t.FakeRunOutErr( + t.Override(&util.DefaultExecCommand, testutil.CmdRunOutErr( strings.Join(getCommandGradle(ctx, tmpDir.Root(), &latest.JibGradleArtifact{Project: "gradle-test"}).Args, " "), test.stdout, test.err, diff --git a/pkg/skaffold/jib/jib_init_test.go b/pkg/skaffold/jib/jib_init_test.go index 12fae3a5302..84a6155b120 100644 --- a/pkg/skaffold/jib/jib_init_test.go +++ b/pkg/skaffold/jib/jib_init_test.go @@ -99,8 +99,14 @@ BEGIN JIB JSON } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, t.FakeRunOut(test.command, test.stdout)) - t.CheckDeepEqual(test.expectedConfig, ValidateJibConfig(test.path)) + t.Override(&util.DefaultExecCommand, testutil.CmdRunOut( + test.command, + test.stdout, + )) + + validated := ValidateJibConfig(test.path) + + t.CheckDeepEqual(test.expectedConfig, validated) }) } } diff --git a/pkg/skaffold/jib/jib_maven_test.go b/pkg/skaffold/jib/jib_maven_test.go index e3ee1e0e908..19a01b1f925 100644 --- a/pkg/skaffold/jib/jib_maven_test.go +++ b/pkg/skaffold/jib/jib_maven_test.go @@ -86,7 +86,7 @@ func TestGetDependenciesMaven(t *testing.T) { } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, t.FakeRunOutErr( + t.Override(&util.DefaultExecCommand, testutil.CmdRunOutErr( strings.Join(getCommandMaven(ctx, tmpDir.Root(), &latest.JibMavenArtifact{Module: "maven-test"}).Args, " "), test.stdout, test.err, diff --git a/pkg/skaffold/jib/jib_test.go b/pkg/skaffold/jib/jib_test.go index ae80e13ed80..b55b378e557 100644 --- a/pkg/skaffold/jib/jib_test.go +++ b/pkg/skaffold/jib/jib_test.go @@ -105,7 +105,10 @@ func TestGetDependencies(t *testing.T) { } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, t.FakeRunOut("ignored", test.stdout)) + t.Override(&util.DefaultExecCommand, testutil.CmdRunOut( + "ignored", + test.stdout, + )) results, err := getDependencies(tmpDir.Root(), exec.Cmd{Args: []string{"ignored"}, Dir: tmpDir.Root()}, util.RandomID()) @@ -119,10 +122,10 @@ func TestGetUpdatedDependencies(t *testing.T) { tmpDir := t.NewTempDir() stdout := fmt.Sprintf("BEGIN JIB JSON\n{\"build\":[\"%s\",\"%s\"],\"inputs\":[],\"ignore\":[]}\n", tmpDir.Path("build.gradle"), tmpDir.Path("settings.gradle")) - t.Override(&util.DefaultExecCommand, t. - FakeRunOut("ignored", stdout). - WithRunOut("ignored", stdout). - WithRunOut("ignored", stdout), + t.Override(&util.DefaultExecCommand, testutil. + CmdRunOut("ignored", stdout). + AndRunOut("ignored", stdout). + AndRunOut("ignored", stdout), ) listCmd := exec.Cmd{Args: []string{"ignored"}, Dir: tmpDir.Root()} diff --git a/pkg/skaffold/kubectl/cli_test.go b/pkg/skaffold/kubectl/cli_test.go index 25d5c41d337..ca7bf713375 100644 --- a/pkg/skaffold/kubectl/cli_test.go +++ b/pkg/skaffold/kubectl/cli_test.go @@ -52,27 +52,32 @@ func TestCLI(t *testing.T) { // test cli.Run() for _, test := range tests { testutil.Run(t, test.name, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, t.FakeRun(test.expectedCommand)) - runCtx := &runcontext.RunContext{ + t.Override(&util.DefaultExecCommand, testutil.CmdRun( + test.expectedCommand, + )) + + cli := NewFromRunContext(&runcontext.RunContext{ Opts: config.SkaffoldOptions{Namespace: test.namespace}, KubeContext: test.kubecontext, - } - cli := NewFromRunContext(runCtx) + }) + err := cli.Run(context.Background(), nil, nil, "exec", "arg1", "arg2") - t.CheckNoError(cli.Run(context.Background(), nil, nil, "exec", "arg1", "arg2")) + t.CheckNoError(err) }) } // test cli.RunOut() for _, test := range tests { testutil.Run(t, test.name, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, t.FakeRunOut(test.expectedCommand, test.output)) - runCtx := &runcontext.RunContext{ + t.Override(&util.DefaultExecCommand, testutil.CmdRunOut( + test.expectedCommand, + test.output, + )) + + cli := NewFromRunContext(&runcontext.RunContext{ Opts: config.SkaffoldOptions{Namespace: test.namespace}, KubeContext: test.kubecontext, - } - cli := NewFromRunContext(runCtx) - + }) out, err := cli.RunOut(context.Background(), "exec", "arg1", "arg2") t.CheckNoError(err) diff --git a/pkg/skaffold/kubectl/version_test.go b/pkg/skaffold/kubectl/version_test.go index 9d0be318c52..e324b3719ba 100644 --- a/pkg/skaffold/kubectl/version_test.go +++ b/pkg/skaffold/kubectl/version_test.go @@ -29,37 +29,37 @@ import ( func TestCheckVersion(t *testing.T) { tests := []struct { description string - command util.Command + commands util.Command shouldErr bool warnings []string expectedVersion string }{ { description: "1.12 is valid", - command: testutil.FakeRunOut(t, "kubectl version --client -ojson", `{"clientVersion":{"major":"1","minor":"12"}}`), + commands: testutil.CmdRunOut("kubectl version --client -ojson", `{"clientVersion":{"major":"1","minor":"12"}}`), expectedVersion: "1.12", }, { description: "1.12+ is valid", - command: testutil.FakeRunOut(t, "kubectl version --client -ojson", `{"clientVersion":{"major":"1","minor":"12+"}}`), + commands: testutil.CmdRunOut("kubectl version --client -ojson", `{"clientVersion":{"major":"1","minor":"12+"}}`), expectedVersion: "1.12+", }, { description: "1.11 is too old", - command: testutil.FakeRunOut(t, "kubectl version --client -ojson", `{"clientVersion":{"major":"1","minor":"11"}}`), + commands: testutil.CmdRunOut("kubectl version --client -ojson", `{"clientVersion":{"major":"1","minor":"11"}}`), shouldErr: true, expectedVersion: "1.11", }, { description: "invalid version", - command: testutil.FakeRunOut(t, "kubectl version --client -ojson", `not json`), + commands: testutil.CmdRunOut("kubectl version --client -ojson", `not json`), shouldErr: true, warnings: []string{"unable to parse client version: invalid character 'o' in literal null (expecting 'u')"}, expectedVersion: "unknown", }, { description: "cli not found", - command: testutil.FakeRunOutErr(t, "kubectl version --client -ojson", ``, errors.New("not found")), + commands: testutil.CmdRunOutErr("kubectl version --client -ojson", ``, errors.New("not found")), shouldErr: true, warnings: []string{"unable to get kubectl client version: not found"}, expectedVersion: "unknown", @@ -69,7 +69,7 @@ func TestCheckVersion(t *testing.T) { testutil.Run(t, test.description, func(t *testutil.T) { fakeWarner := &warnings.Collect{} t.Override(&warnings.Printf, fakeWarner.Warnf) - t.Override(&util.DefaultExecCommand, test.command) + t.Override(&util.DefaultExecCommand, test.commands) cli := CLI{} diff --git a/pkg/skaffold/runner/kind_test.go b/pkg/skaffold/runner/kind_test.go index 039d241cb2a..ae46e0b115c 100644 --- a/pkg/skaffold/runner/kind_test.go +++ b/pkg/skaffold/runner/kind_test.go @@ -35,7 +35,7 @@ func TestLoadImagesInKindNodes(t *testing.T) { description string built []build.Artifact deployed []build.Artifact - command util.Command + commands util.Command shouldErr bool expectedError string }{ @@ -43,24 +43,24 @@ func TestLoadImagesInKindNodes(t *testing.T) { description: "load image", built: []build.Artifact{{Tag: "tag1"}}, deployed: []build.Artifact{{Tag: "tag1"}}, - command: testutil.NewFakeCmd(t). - WithRunOut("kubectl --context kubecontext --namespace namespace get nodes -ojsonpath='{@.items[*].status.images[*].names[*]}'", ""). - WithRun("kind load docker-image tag1"), + commands: testutil. + CmdRunOut("kubectl --context kubecontext --namespace namespace get nodes -ojsonpath='{@.items[*].status.images[*].names[*]}'", ""). + AndRun("kind load docker-image tag1"), }, { description: "load missing image", built: []build.Artifact{{Tag: "tag1"}, {Tag: "tag2"}}, deployed: []build.Artifact{{Tag: "tag1"}, {Tag: "tag2"}}, - command: testutil.NewFakeCmd(t). - WithRunOut("kubectl --context kubecontext --namespace namespace get nodes -ojsonpath='{@.items[*].status.images[*].names[*]}'", "tag1"). - WithRun("kind load docker-image tag2"), + commands: testutil. + CmdRunOut("kubectl --context kubecontext --namespace namespace get nodes -ojsonpath='{@.items[*].status.images[*].names[*]}'", "tag1"). + AndRun("kind load docker-image tag2"), }, { description: "inspect error", built: []build.Artifact{{Tag: "tag"}}, deployed: []build.Artifact{{Tag: "tag"}}, - command: testutil.NewFakeCmd(t). - WithRunOutErr("kubectl --context kubecontext --namespace namespace get nodes -ojsonpath='{@.items[*].status.images[*].names[*]}'", "", errors.New("BUG")), + commands: testutil. + CmdRunOutErr("kubectl --context kubecontext --namespace namespace get nodes -ojsonpath='{@.items[*].status.images[*].names[*]}'", "", errors.New("BUG")), shouldErr: true, expectedError: "unable to inspect", }, @@ -68,9 +68,9 @@ func TestLoadImagesInKindNodes(t *testing.T) { description: "load error", built: []build.Artifact{{Tag: "tag"}}, deployed: []build.Artifact{{Tag: "tag"}}, - command: testutil.NewFakeCmd(t). - WithRunOut("kubectl --context kubecontext --namespace namespace get nodes -ojsonpath='{@.items[*].status.images[*].names[*]}'", ""). - WithRunErr("kind load docker-image tag", errors.New("BUG")), + commands: testutil. + CmdRunOut("kubectl --context kubecontext --namespace namespace get nodes -ojsonpath='{@.items[*].status.images[*].names[*]}'", ""). + AndRunErr("kind load docker-image tag", errors.New("BUG")), shouldErr: true, expectedError: "unable to load", }, @@ -78,26 +78,24 @@ func TestLoadImagesInKindNodes(t *testing.T) { description: "ignore image that's not built", built: []build.Artifact{{Tag: "built"}}, deployed: []build.Artifact{{Tag: "built"}, {Tag: "busybox"}}, - command: testutil.NewFakeCmd(t). - WithRunOut("kubectl --context kubecontext --namespace namespace get nodes -ojsonpath='{@.items[*].status.images[*].names[*]}'", ""). - WithRun("kind load docker-image built"), + commands: testutil. + CmdRunOut("kubectl --context kubecontext --namespace namespace get nodes -ojsonpath='{@.items[*].status.images[*].names[*]}'", ""). + AndRun("kind load docker-image built"), }, { description: "no artifact", deployed: []build.Artifact{}, - command: testutil.NewFakeCmd(t), }, { description: "no built artifact", built: []build.Artifact{}, deployed: []build.Artifact{{Tag: "busybox"}}, - command: testutil.NewFakeCmd(t), }, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&util.DefaultExecCommand, test.command) + t.Override(&util.DefaultExecCommand, test.commands) r := &SkaffoldRunner{ builds: test.built, diff --git a/pkg/skaffold/test/structure/types_test.go b/pkg/skaffold/test/structure/types_test.go index 64c02dec144..fbcc2c8677b 100644 --- a/pkg/skaffold/test/structure/types_test.go +++ b/pkg/skaffold/test/structure/types_test.go @@ -33,9 +33,10 @@ func TestNewRunner(t *testing.T) { testutil.Run(t, "", func(t *testutil.T) { extraEnv := []string{"SOME=env_var", "OTHER=env_value"} - fakeCmd := t.NewFakeCmd(). - WithRunEnv("container-structure-test test -v warn --image "+imageName+" --config "+structureTestName, extraEnv) - t.Override(&util.DefaultExecCommand, fakeCmd) + t.Override(&util.DefaultExecCommand, testutil.CmdRunEnv( + "container-structure-test test -v warn --image "+imageName+" --config "+structureTestName, + extraEnv, + )) testRunner := NewRunner([]string{structureTestName}, extraEnv) err := testRunner.Test(context.Background(), ioutil.Discard, imageName) diff --git a/pkg/skaffold/test/test_test.go b/pkg/skaffold/test/test_test.go index 684ce59a08c..ef06fb654c0 100644 --- a/pkg/skaffold/test/test_test.go +++ b/pkg/skaffold/test/test_test.go @@ -91,10 +91,9 @@ func TestTestSuccess(t *testing.T) { tmpDir := t.NewTempDir() tmpDir.Touch("tests/test1.yaml", "tests/test2.yaml", "test3.yaml") - fakeCmd := t.NewFakeCmd(). - WithRun("container-structure-test test -v warn --image TAG --config " + tmpDir.Path("tests/test1.yaml") + " --config " + tmpDir.Path("tests/test2.yaml")). - WithRun("container-structure-test test -v warn --image TAG --config " + tmpDir.Path("test3.yaml")) - t.Override(&util.DefaultExecCommand, fakeCmd) + t.Override(&util.DefaultExecCommand, testutil. + CmdRun("container-structure-test test -v warn --image TAG --config "+tmpDir.Path("tests/test1.yaml")+" --config "+tmpDir.Path("tests/test2.yaml")). + AndRun("container-structure-test test -v warn --image TAG --config "+tmpDir.Path("test3.yaml"))) runCtx := &runcontext.RunContext{ WorkingDir: tmpDir.Root(), @@ -124,12 +123,12 @@ func TestTestSuccess(t *testing.T) { func TestTestFailure(t *testing.T) { testutil.Run(t, "", func(t *testutil.T) { - tmpDir := t.NewTempDir() - tmpDir.Touch("test.yaml") + tmpDir := t.NewTempDir().Touch("test.yaml") - fakeCmd := t.NewFakeCmd(). - WithRunErr("container-structure-test test -v warn --image broken-image --config "+tmpDir.Path("test.yaml"), errors.New("FAIL")) - t.Override(&util.DefaultExecCommand, fakeCmd) + t.Override(&util.DefaultExecCommand, testutil.CmdRunErr( + "container-structure-test test -v warn --image broken-image --config "+tmpDir.Path("test.yaml"), + errors.New("FAIL"), + )) runCtx := &runcontext.RunContext{ WorkingDir: tmpDir.Root(), diff --git a/testutil/cmd_helper.go b/testutil/cmd_helper.go index 85bfdd373b7..8a7a43a1958 100644 --- a/testutil/cmd_helper.go +++ b/testutil/cmd_helper.go @@ -38,10 +38,8 @@ type run struct { err error } -func NewFakeCmd(t *testing.T) *FakeCmd { - return &FakeCmd{ - t: t, - } +func newFakeCmd() *FakeCmd { + return &FakeCmd{} } func (c *FakeCmd) addRun(r run) *FakeCmd { @@ -59,47 +57,57 @@ func (c *FakeCmd) popRun() (*run, error) { return &run, nil } -func FakeRun(t *testing.T, command string) *FakeCmd { - return NewFakeCmd(t).WithRun(command) +func (c *FakeCmd) ForTest(t *testing.T) { + if c != nil { + c.t = t + } +} + +func CmdRun(command string) *FakeCmd { + return newFakeCmd().AndRun(command) +} + +func CmdRunInput(command, input string) *FakeCmd { + return newFakeCmd().AndRunInput(command, input) } -func FakeRunInput(t *testing.T, command, input string) *FakeCmd { - return NewFakeCmd(t).WithRunInput(command, input) +func CmdRunErr(command string, err error) *FakeCmd { + return newFakeCmd().AndRunErr(command, err) } -func FakeRunErr(t *testing.T, command string, err error) *FakeCmd { - return NewFakeCmd(t).WithRunErr(command, err) +func CmdRunOut(command string, output string) *FakeCmd { + return newFakeCmd().AndRunOut(command, output) } -func FakeRunOut(t *testing.T, command string, output string) *FakeCmd { - return NewFakeCmd(t).WithRunOut(command, output) +func CmdRunOutErr(command string, output string, err error) *FakeCmd { + return newFakeCmd().AndRunOutErr(command, output, err) } -func FakeRunOutErr(t *testing.T, command string, output string, err error) *FakeCmd { - return NewFakeCmd(t).WithRunOutErr(command, output, err) +func CmdRunEnv(command string, env []string) *FakeCmd { + return newFakeCmd().AndRunEnv(command, env) } -func (c *FakeCmd) WithRun(command string) *FakeCmd { +func (c *FakeCmd) AndRun(command string) *FakeCmd { return c.addRun(run{ command: command, }) } -func (c *FakeCmd) WithRunInput(command, input string) *FakeCmd { +func (c *FakeCmd) AndRunInput(command, input string) *FakeCmd { return c.addRun(run{ command: command, input: []byte(input), }) } -func (c *FakeCmd) WithRunErr(command string, err error) *FakeCmd { +func (c *FakeCmd) AndRunErr(command string, err error) *FakeCmd { return c.addRun(run{ command: command, err: err, }) } -func (c *FakeCmd) WithRunOut(command string, output string) *FakeCmd { +func (c *FakeCmd) AndRunOut(command string, output string) *FakeCmd { b := []byte{} if output != "" { b = []byte(output) @@ -110,7 +118,7 @@ func (c *FakeCmd) WithRunOut(command string, output string) *FakeCmd { }) } -func (c *FakeCmd) WithRunOutErr(command string, output string, err error) *FakeCmd { +func (c *FakeCmd) AndRunOutErr(command string, output string, err error) *FakeCmd { return c.addRun(run{ command: command, output: []byte(output), @@ -118,8 +126,7 @@ func (c *FakeCmd) WithRunOutErr(command string, output string, err error) *FakeC }) } -// WithRunEnv registers a command that requires the given env variables to be set. -func (c *FakeCmd) WithRunEnv(command string, env []string) *FakeCmd { +func (c *FakeCmd) AndRunEnv(command string, env []string) *FakeCmd { return c.addRun(run{ command: command, env: env, diff --git a/testutil/util.go b/testutil/util.go index 90fafa000f1..bd6fd3531d9 100644 --- a/testutil/util.go +++ b/testutil/util.go @@ -38,20 +38,8 @@ type T struct { teardownActions []func() } -func (t *T) NewFakeCmd() *FakeCmd { - return NewFakeCmd(t.T) -} - -func (t *T) FakeRun(command string) *FakeCmd { - return FakeRun(t.T, command) -} - -func (t *T) FakeRunOut(command string, output string) *FakeCmd { - return FakeRunOut(t.T, command, output) -} - -func (t *T) FakeRunOutErr(command string, output string, err error) *FakeCmd { - return FakeRunOutErr(t.T, command, output, err) +type ForTester interface { + ForTest(t *testing.T) } func (t *T) Override(dest, tmp interface{}) { @@ -60,6 +48,11 @@ func (t *T) Override(dest, tmp interface{}) { t.Errorf("temporary override value is invalid: %v", err) return } + + if forTester, ok := tmp.(ForTester); ok { + forTester.ForTest(t.T) + } + t.teardownActions = append(t.teardownActions, teardown) }