Skip to content

Commit

Permalink
Add tests for filtering containers not created by Compose
Browse files Browse the repository at this point in the history
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
  • Loading branch information
laurazard authored and ndeloof committed Jan 17, 2023
1 parent 82ef998 commit 0b1c867
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 12 deletions.
27 changes: 27 additions & 0 deletions e2e/cucumber-features/ps.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Feature: PS

Background:
Given a compose file
"""
services:
build:
image: test:latest
build:
context: ./
pull:
image: alpine
command: top
"""
And a dockerfile
"""
FROM golang:1.19-alpine
"""

Scenario: external container from compose image exists
When I run "compose build"
Then the exit code is 0
And I run "docker run --name external-test test:latest ls"
Then the exit code is 0
And I run "compose ps -a"
Then the output does not contain "external-test"

4 changes: 3 additions & 1 deletion e2e/cucumber-features/up.feature
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ Background:

Scenario: --pull always
When I run "compose up --pull=always -d"
Then the output contains "simple Pulled"
And the output contains "simple Pulled"
Then I run "compose up --pull=always -d"
And the output contains "simple Pulled"

48 changes: 42 additions & 6 deletions e2e/cucumber_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"testing"
Expand Down Expand Up @@ -78,16 +79,20 @@ func setup(s *godog.ScenarioContext) {
})

s.Step(`^a compose file$`, th.setComposeFile)
s.Step(`^a dockerfile$`, th.setDockerfile)
s.Step(`^I run "compose (.*)"$`, th.runComposeCommand)
s.Step(`^I run "docker (.*)"$`, th.runDockerCommand)
s.Step(`service "(.*)" is "(.*)"$`, th.serviceIsStatus)
s.Step(`output contains "(.*)"$`, th.outputContains)
s.Step(`output contains "(.*)"$`, th.outputContains(true))
s.Step(`output does not contain "(.*)"$`, th.outputContains(false))
s.Step(`exit code is (\d+)$`, th.exitCodeIs)
}

type testHelper struct {
T *testing.T
ProjectName string
ComposeFile string
TestDir string
CommandOutput string
CommandExitCode int
CLI *e2e.CLI
Expand All @@ -104,16 +109,21 @@ func (th *testHelper) serviceIsStatus(service, status string) error {
return nil
}

func (th *testHelper) outputContains(substring string) error {
if !strings.Contains(th.CommandOutput, substring) {
return fmt.Errorf("Missing output substring: %s\noutput: %s", substring, th.CommandOutput)
func (th *testHelper) outputContains(expected bool) func(string) error {
return func(substring string) error {
contains := strings.Contains(th.CommandOutput, substring)
if contains && !expected {
return fmt.Errorf("Unexpected substring in output: %s\noutput: %s", substring, th.CommandOutput)
} else if !contains && expected {
return fmt.Errorf("Missing substring in output: %s\noutput: %s", substring, th.CommandOutput)
}
return nil
}
return nil
}

func (th *testHelper) exitCodeIs(exitCode int) error {
if exitCode != th.CommandExitCode {
return fmt.Errorf("Wrong exit code: %d expected: %d", th.CommandExitCode, exitCode)
return fmt.Errorf("Wrong exit code: %d expected: %d || command output: %s", th.CommandExitCode, exitCode, th.CommandOutput)
}
return nil
}
Expand All @@ -127,6 +137,21 @@ func (th *testHelper) runComposeCommand(command string) error {

cmd := th.CLI.NewDockerComposeCmd(th.T, commandArgs...)
cmd.Stdin = strings.NewReader(th.ComposeFile)
cmd.Dir = th.TestDir
res := icmd.RunCmd(cmd)
th.CommandOutput = res.Combined()
th.CommandExitCode = res.ExitCode
return nil
}

func (th *testHelper) runDockerCommand(command string) error {
commandArgs, err := shellwords.Parse(command)
if err != nil {
return err
}

cmd := th.CLI.NewDockerCmd(th.T, commandArgs...)
cmd.Dir = th.TestDir
res := icmd.RunCmd(cmd)
th.CommandOutput = res.Combined()
th.CommandExitCode = res.ExitCode
Expand All @@ -137,3 +162,14 @@ func (th *testHelper) setComposeFile(composeString string) error {
th.ComposeFile = composeString
return nil
}

func (th *testHelper) setDockerfile(dockerfileString string) error {
tempDir := th.T.TempDir()
th.TestDir = tempDir

err := os.WriteFile(filepath.Join(tempDir, "Dockerfile"), []byte(dockerfileString), 0o644)
if err != nil {
return err
}
return nil
}
2 changes: 2 additions & 0 deletions pkg/compose/convergence_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func TestServiceLinks(t *testing.T) {
projectFilter(testProject),
serviceFilter("db"),
oneOffFilter(false),
hasConfigHashLabel(),
),
All: true,
}
Expand Down Expand Up @@ -193,6 +194,7 @@ func TestServiceLinks(t *testing.T) {
projectFilter(testProject),
serviceFilter("web"),
oneOffFilter(false),
hasConfigHashLabel(),
),
All: true,
}
Expand Down
5 changes: 3 additions & 2 deletions pkg/compose/kill_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func TestKillAll(t *testing.T) {

ctx := context.Background()
api.EXPECT().ContainerList(ctx, moby.ContainerListOptions{
Filters: filters.NewArgs(projectFilter(name)),
Filters: filters.NewArgs(projectFilter(name), hasConfigHashLabel()),
}).Return(
[]moby.Container{testContainer("service1", "123", false), testContainer("service1", "456", false), testContainer("service2", "789", false)}, nil)
api.EXPECT().VolumeList(gomock.Any(), filters.NewArgs(projectFilter(strings.ToLower(testProject)))).
Expand Down Expand Up @@ -81,7 +81,7 @@ func TestKillSignal(t *testing.T) {

name := strings.ToLower(testProject)
listOptions := moby.ContainerListOptions{
Filters: filters.NewArgs(projectFilter(name), serviceFilter(serviceName)),
Filters: filters.NewArgs(projectFilter(name), serviceFilter(serviceName), hasConfigHashLabel()),
}

ctx := context.Background()
Expand Down Expand Up @@ -133,6 +133,7 @@ func anyCancellableContext() gomock.Matcher {
func projectFilterListOpt(withOneOff bool) moby.ContainerListOptions {
filter := filters.NewArgs(
projectFilter(strings.ToLower(testProject)),
hasConfigHashLabel(),
)
if !withOneOff {
filter.Add("label", fmt.Sprintf("%s=False", compose.OneoffLabel))
Expand Down
4 changes: 2 additions & 2 deletions pkg/compose/logs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func TestComposeService_Logs_Demux(t *testing.T) {
ctx := context.Background()
api.EXPECT().ContainerList(ctx, moby.ContainerListOptions{
All: true,
Filters: filters.NewArgs(oneOffFilter(false), projectFilter(name)),
Filters: filters.NewArgs(oneOffFilter(false), projectFilter(name), hasConfigHashLabel()),
}).Return(
[]moby.Container{
testContainer("service", "c", false),
Expand Down Expand Up @@ -125,7 +125,7 @@ func TestComposeService_Logs_ServiceFiltering(t *testing.T) {
ctx := context.Background()
api.EXPECT().ContainerList(ctx, moby.ContainerListOptions{
All: true,
Filters: filters.NewArgs(oneOffFilter(false), projectFilter(name)),
Filters: filters.NewArgs(oneOffFilter(false), projectFilter(name), hasConfigHashLabel()),
}).Return(
[]moby.Container{
testContainer("serviceA", "c1", false),
Expand Down
2 changes: 1 addition & 1 deletion pkg/compose/ps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func TestPs(t *testing.T) {
cli.EXPECT().Client().Return(api).AnyTimes()

ctx := context.Background()
args := filters.NewArgs(projectFilter(strings.ToLower(testProject)))
args := filters.NewArgs(projectFilter(strings.ToLower(testProject)), hasConfigHashLabel())
args.Add("label", "com.docker.compose.oneoff=False")
listOpts := moby.ContainerListOptions{Filters: args, All: false}
c1, inspect1 := containerDetails("service1", "123", "running", "healthy", 0)
Expand Down

0 comments on commit 0b1c867

Please sign in to comment.