Skip to content

Commit

Permalink
Make Dummy isolation provider more realistic
Browse files Browse the repository at this point in the history
Make the Dummy isolation provider follow the rest of the isolation
providers and perform the second part of the conversion on the host. The
first part of the conversion is just a dummy script that reads a file
from stdin and prints pixels to stdout.
  • Loading branch information
apyrgio committed Oct 8, 2024
1 parent 2c08b5f commit eddc06b
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 80 deletions.
67 changes: 19 additions & 48 deletions dangerzone/isolation_provider/dummy.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import logging
import os
import shutil
import subprocess
import sys
import time
from typing import Callable, Optional

from ..conversion.common import DangerzoneConverter
from ..document import Document
from ..util import get_resource_path
from .base import IsolationProvider, terminate_process_group

log = logging.getLogger(__name__)


def dummy_script() -> None:
sys.stdin.buffer.read()
pages = 2
width = height = 9
DangerzoneConverter._write_int(pages)
for page in range(pages):
DangerzoneConverter._write_int(width)
DangerzoneConverter._write_int(height)
DangerzoneConverter._write_bytes(width * height * 3 * b"A")


class Dummy(IsolationProvider):
"""Dummy Isolation Provider (FOR TESTING ONLY)
Expand All @@ -32,51 +39,15 @@ def __init__(self) -> None:
def install(self) -> bool:
return True

def convert(
self,
document: Document,
ocr_lang: Optional[str],
progress_callback: Optional[Callable] = None,
) -> None:
self.progress_callback = None
log.debug("Dummy converter started:")
log.debug(
f" - document: {os.path.basename(document.input_filename)} ({document.id})"
)
log.debug(f" - ocr : {ocr_lang}")
log.debug("\n(simulating conversion)")
success = True
progress = [
[False, "Converting to PDF using GraphicsMagick", 0.0],
[False, "Separating document into pages", 3.0],
[False, "Converting page 1/1 to pixels", 5.0],
[False, "Converted document to pixels", 50.0],
[False, "Converting page 1/1 from pixels to PDF", 50.0],
[False, "Merging 1 pages into a single PDF", 95.0],
[False, "Compressing PDF", 97.0],
[False, "Safe PDF created", 100.0],
]
for error, text, percentage in progress:
self.print_progress(document, error, text, percentage) # type: ignore [arg-type]
if error:
success = False
if success:
shutil.copy(
get_resource_path("dummy_document.pdf"), document.output_filename
)
document.mark_as_safe()
if document.archive_after_conversion:
document.archive()

def pixels_to_pdf(
self, document: Document, tempdir: str, ocr_lang: Optional[str]
) -> None:
pass

def start_doc_to_pixels_proc(self, document: Document) -> subprocess.Popen:
dummy_cmd = ["python3", "-c", "print('The cake is a lie')"]
cmd = [
sys.executable,
"-c",
"from dangerzone.isolation_provider.dummy import dummy_script;"
" dummy_script()",
]
return subprocess.Popen(
dummy_cmd,
cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=self.proc_stderr,
Expand Down
35 changes: 3 additions & 32 deletions tests/isolation_provider/test_dummy.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import os
import subprocess

import pytest
from pytest_mock import MockerFixture

from dangerzone.conversion import errors
from dangerzone.document import Document
from dangerzone.isolation_provider.base import IsolationProvider
from dangerzone.isolation_provider.dummy import Dummy

Expand All @@ -16,24 +14,6 @@
pytest.skip("Dummy conversion is not enabled", allow_module_level=True)


class DummyWait(Dummy):
"""Dummy isolation provider that spawns a blocking process."""

def start_doc_to_pixels_proc(self, document: Document) -> subprocess.Popen:
return subprocess.Popen(
["python3"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
start_new_session=True,
)


@pytest.fixture
def provider_wait() -> DummyWait:
return DummyWait()


@pytest.fixture
def provider() -> Dummy:
return Dummy()
Expand All @@ -42,21 +22,12 @@ def provider() -> Dummy:
class TestDummyTermination(IsolationProviderTermination):
def test_failed(
self,
provider_wait: IsolationProvider,
provider: IsolationProvider,
mocker: MockerFixture,
) -> None:
mocker.patch.object(
provider_wait,
provider,
"get_proc_exception",
return_value=errors.DocFormatUnsupported(),
)
super().test_failed(provider_wait, mocker)

def test_linger_unkillable(
self,
provider_wait: IsolationProvider,
mocker: MockerFixture,
) -> None:
# We have to spawn a blocking process here, else we can't imitate an
# "unkillable" process.
super().test_linger_unkillable(provider_wait, mocker)
super().test_failed(provider, mocker)

0 comments on commit eddc06b

Please sign in to comment.