diff --git a/extract.py b/extract.py index 42dde685..0c86bcd8 100755 --- a/extract.py +++ b/extract.py @@ -42,24 +42,23 @@ def container_exists(container): return subprocess.run('docker history {}'.format(container), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).returncode == 0 -def call_docker(input_file, container, target, report_file, memory_limit): - tmpdir = TemporaryDirectory() - tmp = tmpdir.name +def call_docker(input_file, container, target, report_file, memory_limit, tmpdir=None): + tmpdir = tmpdir if tmpdir else TemporaryDirectory() for subpath in ['files', 'reports', 'input']: - Path(tmp, subpath).mkdir() + Path(tmpdir.name, subpath).mkdir(exist_ok=True) - shutil.copy(input_file, str(Path(tmp, 'input', Path(input_file).name))) + shutil.copy(input_file, str(Path(tmpdir.name, 'input', Path(input_file).name))) - subprocess.run('docker run --rm -m {}m -v {}:/tmp/extractor -v /dev:/dev --privileged {}'.format(memory_limit, tmp, container), shell=True) + subprocess.run('docker run --rm -m {}m -v {}:/tmp/extractor -v /dev:/dev --privileged {}'.format(memory_limit, tmpdir.name, container), shell=True) logging.warning('Now taking ownership of the files. You may need to enter your password.') subprocess.run('sudo chown -R {} {}'.format(os.environ['USER'], tmpdir.name), shell=True) with suppress(shutil.Error): - shutil.copytree(str(Path(tmp, 'files')), target) + shutil.copytree(str(Path(tmpdir.name, 'files')), target) - handle_report(report_file, tmp) + handle_report(report_file, tmpdir.name) tmpdir.cleanup() diff --git a/fact_extractor/install/common.py b/fact_extractor/install/common.py index 1930d992..17a96d3c 100644 --- a/fact_extractor/install/common.py +++ b/fact_extractor/install/common.py @@ -21,7 +21,7 @@ def main(distribution): # python dependencies apt_install_packages('python3', 'python3-dev', 'python', 'python-dev', 'python-wheel', 'python-setuptools') - pip3_install_packages('pytest==3.5.1', 'pytest-cov') + pip3_install_packages('pytest', 'pytest-cov', 'pytest-pep8') if not xenial: pip3_install_packages('testresources') diff --git a/test_extract.py b/test_extract.py index 304527e8..11716013 100644 --- a/test_extract.py +++ b/test_extract.py @@ -1,6 +1,10 @@ +import logging +from pathlib import Path + import pytest -from extract import container_exists, parse_arguments +from extract import container_exists, parse_arguments, setup_logging, handle_report, main, TemporaryDirectory, \ + call_docker def exec_stub(command, *_, **__): @@ -19,7 +23,7 @@ def test_parse_arguments(monkeypatch): assert args.ARCHIVE[0] == 'ANY' -def test_parse_arguments_missing_archive(monkeypatch, capsys): +def test_parse_arguments_no_archive(monkeypatch, capsys): monkeypatch.setattr('extract.sys.argv', ['extract.py']) with pytest.raises(SystemExit) as sys_exit: @@ -42,3 +46,61 @@ def test_container_exists(monkeypatch): assert not container_exists('please fail') assert container_exists('please succeed') + + +def test_setup_logging(capsys): + logging.info('test') + assert not capsys.readouterr().err + + setup_logging(verbose=False) + logging.info('test') + assert capsys.readouterr().err + + +def test_setup_logging_verbose(capsys): + setup_logging(verbose=False) + logging.debug('test') + assert not capsys.readouterr().err + + setup_logging(verbose=True) + logging.debug('test') + assert capsys.readouterr().err + + +def test_handle_report(monkeypatch, capsys, tmpdir): + monkeypatch.setattr('extract.Path.read_text', lambda *_, **__: '{"a": 5}') + handle_report(None, '') + assert ' "a": 5\n' in capsys.readouterr().out + + handle_report(str(Path(str(tmpdir), 'anyfile')), '') + report = Path(str(tmpdir), 'anyfile').read_bytes().decode() + assert ' "a": 5\n' in report + + +@pytest.mark.parametrize('arguments, return_code, message', [ + [['extract.py', '-o', '/tmp', 'anyfile'], 1, 'Target directory exists'], + [['extract.py', '-o', '/tmp/valid_dir', '-c', 'container_will_fail', 'anyfile'], 1, 'fail doesn\'t exist'], + [['extract.py', '-o', '/tmp/valid_dir', '-c', 'container_will_succeed', 'anyfile'], 1, 'anyfile doesn\'t exist'], + [['extract.py', '-o', '/tmp/valid_dir', '-c', 'container_will_succeed', '-r', '/tmp/bad/path/to/report', '/bin/bash'], 1, 'Check if parent directory exists'], + [['extract.py', '-o', '/tmp/valid_dir', '-c', 'container_will_succeed', '-r', '/etc/environment', '/bin/bash'], 0, 'will be overwritten'], + [['extract.py', '-o', '/tmp/valid_dir', '-c', 'container_will_succeed', '-r', '/tmp/report', '/bin/bash'], 0, ''] +]) +def test_main_return_values(arguments, return_code, message, monkeypatch, capsys): + monkeypatch.setattr('extract.call_docker', lambda input_file, container, target, report_file: None) + monkeypatch.setattr('extract.sys.argv', arguments) + monkeypatch.setattr('extract.subprocess.run', exec_stub) + + assert main() == return_code + assert message in capsys.readouterr().err + + +def test_call_docker(monkeypatch, capsys): + monkeypatch.setattr('extract.subprocess.run', lambda *_, **__: None) + tmpdir = TemporaryDirectory() + target = Path(tmpdir.name, 'target') + Path(tmpdir.name, 'reports').mkdir(parents=True) + Path(tmpdir.name, 'reports', 'meta.json').write_text('{"test": "succeeded"}') + + call_docker('/bin/bash', 'doesnt_matter', str(target), None, tmpdir) + + assert ' "test": "succeeded"\n' in capsys.readouterr().out