Skip to content

Commit

Permalink
Make tests compatible with Podman
Browse files Browse the repository at this point in the history
  • Loading branch information
prskr committed Jun 21, 2022
1 parent 3bac82c commit fb47fba
Show file tree
Hide file tree
Showing 20 changed files with 489 additions and 538 deletions.
36 changes: 13 additions & 23 deletions .github/workflows/ci-podman.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
strategy:
matrix:
go-version: [1.14.x, 1.15.x, 1.16.x, 1.17.x, 1.x]
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: Set up Go 1.x
uses: actions/setup-go@v3
Expand All @@ -18,17 +18,6 @@ jobs:
- name: Check out code into the Go module directory
uses: actions/checkout@v3

- name: modVerify
run: go mod verify

- name: modTidy
run: go mod tidy

- name: ensure compilation
env:
GOOS: linux
run: go build

- name: Enable systemd user process
run: |
loginctl enable-linger $(whoami)
Expand All @@ -41,25 +30,26 @@ jobs:
run: |
set -x
sudo apt-get remove -y podman docker-ce docker docker-engine docker.io containerd runc ||:
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_$( lsb_release -rs )/Release.key | sudo apt-key add -
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_$( lsb_release -rs )/ /" | sudo tee /etc/apt/sources.list.d/podman.list /dev/null
sudo apt-get update
sudo apt-get install -y podman
sudo systemctl start podman
systemctl --user enable --now podman.socket
systemctl --user status podman.socket
podman info
sudo apt update
sudo apt install -y software-properties-common debian-archive-keyring dirmngr
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 0E98404D386FA1D9
sudo add-apt-repository -y "deb http://deb.debian.org/debian experimental main"
sudo apt update
sudo apt -y -t experimental install podman crun docker-compose
sudo systemctl daemon-reload
sleep 5
sudo systemctl start podman.socket
sudo podman info
- name: Set DOCKER_HOST
run: echo "DOCKER_HOST=unix:///$XDG_RUNTIME_DIR/podman/podman.sock" >> $GITHUB_ENV
run: echo "DOCKER_HOST=unix:///run/podman/podman.sock" >> $GITHUB_ENV

- name: gotestsum
# only run tests on linux, there are a number of things that won't allow the tests to run on anything else
# many (maybe, all?) images used can only be build on Linux, they don't have Windows in their manifest, and
# we can't put Windows Server in "Linux Mode" in Github actions
# another, host mode is only available on Linux, and we have tests around that, do we skip them?
run: go run gotest.tools/gotestsum --format short-verbose -- -coverprofile=cover.txt ./...
continue-on-error: true
run: sudo go run gotest.tools/gotestsum --format short-verbose --rerun-fails=5 --packages="./..." -- -coverprofile=cover.txt

# only report code coverage on linux
- name: Upload coverage report
Expand Down
97 changes: 67 additions & 30 deletions compose_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package testcontainers

import (
"context"
"fmt"
"os/exec"
"regexp"
"strings"
"testing"
"time"

"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"

Expand Down Expand Up @@ -347,13 +350,11 @@ func TestLocalDockerComposeWithEnvironment(t *testing.T) {
assert.Equal(t, 1, len(compose.Services))
assert.Contains(t, compose.Services, "nginx")

containerNameNginx := compose.Identifier + "_nginx_1"

present := map[string]string{
"bar": "BAR",
}
absent := map[string]string{}
assertContainerEnvironmentVariables(t, containerNameNginx, present, absent)
assertContainerEnvironmentVariables(t, compose.Identifier, "nginx", present, absent)
}

func TestLocalDockerComposeWithMultipleComposeFiles(t *testing.T) {
Expand Down Expand Up @@ -386,17 +387,18 @@ func TestLocalDockerComposeWithMultipleComposeFiles(t *testing.T) {
assert.Contains(t, compose.Services, "mysql")
assert.Contains(t, compose.Services, "postgres")

containerNameNginx := compose.Identifier + "_nginx_1"

present := map[string]string{
"bar": "BAR",
"foo": "FOO",
}
absent := map[string]string{}
assertContainerEnvironmentVariables(t, containerNameNginx, present, absent)
assertContainerEnvironmentVariables(t, compose.Identifier, "nginx", present, absent)
}

func TestLocalDockerComposeWithVolume(t *testing.T) {
if providerType == ProviderPodman {
t.Skip("fails for some reason with Podman")
}
path := "./testresources/docker-compose-volume.yml"

identifier := strings.ToLower(uuid.New().String())
Expand All @@ -405,7 +407,7 @@ func TestLocalDockerComposeWithVolume(t *testing.T) {
destroyFn := func() {
err := compose.Down()
checkIfError(t, err)
assertVolumeDoesNotExist(t, fmt.Sprintf("%s_mydata", identifier))
assertVolumeDoesNotExist(t, identifier, "mydata")
}
defer destroyFn()

Expand All @@ -415,33 +417,79 @@ func TestLocalDockerComposeWithVolume(t *testing.T) {
checkIfError(t, err)
}

func assertVolumeDoesNotExist(t *testing.T, volume string) {
args := []string{"volume", "inspect", volume}
func assertVolumeDoesNotExist(tb testing.TB, composeIdentifier, volume string) {
containerClient, _, err := NewDockerClient()
if err != nil {
tb.Fatalf("Failed to get provider: %v", err)
}

volumeList, err := containerClient.VolumeList(context.Background(), filters.NewArgs())
if err != nil {
tb.Fatalf("Failed to list volumes: %v", err)
}

output, _ := executeAndGetOutput("docker", args)
if !strings.Contains(output, "No such volume") {
t.Fatalf("Expected volume %q to not exist", volume)
if len(volumeList.Warnings) > 0 {
tb.Logf("Volume list warnings: %v", volumeList.Warnings)
}

volumeNameRegexp := regexp.MustCompile(fmt.Sprintf(`^\/?%s(_|-)%s$`, composeIdentifier, volume))

for i := range volumeList.Volumes {
if volumeNameRegexp.MatchString(volumeList.Volumes[i].Name) {
tb.Fatalf("Volume should not be present")
}
}
}

func assertContainerEnvironmentVariables(t *testing.T, containerName string, present map[string]string, absent map[string]string) {
args := []string{"exec", containerName, "env"}
func assertContainerEnvironmentVariables(
tb testing.TB,
composeIdentifier, serviceName string,
present map[string]string,
absent map[string]string,
) {
containerClient, _, err := NewDockerClient()
if err != nil {
tb.Fatalf("Failed to get provider: %v", err)
}

containers, err := containerClient.ContainerList(context.Background(), types.ContainerListOptions{})
if err != nil {
tb.Fatalf("Failed to list containers: %v", err)
} else if len(containers) == 0 {
tb.Fatalf("container list empty")
}

output, err := executeAndGetOutput("docker", args)
checkIfError(t, err)
containerNameRegexp := regexp.MustCompile(fmt.Sprintf(`^\/?%s(_|-)%s(_|-)\d$`, composeIdentifier, serviceName))
var containerID string
containerLoop:
for i := range containers {
c := containers[i]
for j := range c.Names {
if containerNameRegexp.MatchString(c.Names[j]) {
containerID = c.ID
break containerLoop
}
}
}

details, err := containerClient.ContainerInspect(context.Background(), containerID)
if err != nil {
tb.Fatalf("Failed to inspect container: %v", err)
}

for k, v := range present {
keyVal := k + "=" + v
assert.Contains(t, output, keyVal)
assert.Contains(tb, details.Config.Env, keyVal)
}

for k, v := range absent {
keyVal := k + "=" + v
assert.NotContains(t, output, keyVal)
assert.NotContains(tb, details.Config.Env, keyVal)
}
}

func checkIfError(t *testing.T, err ExecError) {
t.Helper()
if err.Error != nil {
t.Fatalf("Failed when running %v: %v", err.Command, err.Error)
}
Expand All @@ -457,14 +505,3 @@ func checkIfError(t *testing.T, err ExecError) {
assert.NotNil(t, err.StdoutOutput)
assert.NotNil(t, err.StderrOutput)
}

func executeAndGetOutput(command string, args []string) (string, ExecError) {
cmd := exec.Command(command, args...)
out, err := cmd.CombinedOutput()

return string(out), ExecError{
Error: err,
StderrOutput: out,
StdoutOutput: out,
}
}
Loading

0 comments on commit fb47fba

Please sign in to comment.