Skip to content

Commit

Permalink
Merge pull request #876 from p12tic/tests-print-subprocess-errors
Browse files Browse the repository at this point in the history
tests: Print output in case subprocess returns unexpected code
  • Loading branch information
p12tic authored Mar 8, 2024
2 parents ac50340 + f4dc5f3 commit 872664b
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 94 deletions.
29 changes: 7 additions & 22 deletions tests/test_podman_compose.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
# SPDX-License-Identifier: GPL-2.0

from pathlib import Path
import subprocess
import os
import unittest


def run_subprocess(command):
proc = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
out, err = proc.communicate()
return out, err, proc.returncode
from .test_utils import RunSubprocessMixin


def base_path():
Expand All @@ -31,7 +21,7 @@ def podman_compose_path():
return os.path.join(base_path(), "podman_compose.py")


class TestPodmanCompose(unittest.TestCase):
class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
def test_extends_w_file_subdir(self):
"""
Test that podman-compose can execute podman-compose -f <file> up with extended File which
Expand Down Expand Up @@ -69,18 +59,14 @@ def test_extends_w_file_subdir(self):
"docker.io/library/busybox",
]

out, _, returncode = run_subprocess(command_up)
self.assertEqual(returncode, 0)
self.run_subprocess_assert_returncode(command_up)
# check container was created and exists
out, err, returncode = run_subprocess(command_check_container)
self.assertEqual(returncode, 0)
out, _ = self.run_subprocess_assert_returncode(command_check_container)
self.assertEqual(out, b'localhost/subdir_test:me\n')
out, _, returncode = run_subprocess(command_down)
# cleanup test image(tags)
self.assertEqual(returncode, 0)
self.run_subprocess_assert_returncode(command_down)
# check container did not exists anymore
out, _, returncode = run_subprocess(command_check_container)
self.assertEqual(returncode, 0)
out, _ = self.run_subprocess_assert_returncode(command_check_container)
self.assertEqual(out, b'')

def test_extends_w_empty_service(self):
Expand All @@ -100,5 +86,4 @@ def test_extends_w_empty_service(self):
"-d",
]

_, _, returncode = run_subprocess(command_up)
self.assertEqual(returncode, 0)
self.run_subprocess_assert_returncode(command_up)
10 changes: 4 additions & 6 deletions tests/test_podman_compose_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
# pylint: disable=redefined-outer-name
import os
from .test_podman_compose import podman_compose_path
from .test_podman_compose import run_subprocess
from .test_podman_compose import test_path
from .test_utils import RunSubprocessMixin
import unittest
from parameterized import parameterized

Expand All @@ -20,7 +20,7 @@ def profile_compose_file():
return os.path.join(test_path(), "profile", "docker-compose.yml")


class TestComposeConfig(unittest.TestCase):
class TestComposeConfig(unittest.TestCase, RunSubprocessMixin):
def test_config_no_profiles(self):
"""
Tests podman-compose config command without profile enablement.
Expand All @@ -34,8 +34,7 @@ def test_config_no_profiles(self):
"config",
]

out, _, return_code = run_subprocess(config_cmd)
self.assertEqual(return_code, 0)
out, _ = self.run_subprocess_assert_returncode(config_cmd)

string_output = out.decode("utf-8")
self.assertIn("default-service", string_output)
Expand Down Expand Up @@ -68,8 +67,7 @@ def test_config_profiles(self, profiles, expected_services):
config_cmd = ["coverage", "run", podman_compose_path(), "-f", profile_compose_file()]
config_cmd.extend(profiles)

out, _, return_code = run_subprocess(config_cmd)
self.assertEqual(return_code, 0)
out, _ = self.run_subprocess_assert_returncode(config_cmd)

actual_output = out.decode("utf-8")

Expand Down
27 changes: 7 additions & 20 deletions tests/test_podman_compose_include.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,10 @@
import subprocess
import unittest

from .test_utils import RunSubprocessMixin

def run_subprocess(command):
proc = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
out, err = proc.communicate()
return out, err, proc.returncode


class TestPodmanComposeInclude(unittest.TestCase):
class TestPodmanComposeInclude(unittest.TestCase, RunSubprocessMixin):
def test_podman_compose_include(self):
"""
Test that podman-compose can execute podman-compose -f <file> up with include
Expand Down Expand Up @@ -55,22 +47,17 @@ def test_podman_compose_include(self):

command_down = ["podman", "rm", "--force", "CONTAINER_ID"]

out, _, returncode = run_subprocess(command_up)
self.assertEqual(returncode, 0)
out, _, returncode = run_subprocess(command_check_container)
self.assertEqual(returncode, 0)
self.run_subprocess_assert_returncode(command_up)
out, _ = self.run_subprocess_assert_returncode(command_check_container)
self.assertEqual(out, b'"docker.io/library/busybox:latest"\n')
# Get container ID to remove it
out, _, returncode = run_subprocess(command_container_id)
self.assertEqual(returncode, 0)
out, _ = self.run_subprocess_assert_returncode(command_container_id)
self.assertNotEqual(out, b"")
container_id = out.decode().strip().replace('"', "")
command_down[3] = container_id
out, _, returncode = run_subprocess(command_down)
out, _ = self.run_subprocess_assert_returncode(command_down)
# cleanup test image(tags)
self.assertEqual(returncode, 0)
self.assertNotEqual(out, b"")
# check container did not exists anymore
out, _, returncode = run_subprocess(command_check_container)
self.assertEqual(returncode, 0)
out, _ = self.run_subprocess_assert_returncode(command_check_container)
self.assertEqual(out, b"")
67 changes: 28 additions & 39 deletions tests/test_podman_compose_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
import time
import unittest

from .test_podman_compose import run_subprocess
from .test_podman_compose import podman_compose_path
from .test_podman_compose import test_path
from .test_utils import RunSubprocessMixin


class TestPodmanCompose(unittest.TestCase):
class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
def test_exit_from(self):
up_cmd = [
"coverage",
Expand All @@ -27,11 +27,8 @@ def test_exit_from(self):
"up",
]

out, _, return_code = run_subprocess(up_cmd + ["--exit-code-from", "sh1"])
self.assertEqual(return_code, 1)

out, _, return_code = run_subprocess(up_cmd + ["--exit-code-from", "sh2"])
self.assertEqual(return_code, 2)
self.run_subprocess_assert_returncode(up_cmd + ["--exit-code-from", "sh1"], 1)
self.run_subprocess_assert_returncode(up_cmd + ["--exit-code-from", "sh2"], 2)

def test_run(self):
"""
Expand All @@ -51,7 +48,7 @@ def test_run(self):
"wget -q -O - http://web:8000/hosts",
]

out, _, return_code = run_subprocess(run_cmd)
out, _ = self.run_subprocess_assert_returncode(run_cmd)
self.assertIn(b'127.0.0.1\tlocalhost', out)

# Run it again to make sure we can run it twice. I saw an issue where a second run, with the container left up,
Expand All @@ -70,9 +67,8 @@ def test_run(self):
"wget -q -O - http://web:8000/hosts",
]

out, _, return_code = run_subprocess(run_cmd)
assert b'127.0.0.1\tlocalhost' in out
self.assertEqual(return_code, 0)
out, _ = self.run_subprocess_assert_returncode(run_cmd)
self.assertIn(b'127.0.0.1\tlocalhost', out)

# This leaves a container running. Not sure it's intended, but it matches docker-compose
down_cmd = [
Expand All @@ -84,8 +80,7 @@ def test_run(self):
"down",
]

out, _, return_code = run_subprocess(run_cmd)
self.assertEqual(return_code, 0)
self.run_subprocess_assert_returncode(down_cmd)

def test_up_with_ports(self):
up_cmd = [
Expand All @@ -110,12 +105,10 @@ def test_up_with_ports(self):
]

try:
out, _, return_code = run_subprocess(up_cmd)
self.assertEqual(return_code, 0)
self.run_subprocess_assert_returncode(up_cmd)

finally:
out, _, return_code = run_subprocess(down_cmd)
self.assertEqual(return_code, 0)
self.run_subprocess_assert_returncode(down_cmd)

def test_down_with_vols(self):
up_cmd = [
Expand All @@ -139,29 +132,25 @@ def test_down_with_vols(self):
]

try:
out, _, return_code = run_subprocess(["podman", "volume", "create", "my-app-data"])
self.assertEqual(return_code, 0)
out, _, return_code = run_subprocess([
self.run_subprocess_assert_returncode(["podman", "volume", "create", "my-app-data"])
self.run_subprocess_assert_returncode([
"podman",
"volume",
"create",
"actual-name-of-volume",
])
self.assertEqual(return_code, 0)

out, _, return_code = run_subprocess(up_cmd)
self.assertEqual(return_code, 0)

run_subprocess(["podman", "inspect", "volume", ""])
self.run_subprocess_assert_returncode(up_cmd)
self.run_subprocess(["podman", "inspect", "volume", ""])

finally:
out, _, return_code = run_subprocess(down_cmd)
run_subprocess(["podman", "volume", "rm", "my-app-data"])
run_subprocess(["podman", "volume", "rm", "actual-name-of-volume"])
out, _, return_code = self.run_subprocess(down_cmd)
self.run_subprocess(["podman", "volume", "rm", "my-app-data"])
self.run_subprocess(["podman", "volume", "rm", "actual-name-of-volume"])
self.assertEqual(return_code, 0)

def test_down_with_orphans(self):
container_id, _, return_code = run_subprocess([
container_id, _ = self.run_subprocess_assert_returncode([
"podman",
"run",
"--rm",
Expand All @@ -187,14 +176,14 @@ def test_down_with_orphans(self):
"--remove-orphans",
]

out, _, return_code = run_subprocess(down_cmd)
self.assertEqual(return_code, 0)

_, _, exists = run_subprocess([
"podman",
"container",
"exists",
container_id.decode("utf-8"),
])
self.run_subprocess_assert_returncode(down_cmd)

self.assertEqual(exists, 1)
self.run_subprocess_assert_returncode(
[
"podman",
"container",
"exists",
container_id.decode("utf-8"),
],
1,
)
12 changes: 5 additions & 7 deletions tests/test_podman_compose_up_down.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

# pylint: disable=redefined-outer-name
import os
from .test_podman_compose import run_subprocess
from .test_podman_compose import podman_compose_path
from .test_podman_compose import test_path
from .test_utils import RunSubprocessMixin
from parameterized import parameterized
import unittest

Expand All @@ -20,7 +20,7 @@ def profile_compose_file():
return os.path.join(test_path(), "profile", "docker-compose.yml")


class TestUpDown(unittest.TestCase):
class TestUpDown(unittest.TestCase, RunSubprocessMixin):
def tearDown(self):
"""
Ensures that the services within the "profile compose file" are removed between each test case.
Expand All @@ -39,7 +39,7 @@ def tearDown(self):
profile_compose_file(),
"down",
]
run_subprocess(down_cmd)
self.run_subprocess(down_cmd)

@parameterized.expand(
[
Expand Down Expand Up @@ -67,8 +67,7 @@ def test_up(self, profiles, expected_services):
]
up_cmd.extend(profiles)

out, _, return_code = run_subprocess(up_cmd)
self.assertEqual(return_code, 0)
self.run_subprocess_assert_returncode(up_cmd)

check_cmd = [
"podman",
Expand All @@ -77,8 +76,7 @@ def test_up(self, profiles, expected_services):
"--format",
'"{{.Names}}"',
]
out, _, return_code = run_subprocess(check_cmd)
self.assertEqual(return_code, 0)
out, _ = self.run_subprocess_assert_returncode(check_cmd)

self.assertEqual(len(expected_services), 3)
actual_output = out.decode("utf-8")
Expand Down
24 changes: 24 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# SPDX-License-Identifier: GPL-2.0

import subprocess


class RunSubprocessMixin:
def run_subprocess(self, args):
proc = subprocess.Popen(
args,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
out, err = proc.communicate()
return out, err, proc.returncode

def run_subprocess_assert_returncode(self, args, expected_returncode=0):
out, err, returncode = self.run_subprocess(args)
self.assertEqual(
returncode,
expected_returncode,
f"Invalid return code of process {returncode} != {expected_returncode}\n"
f"stdout: {out}\nstderr: {err}\n",
)
return out, err

0 comments on commit 872664b

Please sign in to comment.