diff --git a/tests/compute/docker/test_docker.py b/tests/compute/docker/test_docker.py index 5155d4eb..98096deb 100644 --- a/tests/compute/docker/test_docker.py +++ b/tests/compute/docker/test_docker.py @@ -15,6 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import asyncio import pytest import pytest_asyncio from unittest.mock import MagicMock, patch @@ -209,3 +210,49 @@ async def test_docker_check_connection_docker_preferred_version_against_older(vm vm._connected = False await vm._check_connection() assert vm._api_version == DOCKER_MINIMUM_API_VERSION + + +@pytest.mark.asyncio +async def test_install_busybox(): + + mock_process = MagicMock(spec=asyncio.subprocess.Process) + mock_process.communicate.return_value = (b"", b"not a dynamic executable") + mock_process.returncode = 1 # means that busybox is not dynamically linked + + with patch("os.path.isfile", return_value=False): + with patch("shutil.which", return_value="/usr/bin/busybox"): + with patch("asyncio.create_subprocess_exec", return_value=mock_process) as create_subprocess_mock: + with patch("shutil.copy2") as copy2_mock: + await Docker.install_busybox() + create_subprocess_mock.assert_called_with( + "ldd", + "/usr/bin/busybox", + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.DEVNULL, + ) + assert copy2_mock.called + + +@pytest.mark.asyncio +async def test_install_busybox_dynamic_linked(): + + mock_process = MagicMock(spec=asyncio.subprocess.Process) + mock_process.communicate.return_value = (b"Dynamically linked library", b"") + mock_process.returncode = 0 # means that busybox is dynamically linked + + with patch("os.path.isfile", return_value=False): + with patch("shutil.which", return_value="/usr/bin/busybox"): + with patch("asyncio.create_subprocess_exec", return_value=mock_process): + with pytest.raises(DockerError) as e: + await Docker.install_busybox() + assert str(e.value) == "No busybox executable could be found" + + +@pytest.mark.asyncio +async def test_install_busybox_no_executables(): + + with patch("os.path.isfile", return_value=False): + with patch("shutil.which", return_value=None): + with pytest.raises(DockerError) as e: + await Docker.install_busybox() + assert str(e.value) == "No busybox executable could be found" diff --git a/tests/conftest.py b/tests/conftest.py index 579c4f78..40dd9604 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -8,6 +8,7 @@ import os import uuid import configparser import base64 +import stat from fastapi import FastAPI from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine @@ -405,13 +406,24 @@ def run_around_tests(monkeypatch, config, port_manager): monkeypatch.setattr("gns3server.utils.path.get_default_project_directory", lambda *args: os.path.join(tmppath, 'projects')) - # Force sys.platform to the original value. Because it seem not be restore correctly at each tests + # Force sys.platform to the original value. Because it seems not be restored correctly after each test sys.platform = sys.original_platform yield - # An helper should not raise Exception + # A helper should not raise Exception try: shutil.rmtree(tmppath) except BaseException: pass + + +@pytest.fixture +def fake_executable(monkeypatch, tmpdir) -> str: + + monkeypatch.setenv("PATH", str(tmpdir)) + executable_path = os.path.join(os.environ["PATH"], "fake_executable") + with open(executable_path, "w+") as f: + f.write("1") + os.chmod(executable_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) + return executable_path