def test_volumes_v2_using_v1_format(call_read_config, basic_dog_config_with_image, tmp_path, capsys): update_dog_config( tmp_path, {DOG: { AUTO_MOUNT: False, 'dog-config-file-version': '2' }}) update_dog_config(tmp_path, {VOLUMES: {'/foo': '/bar'}}) with pytest.raises(SystemExit): call_read_config() captured = capsys.readouterr() assert '"/foo=/bar" found in volumes' in captured.err
def test_dog_is_too_old_for_minimum_version(call_read_config, basic_dog_config_with_image, tmp_path, capsys): update_dog_config(tmp_path, {DOG: { MINIMUM_VERSION: ACTUAL_DOG_VERSION + 5 }}) with pytest.raises(SystemExit): call_read_config() captured = capsys.readouterr() expected_error = ( f'Minimum version required ({ACTUAL_DOG_VERSION + 5}) is greater than your' f' dog version ({ACTUAL_DOG_VERSION}) - please upgrade dog') assert expected_error in captured.err
def test_variable_subst(call_read_config, basic_v2_dog_config_with_image, tmp_path, capsys): update_dog_config( tmp_path, {DOG: { 'test1': 'foo', 'test2': '${test1}_bar', '${test1}': 'baz' }}) config = call_read_config() assert config['test1'] == 'foo' assert config['test2'] == 'foo_bar' assert config['foo'] == 'baz' assert '${test1}' not in config
def test_subst_for_usb_devices(call_read_config, basic_v2_dog_config_with_image, tmp_path): update_dog_config( tmp_path, { 'usb': { 'vendor1': 'abcd', 'product1': '4242' }, USB_DEVICES: { 'dev1': '${usb_vendor1}:${usb_product1}' }, }, ) assert call_read_config()[USB_DEVICES] == {'dev1': 'abcd:4242'}
def test_volumes_v1_conditional(call_read_config, basic_dog_config_with_image, tmp_path, monkeypatch): update_dog_config( tmp_path, { DOG: { AUTO_MOUNT: False }, VOLUMES: { '?/test_path': str(tmp_path / 'not_there'), '/there': str(tmp_path / 'there'), }, }, ) monkeypatch.setattr(os.path, 'exists', lambda x: x == str(tmp_path / 'there')) assert call_read_config()[VOLUMES] == {'/there': str(tmp_path / 'there')}
def test_volumes_v2_conditional(call_read_config, basic_dog_config_with_image, tmp_path, monkeypatch): update_dog_config( tmp_path, { DOG: { AUTO_MOUNT: False, 'dog-config-file-version': '2' }, VOLUMES: { 'vol1?': f'{tmp_path / "not_there"}:/test_path', 'vol2': f'{tmp_path / "there"}:/there', }, }, ) monkeypatch.setattr(os.path, 'exists', lambda x: x == str(tmp_path / 'there')) assert call_read_config()[VOLUMES] == {'/there': str(tmp_path / 'there')}
def test_volumes_from( basic_dog_config_with_image, call_main, tmp_path, mock_execvp, home_temp_dir, volumes_from: dict, ): update_dog_config(tmp_path, {VOLUMES_FROM: volumes_from}) call_main('echo', 'foo') args_left = assert_docker_std_cmdline(mock_execvp) args_left = assert_docker_image_and_cmd_inside_docker( args_left, 'debian:latest', ['echo', 'foo'] ) args_left = assert_workdir_param(args_left, get_workdir(tmp_path)) args_left = std_assert_hostname_param(args_left) args_left = std_assert_interactive(args_left) args_left = std_assert_env_params(home_temp_dir, args_left) args_left = std_assert_volume_params(tmp_path, args_left) args_left = assert_volumes_from_params(args_left, volumes_from.keys()) assert args_left == []
def test_network( basic_dog_config_with_image, call_main, tmp_path, mock_execvp, home_temp_dir, network: str, ): update_dog_config(tmp_path, {DOG: {NETWORK: network}}) call_main('echo', 'foo') args_left = assert_docker_std_cmdline(mock_execvp) args_left = assert_docker_image_and_cmd_inside_docker( args_left, 'debian:latest', ['echo', 'foo'] ) args_left = assert_workdir_param(args_left, get_workdir(tmp_path)) args_left = std_assert_hostname_param(args_left) args_left = assert_network_param(args_left, network) args_left = std_assert_volume_params(tmp_path, args_left) args_left = std_assert_interactive(args_left) args_left = std_assert_env_params(home_temp_dir, args_left) assert args_left == []
def test_subst_for_values_from(call_read_config, basic_v2_dog_config_with_image, tmp_path): update_dog_config( tmp_path, { DOG: { 'registry': 'my.example.com/my-custom-dockers' }, 'tool-versions': { 'my_tool': '220301.1' }, VOLUMES_FROM: { 'my_tool_${tool-versions_my_tool}': ('${registry}/my_tool:${tool-versions_my_tool}') }, }, ) assert call_read_config()[VOLUMES_FROM] == { 'my_tool_220301.1': 'my.example.com/my-custom-dockers/my_tool:220301.1' }
def test_versions_in_included_file(call_read_config, basic_dog_config_with_image, tmp_path, capsys): empty_config_file = 'empty.config' update_dog_config(tmp_path, {DOG: {INCLUDE_DOG_CONFIG: empty_config_file}}) update_dog_config(tmp_path / empty_config_file, {DOG: {}}) with pytest.raises(SystemExit): call_read_config() captured = capsys.readouterr() expected_error = ('Do not know how to handle a dog.config file without' ' dog-config-file-version specified') assert expected_error in captured.err update_dog_config( tmp_path / empty_config_file, { DOG: { 'dog-config-file-version': '1', MINIMUM_VERSION: ACTUAL_DOG_VERSION + 5, } }, ) with pytest.raises(SystemExit): call_read_config() captured = capsys.readouterr() expected_error = ( f'Minimum version required ({ACTUAL_DOG_VERSION + 5}) is greater than your' f' dog version ({ACTUAL_DOG_VERSION}) - please upgrade dog') assert expected_error in captured.err
def test_user_sections(call_read_config, basic_dog_config_with_image, tmp_path): update_dog_config(tmp_path, {'vars': {'test1': 'foo', 'test2': 'bar'}}) config = call_read_config() assert config['vars_test1'] == 'foo' assert config['vars_test2'] == 'bar' update_dog_config(tmp_path, { 'vars': { 'test3': 42 }, 'my-vars': { 'test': 'foobar' } }) config = call_read_config() assert config['vars_test1'] == 'foo' assert config['vars_test2'] == 'bar' assert config['vars_test3'] == '42' assert config['my-vars_test'] == 'foobar'
def test_simple_docker_cmdline( basic_dog_config, call_main, tmp_path, mock_execvp, home_temp_dir, use_podman: bool, ): update_dog_config( tmp_path, { DOG: { IMAGE: 'ghcr.io/rasmus-toftdahl-olesen/dog/centos-for-dog', USE_PODMAN: use_podman, } }, ) call_main('echo', 'foo') args_left = assert_docker_std_cmdline(mock_execvp, use_podman=use_podman) args_left = assert_docker_image_and_cmd_inside_docker( args_left, 'ghcr.io/rasmus-toftdahl-olesen/dog/centos-for-dog', ['echo', 'foo'] ) args_left = assert_workdir_param(args_left, get_workdir(tmp_path)) args_left = std_assert_hostname_param(args_left) args_left = std_assert_volume_params(tmp_path, args_left) args_left = std_assert_interactive(args_left) args_left = std_assert_env_params(home_temp_dir, args_left) assert args_left == []
def test_device( basic_dog_config_with_image, call_main, tmp_path, mock_execvp, home_temp_dir, monkeypatch, device: str, usb_devices: dict, expected_device_param: str, ): def test_path(x): assert x == usb_devices['dev1'] if device: usb_dev_paths = expected_device_param[1:] else: usb_dev_paths = expected_device_param return usb_dev_paths monkeypatch.setattr(UsbDevices, 'get_bus_paths', lambda _, x: test_path(x)) update_dog_config(tmp_path, {USB_DEVICES: usb_devices}) if device: update_dog_config(tmp_path, {DOG: {DEVICE: device}}) call_main('echo', 'foo') args_left = assert_docker_std_cmdline(mock_execvp) args_left = assert_docker_image_and_cmd_inside_docker( args_left, 'debian:latest', ['echo', 'foo'] ) args_left = assert_workdir_param(args_left, get_workdir(tmp_path)) args_left = std_assert_hostname_param(args_left) args_left = std_assert_volume_params(tmp_path, args_left) args_left = std_assert_interactive(args_left) args_left = std_assert_env_params(home_temp_dir, args_left) args_left = assert_device_params(args_left, expected_device_param) assert args_left == []
def test_usb_devices(call_read_config, basic_dog_config_with_image, tmp_path, monkeypatch): assert call_read_config()[USB_DEVICES] == {} assert DEVICE not in call_read_config() dev1 = '1111:aaaa' dev2 = '2222:aaaa' dev3 = 'cccc:dddd' usb_dev_path1 = ['/dev/bus/usb/001/004'] usb_dev_path2 = ['/dev/bus/usb/002/013'] usb_dev_path3 = ['/dev/bus/usb/002/010', '/dev/bus/usb/001/002'] def test_path(x): if x == dev1: return usb_dev_path1 elif x == dev2: return usb_dev_path2 elif x == dev3: return usb_dev_path3 assert False monkeypatch.setattr(UsbDevices, 'get_bus_paths', lambda _, x: test_path(x)) update_dog_config(tmp_path, {USB_DEVICES: {'dev1': dev1}}) assert call_read_config()[DEVICE] == usb_dev_path1 update_dog_config(tmp_path, {USB_DEVICES: {'dev2': dev2}}) assert call_read_config()[DEVICE] == usb_dev_path1 + usb_dev_path2 update_dog_config(tmp_path, {USB_DEVICES: {'dev3': dev3}}) assert call_read_config( )[DEVICE] == usb_dev_path1 + usb_dev_path2 + usb_dev_path3 my_dev = '/dev/my_strange_dev' update_dog_config(tmp_path, {DOG: {DEVICE: my_dev}}) assert (call_read_config()[DEVICE] == [f'{my_dev}'] + usb_dev_path1 + usb_dev_path2 + usb_dev_path3)
def test_multi_level_include(call_read_config, basic_dog_config_with_image, tmp_path): inc_config_1 = tmp_path / 'config1.config' inc_config_2 = tmp_path / 'config2.config' update_dog_config(tmp_path, {DOG: {INCLUDE_DOG_CONFIG: str(inc_config_1)}}) update_dog_config( inc_config_1, { DOG: { 'dog-config-file-version': '1', INCLUDE_DOG_CONFIG: str(inc_config_2) } }, ) update_dog_config(inc_config_2, {DOG: {'dog-config-file-version': '1'}}) assert INCLUDE_DOG_CONFIG not in call_read_config()
def test_include_with_path(call_read_config, basic_dog_config_with_image, tmp_path, tmp_path_factory): test_dir = tmp_path_factory.mktemp('test_dir') empty_config_file = test_dir / 'empty.config' update_dog_config(tmp_path, {DOG: { INCLUDE_DOG_CONFIG: str(empty_config_file) }}) update_dog_config(empty_config_file, {DOG: { 'dog-config-file-version': '1' }}) assert INCLUDE_DOG_CONFIG not in call_read_config() relative_path = empty_config_file.relative_to(tmp_path.parent) update_dog_config(tmp_path, {DOG: { INCLUDE_DOG_CONFIG: f'../{relative_path}' }}) assert INCLUDE_DOG_CONFIG not in call_read_config()
def test_network_in_dog_config(call_read_config, basic_dog_config_with_image, tmp_path, network: str): update_dog_config(tmp_path, {DOG: {NETWORK: network}}) assert call_read_config()[NETWORK] == network
def user_config_file(home_temp_dir, config): conf_file = home_temp_dir / ('.' + CONFIG_FILE) update_dog_config(conf_file, config)
def test_include_config_order(call_read_config, basic_dog_config_with_image, tmp_path, home_temp_dir): user_config_file( home_temp_dir, { DOG: { 'dog-config-file-version': '1', 'user1': 'user1', 'user_common': 'user1', 'global_common': 'user1', INCLUDE_DOG_CONFIG: 'user2.config', } }, ) update_dog_config( home_temp_dir / 'user2.config', { DOG: { 'dog-config-file-version': 1, 'user2': 'user2', 'user_common': 'user2', 'global_common': 'user2', } }, ) assert call_read_config()['user1'] == 'user1' assert call_read_config()['user2'] == 'user2' assert call_read_config()['user_common'] == 'user1' assert call_read_config()['global_common'] == 'user1' update_dog_config( tmp_path, { DOG: { INCLUDE_DOG_CONFIG: 'dog2.config', 'dog': 'dog', 'dog_common': 'dog', 'global_common': 'dog', } }, ) update_dog_config( tmp_path / 'dog2.config', { DOG: { 'dog-config-file-version': 1, 'dog2': 'dog2', 'dog_common': 'dog2', 'global_common': 'dog2', } }, ) assert call_read_config()['user1'] == 'user1' assert call_read_config()['user2'] == 'user2' assert call_read_config()['user_common'] == 'user1' assert call_read_config()['dog'] == 'dog' assert call_read_config()['dog2'] == 'dog2' assert call_read_config()['dog_common'] == 'dog' assert call_read_config()['global_common'] == 'dog'
def test_dog_is_minimum_version_or_newer(call_read_config, basic_dog_config_with_image, tmp_path, minimum_version: int): update_dog_config(tmp_path, {DOG: {MINIMUM_VERSION: minimum_version}}) call_read_config()
def test_volumes_v1(call_read_config, basic_dog_config_with_image, tmp_path, home_temp_dir): update_dog_config(tmp_path, {DOG: {AUTO_MOUNT: False}}) assert call_read_config()[VOLUMES] == {} update_dog_config(tmp_path, {VOLUMES: {'/foo': '/bar'}}) assert call_read_config()[VOLUMES] == {'/foo': '/bar'} update_dog_config(tmp_path, {VOLUMES: {'/Foo': '/bar'}}) assert call_read_config()[VOLUMES] == {'/foo': '/bar'} update_dog_config(tmp_path, {VOLUMES: {'/FOO': '/bar'}}) assert call_read_config()[VOLUMES] == {'/foo': '/bar'} update_dog_config(tmp_path, {VOLUMES: {'/FOO': '/bar', '/foobar': '/baz'}}) assert call_read_config()[VOLUMES] == {'/foo': '/bar', '/foobar': '/baz'} update_dog_config(tmp_path, {VOLUMES: {'$home/.ssh:ro': '~/.ssh'}}) assert call_read_config()[VOLUMES] == { '/foo': '/bar', '/foobar': '/baz', str(home_temp_dir / '.ssh:ro'): str(home_temp_dir / '.ssh'), }
def test_volumes_v2(call_read_config, basic_dog_config_with_image, tmp_path, home_temp_dir): update_dog_config( tmp_path, {DOG: { AUTO_MOUNT: False, 'dog-config-file-version': '2' }}) assert call_read_config()[VOLUMES] == {} update_dog_config(tmp_path, {VOLUMES: {'vol1': '/bar:/foo'}}) assert call_read_config()[VOLUMES] == {'/foo': '/bar'} update_dog_config(tmp_path, {VOLUMES: {'vol1': '/bar:/Foo'}}) assert call_read_config()[VOLUMES] == {'/Foo': '/bar'} update_dog_config(tmp_path, {VOLUMES: {'vol1': '/bar:/FOO'}}) assert call_read_config()[VOLUMES] == {'/FOO': '/bar'} update_dog_config(tmp_path, {VOLUMES: { 'vol1': '/bar:/FOO', 'vol2': '/baz:/foobar' }}) assert call_read_config()[VOLUMES] == {'/FOO': '/bar', '/foobar': '/baz'} update_dog_config(tmp_path, {VOLUMES: {'vol3': '~/.ssh:${home}/.ssh:ro'}}) assert call_read_config()[VOLUMES] == { '/FOO': '/bar', '/foobar': '/baz', str(home_temp_dir / '.ssh:ro'): str(home_temp_dir / '.ssh'), }