diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..ba79221 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,2 @@ +[run] +parallel=True diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index d962053..3cc3fad 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -21,9 +21,10 @@ jobs: python-version: "3.10" - name: Install dependencies run: | + apt update && apt install podman python -m pip install --upgrade pip - pip install flake8 pytest if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + if [ -f test-requirements.txt ]; then pip install -r test-requirements.txt; fi - name: Lint with flake8 run: | # stop the build if there are Python syntax errors or undefined names @@ -32,5 +33,7 @@ jobs: flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Test with pytest run: | - python -m pytest ./pytests - + coverage run --source podman_compose -m pytest ./pytests + python -m pytest ./tests + coverage combine + coverage report diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5cd371b..3aca322 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,7 +39,15 @@ $ pre-commit install ```shell $ pre-commit run --all-files ``` -6. Commit your code to your fork's branch. +6. Run code coverage +```shell +coverage run --source podman_compose -m pytest ./pytests +python -m pytest ./tests +coverage combine +coverage report +coverage html +``` +7. Commit your code to your fork's branch. - Make sure you include a `Signed-off-by` message in your commits. Read [this guide](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits) to learn how to sign your commits - In the commit message reference the Issue ID that your code fixes and a brief description of the changes. Example: `Fixes #516: allow empty network` 7. Open a PR to `containers/podman-compose:devel` and wait for a maintainer to review your work. @@ -48,18 +56,18 @@ $ pre-commit run --all-files To add a command you need to add a function that is decorated with `@cmd_run` passing the compose instance, command name and -description. the wrapped function should accept two arguments -the compose instance and the command-specific arguments (resulted -from python's `argparse` package) inside that command you can -run PodMan like this `compose.podman.run(['inspect', 'something'])` -and inside that function you can access `compose.pods` -and `compose.containers` ...etc. -Here is an example +description. This function must be declared `async` the wrapped +function should accept two arguments the compose instance and +the command-specific arguments (resulted from python's `argparse` +package) inside that command you can run PodMan like this +`await compose.podman.run(['inspect', 'something'])`and inside +that function you can access `compose.pods` and `compose.containers` +...etc. Here is an example ``` @cmd_run(podman_compose, 'build', 'build images defined in the stack') -def compose_build(compose, args): - compose.podman.run(['build', 'something']) +async def compose_build(compose, args): + await compose.podman.run(['build', 'something']) ``` ## Command arguments parsing @@ -90,10 +98,10 @@ do something like: ``` @cmd_run(podman_compose, 'up', 'up desc') -def compose_up(compose, args): - compose.commands['down'](compose, args) +async def compose_up(compose, args): + await compose.commands['down'](compose, args) # or - compose.commands['down'](argparse.Namespace(foo=123)) + await compose.commands['down'](argparse.Namespace(foo=123)) ``` diff --git a/podman_compose.py b/podman_compose.py index ee66129..973ddb2 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -2248,7 +2248,8 @@ async def compose_up(compose: PodmanCompose, args): if not args.no_build: # `podman build` does not cache, so don't always build build_args = argparse.Namespace(if_not_exists=(not args.build), **args.__dict__) - ret = await compose.commands["build"](compose, build_args) + if await compose.commands["build"](compose, build_args) != 0: + log("Build command failed") hashes = ( (await compose.podman.output( @@ -2317,7 +2318,12 @@ async def compose_up(compose: PodmanCompose, args): log("** skipping: ", cnt["name"]) continue - tasks.add(asyncio.create_task(compose.podman.run([], "start", ["-a", cnt["name"]], wait=True, sleep=None, log_formatter=log_formatter), name=cnt["_service"])) + tasks.add( + asyncio.create_task( + compose.podman.run([], "start", ["-a", cnt["name"]], sleep=None, log_formatter=log_formatter), + name=cnt["_service"] + ) + ) exit_code = 0 for task in asyncio.as_completed(tasks): diff --git a/setup.py b/setup.py index 5222c14..4994d33 100644 --- a/setup.py +++ b/setup.py @@ -45,6 +45,7 @@ setup( "black", "pylint", "pre-commit", + "coverage" ] } # test_suite='tests', diff --git a/test-requirements.txt b/test-requirements.txt index 5a20426..55c142a 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -3,7 +3,6 @@ # process, which may cause wedges in the gate later. coverage -pytest-cov pytest tox black diff --git a/tests/test_podman_compose.py b/tests/test_podman_compose.py index 0984431..5be6629 100644 --- a/tests/test_podman_compose.py +++ b/tests/test_podman_compose.py @@ -21,7 +21,8 @@ def test_podman_compose_extends_w_file_subdir(): main_path = Path(__file__).parent.parent command_up = [ - "python3", + "coverage", + "run", str(main_path.joinpath("podman_compose.py")), "-f", str(main_path.joinpath("tests", "extends_w_file_subdir", "docker-compose.yml")), diff --git a/tests/test_podman_compose_config.py b/tests/test_podman_compose_config.py index 2f879ba..96f9814 100644 --- a/tests/test_podman_compose_config.py +++ b/tests/test_podman_compose_config.py @@ -22,7 +22,7 @@ def test_config_no_profiles(podman_compose_path, profile_compose_file): :param podman_compose_path: The fixture used to specify the path to the podman compose file. :param profile_compose_file: The fixtued used to specify the path to the "profile" compose used in the test. """ - config_cmd = ["python3", podman_compose_path, "-f", profile_compose_file, "config"] + config_cmd = ["coverage", "run", podman_compose_path, "-f", profile_compose_file, "config"] out, _, return_code = capture(config_cmd) assert return_code == 0 @@ -61,7 +61,7 @@ def test_config_profiles( :param expected_services: Dictionary used to model the expected "enabled" services in the profile. Key = service name, Value = True if the service is enabled, otherwise False. """ - config_cmd = ["python3", podman_compose_path, "-f", profile_compose_file] + config_cmd = ["coverage", "run", podman_compose_path, "-f", profile_compose_file] config_cmd.extend(profiles) out, _, return_code = capture(config_cmd) diff --git a/tests/test_podman_compose_include.py b/tests/test_podman_compose_include.py index c9867f5..0fec773 100644 --- a/tests/test_podman_compose_include.py +++ b/tests/test_podman_compose_include.py @@ -20,7 +20,8 @@ def test_podman_compose_include(): main_path = Path(__file__).parent.parent command_up = [ - "python3", + "coverage", + "run", str(main_path.joinpath("podman_compose.py")), "-f", str(main_path.joinpath("tests", "include", "docker-compose.yaml")), diff --git a/tests/test_podman_compose_up_down.py b/tests/test_podman_compose_up_down.py index 833604e..a06a2c4 100644 --- a/tests/test_podman_compose_up_down.py +++ b/tests/test_podman_compose_up_down.py @@ -27,7 +27,8 @@ def teardown(podman_compose_path, profile_compose_file): yield down_cmd = [ - "python3", + "coverage", + "run", podman_compose_path, "--profile", "profile-1", @@ -59,7 +60,8 @@ def teardown(podman_compose_path, profile_compose_file): ) def test_up(podman_compose_path, profile_compose_file, profiles, expected_services): up_cmd = [ - "python3", + "coverage", + "run", podman_compose_path, "-f", profile_compose_file,