Skip to content

Commit

Permalink
Tests: add tests for container installation failure
Browse files Browse the repository at this point in the history
  • Loading branch information
almet committed Oct 14, 2024
1 parent cec533f commit 3964e6d
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 12 deletions.
18 changes: 12 additions & 6 deletions dangerzone/gui/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@
from ..isolation_provider.container import Container, NoContainerTechException
from ..isolation_provider.dummy import Dummy
from ..isolation_provider.qubes import Qubes, is_qubes_native_conversion
from ..util import get_resource_path, get_subprocess_startupinfo, get_version, format_exception
from ..util import (
get_resource_path,
get_subprocess_startupinfo,
get_version,
format_exception,
)
from .logic import Alert, CollapsibleBox, DangerzoneGui, UpdateDialog
from .updater import UpdateReport

Expand Down Expand Up @@ -432,9 +437,10 @@ def __init__(self) -> None:
# Enable copying
self.setTextInteractionFlags(Qt.TextSelectableByMouse)

def set_content(self, error: str) -> None:
self.setPlainText(error)
self.setVisible(True)
def set_content(self, error: Optional[str] = None) -> None:
if error:
self.setPlainText(error)
self.setVisible(True)


class WaitingWidgetContainer(WaitingWidget):
Expand Down Expand Up @@ -529,8 +535,8 @@ def show_message(self, msg: str) -> None:
self.label.setText(msg)
self.traceback.setVisible(False)
self.buttons.hide()
def installation_finished(self, error:Optional[str] = None):

def installation_finished(self, error: Optional[str] = None):
if error:
msg = (
"During installation of the dangerzone image, <br>"
Expand Down
8 changes: 5 additions & 3 deletions dangerzone/isolation_provider/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ def install() -> bool:
break
_, err = p.communicate()
if p.returncode < 0:
raise RuntimeError(f"Could not install container image: {err}")
raise RuntimeError(f"Could not install container image: {err.decode()}")

if not Container.is_container_installed(raise_on_error=True):
return False
Expand Down Expand Up @@ -215,8 +215,10 @@ def is_container_installed(raise_on_error: bool = False) -> bool:
elif found_image_id == "":
pass
else:
msg = (f"{Container.CONTAINER_NAME} images found, but IDs do not match."
f"Found: {found_image_id}, Expected: {','.join(expected_image_ids)}")
msg = (
f"{Container.CONTAINER_NAME} images found, but IDs do not match."
f"Found: {found_image_id}, Expected: {','.join(expected_image_ids)}"
)
if raise_on_error:
raise RuntimeError(msg)
log.info(msg)
Expand Down
47 changes: 46 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ pytest-mock = "^3.10.0"
pytest-qt = "^4.2.0"
pytest-cov = "^5.0.0"
strip-ansi = "*"
pytest-subprocess = "^1.5.2"
pytest-xvfb = "^3.0.0"

[tool.poetry.group.qubes.dependencies]
pymupdf = "^1.23.6"
Expand Down
88 changes: 87 additions & 1 deletion tests/gui/test_main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,25 @@

from pytest import MonkeyPatch, fixture
from pytest_mock import MockerFixture
from pytest_subprocess import FakeProcess
from pytestqt.qtbot import QtBot

from dangerzone.document import Document
from dangerzone.gui import MainWindow
from dangerzone.gui import main_window as main_window_module
from dangerzone.gui import updater as updater_module
from dangerzone.gui.logic import DangerzoneGui
from dangerzone.gui.main_window import ( # import Pyside related objects from here to avoid duplicating import logic.

# import Pyside related objects from here to avoid duplicating import logic.
from dangerzone.gui.main_window import (
ContentWidget,
QtCore,
QtGui,
WaitingWidgetContainer,
InstallContainerThread,
)
from dangerzone.gui.updater import UpdateReport, UpdaterThread
from dangerzone.isolation_provider.container import Container

from .test_updater import assert_report_equal, default_updater_settings

Expand Down Expand Up @@ -492,3 +498,83 @@ def test_drop_1_invalid_2_valid_documents(
content_widget.doc_selection_wrapper.dropEvent(
drag_1_invalid_and_2_valid_files_event
)


def test_installation_image_ls_error(
qtbot: QtBot, mocker: MockerFixture, fp: FakeProcess
):
# Setup
mock_app = mocker.MagicMock()
dummy = mocker.MagicMock(spec=Container)
dummy.get_runtime.return_value = "podman"

# Make "podman image ls" return an error
fp.register_subprocess(
["podman", "image", "ls"], returncode=-1, stderr="podman image ls logs"
)
fp.pass_command(["xdg-mime", "query", "default", "application/pdf"])

dz = DangerzoneGui(mock_app, dummy)
widget = WaitingWidgetContainer(dz)
qtbot.addWidget(widget)

# Assert that the error is displayed in the GUI
assert "Podman is installed but cannot run properly" in widget.label.text()
assert "podman image ls logs" in widget.traceback.toPlainText()


def test_installation_failure_exception(
qtbot: QtBot, mocker: MockerFixture, fp: FakeProcess
):
# Setup
mock_app = mocker.MagicMock()
dummy = mocker.MagicMock(spec=Container)
dummy.get_runtime.return_value = "podman"
dummy.install.side_effect = RuntimeError("Error during install")

# Make "podman image ls" return an error
fp.register_subprocess(["podman", "image", "ls"], returncode=0)
fp.pass_command(["xdg-mime", "query", "default", "application/pdf"])

dz = DangerzoneGui(mock_app, dummy)
widget = WaitingWidgetContainer(dz)
qtbot.addWidget(widget)

# Assert that the error is displayed in the GUI
assert "Installing the Dangerzone container image" in widget.label.text()
# Start the installation process
install_thread = InstallContainerThread(dz)
with qtbot.waitSignal(install_thread.finished, timeout=5000):
install_thread.start()

assert "the following error occured" in widget.label.text()
assert "Traceback" in widget.traceback.toPlainText()
assert "Error during install" in widget.traceback.toPlainText()


def test_installation_failure_return_false(
qtbot: QtBot, mocker: MockerFixture, fp: FakeProcess
):
# Setup
mock_app = mocker.MagicMock()
dummy = mocker.MagicMock(spec=Container)
dummy.get_runtime.return_value = "podman"
dummy.install.return_value = False

# Make "podman image ls" return an error
fp.register_subprocess(["podman", "image", "ls"], returncode=0)
fp.pass_command(["xdg-mime", "query", "default", "application/pdf"])

dz = DangerzoneGui(mock_app, dummy)
widget = WaitingWidgetContainer(dz)
qtbot.addWidget(widget)

# Assert that the error is displayed in the GUI
assert "Installing the Dangerzone container image" in widget.label.text()
# Start the installation process
install_thread = InstallContainerThread(dz)
with qtbot.waitSignal(install_thread.finished, timeout=5000):
install_thread.start()

assert "the following error occured" in widget.label.text()
assert "The image cannot be found" in widget.traceback.toPlainText()
1 change: 0 additions & 1 deletion tests/isolation_provider/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from dangerzone.conversion import errors
from dangerzone.document import Document
from dangerzone.isolation_provider import base
from dangerzone.isolation_provider.qubes import running_on_qubes

TIMEOUT_STARTUP = 60 # Timeout in seconds until the conversion sandbox starts.

Expand Down
1 change: 1 addition & 0 deletions tests/isolation_provider/test_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import time

import pytest
from pytest_subprocess import FakeProcess

from dangerzone.isolation_provider.container import Container
from dangerzone.isolation_provider.qubes import is_qubes_native_conversion
Expand Down
Binary file added tests/test_docs/unsafe/sample-bmp.bmp
Binary file not shown.
Binary file added tests/test_docs/unsafe/sample-doc.doc
Binary file not shown.
Binary file added tests/test_docs/unsafe/sample-docm.docm
Binary file not shown.

0 comments on commit 3964e6d

Please sign in to comment.