diff --git a/e2e/stack/deploy_test.go b/e2e/stack/deploy_test.go index 27790acd46..a19f1ea81a 100644 --- a/e2e/stack/deploy_test.go +++ b/e2e/stack/deploy_test.go @@ -1,25 +1,43 @@ package stack import ( + "fmt" "sort" "strings" "testing" + "github.com/docker/cli/internal/test/environment" "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/golden" "github.com/gotestyourself/gotestyourself/icmd" + "github.com/gotestyourself/gotestyourself/skip" ) func TestDeployWithNamedResources(t *testing.T) { - stackname := "test-stack-deploy-with-names" + t.Run("Swarm", func(t *testing.T) { + testDeployWithNamedResources(t, "swarm") + }) + t.Run("Kubernetes", func(t *testing.T) { + // FIXME(chris-crone): currently does not work with compose for kubernetes. + t.Skip("FIXME(chris-crone): currently does not work with compose for kubernetes.") + skip.If(t, !environment.KubernetesEnabled()) + + testDeployWithNamedResources(t, "kubernetes") + }) +} + +func testDeployWithNamedResources(t *testing.T, orchestrator string) { + stackname := fmt.Sprintf("test-stack-deploy-with-names-%s", orchestrator) composefile := golden.Path("stack-with-named-resources.yml") - result := icmd.RunCommand( - "docker", "stack", "deploy", "-c", composefile, stackname) + result := icmd.RunCommand("docker", "--orchestrator", orchestrator, + "stack", "deploy", "-c", composefile, stackname) + defer icmd.RunCommand("docker", "--orchestrator", orchestrator, + "stack", "rm", stackname) result.Assert(t, icmd.Success) stdout := strings.Split(result.Stdout(), "\n") - expected := strings.Split(string(golden.Get(t, "stack-deploy-with-names.golden")), "\n") + expected := strings.Split(string(golden.Get(t, fmt.Sprintf("stack-deploy-with-names-%s.golden", orchestrator))), "\n") sort.Strings(stdout) sort.Strings(expected) assert.DeepEqual(t, stdout, expected) diff --git a/e2e/stack/remove_test.go b/e2e/stack/remove_test.go index a75939084e..47ec92bbef 100644 --- a/e2e/stack/remove_test.go +++ b/e2e/stack/remove_test.go @@ -1,6 +1,7 @@ package stack import ( + "fmt" "strings" "testing" @@ -8,50 +9,69 @@ import ( "github.com/gotestyourself/gotestyourself/golden" "github.com/gotestyourself/gotestyourself/icmd" "github.com/gotestyourself/gotestyourself/poll" + "github.com/gotestyourself/gotestyourself/skip" ) var pollSettings = environment.DefaultPollSettings func TestRemove(t *testing.T) { - stackname := "test-stack-remove" - deployFullStack(t, stackname) - defer cleanupFullStack(t, stackname) + t.Run("Swarm", func(t *testing.T) { + testRemove(t, "swarm") + }) + t.Run("Kubernetes", func(t *testing.T) { + skip.If(t, !environment.KubernetesEnabled()) - result := icmd.RunCommand("docker", "stack", "rm", stackname) - - result.Assert(t, icmd.Expected{Err: icmd.None}) - golden.Assert(t, result.Stdout(), "stack-remove-success.golden") + testRemove(t, "kubernetes") + }) } -func deployFullStack(t *testing.T, stackname string) { +func testRemove(t *testing.T, orchestrator string) { + stackname := "test-stack-remove-" + orchestrator + deployFullStack(t, orchestrator, stackname) + defer cleanupFullStack(t, orchestrator, stackname) + result := icmd.RunCommand("docker", "--orchestrator", orchestrator, + "stack", "rm", stackname) + result.Assert(t, icmd.Expected{Err: icmd.None}) + golden.Assert(t, result.Stdout(), + fmt.Sprintf("stack-remove-%s-success.golden", orchestrator)) +} + +func deployFullStack(t *testing.T, orchestrator, stackname string) { // TODO: this stack should have full options not minimal options - result := icmd.RunCommand("docker", "stack", "deploy", - "--compose-file=./testdata/full-stack.yml", stackname) + result := icmd.RunCommand("docker", "--orchestrator", orchestrator, + "stack", "deploy", "--compose-file=./testdata/full-stack.yml", stackname) result.Assert(t, icmd.Success) - poll.WaitOn(t, taskCount(stackname, 2), pollSettings) + poll.WaitOn(t, taskCount(orchestrator, stackname, 2), pollSettings) } -func cleanupFullStack(t *testing.T, stackname string) { +func cleanupFullStack(t *testing.T, orchestrator, stackname string) { // FIXME(vdemeester) we shouldn't have to do that. it is hidding a race on docker stack rm - poll.WaitOn(t, stackRm(stackname), pollSettings) - poll.WaitOn(t, taskCount(stackname, 0), pollSettings) + poll.WaitOn(t, stackRm(orchestrator, stackname), pollSettings) + poll.WaitOn(t, taskCount(orchestrator, stackname, 0), pollSettings) } -func stackRm(stackname string) func(t poll.LogT) poll.Result { +func stackRm(orchestrator, stackname string) func(t poll.LogT) poll.Result { return func(poll.LogT) poll.Result { - result := icmd.RunCommand("docker", "stack", "rm", stackname) + result := icmd.RunCommand("docker", "--orchestrator", orchestrator, "stack", "rm", stackname) if result.Error != nil { + if strings.Contains(result.Stderr(), "not found") { + return poll.Success() + } return poll.Continue("docker stack rm %s failed : %v", stackname, result.Error) } return poll.Success() } } -func taskCount(stackname string, expected int) func(t poll.LogT) poll.Result { +func taskCount(orchestrator, stackname string, expected int) func(t poll.LogT) poll.Result { return func(poll.LogT) poll.Result { - result := icmd.RunCommand( - "docker", "stack", "ps", "-f=desired-state=running", stackname) + args := []string{"--orchestrator", orchestrator, "stack", "ps", stackname} + // FIXME(chris-crone): remove when we support filtering by desired-state on kubernetes + if orchestrator == "swarm" { + args = append(args, "-f=desired-state=running") + } + result := icmd.RunCommand("docker", args...) count := lines(result.Stdout()) - 1 if count == expected { return poll.Success() diff --git a/e2e/stack/testdata/stack-deploy-with-names-kubernetes.golden b/e2e/stack/testdata/stack-deploy-with-names-kubernetes.golden new file mode 100644 index 0000000000..f97dd682cf --- /dev/null +++ b/e2e/stack/testdata/stack-deploy-with-names-kubernetes.golden @@ -0,0 +1,7 @@ +Creating network test-stack-deploy-with-names_network2 +Creating network named-network +Creating secret named-secret +Creating secret test-stack-deploy-with-names_secret2 +Creating config test-stack-deploy-with-names_config2 +Creating config named-config +Creating service test-stack-deploy-with-names_web diff --git a/e2e/stack/testdata/stack-deploy-with-names-swarm.golden b/e2e/stack/testdata/stack-deploy-with-names-swarm.golden new file mode 100644 index 0000000000..c7f421ba9c --- /dev/null +++ b/e2e/stack/testdata/stack-deploy-with-names-swarm.golden @@ -0,0 +1,7 @@ +Creating network test-stack-deploy-with-names-swarm_network2 +Creating network named-network +Creating secret named-secret +Creating secret test-stack-deploy-with-names-swarm_secret2 +Creating config test-stack-deploy-with-names-swarm_config2 +Creating config named-config +Creating service test-stack-deploy-with-names-swarm_web diff --git a/e2e/stack/testdata/stack-remove-kubernetes-success.golden b/e2e/stack/testdata/stack-remove-kubernetes-success.golden new file mode 100644 index 0000000000..3c13671398 --- /dev/null +++ b/e2e/stack/testdata/stack-remove-kubernetes-success.golden @@ -0,0 +1 @@ +Removing stack: test-stack-remove-kubernetes diff --git a/e2e/stack/testdata/stack-remove-success.golden b/e2e/stack/testdata/stack-remove-success.golden deleted file mode 100644 index f41a891702..0000000000 --- a/e2e/stack/testdata/stack-remove-success.golden +++ /dev/null @@ -1,3 +0,0 @@ -Removing service test-stack-remove_one -Removing service test-stack-remove_two -Removing network test-stack-remove_default diff --git a/e2e/stack/testdata/stack-remove-swarm-success.golden b/e2e/stack/testdata/stack-remove-swarm-success.golden new file mode 100644 index 0000000000..db77e8dc36 --- /dev/null +++ b/e2e/stack/testdata/stack-remove-swarm-success.golden @@ -0,0 +1,3 @@ +Removing service test-stack-remove-swarm_one +Removing service test-stack-remove-swarm_two +Removing network test-stack-remove-swarm_default diff --git a/internal/test/environment/testenv.go b/internal/test/environment/testenv.go index f454f6722a..9d719014b7 100644 --- a/internal/test/environment/testenv.go +++ b/internal/test/environment/testenv.go @@ -28,6 +28,12 @@ func Setup() error { } } + if kubeConfig := os.Getenv("TEST_KUBECONFIG"); kubeConfig != "" { + if err := os.Setenv("KUBECONFIG", kubeConfig); err != nil { + return err + } + } + if val := boolFromString(os.Getenv("TEST_REMOTE_DAEMON")); val { if err := os.Setenv("REMOTE_DAEMON", "1"); err != nil { return err @@ -43,6 +49,11 @@ func Setup() error { return nil } +// KubernetesEnabled returns if Kubernetes testing is enabled +func KubernetesEnabled() bool { + return os.Getenv("KUBECONFIG") != "" +} + // RemoteDaemon returns true if running against a remote daemon func RemoteDaemon() bool { return os.Getenv("REMOTE_DAEMON") != ""