def test_csv_values_recovery_options(self): """ Simple test for recovery_options values: '' and get-wal test case global value: recovery_options = '' expected: recovery_options = None test case global value: recovery_options = 'get-wal' expected: recovery_options = empty RecoveryOptions obj """ # Build configuration with empty recovery_options c = build_config_from_dicts({'recovery_options': ''}, None) main = c.get_server('main') expected = build_config_dictionary({ 'config': c, 'recovery_options': RecoveryOptions('', '', ''), }) assert main.__dict__ == expected # Build configuration with recovery_options set to get-wal c = build_config_from_dicts({'recovery_options': 'get-wal'}, None) main = c.get_server('main') expected = build_config_dictionary({ 'config': c, 'recovery_options': RecoveryOptions('get-wal', '', ''), }) assert main.__dict__ == expected
def test_config(self): """ Test for a basic configuration object construction """ fp = StringIO(TEST_CONFIG.format(**os.environ)) c = Config(fp) main = c.get_server('main') # create the expected dictionary expected = build_config_dictionary({ 'config': main.config, 'compression': 'gzip', 'last_backup_maximum_age': timedelta(1), 'last_backup_minimum_size': 1048576, 'last_wal_maximum_age': timedelta(hours=1), 'retention_policy': 'redundancy 3', 'reuse_backup': 'link', 'description': 'Main PostgreSQL Database', 'ssh_command': 'ssh -c arcfour -p 22 [email protected]', 'wal_retention_policy': 'base', 'custom_compression_filter': 'bzip2 -c -9', 'wals_directory': 'wals', 'custom_decompression_filter': 'bzip2 -c -d' }) assert main.__dict__ == expected web = c.get_server('web') # create the expected dictionary expected = build_config_dictionary({ 'config': web.config, 'backup_directory': '/some/barman/home/web', 'basebackups_directory': '/some/barman/home/web/base', 'compression': None, 'conninfo': 'host=web01 user=postgres port=5432', 'description': 'Web applications database', 'incoming_wals_directory': '/some/barman/home/web/incoming', 'name': 'web', 'reuse_backup': None, 'retention_policy': 'redundancy 2', 'wals_directory': '/some/barman/home/web/wals', 'wal_retention_policy': 'base', 'last_backup_maximum_age': timedelta(1), 'last_backup_minimum_size': 1048576, 'last_wal_maximum_age': timedelta(hours=1), 'ssh_command': 'ssh -I ~/.ssh/web01_rsa -c arcfour ' '-p 22 postgres@web01', 'streaming_conninfo': 'host=web01 user=postgres port=5432', 'streaming_wals_directory': '/some/barman/home/web/streaming', 'errors_directory': '/some/barman/home/web/errors', }) assert web.__dict__ == expected
def test_config(self): """ Test for a basic configuration object construction """ fp = StringIO(TEST_CONFIG.format(**os.environ)) c = Config(fp) main = c.get_server('main') # create the expected dictionary expected = build_config_dictionary({ 'config': main.config, 'compression': 'gzip', 'last_backup_maximum_age': timedelta(1), 'retention_policy': 'redundancy 3', 'reuse_backup': 'link', 'description': 'Main PostgreSQL Database', 'ssh_command': 'ssh -c arcfour -p 22 [email protected]', 'wal_retention_policy': 'base', 'custom_compression_filter': 'bzip2 -c -9', 'wals_directory': 'wals', 'custom_decompression_filter': 'bzip2 -c -d', 'backup_method': 'rsync' }) assert main.__dict__ == expected web = c.get_server('web') # create the expected dictionary expected = build_config_dictionary({ 'config': web.config, 'backup_directory': '/some/barman/home/web', 'basebackups_directory': '/some/barman/home/web/base', 'compression': None, 'conninfo': 'host=web01 user=postgres port=5432', 'description': 'Web applications database', 'incoming_wals_directory': '/some/barman/home/web/incoming', 'name': 'web', 'reuse_backup': None, 'retention_policy': 'redundancy 2', 'wals_directory': '/some/barman/home/web/wals', 'wal_retention_policy': 'base', 'last_backup_maximum_age': timedelta(1), 'ssh_command': 'ssh -I ~/.ssh/web01_rsa -c arcfour ' '-p 22 postgres@web01', 'streaming_conninfo': 'host=web01 user=postgres port=5432', 'streaming_wals_directory': '/some/barman/home/web/streaming', 'errors_directory': '/some/barman/home/web/errors', }) assert web.__dict__ == expected
def test_server_conflict_paths(self): """ Test for the presence of conflicting paths for a server """ # Build a configuration with conflicts: # basebackups_directory = /some/barman/home/main/wals # wals_directory = /some/barman/home/main/wals c = build_config_from_dicts(main_conf={ 'archiver': 'on', 'basebackups_directory': '/some/barman/home/main/wals', 'description': ' Text with quotes ', }) main = c.get_server('main') # create the expected dictionary expected = build_config_dictionary({ 'config': main.config, 'disabled': True, 'basebackups_directory': '/some/barman/home/main/wals', 'msg_list': [ 'Conflicting path: wals_directory=/some/barman/home/main/wals ' 'conflicts with \'basebackups_directory\' ' 'for server \'main\''], 'description': 'Text with quotes', }) assert main.__dict__ == expected
def test_csv_values_global_concurrent(self): """ test case global value: backup_options = concurrent_backup expected: backup_options = concurrent_backup Simple test for concurrent_backup option parsing """ # add backup_options to minimal configuration string c = build_config_from_dicts(global_conf={ 'archiver': 'on', 'backup_options': BackupOptions.CONCURRENT_BACKUP }, main_conf=None) main = c.get_server('main') # create the expected dictionary expected = build_config_dictionary({ 'config': main.config, 'backup_options': set(['concurrent_backup']), 'backup_method': 'rsync', }) assert main.__dict__ == expected
def test_csv_values_invalid_server_value(self, out_mock): """ test case global: backup_options = exclusive_backup server: backup_options = none_of_your_business result = backup_options = exclusive_backup The 'none_of_your_business' value on server section, is not an allowed value for the BackupOptions class, We expect to the config builder to fallback to the global 'exclusive_backup' value """ # add backup_options to minimal configuration string c = build_config_from_dicts( global_conf={ 'archiver': 'on', 'backup_options': BackupOptions.EXCLUSIVE_BACKUP }, main_conf={'backup_options': 'none_of_your_business'}) main = c.get_server('main') # create the expected dictionary expected = build_config_dictionary({ 'config': main.config, 'backup_options': set([BackupOptions.EXCLUSIVE_BACKUP]) }) assert main.__dict__ == expected # use the mocked output class to verify the presence of the warning # for a bad configuration parameter out_mock.warning.assert_called_with( "Ignoring invalid configuration " "value '%s' for key %s in %s: %s", 'none_of_your_business', 'backup_options', '[main] section', mock.ANY)
def test_server_conflict_paths(self): """ Test for the presence of conflicting paths for a server """ # Build a configuration with conflicts: # basebackups_directory = /some/barman/home/main/wals # wals_directory = /some/barman/home/main/wals c = build_config_from_dicts( main_conf={ 'archiver': 'on', 'basebackups_directory': '/some/barman/home/main/wals', 'description': ' Text with quotes ', }) main = c.get_server('main') # create the expected dictionary expected = build_config_dictionary({ 'config': main.config, 'disabled': True, 'basebackups_directory': '/some/barman/home/main/wals', 'msg_list': [ 'Conflicting path: wals_directory=/some/barman/home/main/wals ' 'conflicts with \'basebackups_directory\' ' 'for server \'main\'' ], 'description': 'Text with quotes', }) assert main.__dict__ == expected
def test_csv_values_global_conflict(self, out_mock): """ test case global value: backup_options = exclusive_backup, concurrent_backup server value: backup_options = expected: backup_options = exclusive_backup Empty value is not allowed in BackupOptions class, so we expect the configuration parser to fall back to the global value. The global backup_options holds conflicting parameters, so we expect the config builder to fall back to ignore de directive. :param out_mock: Mock the output """ # build a string with conflicting values conflict = "%s, %s" % (BackupOptions.EXCLUSIVE_BACKUP, BackupOptions.CONCURRENT_BACKUP) # add backup_options to minimal configuration string c = build_config_from_dicts(global_conf={ 'archiver': 'on', 'backup_options': conflict }, main_conf=None) main = c.get_server('main') # create the expected dictionary expected = build_config_dictionary({'config': main.config}) assert main.__dict__ == expected # use the mocked output class to verify the presence of the warning # for a bad configuration parameter out_mock.warning.assert_called_with( "Ignoring invalid configuration " "value '%s' for key %s in %s: %s", 'exclusive_backup, ' 'concurrent_backup', 'backup_options', '[barman] section', mock.ANY)
def test_csv_values_invalid_server_value(self, out_mock): """ test case global: backup_options = exclusive_backup server: backup_options = none_of_your_business result = backup_options = exclusive_backup The 'none_of_your_business' value on server section, is not an allowed value for the BackupOptions class, We expect to the config builder to fallback to the global 'exclusive_backup' value """ # add backup_options to minimal configuration string c = build_config_from_dicts( {'backup_options': BackupOptions.EXCLUSIVE_BACKUP}, {'backup_options': 'none_of_your_business'}) main = c.get_server('main') # create the expected dictionary expected = build_config_dictionary({'config': main.config}) assert main.__dict__ == expected # use the mocked output class to verify the presence of the warning # for a bad configuration parameter out_mock.warning.assert_called_with("Invalid configuration value '%s' " "for key %s in %s: %s", None, 'backup_options', '[main] section', mock.ANY)
def test_csv_values_multikey_invalid_server_value(self, out_mock): """ test case global: backup_options = concurrent_backup server: backup_options = exclusive_backup, none_of_your_business result = backup_options = concurrent_backup the 'none_of_your_business' value on server section invalidates the whole csv string, because is not an allowed value of the BackupOptions class. We expect to fallback to the global 'concurrent_backup' value. """ # build a string with a wrong value wrong_parameters = "%s, %s" % (BackupOptions.EXCLUSIVE_BACKUP, 'none_of_your_business') # add backup_options to minimal configuration string c = build_config_from_dicts( {'backup_options': BackupOptions.CONCURRENT_BACKUP}, {'backup_options': wrong_parameters}) main = c.get_server('main') # create the expected dictionary expected = build_config_dictionary({ 'config': main.config, 'backup_options': set(['concurrent_backup']), }) assert main.__dict__ == expected # use the mocked output class to verify the presence of the warning # for a bad configuration parameter out_mock.warning.assert_called_with("Invalid configuration value '%s' " "for key %s in %s: %s", None, 'backup_options', '[main] section', mock.ANY)
def test_csv_values_global_conflict(self, out_mock): """ test case global value: backup_options = exclusive_backup, concurrent_backup server value: backup_options = expected: backup_options = exclusive_backup Empty value is not allowed in BackupOptions class, so we expect the configuration parser to fall back to the global value. The global backup_options holds conflicting parameters, so we expect the config builder to fall back to ignore de directive. :param out_mock: Mock the output """ # build a string with conflicting values conflict = "%s, %s" % (BackupOptions.EXCLUSIVE_BACKUP, BackupOptions.CONCURRENT_BACKUP) # add backup_options to minimal configuration string c = build_config_from_dicts( {'backup_options': conflict}, None) main = c.get_server('main') # create the expected dictionary expected = build_config_dictionary({'config': main.config}) assert main.__dict__ == expected # use the mocked output class to verify the presence of the warning # for a bad configuration parameter out_mock.warning.assert_called_with("Invalid configuration value '%s' " "for key %s in %s: %s", None, 'backup_options', '[barman] section', mock.ANY)
def test_interpolation(self): """ Basic interpolation test """ fp = StringIO(MINIMAL_CONFIG) c = Config(fp) main = c.get_server('main') # create the expected dictionary expected = build_config_dictionary({'config': main.config}) assert main.__dict__ == expected
def test_interpolation(self): """ Basic interpolation test """ fp = StringIO(MINIMAL_CONFIG.format(**os.environ)) c = Config(fp) main = c.get_server('main') # create the expected dictionary expected = build_config_dictionary({'config': main.config}) assert main.__dict__ == expected
def test_manage_server_command(self, monkeypatch, capsys): """ Test manage_server_command method checking the various types of error output :param monkeypatch monkeypatch: pytest patcher """ # Build a server with a config with path conflicts monkeypatch.setattr( barman, "__config__", build_config_from_dicts( main_conf=build_config_dictionary( { "wals_directory": "/some/barman/home/main/wals", "basebackups_directory": "/some/barman/home/main/wals", "archiver": "on", } ) ), ) server = Server(barman.__config__.get_server("main")) # Test a not blocking WARNING message manage_server_command(server) out, err = capsys.readouterr() # Expect an ERROR message because of conflicting paths assert "ERROR: Conflicting path" in err # Build a server with a config without path conflicts monkeypatch.setattr(barman, "__config__", build_config_from_dicts()) server = Server(barman.__config__.get_server("main")) # Set the server as not active server.config.active = False # Request to treat inactive as errors to_be_executed = manage_server_command(server, inactive_is_error=True) out, err = capsys.readouterr() # Expect a ERROR message because of a not active server assert "ERROR: Inactive server" in err assert not to_be_executed # Request to treat inactive as warning to_be_executed = manage_server_command(server, inactive_is_error=False) out, err = capsys.readouterr() # Expect no error whatsoever assert err == "" assert not to_be_executed
def test_csv_values_global_concurrent(self): """ test case global value: backup_options = concurrent_backup expected: backup_options = concurrent_backup Simple test for concurrent_backup option parsing """ # add backup_options to minimal configuration string c = build_config_from_dicts( {'backup_options': BackupOptions.CONCURRENT_BACKUP}, None) main = c.get_server('main') # create the expected dictionary expected = build_config_dictionary({ 'config': main.config, 'backup_options': set(['concurrent_backup']), }) assert main.__dict__ == expected
def test_csv_values_global_exclusive(self): """ test case global value: backup_options = exclusive_backup server value: backup_options = expected: backup_options = exclusive_backup Empty value is not allowed in BackupOptions class, so we expect the configuration parser to fall back to the global value. """ # add backup_options configuration to minimal configuration string c = build_config_from_dicts( {'backup_options': BackupOptions.EXCLUSIVE_BACKUP}, {'backup_options': ''}) main = c.get_server('main') # create the expected dictionary expected = build_config_dictionary({'config': main.config}) assert main.__dict__ == expected
def test_manage_server_command(self, monkeypatch, capsys): """ Test manage_server_command method checking the various types of error output :param monkeypatch monkeypatch: pytest patcher """ # Build a server with a config with path conflicts monkeypatch.setattr(barman, '__config__', build_config_from_dicts( main_conf=build_config_dictionary({ 'wals_directory': '/some/barman/home/main/wals', 'basebackups_directory': '/some/barman/home/main/wals', 'archiver': 'on', }))) server = Server(barman.__config__.get_server('main')) # Test a not blocking WARNING message manage_server_command(server) out, err = capsys.readouterr() # Expect an ERROR message because of conflicting paths assert 'ERROR: Conflicting path' in err # Build a server with a config without path conflicts monkeypatch.setattr(barman, '__config__', build_config_from_dicts()) server = Server(barman.__config__.get_server('main')) # Set the server as not active server.config.active = False # Request to treat inactive as errors to_be_executed = manage_server_command(server, inactive_is_error=True) out, err = capsys.readouterr() # Expect a ERROR message because of a not active server assert 'ERROR: Inactive server' in err assert not to_be_executed # Request to treat inactive as warning to_be_executed = manage_server_command(server, inactive_is_error=False) out, err = capsys.readouterr() # Expect no error whatsoever assert err == '' assert not to_be_executed
def test_primary_ssh_command(self): """ test command at server and global level test case 1: global: Nothing server: "*****@*****.**" expected: "*****@*****.**" test case 2: global: "*****@*****.**" server: Nothing expected: "*****@*****.**" test case 3: global: "*****@*****.**" server: "*****@*****.**" expected: "*****@*****.**" """ # test case 1 # primary_ssh_command set only for server main c = build_config_from_dicts(global_conf=None, main_conf={ 'primary_ssh_command': '*****@*****.**', }) main = c.get_server('main') expected = build_config_dictionary({ 'config': c, 'primary_ssh_command': '*****@*****.**', }) assert main.__dict__ == expected # test case 2 # primary_ssh_command set only globally c = build_config_from_dicts(global_conf={ 'primary_ssh_command': '*****@*****.**', }, main_conf=None) main = c.get_server('main') expected = build_config_dictionary({ 'config': c, 'primary_ssh_command': '*****@*****.**', }) assert main.__dict__ == expected # test case 3 # primary_ssh_command set both globally and on server main c = build_config_from_dicts(global_conf={ 'primary_ssh_command': '*****@*****.**', }, main_conf={ 'primary_ssh_command': '*****@*****.**', }) main = c.get_server('main') expected = build_config_dictionary({ 'config': c, 'primary_ssh_command': '*****@*****.**', }) assert main.__dict__ == expected