| package stack |
| |
| import ( |
| "fmt" |
| "strings" |
| "testing" |
| |
| "github.com/docker/cli/internal/test/environment" |
| "gotest.tools/golden" |
| "gotest.tools/icmd" |
| "gotest.tools/poll" |
| "gotest.tools/skip" |
| ) |
| |
| var pollSettings = environment.DefaultPollSettings |
| |
| func TestRemove(t *testing.T) { |
| t.Run("Swarm", func(t *testing.T) { |
| testRemove(t, "swarm") |
| }) |
| t.Run("Kubernetes", func(t *testing.T) { |
| skip.If(t, !environment.KubernetesEnabled()) |
| |
| testRemove(t, "kubernetes") |
| }) |
| } |
| |
| 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", "stack", "rm", |
| stackname, "--orchestrator", orchestrator) |
| 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, "--orchestrator", orchestrator) |
| result.Assert(t, icmd.Success) |
| |
| poll.WaitOn(t, taskCount(orchestrator, stackname, 2), pollSettings) |
| } |
| |
| 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(orchestrator, stackname), pollSettings) |
| poll.WaitOn(t, taskCount(orchestrator, stackname, 0), pollSettings) |
| } |
| |
| func stackRm(orchestrator, stackname string) func(t poll.LogT) poll.Result { |
| return func(poll.LogT) poll.Result { |
| result := icmd.RunCommand("docker", "stack", "rm", stackname, "--orchestrator", orchestrator) |
| 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(orchestrator, stackname string, expected int) func(t poll.LogT) poll.Result { |
| return func(poll.LogT) poll.Result { |
| args := []string{"stack", "ps", stackname, "--orchestrator", orchestrator} |
| // 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() |
| } |
| return poll.Continue("task count is %d waiting for %d", count, expected) |
| } |
| } |
| |
| func lines(out string) int { |
| return len(strings.Split(strings.TrimSpace(out), "\n")) |
| } |