def test_parse_args_version(capsys): """Calling parse_args with --version should print the version and exit.""" with pytest.raises(SystemExit): cli.parse_args(['--version']) out, err = capsys.readouterr() msg = 'debmonitor-client {ver}'.format(ver=cli.__version__) assert msg in out
def test_parse_args_config_invalid(capsys): """Calling parse_args with --config with an invalid file should raise SystemExit.""" with pytest.raises(SystemExit): cli.parse_args( ['--config', DEBMONITOR_CLIENT_CONFIG.format(mode='ko')]) _, err = capsys.readouterr() assert 'Unable to parse configuration file' in err
def test_main_dpkg_hook(mocked_getfqdn, mocked_requests): """Calling main() with -g should parse the input for a Dpkg::Pre-Install-Pkgs hook and send the update.""" args = cli.parse_args(['--config', DEBMONITOR_CLIENT_CONFIG_OK, '-g']) input_lines = _get_dpkg_hook_preamble(3) + APT_HOOK_LINES[3][0:2] mocked_requests.register_uri('POST', DEBMONITOR_UPDATE_URL, status_code=201) mocked_apt.cache.Cache().__getitem__.return_value = AptPackage( name='package-name', is_installed=False, installed=None, candidate=AptPkgVersion(source_name='package-name', version='1.0.0-1')) with mock.patch('{mod}.open'.format(mod=BUILTINS), mock.mock_open(read_data=OS_RELEASE), create=True) as mocked_open: exit_code = cli.main(args, input_lines=input_lines) assert mock.call(cli.OS_RELEASE_FILE, mode='r') in mocked_open.mock_calls mocked_getfqdn.assert_called_once_with() assert mocked_requests.called assert exit_code == 0 assert mocked_requests.last_request.json() == _get_payload_with_packages( ['-g'])
def test_main_update_ok(mocked_getfqdn, mocked_requests, caplog): """Calling main() whit --update that succeed should update the CLI script.""" args = cli.parse_args(['-s', DEBMONITOR_SERVER, '--update']) mocked_requests.register_uri('POST', DEBMONITOR_UPDATE_URL, status_code=201) mocked_requests.register_uri( 'HEAD', DEBMONITOR_CLIENT_URL, status_code=200, headers={cli.CLIENT_VERSION_HEADER: DEBMONITOR_CLIENT_VERSION}) mocked_requests.register_uri('GET', DEBMONITOR_CLIENT_URL, status_code=200, text='data', headers={ cli.CLIENT_VERSION_HEADER: DEBMONITOR_CLIENT_VERSION, cli.CLIENT_CHECKSUM_HEADER: DEBMONITOR_CLIENT_CHECKSUM }) _reset_apt_caches() with patch('builtins.open', mock_open()) as mocked_open: exit_code = cli.main(args) mocked_open.assert_called_once_with(os.path.realpath(cli.__file__), mode='w') mocked_handler = mocked_open() mocked_handler.write.assert_called_once_with('data') assert mocked_requests.called mocked_getfqdn.assert_called_once_with() assert exit_code == 0 assert 'Successfully self-updated DebMonitor CLI' in caplog.text
def test_main_no_packages(mocked_getfqdn): """Calling main() if there are no updates should success without sending any update to the DebMonitor server.""" args = cli.parse_args(['-s', DEBMONITOR_SERVER]) _reset_apt_caches(empty=True) exit_code = cli.main(args) mocked_getfqdn.assert_called_once_with() assert exit_code == 0
def test_parse_args_config(): """Calling parse_args with --config should initialize the values from the configuration file.""" args = cli.parse_args(['--config', DEBMONITOR_CLIENT_CONFIG_OK]) assert args.config == DEBMONITOR_CLIENT_CONFIG_OK assert args.server == DEBMONITOR_SERVER assert args.port == 443 assert args.cert == 'CERT_PATH' assert args.key == 'KEY_PATH' assert args.ca == 'CA_PATH'
def test_main_dry_run_image_file(capsys): """Calling main() with image_file and dry_run parameters should print the content of the JSON file.""" args = cli.parse_args( ['--config', DEBMONITOR_CLIENT_CONFIG_OK, '-n', '-f', VALID_JSON_FILE]) _reset_apt_caches() exit_code = cli.main(args) out, _ = capsys.readouterr() assert exit_code == 0 assert json.loads(out) == {'key': 'value'}
def test_main_dry_run(mocked_getfqdn, capsys): """Calling main() with dry-run parameter should print the updates without sending them to the DebMonitor server.""" args = cli.parse_args(['-s', DEBMONITOR_SERVER, '-n']) _reset_apt_caches() exit_code = cli.main(args) out, _ = capsys.readouterr() mocked_getfqdn.assert_called_once_with() assert exit_code == 0 assert json.loads(out) == _get_payload_with_packages([])
def test_parse_args_config_override(): """Calling parse_args with --config should allow to override the values with CLI arguments.""" cert = 'DUMMY_CERT' key = 'DUMMY_KEY' args = cli.parse_args([ '--config', DEBMONITOR_CLIENT_CONFIG_OK, '-c', cert, '-k', key, '-p', '18081' ]) assert args.cert == cert assert args.key == key assert args.port == 18081
def test_main(mocked_getfqdn, params, mocked_requests): """Calling main() should send the updates to the DebMonitor server with the above parameters.""" args = cli.parse_args(['-s', DEBMONITOR_SERVER] + params) mocked_requests.register_uri('POST', DEBMONITOR_UPDATE_URL, status_code=201) _reset_apt_caches() exit_code = cli.main(args) mocked_getfqdn.assert_called_once_with() assert mocked_requests.called assert exit_code == 0 assert mocked_requests.last_request.json() == _get_payload_with_packages( params)
def test_main_dry_run(mocked_getfqdn, capsys): """Calling main() with dry-run parameter should print the updates without sending them to the DebMonitor server.""" args = cli.parse_args(['--config', DEBMONITOR_CLIENT_CONFIG_OK, '-n']) _reset_apt_caches() with mock.patch('{mod}.open'.format(mod=BUILTINS), mock.mock_open(read_data=OS_RELEASE), create=True) as mocked_open: exit_code = cli.main(args) assert mock.call(cli.OS_RELEASE_FILE, mode='r') in mocked_open.mock_calls out, _ = capsys.readouterr() mocked_getfqdn.assert_called_once_with() assert exit_code == 0 assert json.loads(out) == _get_payload_with_packages([])
def test_main_wrong_http_code(mocked_getfqdn, params, mocked_requests, caplog): """Calling main() when the DebMonitor server returns a wrong HTTP code should return 1.""" args = cli.parse_args(['-s', DEBMONITOR_SERVER] + params) mocked_requests.register_uri('POST', DEBMONITOR_UPDATE_URL, status_code=400) _reset_apt_caches() exit_code = cli.main(args) mocked_getfqdn.assert_called_once_with() assert mocked_requests.called assert exit_code == 1 assert mocked_requests.last_request.json() == _get_payload_with_packages( params) assert 'Failed to send the update to the DebMonitor server' in caplog.text
def test_main_dry_run_image_name(capsys): """Calling main() with image_name and dry_run parameters should print the updates for an image container.""" args = cli.parse_args( ['--config', DEBMONITOR_CLIENT_CONFIG_OK, '-n', '-i', IMAGENAME]) _reset_apt_caches() with mock.patch('builtins.open', mock.mock_open(read_data=OS_RELEASE), create=True) as mocked_open: exit_code = cli.main(args) assert mock.call(cli.OS_RELEASE_FILE, mode='r') in mocked_open.mock_calls out, _ = capsys.readouterr() assert exit_code == 0 assert json.loads(out) == _get_payload_with_packages(['-i'])
def test_main_update_fail(mocked_getfqdn, mocked_requests, caplog): """Calling main() whit --update that fails the update should log the error and continue.""" args = cli.parse_args(['-s', DEBMONITOR_SERVER, '--update']) mocked_requests.register_uri('POST', DEBMONITOR_UPDATE_URL, status_code=201) mocked_requests.register_uri('HEAD', DEBMONITOR_CLIENT_URL, status_code=500) _reset_apt_caches() exit_code = cli.main(args) assert mocked_requests.called mocked_getfqdn.assert_called_once_with() assert exit_code == 0 assert 'Unable to self-update this script' in caplog.text
def test_main_wrong_http_code(params, mocked_getfqdn, mocked_requests, caplog): """Calling main() when the DebMonitor server returns a wrong HTTP code should return 1.""" args = cli.parse_args(['--config', DEBMONITOR_CLIENT_CONFIG_OK] + params) mocked_requests.register_uri('POST', DEBMONITOR_UPDATE_URL, status_code=400) _reset_apt_caches() # Explicitely avoiding mocking open() due to a bug in Python 3.4.2 (jessie default version) that make it fail. cli.OS_RELEASE_FILE = OS_RELEASE_FILE exit_code = cli.main(args) mocked_getfqdn.assert_called_once_with() assert mocked_requests.called assert exit_code == 1 assert mocked_requests.last_request.json() == _get_payload_with_packages( params) assert 'Failed to send the update to the DebMonitor server' in caplog.text
def test_main_image_file(monkeypatch, mocked_getfqdn, mocked_requests): """Calling main() with an image file should send the updates to the DebMonitor server.""" payload = _get_payload_with_packages(['-i']) stdin = json.dumps(payload) if sys.version_info[0] < 3: stdin = stdin.decode() monkeypatch.setattr('sys.stdin', io.StringIO(stdin)) args = cli.parse_args( ['--config', '/dev/null', '-s', DEBMONITOR_SERVER, '-f', '-']) mocked_requests.register_uri('POST', DEBMONITOR_IMAGE_UPDATE_URL, status_code=201) exit_code = cli.main(args) assert not mocked_getfqdn.called assert mocked_requests.called assert exit_code == 0 assert mocked_requests.last_request.json() == payload
def test_main_dpkg_hook(mocked_getfqdn, mocked_requests): """Calling main() with -g should parse the input for a Dpkg::Pre-Install-Pkgs hook and send the update.""" args = cli.parse_args(['-s', DEBMONITOR_SERVER, '-g']) input_lines = _get_dpkg_hook_preamble(3) + APT_HOOK_LINES[3][0:2] mocked_requests.register_uri('POST', DEBMONITOR_UPDATE_URL, status_code=201) mocked_apt.cache.Cache().__getitem__.return_value = AptPackage( name='package-name', is_installed=False, installed=None, candidate=AptPkgVersion(source_name='package-name', version='1.0.0-1')) exit_code = cli.main(args, input_lines=input_lines) mocked_getfqdn.assert_called_once_with() assert mocked_requests.called assert exit_code == 0 assert mocked_requests.last_request.json() == _get_payload_with_packages( ['-g'])
def test_main_no_packages(mocked_getfqdn, mocked_requests): """Calling main() if there are no updates should success sending an empty update to the DebMonitor server.""" args = cli.parse_args(['--config', DEBMONITOR_CLIENT_CONFIG_OK, '-u']) mocked_requests.register_uri('POST', DEBMONITOR_UPDATE_URL, status_code=201) _reset_apt_caches(empty=True) with mock.patch('{mod}.open'.format(mod=BUILTINS), mock.mock_open(read_data=OS_RELEASE), create=True) as mocked_open: exit_code = cli.main(args) assert mock.call(cli.OS_RELEASE_FILE, mode='r') in mocked_open.mock_calls mocked_getfqdn.assert_called_once_with() assert mocked_requests.called assert exit_code == 0 assert mocked_requests.last_request.json() == _get_payload_with_packages( ['empty'])
def test_main_update_ok(mocked_getfqdn, mocked_requests, caplog): """Calling main() whit --update that succeed should update the CLI script.""" caplog.set_level(logging.INFO) args = cli.parse_args( ['--config', DEBMONITOR_CLIENT_CONFIG_OK, '--update']) mocked_requests.register_uri('POST', DEBMONITOR_UPDATE_URL, status_code=201) mocked_requests.register_uri( 'HEAD', DEBMONITOR_CLIENT_URL, status_code=200, headers={cli.CLIENT_VERSION_HEADER: tests_deb.CLIENT_VERSION}) mocked_requests.register_uri('GET', DEBMONITOR_CLIENT_URL, status_code=200, text=tests_deb.CLIENT_BODY_DUMMY_1, headers={ cli.CLIENT_VERSION_HEADER: tests_deb.CLIENT_VERSION, cli.CLIENT_CHECKSUM_HEADER: tests_deb.CLIENT_CHECKSUM_DUMMY_1 }) _reset_apt_caches() with mock.patch('{mod}.open'.format(mod=BUILTINS), mock.mock_open(read_data=OS_RELEASE), create=True) as mocked_open: exit_code = cli.main(args) assert mock.call(cli.OS_RELEASE_FILE, mode='r') in mocked_open.mock_calls assert mock.call(os.path.realpath(cli.__file__), mode='w') in mocked_open.mock_calls mocked_handler = mocked_open() mocked_handler.write.assert_called_once_with( tests_deb.CLIENT_BODY_DUMMY_1) assert mocked_requests.called mocked_getfqdn.assert_called_once_with() assert exit_code == 0 assert 'Successfully self-updated DebMonitor CLI' in caplog.text
def test_main_wrong_http_code(params, mocked_getfqdn, mocked_requests, caplog): """Calling main() when the DebMonitor server returns a wrong HTTP code should return 1.""" args = cli.parse_args(['--config', DEBMONITOR_CLIENT_CONFIG_OK] + params) mocked_requests.register_uri('POST', DEBMONITOR_HOST_UPDATE_URL, status_code=400) _reset_apt_caches() with mock.patch('builtins.open', mock.mock_open(read_data=OS_RELEASE), create=True) as mocked_open: exit_code = cli.main(args) assert mock.call(cli.OS_RELEASE_FILE, mode='r') in mocked_open.mock_calls mocked_getfqdn.assert_called_once_with() assert mocked_requests.called assert exit_code == 1 assert mocked_requests.last_request.json() == _get_payload_with_packages( params) assert 'Failed to send the update to the DebMonitor server' in caplog.text
def test_main_image(mocked_getfqdn, mocked_requests): """Calling main() with an image should send the updates to the DebMonitor server.""" args = cli.parse_args( ['--config', '/dev/null', '-s', DEBMONITOR_SERVER, '-i', IMAGENAME]) mocked_requests.register_uri('POST', DEBMONITOR_IMAGE_UPDATE_URL, status_code=201) _reset_apt_caches() with mock.patch('builtins.open', mock.mock_open(read_data=OS_RELEASE), create=True) as mocked_open: exit_code = cli.main(args) assert mock.call(cli.OS_RELEASE_FILE, mode='r') in mocked_open.mock_calls assert not mocked_getfqdn.called assert mocked_requests.called assert exit_code == 0 assert mocked_requests.last_request.json() == _get_payload_with_packages( ['-i'])
def test_main(params, mocked_getfqdn, mocked_requests): """Calling main() should send the updates to the DebMonitor server with the above parameters.""" args = cli.parse_args(['--config', '/dev/null', '-s', DEBMONITOR_SERVER] + params) mocked_requests.register_uri('POST', DEBMONITOR_UPDATE_URL, status_code=201) _reset_apt_caches() with mock.patch('{mod}.open'.format(mod=BUILTINS), mock.mock_open(read_data=OS_RELEASE), create=True) as mocked_open: exit_code = cli.main(args) assert mock.call(cli.OS_RELEASE_FILE, mode='r') in mocked_open.mock_calls mocked_getfqdn.assert_called_once_with() assert mocked_requests.called assert exit_code == 0 assert mocked_requests.last_request.json() == _get_payload_with_packages( params)
def test_main_update_fail(mocked_getfqdn, mocked_requests, caplog): """Calling main() whit --update that fails the update should log the error and continue.""" args = cli.parse_args( ['--config', DEBMONITOR_CLIENT_CONFIG_OK, '--update']) mocked_requests.register_uri('POST', DEBMONITOR_UPDATE_URL, status_code=201) mocked_requests.register_uri('HEAD', DEBMONITOR_CLIENT_URL, status_code=500) _reset_apt_caches() with mock.patch('{mod}.open'.format(mod=BUILTINS), mock.mock_open(read_data=OS_RELEASE), create=True) as mocked_open: exit_code = cli.main(args) assert mock.call(cli.OS_RELEASE_FILE, mode='r') in mocked_open.mock_calls assert mocked_requests.called mocked_getfqdn.assert_called_once_with() assert exit_code == 0 assert 'Unable to self-update this script' in caplog.text
def test_parse_args_key_with_no_cert(capsys): """Calling parse_args with -k/--key but without -c/--cert should raise an error.""" with pytest.raises(SystemExit): cli.parse_args(['-n', '-k', 'cert.key']) _, err = capsys.readouterr() assert 'argument -c/--cert is required when -k/--key is set' in err
def test_parse_args_missing_server(capsys): """Calling parse_args without a -s/--server parameter should raise an error if -n/--dry-run is not set.""" with pytest.raises(SystemExit): cli.parse_args([]) _, err = capsys.readouterr() assert 'argument -s/--server is required unless -n/--dry-run is set' in err
def test_parse_args_missing_server_dry_run(): """Calling parse_args without a -s/--server parameter should not raise an error if -n/--dry-run is set.""" args = cli.parse_args(['-n']) assert args.dry_run
def test_parse_args_update_no_ca(capsys): """Calling parse_args with --update but without --ca should raise an error.""" with pytest.raises(SystemExit): cli.parse_args(['-n', '--update']) _, err = capsys.readouterr() assert 'argument --ca is required when --update is set' in err
def test_parse_args_update_ca(capsys): """Calling parse_args with --update and --ca should set verify to the ca path.""" args = cli.parse_args( ['-n', '--update', '--ca', DEBMONITOR_CLIENT_CA_BUNDLE]) assert args.ca == DEBMONITOR_CLIENT_CA_BUNDLE assert args.verify == DEBMONITOR_CLIENT_CA_BUNDLE
def test_parse_args_no_ca(capsys): """Calling parse_args without --ca should set verify to True.""" args = cli.parse_args(['-n']) assert args.ca is None assert args.verify is True
def test_parse_args_upgradable_dpkg(capsys): """Calling parse_args with both -u/--upgradable and -g/--dpkg should raise an error.""" with pytest.raises(SystemExit): cli.parse_args(['-n', '-u', '-g']) _, err = capsys.readouterr() assert 'argument -u/--upgradable and -g/--dpkg-hook are mutually exclusive' in err