Files
computer-playbook/tests/unit/python/utils/install/test_php.py
T
kevinveenbirkenbach 2e3f257134 feat(image): bake the php and ruby interpreters into the image
The unit suites had to install their toolchain on every run. The image
now carries the interpreters, so the make prerequisite finds them present.

The Composer vendor tree deliberately stays out of the image build: the
package cache is reached through the compose extra_hosts mapping, which
only exists for a running container, so a build-time composer install
would bypass the cache and talk to packagist directly. Fetching it from
the test target keeps it on the cached path.
2026-08-22 20:56:55 +02:00

89 lines
3.1 KiB
Python

"""Unit tests for :mod:`utils.install.php`."""
from __future__ import annotations
import subprocess
import unittest
import unittest.mock as mock
from utils.install import php as php_mod
class TestEnsurePhpToolchain(unittest.TestCase):
def test_installs_the_binaries_only(self) -> None:
with (
mock.patch.object(php_mod, "ensure_command_present") as ensure,
mock.patch.object(php_mod.subprocess, "run") as run,
):
php_mod.ensure_php_toolchain()
self.assertEqual([c.args[0] for c in ensure.call_args_list], ["php", "composer"])
run.assert_not_called()
class TestEnsurePhpPresent(unittest.TestCase):
def test_vendor_tree_present_skips_composer(self) -> None:
with (
mock.patch.object(php_mod, "ensure_command_present") as ensure,
mock.patch.object(php_mod, "_PHPUNIT") as phpunit,
mock.patch.object(php_mod.subprocess, "run") as run,
):
phpunit.is_file.return_value = True
php_mod.ensure_php_present()
self.assertEqual(
[c.args[0] for c in ensure.call_args_list], ["php", "composer"]
)
run.assert_not_called()
def test_missing_vendor_tree_runs_composer_install(self) -> None:
with (
mock.patch.object(php_mod, "ensure_command_present"),
mock.patch.object(php_mod, "_PHPUNIT") as phpunit,
mock.patch.object(php_mod.subprocess, "run") as run,
):
phpunit.is_file.side_effect = [False, True]
php_mod.ensure_php_present()
run.assert_called_once_with(
["composer", "install", "--no-interaction", "--no-progress"],
cwd=php_mod.PROJECT_ROOT,
check=True,
)
def test_raises_when_phpunit_still_missing(self) -> None:
with (
mock.patch.object(php_mod, "ensure_command_present"),
mock.patch.object(php_mod, "_PHPUNIT") as phpunit,
mock.patch.object(php_mod.subprocess, "run"),
self.assertRaises(RuntimeError),
):
phpunit.is_file.return_value = False
php_mod.ensure_php_present()
def test_propagates_a_failed_composer_install(self) -> None:
with (
mock.patch.object(php_mod, "ensure_command_present"),
mock.patch.object(php_mod, "_PHPUNIT") as phpunit,
mock.patch.object(
php_mod.subprocess,
"run",
side_effect=subprocess.CalledProcessError(1, "composer"),
),
self.assertRaises(subprocess.CalledProcessError),
):
phpunit.is_file.return_value = False
php_mod.ensure_php_present()
def test_missing_interpreter_fails_before_composer(self) -> None:
with (
mock.patch.object(
php_mod, "ensure_command_present", side_effect=RuntimeError("boom")
),
mock.patch.object(php_mod.subprocess, "run") as run,
self.assertRaises(RuntimeError),
):
php_mod.ensure_php_present()
run.assert_not_called()
if __name__ == "__main__":
unittest.main()