Project

General

Profile

« Previous | Next » 

Revision bd588eb9

Added by koszko over 1 year ago

add missing english translations and verify message texts of raised exceptions in tests

View differences:

conftest.py
8 8
from pathlib import Path
9 9

  
10 10
import pytest
11
import pkgutil
11 12

  
12 13
here = Path(__file__).resolve().parent
13 14
sys.path.insert(0, str(here / 'src'))
......
34 35
        run = mocked_run
35 36

  
36 37
    monkeypatch.setattr(where, 'subprocess', MockedSubprocess)
38

  
39
@pytest.fixture(autouse=True)
40
def no_gettext(monkeypatch, request):
41
    """
42
    Make gettext return all strings untranslated unless we request otherwise.
43
    """
44
    if request.node.get_closest_marker('enable_gettext'):
45
        return
46

  
47
    import hydrilla
48
    modules_to_process = [hydrilla]
49

  
50
    def add_child_modules(parent):
51
        """
52
        Recursuvely collect all modules descending from 'parent' into an array.
53
        """
54
        try:
55
            load_paths = parent.__path__
56
        except AttributeError:
57
            return
58

  
59
        for module_info in pkgutil.iter_modules(load_paths):
60
            if module_info.name != '__main__':
61
                __import__(f'{parent.__name__}.{module_info.name}')
62
                modules_to_process.append(getattr(parent, module_info.name))
63
                add_child_modules(getattr(parent, module_info.name))
64

  
65
    add_child_modules(hydrilla)
66

  
67
    for module in modules_to_process:
68
        if hasattr(module, '_'):
69
            monkeypatch.setattr(module, '_', lambda message: message)
src/hydrilla/builder/build.py
83 83
        try:
84 84
            cp = subprocess.run(command, capture_output=True, text=True)
85 85
        except FileNotFoundError:
86
            raise ReuseError(_('couldnt_execute_reuse_is_it_installed'))
86
            msg = _('couldnt_execute_{}_is_it_installed').format('reuse')
87
            raise ReuseError(msg)
87 88

  
88 89
        if cp.returncode != 0:
89
            msg = _('reuse_command_{}_failed').format(' '.join(command))
90
            msg = _('command_{}_failed').format(' '.join(command))
90 91
            raise ReuseError(msg, cp)
91 92

  
92 93
    return cp.stdout.encode()
src/hydrilla/builder/local_apt.py
114 114
        try:
115 115
            cp = run(command, **kwargs)
116 116
        except FileNotFoundError:
117
            raise AptError(_('couldnt_execute_apt_get_is_it_installed'))
117
            msg = _('couldnt_execute_{}_is_it_installed').format('apt-get')
118
            raise AptError(msg)
118 119

  
119 120
        if cp.returncode != 0:
120
            msg = _('apt_get_command_{}_failed').format(' '.join(command))
121
            msg = _('command_{}_failed').format(' '.join(command))
121 122
            raise AptError(msg, cp)
122 123

  
123 124
        return cp
......
185 186
    try:
186 187
        from gnupg import GPG
187 188
    except ModuleNotFoundError:
188
        raise GpgError(_('couldnt_import_gnupg_is_it_installed'))
189
        raise GpgError(_('couldnt_import_{}_is_it_installed').format('gnupg'))
189 190

  
190 191
    gpg = GPG(keyring=str(cache_dir() / 'master_keyring.gpg'))
191 192
    for key in keys:
......
193 194
            continue
194 195

  
195 196
        if gpg.recv_keys(default_keyserver, key).imported == 0:
196
            raise GpgError(_('gpg_couldnt_recv_key'))
197
            raise GpgError(_('gpg_couldnt_recv_key_{}').format(key))
197 198

  
198 199
    return gpg.export_keys(keys, armor=False, minimal=True)
199 200

  
......
404 405
            try:
405 406
                cp = run(command)
406 407
            except FileNotFoundError:
407
                raise AptError(_('couldnt_execute_dpkg_deb_is_it_installed'))
408
                msg = _('couldnt_execute_{}_is_it_installed'.format('dpkg-deb'))
409
                raise AptError(msg)
408 410

  
409 411
            if cp.returncode != 0:
410
                msg = _('dpkg_deb_command_{}_failed').format(' '.join(command))
412
                msg = _('command_{}_failed').format(' '.join(command))
411 413
                raise AptError(msg, cp)
412 414

  
413 415
        docs_dir = root / 'usr' / 'share' / 'doc'
src/hydrilla/builder/locales/en_US/LC_MESSAGES/hydrilla-messages.po
7 7
msgstr ""
8 8
"Project-Id-Version: hydrilla.builder 0.1.dev16+g4e46d7f.d20220211\n"
9 9
"Report-Msgid-Bugs-To: koszko@koszko.org\n"
10
"POT-Creation-Date: 2022-04-19 13:51+0200\n"
10
"POT-Creation-Date: 2022-05-10 16:47+0200\n"
11 11
"PO-Revision-Date: 2022-02-12 00:00+0000\n"
12 12
"Last-Translator: Wojtek Kosior <koszko@koszko.org>\n"
13 13
"Language: en_US\n"
......
18 18
"Content-Transfer-Encoding: 8bit\n"
19 19
"Generated-By: Babel 2.8.0\n"
20 20

  
21
#: src/hydrilla/builder/build.py:118
22
msgid "couldnt_import_reuse_is_it_installed"
23
msgstr ""
24
"Could not import 'reuse'. Is the tool installed and visible to this "
25
"Python instance?"
21
#: src/hydrilla/builder/build.py:86 src/hydrilla/builder/local_apt.py:117
22
#: src/hydrilla/builder/local_apt.py:408
23
msgid "couldnt_execute_{}_is_it_installed"
24
msgstr "Could not execute '{}'. Is the tool installed and reachable via PATH?"
25

  
26
#: src/hydrilla/builder/build.py:90 src/hydrilla/builder/local_apt.py:121
27
#: src/hydrilla/builder/local_apt.py:412
28
msgid "command_{}_failed"
29
msgstr "The following command finished execution with a non-zero exit status: {}"
26 30

  
27
#: src/hydrilla/builder/build.py:123
28
msgid "spdx_report_from_reuse_incompliant"
29
msgstr "Attempt to generate an SPDX report for a REUSE-incompliant package."
31
#: src/hydrilla/builder/build.py:198
32
msgid "path_contains_double_dot_{}"
33
msgstr ""
34
"Attempt to load '{}' which includes a forbidden parent reference ('..') "
35
"in the path."
30 36

  
31
#: src/hydrilla/builder/build.py:207
37
#: src/hydrilla/builder/build.py:205
32 38
msgid "loading_{}_outside_package_dir"
33 39
msgstr "Attempt to load '{}' which lies outside package source directory."
34 40

  
35
#: src/hydrilla/builder/build.py:211
41
#: src/hydrilla/builder/build.py:209
36 42
msgid "loading_reserved_index_json"
37 43
msgstr "Attempt to load 'index.json' which is a reserved filename."
38 44

  
39
#: src/hydrilla/builder/build.py:329
45
#: src/hydrilla/builder/build.py:350
40 46
msgid "report_spdx_not_in_copyright_list"
41 47
msgstr ""
42 48
"Told to generate 'report.spdx' but 'report.spdx' is not listed among "
43 49
"copyright files. Refusing to proceed."
44 50

  
45
#: src/hydrilla/builder/build.py:402
51
#: src/hydrilla/builder/build.py:421
52
msgid "build_package_from_srcdir_to_dstdir"
53
msgstr ""
54
"Build Hydrilla package from `scrdir` and write the resulting files under "
55
"`dstdir`."
56

  
57
#: src/hydrilla/builder/build.py:423
46 58
msgid "source_directory_to_build_from"
47 59
msgstr "Source directory to build from."
48 60

  
49
#: src/hydrilla/builder/build.py:404
61
#: src/hydrilla/builder/build.py:425
50 62
msgid "path_instead_of_index_json"
51 63
msgstr ""
52 64
"Path to file to be processed instead of index.json (if not absolute, "
53 65
"resolved relative to srcdir)."
54 66

  
55
#: src/hydrilla/builder/build.py:406
67
#: src/hydrilla/builder/build.py:427
68
msgid "path_instead_for_piggyback_files"
69
msgstr ""
70
"Path to a non-standard directory with foreign packages' archive files to "
71
"use."
72

  
73
#: src/hydrilla/builder/build.py:429
56 74
msgid "built_package_files_destination"
57 75
msgstr "Destination directory to write built package files to."
58 76

  
59
#: src/hydrilla/builder/build.py:408
77
#: src/hydrilla/builder/build.py:431
60 78
#, python-format
61 79
msgid "%(prog)s_%(version)s_license"
62 80
msgstr ""
......
67 85
"This is free software: you are free to change and redistribute it.\n"
68 86
"There is NO WARRANTY, to the extent permitted by law."
69 87

  
70
#: src/hydrilla/builder/build.py:409
88
#: src/hydrilla/builder/build.py:432
71 89
msgid "version_printing"
72 90
msgstr "Print version information and exit."
73 91

  
74
#: src/hydrilla/builder/build.py:415
75
msgid "build_package_from_srcdir_to_dstdir"
92
#: src/hydrilla/builder/common_errors.py:62
93
msgid "STDOUT_OUTPUT_heading"
94
msgstr "## Command's standard output ##"
95

  
96
#: src/hydrilla/builder/common_errors.py:65
97
msgid "STDERR_OUTPUT_heading"
98
msgstr "## Command's standard error output ##"
99

  
100
#: src/hydrilla/builder/local_apt.py:146
101
msgid "distro_{}_unknown"
102
msgstr "Attempt to use an unknown software distribution '{}'."
103

  
104
#: src/hydrilla/builder/local_apt.py:189
105
msgid "couldnt_import_{}_is_it_installed"
76 106
msgstr ""
77
"Build Hydrilla package from `scrdir` and write the resulting files under "
78
"`dstdir`."
107
"Could not import '{}'. Is the module installed and visible to this Python"
108
" instance?"
109

  
110
#: src/hydrilla/builder/local_apt.py:197
111
msgid "gpg_couldnt_recv_key_{}"
112
msgstr "Could not import PGP key '{}'."
113

  
114
#: src/hydrilla/builder/local_apt.py:314
115
msgid "apt_install_output_not_understood"
116
msgstr "The output of an 'apt-get install' command was not understood."
117

  
118
#: src/hydrilla/builder/local_apt.py:342
119
msgid "apt_download_gave_bad_filename_{}"
120
msgstr "The 'apt-get download' command produced a file with unexpected name '{}'."
121

  
122
#: src/hydrilla/builder/piggybacking.py:102
123
msgid "loading_{}_outside_piggybacked_dir"
124
msgstr ""
125
"Attempt to load '{}' which lies outside piggybacked packages files root "
126
"directory."
79 127

  
80 128
#: src/hydrilla/util/_util.py:79
81 129
msgid "bad_comment"
tests/test_build.py
582 582
    Modify index.json to expect missing report.spdx file and cause an error.
583 583
    """
584 584
    monkeypatch.delitem(index_obj, 'reuse_generate_spdx_report')
585
    return FileNotFoundError
585
    return FileNotFoundError,
586 586

  
587 587
@error_maker
588 588
def sample_source_error_index_schema(monkeypatch, sample_source):
589 589
    """Modify index.json to be incompliant with the schema."""
590 590
    monkeypatch.delitem(index_obj, 'definitions')
591
    return ValidationError
591
    return ValidationError,
592 592

  
593 593
@error_maker
594 594
def sample_source_error_bad_comment(monkeypatch, sample_source):
595 595
    """Modify index.json to have an invalid '/' in it."""
596
    return json.JSONDecodeError, json.dumps(index_obj) + '/something\n'
596
    return json.JSONDecodeError, '^bad_comment: .*', \
597
        json.dumps(index_obj) + '/something\n'
597 598

  
598 599
@error_maker
599 600
def sample_source_error_bad_json(monkeypatch, sample_source):
600 601
    """Modify index.json to not be valid json even after comment stripping."""
601
    return json.JSONDecodeError, json.dumps(index_obj) + '???/\n'
602
    return json.JSONDecodeError, '', json.dumps(index_obj) + '???\n'
602 603

  
603 604
@error_maker
604 605
def sample_source_error_missing_reuse(monkeypatch, sample_source):
605 606
    """Cause mocked reuse process invocation to fail with FileNotFoundError."""
606 607
    (sample_source / 'mock_reuse_missing').touch()
607
    return build.ReuseError
608
    return build.ReuseError, '^couldnt_execute_reuse_is_it_installed$'
608 609

  
609 610
@error_maker
610 611
def sample_source_error_missing_license(monkeypatch, sample_source):
611 612
    """Remove a file to make package REUSE-incompliant."""
612 613
    (sample_source / 'README.txt.license').unlink()
613
    return build.ReuseError
614

  
615
    error_regex = """^\
616
command_reuse --root \\S+ lint_failed
617

  
618
STDOUT_OUTPUT_heading
619

  
620
dummy lint output
621

  
622
STDERR_OUTPUT_heading
623

  
624
some error output\
625
$\
626
"""
627

  
628
    return build.ReuseError, error_regex
614 629

  
615 630
@error_maker
616 631
def sample_source_error_file_outside(monkeypatch, sample_source):
617 632
    """Make index.json illegally reference a file outside srcdir."""
618 633
    new_list = [*index_obj['copyright'], {'file': '../abc'}]
619 634
    monkeypatch.setitem(index_obj, 'copyright', new_list)
620
    return FileReferenceError
635
    return FileReferenceError, '^path_contains_double_dot_\\.\\./abc$'
621 636

  
622 637
@error_maker
623 638
def sample_source_error_reference_itself(monkeypatch, sample_source):
624 639
    """Make index.json illegally reference index.json."""
625 640
    new_list = [*index_obj['copyright'], {'file': 'index.json'}]
626 641
    monkeypatch.setitem(index_obj, 'copyright', new_list)
627
    return FileReferenceError
642
    return FileReferenceError, '^loading_reserved_index_json$'
628 643

  
629 644
@error_maker
630 645
def sample_source_error_report_excluded(monkeypatch, sample_source):
......
635 650
    new_list = [file_ref for file_ref in index_obj['copyright']
636 651
                if file_ref['file'] != 'report.spdx']
637 652
    monkeypatch.setitem(index_obj, 'copyright', new_list)
638
    return FileReferenceError
653
    return FileReferenceError, '^report_spdx_not_in_copyright_list$'
639 654

  
640 655
@pytest.fixture(params=error_makers)
641 656
def sample_source_make_errors(request, monkeypatch, sample_source):
......
644 659
    broken versions. Return an error type that should be raised when running
645 660
    test build.
646 661
    """
647
    index_text = None
648
    error_type = request.param(monkeypatch, sample_source)
649
    if type(error_type) is tuple:
650
        error_type, index_text = error_type
662
    error_type, error_regex, index_text = \
663
        [*request.param(monkeypatch, sample_source), '', ''][0:3]
651 664

  
652 665
    index_text = index_text or json.dumps(index_obj)
653 666

  
......
655 668

  
656 669
    monkeypatch.setitem(src_files, 'index.json', index_text.encode())
657 670

  
658
    return error_type
671
    return error_type, error_regex
659 672

  
660 673
@pytest.mark.subprocess_run(build, run_reuse)
661 674
@pytest.mark.usefixtures('mock_subprocess_run')
662 675
def test_build_error(tmpdir, sample_source, sample_source_make_errors):
663 676
    """Try building the sample source package and verify generated errors."""
664
    error_type = sample_source_make_errors
677
    error_type, error_regex = sample_source_make_errors
665 678

  
666 679
    dstdir = Path(tmpdir) / 'dstdir'
667 680
    tmpdir = Path(tmpdir) / 'example'
......
669 682
    dstdir.mkdir(exist_ok=True)
670 683
    tmpdir.mkdir(exist_ok=True)
671 684

  
672
    with pytest.raises(error_type):
685
    with pytest.raises(error_type, match=error_regex):
673 686
        build.Build(sample_source, Path('index.json'))\
674 687
             .write_package_files(dstdir)
tests/test_local_apt.py
290 290
    """
291 291
    sources_list = local_apt.SourcesList(['deb-src sth', 'deb sth'])
292 292

  
293
    with pytest.raises(local_apt.AptError) as excinfo:
293
    with pytest.raises(local_apt.AptError,
294
                       match='^couldnt_execute_apt-get_is_it_installed$'):
294 295
        with local_apt.local_apt(sources_list, local_apt.default_keys) as apt:
295 296
            pass
296 297

  
297
    assert len(excinfo.value.args) == 1
298
    assert isinstance(excinfo.value.args[0], str)
299
    assert '\n' not in excinfo.value.args[0]
300

  
301 298
@pytest.mark.subprocess_run(local_apt, make_run_apt_get(update_code=1))
302 299
@pytest.mark.usefixtures('mock_subprocess_run', 'mock_gnupg_import')
303 300
def test_local_apt_update_fail(mock_cache_dir):
......
307 304
    """
308 305
    sources_list = local_apt.SourcesList(['deb-src sth', 'deb sth'])
309 306

  
310
    with pytest.raises(local_apt.AptError) as excinfo:
311
        with local_apt.local_apt(sources_list, local_apt.default_keys) as apt:
312
            pass
307
    error_regex = """^\
308
command_apt-get -c \\S+ update_failed
309

  
310
STDOUT_OUTPUT_heading
311

  
312
some output
313 313

  
314
    assert len(excinfo.value.args) == 1
314
STDERR_OUTPUT_heading
315 315

  
316
    assert re.match(r'.*\n\n.*\n\nsome output\n\n.*\n\nsome error output',
317
                    excinfo.value.args[0])
316
some error output\
317
$\
318
"""
319

  
320
    with pytest.raises(local_apt.AptError, match=error_regex):
321
        with local_apt.local_apt(sources_list, local_apt.default_keys) as apt:
322
            pass
318 323

  
319 324
@pytest.mark.subprocess_run(local_apt, make_run_apt_get())
320 325
@pytest.mark.usefixtures('mock_subprocess_run', 'mock_gnupg_import')
......
359 364
    destination = mock_cache_dir / 'destination'
360 365
    destination.mkdir()
361 366

  
362
    with pytest.raises(local_apt.AptError) as excinfo:
367
    error_regex = f"""^\
368
command_apt-get -c \\S+ install --yes --just-print libjs-mathjax_failed
369

  
370
STDOUT_OUTPUT_heading
371

  
372
{re.escape(sample_install_stdout)}
373

  
374
STDERR_OUTPUT_heading
375

  
376
some error output\
377
$\
378
"""
379

  
380
    with pytest.raises(local_apt.AptError, match=error_regex):
363 381
        local_apt.download_apt_packages(sources_list, local_apt.default_keys,
364 382
                                        ['libjs-mathjax'], destination,
365 383
                                        with_deps=True)
366 384

  
367
    assert len(excinfo.value.args) == 1
368

  
369
    assert re.match(r'^.*\n\n.*\n\n', excinfo.value.args[0])
370
    assert re.search(r'\n\nsome error output$', excinfo.value.args[0])
371
    assert sample_install_stdout in excinfo.value.args[0]
372

  
373 385
    assert [*destination.iterdir()] == []
374 386

  
375 387
@pytest.mark.subprocess_run(local_apt, make_run_apt_get(download_code=1))
......
383 395
    destination = mock_cache_dir / 'destination'
384 396
    destination.mkdir()
385 397

  
386
    with pytest.raises(local_apt.AptError) as excinfo:
398
    error_regex = """^\
399
command_apt-get -c \\S+ download libjs-mathjax_failed
400

  
401
STDOUT_OUTPUT_heading
402

  
403
some output
404

  
405
STDERR_OUTPUT_heading
406

  
407
some error output\
408
$\
409
"""
410

  
411
    with pytest.raises(local_apt.AptError, match=error_regex):
387 412
        local_apt.download_apt_packages(sources_list, local_apt.default_keys,
388 413
                                        ['libjs-mathjax'], destination)
389 414

  
390
    assert len(excinfo.value.args) == 1
415
    assert [*destination.iterdir()] == []
391 416

  
392
    assert re.match(r'.*\n\n.*\n\nsome output\n\n.*\n\nsome error output',
393
                    excinfo.value.args[0])
417
@pytest.fixture
418
def mock_bad_deb_file(monkeypatch, mock_subprocess_run):
419
    """
420
    Make mocked 'apt-get download' command produce an incorrectly-named file.
421
    """
422
    old_run = local_apt.subprocess.run
423

  
424
    def twice_mocked_run(command, **kwargs):
425
        """
426
        Create an evil file if needed; then act just like the run() function
427
        that got replaced by this one.
428
        """
429
        if 'download' in command:
430
            destination = Path(kwargs.get('cwd') or Path.cwd())
431
            (destination / 'arbitrary-name').write_text('anything')
432

  
433
        return old_run(command, **kwargs)
434

  
435
    monkeypatch.setattr(local_apt.subprocess, 'run', twice_mocked_run)
436

  
437
@pytest.mark.subprocess_run(local_apt, make_run_apt_get())
438
@pytest.mark.usefixtures('mock_subprocess_run', 'mock_gnupg_import',
439
                         'mock_bad_deb_file')
440
def test_local_apt_download_bad_filename(mock_cache_dir):
441
    """
442
    Verify that the download_apt_packages() function raises a proper error when
443
    'apt-get download' command produces an incorrectly-named file.
444
    """
445
    sources_list = local_apt.SourcesList([], 'nabia')
446
    destination = mock_cache_dir / 'destination'
447
    destination.mkdir()
448

  
449
    error_regex = """^\
450
apt_download_gave_bad_filename_arbitrary-name
451

  
452
STDOUT_OUTPUT_heading
453

  
454
some output
455

  
456
STDERR_OUTPUT_heading
457

  
458
some error output\
459
$\
460
"""
461

  
462
    with pytest.raises(local_apt.AptError, match=error_regex):
463
        local_apt.download_apt_packages(sources_list, local_apt.default_keys,
464
                                        ['libjs-mathjax'], destination)
394 465

  
395 466
    assert [*destination.iterdir()] == []
396 467

  
......
405 476
    destination = mock_cache_dir / 'destination'
406 477
    destination.mkdir()
407 478

  
408
    with pytest.raises(local_apt.AptError) as excinfo:
409
        local_apt.download_apt_packages(sources_list, local_apt.default_keys,
410
                                        ['libjs-mathjax'], destination)
479
    error_regex = """^\
480
command_apt-get -c \\S* source --download-only \\S+_failed
481

  
482
STDOUT_OUTPUT_heading
411 483

  
412
    assert len(excinfo.value.args) == 1
484
some output
413 485

  
414
    assert re.match(r'.*\n\n.*\n\nsome output\n\n.*\n\nsome error output',
415
                    excinfo.value.args[0])
486
STDERR_OUTPUT_heading
487

  
488
some error output\
489
$\
490
"""
491

  
492
    with pytest.raises(local_apt.AptError, match=error_regex):
493
        local_apt.download_apt_packages(sources_list, local_apt.default_keys,
494
                                        ['libjs-mathjax'], destination)
416 495

  
417 496
    assert [*destination.iterdir()] == []
418 497

  
......
421 500
    list = local_apt.SourcesList([], 'nabia')
422 501
    assert list.identity() == 'nabia'
423 502

  
424
    with pytest.raises(local_apt.DistroError):
503
    with pytest.raises(local_apt.DistroError, match='^distro_nabiał_unknown$'):
425 504
        local_apt.SourcesList([], 'nabiał')
426 505

  
427 506
    list = local_apt.SourcesList(['deb sth', 'deb-src sth'], 'nabia')
......
557 636
        assert piggybacked.resolve_file(PurePosixPath('a/b/c')) == None
558 637
        assert piggybacked.resolve_file(PurePosixPath('')) == None
559 638

  
560
        with pytest.raises(FileReferenceError):
639
        output_text = 'loading_.apt-root/a/../../../b_outside_piggybacked_dir'
640
        with pytest.raises(FileReferenceError,
641
                           match=f'^{re.escape(output_text)}$'):
561 642
            piggybacked.resolve_file(PurePosixPath('.apt-root/a/../../../b'))
562 643

  
563 644
        root = piggybacked.resolve_file(PurePosixPath('.apt-root/dummy')).parent
......
615 696
    Verify that the piggybacked_system() function raises a proper error when
616 697
    'dpkg-deb' is missing.
617 698
    """
618
    with pytest.raises(local_apt.AptError) as excinfo:
699
    with pytest.raises(local_apt.AptError,
700
                       match='^couldnt_execute_dpkg-deb_is_it_installed$'):
619 701
        with local_apt.piggybacked_system({
620 702
                'system': 'apt',
621 703
                'distribution': 'nabia',
......
624 706
        }, None) as piggybacked:
625 707
            pass
626 708

  
627
    assert len(excinfo.value.args) == 1
628

  
629
    assert '\n' not in excinfo.value.args[0]
630

  
631

  
632 709
@pytest.mark.subprocess_run(local_apt, lambda c, **kw: run_dpkg_deb(c, 1, **kw))
633 710
@pytest.mark.usefixtures('mock_download_packages', 'mock_subprocess_run')
634 711
def test_piggybacked_system_fail():
......
636 713
    Verify that the piggybacked_system() function raises a proper error when
637 714
    'dpkg-deb -x' command returns non-0.
638 715
    """
639
    with pytest.raises(local_apt.AptError) as excinfo:
716
    error_regex = """^\
717
command_dpkg-deb -x \\S+\\.deb \\S+_failed
718

  
719
STDOUT_OUTPUT_heading
720

  
721
some output
722

  
723
STDERR_OUTPUT_heading
724

  
725
some error output\
726
$\
727
"""
728

  
729
    with pytest.raises(local_apt.AptError, match=error_regex):
640 730
        with local_apt.piggybacked_system({
641 731
                'system': 'apt',
642 732
                'distribution': 'nabia',
......
644 734
                'dependencies': False
645 735
        }, None) as piggybacked:
646 736
            pass
647

  
648
    assert len(excinfo.value.args) == 1
649

  
650
    assert re.match(r'.*\n\n.*\n\nsome output\n\n.*\n\nsome error output',
651
                    excinfo.value.args[0])

Also available in: Unified diff