diff --git a/tests/replace_ghostscript_nopdfa.py b/tests/replace_ghostscript_nopdfa.py new file mode 100755 index 00000000..d07682a3 --- /dev/null +++ b/tests/replace_ghostscript_nopdfa.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +import sys +import os + +''' +For testing PDF/A generation failures, this wrapper calls ghostscript +but filters out all PDF/A information so that a regular PDF will be +created instead. + +It assumes that it is called from a staged system PATH where the first +item on the PATH contains a file named 'gs' which is a symlink to this +file. It will strip out the first item on path to invoke the real +'gs'. +''' + + +def pdfa_param(arg): + if arg.startswith('-sPDFA'): + return True + if arg.startswith('-dPDFA'): + return True + if arg.endswith('.ps'): + return True + return False + + +if __name__ == '__main__': + args = [arg for arg in sys.argv[1:] + if not pdfa_param(arg)] + + print("Fake Ghostscript wrapper", file=sys.stderr) + + exec_path = os.environ['PATH'].split(os.pathsep) + env = os.environ.copy() + env['PATH'] = os.pathsep.join(exec_path[1:]) + + print("Calling real Ghostscript with modified args and env", + file=sys.stderr) + print(args, file=sys.stderr) + print(env['PATH'], file=sys.stderr) + + sys.stderr.flush() + os.execvpe('gs', ['gs'] + args, env) diff --git a/tests/test_main.py b/tests/test_main.py index c5c033a0..3935349b 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -22,6 +22,7 @@ PROJECT_ROOT = os.path.dirname(TESTS_ROOT) OCRMYPDF = os.path.join(PROJECT_ROOT, 'OCRmyPDF.sh') TEST_RESOURCES = os.path.join(PROJECT_ROOT, 'tests', 'resources') TEST_OUTPUT = os.path.join(PROJECT_ROOT, 'tests', 'output') +TEST_BINARY_PATH = os.path.join(TEST_OUTPUT, 'bin') def setup_module(): @@ -59,6 +60,18 @@ def check_ocrmypdf(input_basename, output_basename, *args): return output_file +def run_ocrmypdf_env(input_basename, output_basename, env, *args): + input_file = _make_input(input_basename) + output_file = _make_output(output_basename) + + p_args = ['ocrmypdf'] + list(args) + [input_file, output_file] + p = Popen( + p_args, close_fds=True, stdout=PIPE, stderr=PIPE, + universal_newlines=True, env=env) + out, err = p.communicate() + return p, out, err + + def test_quick(): check_ocrmypdf('c02-22.pdf', 'test_quick.pdf') @@ -200,3 +213,34 @@ def check_maximum_options(renderer): def test_maximum_options(): yield check_maximum_options, 'hocr' yield check_maximum_options, 'tesseract' + + +def override_binary(binary, replacement): + with suppress(FileExistsError): + os.makedirs(TEST_BINARY_PATH) + + replacement_path = os.path.abspath(os.path.join(TESTS_ROOT, + replacement)) + binary_path = os.path.abspath(os.path.join(TEST_BINARY_PATH, + binary)) + assert not os.path.lexists(binary_path) + print("symlink %s -> %s" % (replacement_path, binary_path)) + os.symlink(replacement_path, binary_path) + + os.chmod(replacement_path, int('755', base=8)) + + return os.path.dirname(binary_path) + os.pathsep + os.environ["PATH"] + + +@pytest.fixture +def break_ghostscript_pdfa(): + return override_binary('gs', 'replace_ghostscript_nopdfa.py') + + +def test_ghostscript_pdfa_fails(break_ghostscript_pdfa): + env = os.environ + env['PATH'] = break_ghostscript_pdfa + + p, out, err = run_ocrmypdf_env( + 'graph_ocred.pdf', 'not_a_pdfa.pdf', env, '-v', '1', '--skip-text') + assert p.returncode == 4, err # not PDFA