def test_check_output_strategy_log(self, caplog): """ Test correct output log :type caplog: pytest_capturelog.CaptureLogFuncArg """ strategy = CheckOutputStrategy() # Expected result OK strategy.result('test_server_one', 'wal_level', True) records = list(caplog.records) assert len(records) == 1 record = records.pop() assert record.msg == \ "Check 'wal_level' succeeded for server 'test_server_one'" assert record.levelname == 'DEBUG' # Expected result FAILED strategy = CheckOutputStrategy() strategy.result('test_server_one', 'wal_level', False) strategy.result('test_server_one', 'backup maximum age', False) records = list(caplog.records) assert len(records) == 3 record = records.pop() assert record.levelname == 'ERROR' assert record.msg == \ "Check 'backup maximum age' failed for server 'test_server_one'" record = records.pop() assert record.levelname == 'ERROR' assert record.msg == \ "Check 'wal_level' failed for server 'test_server_one'"
def test_check_postgres(self, postgres_mock, capsys): """ Test management of check_postgres view output :param postgres_mock: mock get_remote_status function :param capsys: retrieve output from consolle """ postgres_mock.return_value = {'server_txt_version': None} # Create server server = build_real_server() # Case: no reply by PostgreSQL # Expect out: PostgreSQL: FAILED strategy = CheckOutputStrategy() server.check_postgres(strategy) (out, err) = capsys.readouterr() assert out == ' PostgreSQL: FAILED\n' # Case: correct configuration postgres_mock.return_value = {'current_xlog': None, 'archive_command': 'wal to archive', 'pgespresso_installed': None, 'server_txt_version': 'PostgresSQL 9_4', 'data_directory': '/usr/local/postgres', 'archive_mode': 'on', 'wal_level': 'replica'} # Expect out: all parameters: OK # Postgres version >= 9.0 - check wal_level server = build_real_server() server.check_postgres(strategy) (out, err) = capsys.readouterr() assert out == "\tPostgreSQL: OK\n" \ "\twal_level: OK\n" # Postgres version < 9.0 - avoid wal_level check del postgres_mock.return_value['wal_level'] server = build_real_server() server.check_postgres(strategy) (out, err) = capsys.readouterr() assert out == "\tPostgreSQL: OK\n" # Case: wal_level and archive_command values are not acceptable postgres_mock.return_value = {'current_xlog': None, 'archive_command': None, 'pgespresso_installed': None, 'server_txt_version': 'PostgresSQL 9_4', 'data_directory': '/usr/local/postgres', 'archive_mode': 'on', 'wal_level': 'minimal'} # Expect out: some parameters: FAILED strategy = CheckOutputStrategy() server.check_postgres(strategy) (out, err) = capsys.readouterr() assert out == "\tPostgreSQL: OK\n" \ "\twal_level: FAILED (please set it to a higher level " \ "than 'minimal')\n"
def test_check(self, command_mock, capsys): """ Check the ssh connection to a remote server """ backup_manager = build_backup_manager() # Test 1: ssh ok check_strategy = CheckOutputStrategy() command_mock.return_value.get_last_output.return_value = ('', '') backup_manager.executor.check(check_strategy) out, err = capsys.readouterr() assert err == '' assert 'ssh: OK' in out # Test 2: ssh success, with unclean output (out) command_mock.reset_mock() command_mock.return_value.get_last_output.return_value = ( 'This is unclean', '') backup_manager.executor.check(check_strategy) out, err = capsys.readouterr() assert err == '' assert 'ssh output clean: FAILED' in out # Test 2bis: ssh success, with unclean output (err) command_mock.reset_mock() command_mock.return_value.get_last_output.return_value = ( '', 'This is unclean') backup_manager.executor.check(check_strategy) out, err = capsys.readouterr() assert err == '' assert 'ssh output clean: FAILED' in out # Test 3: ssh ok and PostgreSQL is not responding command_mock.reset_mock() command_mock.return_value.get_last_output.return_value = ('', '') check_strategy = CheckOutputStrategy() backup_manager.server.get_remote_status.return_value = { 'server_txt_version': None } backup_manager.server.get_backup.return_value.pgdata = 'test/' backup_manager.executor.check(check_strategy) out, err = capsys.readouterr() assert err == '' assert 'ssh: OK' in out assert "Check that the PostgreSQL server is up and no " \ "'backup_label' file is in PGDATA." # Test 4: ssh failed command_mock.reset_mock() command_mock.side_effect = FsOperationFailed backup_manager.executor.check(check_strategy) out, err = capsys.readouterr() assert err == '' assert 'ssh: FAILED' in out
def test_check_output_strategy(self, capsys): """ Test correct output result """ strategy = CheckOutputStrategy() # Expected result OK strategy.result('test_server_one', 'wal_level', True) out, err = capsys.readouterr() assert out == ' wal_level: OK\n' # Expected result FAILED strategy.result('test_server_one', 'wal_level', False) out, err = capsys.readouterr() assert out == ' wal_level: FAILED\n'
def test_check_config_missing(self, tmpdir): """ Verify the check method can be called on an empty configuration """ server = Server(build_config_from_dicts( global_conf={ # Required by server.check_archive method "barman_lock_directory": tmpdir.mkdir('lock').strpath }, main_conf={ 'conninfo': '', 'ssh_command': '', # Required by server.check_archive method 'wals_directory': tmpdir.mkdir('wals').strpath, } ).get_server('main')) check_strategy = CheckOutputStrategy() server.check(check_strategy) assert check_strategy.has_error
def check(self, server_name, check_strategy=CheckOutputStrategy()): output.init('check', server_name) server = self.servers[server_name] server.check_archive(check_strategy) if not server.passive_node: server.check_postgres(check_strategy) server.check_directories(check_strategy) server.check_retention_policy_settings(check_strategy) server.check_backup_validity(check_strategy) server.backup_manager.check(check_strategy) server.check_configuration(check_strategy) for archiver in server.archivers: archiver.check(check_strategy) server.check_archiver_errors(check_strategy) server.close() results = output._writer.close() return results
def test_check(self, remote_mock, capsys): """ Test management of check_postgres view output :param remote_mock: mock get_remote_status function :param capsys: retrieve output from consolle """ # Create a backup_manager backup_manager = build_backup_manager() # Set up mock responses streaming = backup_manager.server.streaming streaming.server_txt_version = "9.5" # Instantiate a StreamingWalArchiver obj archiver = StreamingWalArchiver(backup_manager) # Prepare the output check strategy strategy = CheckOutputStrategy() # Case: correct configuration remote_mock.return_value = { "pg_receivexlog_installed": True, "pg_receivexlog_compatible": True, "pg_receivexlog_path": "fake/path", "incoming_wals_count": 0, } # Expect out: all parameters: OK backup_manager.server.process_manager.list.return_value = [] archiver.check(strategy) (out, err) = capsys.readouterr() assert ( out == "\tpg_receivexlog: OK\n" "\tpg_receivexlog compatible: OK\n" "\treceive-wal running: FAILED " "(See the Barman log file for more details)\n" ) # Case: pg_receivexlog is not compatible remote_mock.return_value = { "pg_receivexlog_installed": True, "pg_receivexlog_compatible": False, "pg_receivexlog_path": "fake/path", "pg_receivexlog_version": "9.2", "incoming_wals_count": 0, } # Expect out: some parameters: FAILED strategy = CheckOutputStrategy() archiver.check(strategy) (out, err) = capsys.readouterr() assert ( out == "\tpg_receivexlog: OK\n" "\tpg_receivexlog compatible: FAILED " "(PostgreSQL version: 9.5, pg_receivexlog version: 9.2)\n" "\treceive-wal running: FAILED " "(See the Barman log file for more details)\n" ) # Case: pg_receivexlog returned error remote_mock.return_value = { "pg_receivexlog_installed": True, "pg_receivexlog_compatible": None, "pg_receivexlog_path": "fake/path", "pg_receivexlog_version": None, "incoming_wals_count": 0, } # Expect out: all parameters: OK archiver.check(strategy) (out, err) = capsys.readouterr() assert ( out == "\tpg_receivexlog: OK\n" "\tpg_receivexlog compatible: FAILED " "(PostgreSQL version: 9.5, pg_receivexlog version: None)\n" "\treceive-wal running: FAILED " "(See the Barman log file for more details)\n" ) # Case: receive-wal running backup_manager.server.process_manager.list.return_value = [ ProcessInfo( pid=1, server_name=backup_manager.config.name, task="receive-wal" ) ] archiver.check(strategy) (out, err) = capsys.readouterr() assert ( out == "\tpg_receivexlog: OK\n" "\tpg_receivexlog compatible: FAILED " "(PostgreSQL version: 9.5, pg_receivexlog version: None)\n" "\treceive-wal running: OK\n" ) # Case: streaming connection not configured backup_manager.server.streaming = None archiver.check(strategy) (out, err) = capsys.readouterr() assert ( out == "\tpg_receivexlog: OK\n" "\tpg_receivexlog compatible: FAILED " "(PostgreSQL version: Unknown, pg_receivexlog version: None)\n" "\treceive-wal running: OK\n" ) # Case: too many wal files in the incoming queue archiver.config.max_incoming_wals_queue = 10 remote_mock.return_value = { "pg_receivexlog_installed": True, "pg_receivexlog_compatible": None, "pg_receivexlog_path": "fake/path", "pg_receivexlog_version": None, "incoming_wals_count": 20, } # Expect out: the wals incoming queue is too big archiver.check(strategy) (out, err) = capsys.readouterr() assert ( out == "\tpg_receivexlog: OK\n" "\tpg_receivexlog compatible: FAILED " "(PostgreSQL version: Unknown, pg_receivexlog version: None)\n" "\treceive-wal running: OK\n" )
def test_check(self, remote_mock, capsys): """ Test management of check_postgres view output :param remote_mock: mock get_remote_status function :param capsys: retrieve output from consolle """ # Create a backup_manager backup_manager = build_backup_manager() # Set up mock responses postgres = backup_manager.server.postgres postgres.server_version = 90501 # Instantiate a FileWalArchiver obj archiver = FileWalArchiver(backup_manager) # Prepare the output check strategy strategy = CheckOutputStrategy() # Case: no reply by PostgreSQL remote_mock.return_value = { "archive_mode": None, "archive_command": None, } # Expect no output from check archiver.check(strategy) (out, err) = capsys.readouterr() assert out == "" # Case: correct configuration remote_mock.return_value = { "archive_mode": "on", "archive_command": "wal to archive", "is_archiving": True, "incoming_wals_count": 0, } # Expect out: all parameters: OK archiver.check(strategy) (out, err) = capsys.readouterr() assert ( out == "\tarchive_mode: OK\n" "\tarchive_command: OK\n" "\tcontinuous archiving: OK\n" ) # Case: archive_command value is not acceptable remote_mock.return_value = { "archive_command": None, "archive_mode": "on", "is_archiving": False, "incoming_wals_count": 0, } # Expect out: some parameters: FAILED archiver.check(strategy) (out, err) = capsys.readouterr() assert ( out == "\tarchive_mode: OK\n" "\tarchive_command: FAILED " "(please set it accordingly to documentation)\n" ) # Case: all but is_archiving ok remote_mock.return_value = { "archive_mode": "on", "archive_command": "wal to archive", "is_archiving": False, "incoming_wals_count": 0, } # Expect out: all parameters: OK archiver.check(strategy) (out, err) = capsys.readouterr() assert ( out == "\tarchive_mode: OK\n" "\tarchive_command: OK\n" "\tcontinuous archiving: FAILED\n" ) # Case: too many wal files in the incoming queue archiver.config.max_incoming_wals_queue = 10 remote_mock.return_value = { "archive_mode": "on", "archive_command": "wal to archive", "is_archiving": False, "incoming_wals_count": 20, } # Expect out: the wals incoming queue is too big archiver.check(strategy) (out, err) = capsys.readouterr() assert ( out == "\tarchive_mode: OK\n" "\tarchive_command: OK\n" "\tcontinuous archiving: FAILED\n" )
def test_check_replication_slot(self, postgres_mock, capsys): """ Extension of the check_postgres test. Tests the replication_slot check :param postgres_mock: mock get_remote_status function :param capsys: retrieve output from console """ postgres_mock.return_value = { 'current_xlog': None, 'archive_command': 'wal to archive', 'pgespresso_installed': None, 'server_txt_version': '9.3.1', 'data_directory': '/usr/local/postgres', 'archive_mode': 'on', 'wal_level': 'replica', 'replication_slot_support': False, 'replication_slot': None, } # Create server server = build_real_server() # Case: Postgres version < 9.4 strategy = CheckOutputStrategy() server.check_postgres(strategy) (out, err) = capsys.readouterr() assert '\treplication slot:' not in out # Case: correct configuration # use a mock as a quick disposable obj rep_slot = mock.Mock() rep_slot.slot_name = 'test' rep_slot.active = True rep_slot.restart_lsn = 'aaaBB' postgres_mock.return_value = { 'server_txt_version': '9.4.1', 'replication_slot_support': True, 'replication_slot': rep_slot, } server = build_real_server() server.config.streaming_archiver = True server.config.slot_name = 'test' server.check_postgres(strategy) (out, err) = capsys.readouterr() # Everything is ok assert '\treplication slot: OK\n' in out rep_slot.active = False rep_slot.restart_lsn = None postgres_mock.return_value = { 'server_txt_version': '9.4.1', 'replication_slot_support': True, 'replication_slot': rep_slot, } # Replication slot not initialised. server = build_real_server() server.config.slot_name = 'test' server.config.streaming_archiver = True server.check_postgres(strategy) (out, err) = capsys.readouterr() # Everything is ok assert "\treplication slot: FAILED (slot '%s' not initialised: " \ "is 'receive-wal' running?)\n" \ % server.config.slot_name in out rep_slot.reset_mock() rep_slot.active = False rep_slot.restart_lsn = 'Test' postgres_mock.return_value = { 'server_txt_version': '9.4.1', 'replication_slot_support': True, 'replication_slot': rep_slot } # Replication slot not active. server = build_real_server() server.config.slot_name = 'test' server.config.streaming_archiver = True server.check_postgres(strategy) (out, err) = capsys.readouterr() # Everything is ok assert "\treplication slot: FAILED (slot '%s' not active: " \ "is 'receive-wal' running?)\n" % server.config.slot_name in out rep_slot.reset_mock() rep_slot.active = False rep_slot.restart_lsn = 'Test' postgres_mock.return_value = { 'server_txt_version': 'PostgreSQL 9.4.1', 'replication_slot_support': True, 'replication_slot': rep_slot } # Replication slot not active with streaming_archiver off. server = build_real_server() server.config.slot_name = 'test' server.config.streaming_archiver = False server.check_postgres(strategy) (out, err) = capsys.readouterr() # Everything is ok assert "\treplication slot: OK (WARNING: slot '%s' is initialised " \ "but not required by the current config)\n" \ % server.config.slot_name in out rep_slot.reset_mock() rep_slot.active = True rep_slot.restart_lsn = 'Test' postgres_mock.return_value = { 'server_txt_version': 'PostgreSQL 9.4.1', 'replication_slot_support': True, 'replication_slot': rep_slot, } # Replication slot not active with streaming_archiver off. server = build_real_server() server.config.slot_name = 'test' server.config.streaming_archiver = False server.check_postgres(strategy) (out, err) = capsys.readouterr() # Everything is ok assert "\treplication slot: OK (WARNING: slot '%s' is active " \ "but not required by the current config)\n" \ % server.config.slot_name in out
def test_check(self, command_mock, capsys): """ Check the ssh connection to a remote server """ backup_manager = build_backup_manager(global_conf={ # Silence the warning for default backup strategy 'backup_options': 'exclusive_backup', }) # Test 1: ssh ok check_strategy = CheckOutputStrategy() command_mock.return_value.get_last_output.return_value = ('', '') backup_manager.executor.check(check_strategy) out, err = capsys.readouterr() assert err == '' assert 'ssh: OK' in out # Test 2: ssh success, with unclean output (out) command_mock.reset_mock() command_mock.return_value.get_last_output.return_value = ( 'This is unclean', '') backup_manager.executor.check(check_strategy) out, err = capsys.readouterr() assert err == '' assert 'ssh output clean: FAILED' in out # Test 2bis: ssh success, with unclean output (err) command_mock.reset_mock() command_mock.return_value.get_last_output.return_value = ( '', 'This is unclean') backup_manager.executor.check(check_strategy) out, err = capsys.readouterr() assert err == '' assert 'ssh output clean: FAILED' in out # Test 3: ssh ok and PostgreSQL is not responding command_mock.reset_mock() command_mock.return_value.get_last_output.return_value = ('', '') check_strategy = CheckOutputStrategy() backup_manager.server.get_remote_status.return_value = { 'server_txt_version': None } backup_manager.server.get_backup.return_value.pgdata = 'test/' backup_manager.executor.check(check_strategy) out, err = capsys.readouterr() assert err == '' assert 'ssh: OK' in out assert "Check that the PostgreSQL server is up and no " \ "'backup_label' file is in PGDATA." in out # Test 3-err: ssh ok and PostgreSQL is not configured command_mock.reset_mock() command_mock.return_value.get_last_output.return_value = ('', '') check_strategy = CheckOutputStrategy() # No postgres instance, so no remote status keys available backup_manager.server.get_remote_status.return_value = {} backup_manager.server.get_backup.return_value.pgdata = 'test/' # No exception must raise backup_manager.executor.check(check_strategy) out, err = capsys.readouterr() assert err == '' assert 'ssh: OK' in out # Test 4: ssh failed command_mock.reset_mock() command_mock.side_effect = FsOperationFailed backup_manager.executor.check(check_strategy) out, err = capsys.readouterr() assert err == '' assert 'ssh: FAILED' in out
def test_check(self, remote_mock, capsys): """ Test management of check_postgres view output :param remote_mock: mock get_remote_status function :param capsys: retrieve output from consolle """ # Create a backup_manager backup_manager = build_backup_manager() # Set up mock responses postgres = backup_manager.server.postgres postgres.server_version = 90501 # Instantiate a FileWalArchiver obj archiver = FileWalArchiver(backup_manager) # Prepare the output check strategy strategy = CheckOutputStrategy() # Case: no reply by PostgreSQL remote_mock.return_value = { 'archive_mode': None, 'archive_command': None, } # Expect no output from check archiver.check(strategy) (out, err) = capsys.readouterr() assert out == '' # Case: correct configuration remote_mock.return_value = { 'archive_mode': 'on', 'archive_command': 'wal to archive', 'is_archiving': True, } # Expect out: all parameters: OK archiver.check(strategy) (out, err) = capsys.readouterr() assert out == \ "\tarchive_mode: OK\n" \ "\tarchive_command: OK\n" \ "\tcontinuous archiving: OK\n" # Case: archive_command value is not acceptable remote_mock.return_value = { 'archive_command': None, 'archive_mode': 'on', 'is_archiving': False, } # Expect out: some parameters: FAILED archiver.check(strategy) (out, err) = capsys.readouterr() assert out == \ "\tarchive_mode: OK\n" \ "\tarchive_command: FAILED " \ "(please set it accordingly to documentation)\n" # Case: all but is_archiving ok remote_mock.return_value = { 'archive_mode': 'on', 'archive_command': 'wal to archive', 'is_archiving': False, } # Expect out: all parameters: OK archiver.check(strategy) (out, err) = capsys.readouterr() assert out == \ "\tarchive_mode: OK\n" \ "\tarchive_command: OK\n" \ "\tcontinuous archiving: FAILED\n"
def test_check(self, remote_mock, capsys): """ Test management of check_postgres view output :param remote_mock: mock get_remote_status function :param capsys: retrieve output from consolle """ # Create a backup_manager backup_manager = build_backup_manager() # Set up mock responses streaming = backup_manager.server.streaming streaming.server_txt_version = '9.5' # Instantiate a StreamingWalArchiver obj archiver = StreamingWalArchiver(backup_manager) # Prepare the output check strategy strategy = CheckOutputStrategy() # Case: correct configuration remote_mock.return_value = { 'pg_receivexlog_installed': True, 'pg_receivexlog_compatible': True, 'pg_receivexlog_path': 'fake/path', } # Expect out: all parameters: OK backup_manager.server.process_manager.list.return_value = [] archiver.check(strategy) (out, err) = capsys.readouterr() assert out == \ "\tpg_receivexlog: OK\n" \ "\tpg_receivexlog compatible: OK\n" \ "\treceive-wal running: FAILED " \ "(See the Barman log file for more details)\n" # Case: pg_receivexlog is not compatible remote_mock.return_value = { 'pg_receivexlog_installed': True, 'pg_receivexlog_compatible': False, 'pg_receivexlog_path': 'fake/path', 'pg_receivexlog_version': '9.2', } # Expect out: some parameters: FAILED strategy = CheckOutputStrategy() archiver.check(strategy) (out, err) = capsys.readouterr() assert out == \ "\tpg_receivexlog: OK\n" \ "\tpg_receivexlog compatible: FAILED " \ "(PostgreSQL version: 9.5, pg_receivexlog version: 9.2)\n" \ "\treceive-wal running: FAILED " \ "(See the Barman log file for more details)\n" # Case: pg_receivexlog returned error remote_mock.return_value = { 'pg_receivexlog_installed': True, 'pg_receivexlog_compatible': None, 'pg_receivexlog_path': 'fake/path', 'pg_receivexlog_version': None, } # Expect out: all parameters: OK archiver.check(strategy) (out, err) = capsys.readouterr() assert out == \ "\tpg_receivexlog: OK\n" \ "\tpg_receivexlog compatible: FAILED " \ "(PostgreSQL version: 9.5, pg_receivexlog version: None)\n" \ "\treceive-wal running: FAILED " \ "(See the Barman log file for more details)\n" # Case: receive-wal running backup_manager.server.process_manager.list.return_value = [ ProcessInfo(pid=1, server_name=backup_manager.config.name, task="receive-wal") ] archiver.check(strategy) (out, err) = capsys.readouterr() assert out == \ "\tpg_receivexlog: OK\n" \ "\tpg_receivexlog compatible: FAILED " \ "(PostgreSQL version: 9.5, pg_receivexlog version: None)\n" \ "\treceive-wal running: OK\n"