Exemplo n.º 1
0
def test_is_base_available(mock_get_host_architecture, name, channel,
                           architectures, expected_valid, expected_reason):
    base = Base(name=name, channel=channel, architectures=architectures)
    provider = providers.MultipassProvider()

    valid, reason = provider.is_base_available(base)

    assert (valid, reason) == (expected_valid, expected_reason)
Exemplo n.º 2
0
def test_clean_project_environments(mock_multipass, mock_path):
    mock_multipass.list.return_value = [
        "do-not-delete-me-please",
        "charmcraft-testcharm-445566-b-c-d",
        "charmcraft-my-charm---",
        "charmcraft-my-charm-445566---",
        "charmcraft-my-charm-project-445566-0-0-amd99",
        "charmcraft-my-charm-project-445566-999-444-arm64",
        "charmcraft_445566_a_b_c_d",
    ]
    provider = providers.MultipassProvider(multipass=mock_multipass)

    assert provider.clean_project_environments(
        charm_name="my-charm-project",
        project_path=mock_path,
    ) == [
        "charmcraft-my-charm-project-445566-0-0-amd99",
        "charmcraft-my-charm-project-445566-999-444-arm64",
    ]
    assert mock_multipass.mock_calls == [
        mock.call.list(),
        mock.call.delete(
            instance_name="charmcraft-my-charm-project-445566-0-0-amd99",
            purge=True,
        ),
        mock.call.delete(
            instance_name="charmcraft-my-charm-project-445566-999-444-arm64",
            purge=True,
        ),
    ]

    mock_multipass.reset_mock()

    assert provider.clean_project_environments(
        charm_name="testcharm",
        project_path=mock_path,
    ) == [
        "charmcraft-testcharm-445566-b-c-d",
    ]
    assert mock_multipass.mock_calls == [
        mock.call.list(),
        mock.call.delete(
            instance_name="charmcraft-testcharm-445566-b-c-d",
            purge=True,
        ),
    ]

    mock_multipass.reset_mock()

    assert (provider.clean_project_environments(
        charm_name="unknown-charm",
        project_path=mock_path,
    ) == [])
    assert mock_multipass.mock_calls == [
        mock.call.list(),
    ]
Exemplo n.º 3
0
def test_launched_environment(
    channel,
    alias,
    mock_buildd_base_configuration,
    mock_multipass_launch,
    monkeypatch,
    tmp_path,
    mock_path,
):
    expected_environment = {
        "CHARMCRAFT_MANAGED_MODE":
        "1",
        "PATH":
        "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin",
    }

    base = Base(name="ubuntu", channel=channel, architectures=["host-arch"])
    provider = providers.MultipassProvider()

    with provider.launched_environment(
            charm_name="test-charm",
            project_path=mock_path,
            base=base,
            bases_index=1,
            build_on_index=2,
    ) as instance:
        assert instance is not None
        assert mock_multipass_launch.mock_calls == [
            mock.call(
                name="charmcraft-test-charm-445566-1-2-host-arch",
                base_configuration=mock_buildd_base_configuration.return_value,
                image_name=channel,
                cpus=2,
                disk_gb=64,
                mem_gb=2,
                auto_clean=True,
            ),
            mock.call().mount(host_source=mock_path,
                              target=pathlib.Path("/root/project")),
        ]
        assert mock_buildd_base_configuration.mock_calls == [
            call(
                alias=alias,
                environment=expected_environment,
                hostname="charmcraft-test-charm-445566-1-2-host-arch",
            )
        ]

        mock_multipass_launch.reset_mock()

    assert mock_multipass_launch.mock_calls == [
        mock.call().unmount_all(),
        mock.call().stop(),
    ]
Exemplo n.º 4
0
def test_get_instance_name(bases_index, build_on_index, project_name,
                           target_arch, expected, mock_path):
    provider = providers.MultipassProvider()

    assert (provider.get_instance_name(
        bases_index=bases_index,
        build_on_index=build_on_index,
        project_name=project_name,
        project_path=mock_path,
        target_arch=target_arch,
    ) == expected.format(inode="445566"))
Exemplo n.º 5
0
def test_clean_project_environments_without_multipass(
        mock_multipass, mock_multipass_is_installed, mock_path):
    mock_multipass_is_installed.return_value = False
    provider = providers.MultipassProvider(multipass=mock_multipass)

    assert (provider.clean_project_environments(
        charm_name="my-charm",
        project_path=mock_path,
    ) == [])

    assert mock_multipass_is_installed.mock_calls == [mock.call()]
    assert mock_multipass.mock_calls == []
Exemplo n.º 6
0
def test_clean_project_environments_list_failure(mock_multipass, mock_path):
    error = MultipassError(brief="fail")
    mock_multipass.list.side_effect = error
    provider = providers.MultipassProvider(multipass=mock_multipass)

    with pytest.raises(CommandError, match="fail") as exc_info:
        provider.clean_project_environments(
            charm_name="charm",
            project_path=mock_path,
        )

    assert exc_info.value.__cause__ is error
Exemplo n.º 7
0
def test_get_command_environment_minimal(monkeypatch):
    monkeypatch.setenv("IGNORE_ME", "or-im-failing")
    monkeypatch.setenv("PATH", "not-using-host-path")
    provider = providers.MultipassProvider()

    env = provider.get_command_environment()

    assert env == {
        "CHARMCRAFT_MANAGED_MODE":
        "1",
        "PATH":
        "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin",
    }
Exemplo n.º 8
0
def test_clean_project_environments_delete_failure(mock_multipass, mock_path):
    error = MultipassError(brief="fail")
    mock_multipass.list.return_value = ["charmcraft-testcharm-445566-b-c-d"]
    mock_multipass.delete.side_effect = error
    provider = providers.MultipassProvider(multipass=mock_multipass)

    with pytest.raises(CommandError, match="fail") as exc_info:
        provider.clean_project_environments(
            charm_name="testcharm",
            project_path=mock_path,
        )

    assert exc_info.value.__cause__ is error
Exemplo n.º 9
0
def test_launched_environment_stop_error(mock_buildd_base_configuration,
                                         mock_multipass_launch, tmp_path):
    error = MultipassError(brief="fail")
    mock_multipass_launch.return_value.stop.side_effect = error
    base = Base(name="ubuntu", channel="20.04", architectures=["host-arch"])
    provider = providers.MultipassProvider()

    with pytest.raises(CommandError, match="fail") as exc_info:
        with provider.launched_environment(
                charm_name="test-charm",
                project_path=tmp_path,
                base=base,
                bases_index=1,
                build_on_index=2,
        ):
            pass

    assert exc_info.value.__cause__ is error
Exemplo n.º 10
0
def test_ensure_provider_is_available_errors_when_user_declines(
        mock_confirm_with_user, mock_multipass_is_installed):
    mock_confirm_with_user.return_value = False
    mock_multipass_is_installed.return_value = False
    provider = providers.MultipassProvider()

    match = re.escape(
        "Multipass is required, but not installed. Visit https://multipass.run/ for "
        "instructions on installing Multipass for your operating system.")
    with pytest.raises(CommandError, match=match):
        provider.ensure_provider_is_available()

    assert mock_confirm_with_user.mock_calls == [
        mock.call(
            "Multipass is required, but not installed. "
            "Do you wish to install Multipass and configure it with the defaults?",
            default=False,
        )
    ]
Exemplo n.º 11
0
def test_launched_environment_unmounts_and_stops_after_error(
        mock_buildd_base_configuration, mock_multipass_launch, tmp_path):
    base = Base(name="ubuntu", channel="20.04", architectures=["host-arch"])
    provider = providers.MultipassProvider()

    with pytest.raises(RuntimeError):
        with provider.launched_environment(
                charm_name="test-charm",
                project_path=tmp_path,
                base=base,
                bases_index=1,
                build_on_index=2,
        ):
            mock_multipass_launch.reset_mock()
            raise RuntimeError("this is a test")

    assert mock_multipass_launch.mock_calls == [
        mock.call().unmount_all(),
        mock.call().stop(),
    ]
Exemplo n.º 12
0
def test_ensure_provider_is_available_errors_when_multipass_not_ready(
    mock_confirm_with_user,
    mock_multipass_is_installed,
    mock_multipass_install,
    mock_multipass_ensure_multipass_is_ready,
):
    error = MultipassError(brief="some error",
                           details="some details",
                           resolution="some resolution")
    mock_confirm_with_user.return_value = True
    mock_multipass_is_installed.return_value = True
    mock_multipass_ensure_multipass_is_ready.side_effect = error
    provider = providers.MultipassProvider()

    with pytest.raises(
            CommandError,
            match=re.escape("some error\nsome details\nsome resolution"),
    ) as exc_info:
        provider.ensure_provider_is_available()

    assert exc_info.value.__cause__ is error
Exemplo n.º 13
0
def test_ensure_provider_is_available_errors_when_multipass_install_fails(
        mock_confirm_with_user, mock_multipass_is_installed,
        mock_multipass_install):
    error = MultipassInstallationError("foo")
    mock_confirm_with_user.return_value = True
    mock_multipass_is_installed.return_value = False
    mock_multipass_install.side_effect = error
    provider = providers.MultipassProvider()

    match = re.escape(
        "Failed to install Multipass. Visit https://multipass.run/ for "
        "instructions on installing Multipass for your operating system.")
    with pytest.raises(CommandError, match=match) as exc_info:
        provider.ensure_provider_is_available()

    assert mock_confirm_with_user.mock_calls == [
        mock.call(
            "Multipass is required, but not installed. "
            "Do you wish to install Multipass and configure it with the defaults?",
            default=False,
        )
    ]
    assert exc_info.value.__cause__ is error
Exemplo n.º 14
0
def test_is_provider_available(is_installed, mock_multipass_is_installed):
    mock_multipass_is_installed.return_value = is_installed
    provider = providers.MultipassProvider()

    assert provider.is_provider_available() == is_installed
Exemplo n.º 15
0
def test_ensure_provider_is_available_ok_when_installed(
        mock_multipass_is_installed):
    mock_multipass_is_installed.return_value = True
    provider = providers.MultipassProvider()

    provider.ensure_provider_is_available()