def test_exclusive_start_backup(self): """ Basic test for the start_backup method :param start_mock: mock for the _pgespresso_start_backup :param start_mock: mock for the pg_start_backup """ # Build a backup_manager using a mocked server server = build_mocked_server(main_conf={ 'backup_options': BackupOptions.EXCLUSIVE_BACKUP }) backup_manager = build_backup_manager(server=server) # Mock server.get_pg_setting('data_directory') call backup_manager.server.postgres.get_setting.return_value = '/pg/data' # Mock server.get_pg_configuration_files() call server.postgres.get_configuration_files.return_value = dict( config_file="/etc/postgresql.conf", hba_file="/pg/pg_hba.conf", ident_file="/pg/pg_ident.conf", ) # Mock server.get_pg_tablespaces() call tablespaces = [Tablespace._make(('test_tbs', 1234, '/tbs/test'))] server.postgres.get_tablespaces.return_value = tablespaces # Test 1: start exclusive backup # Mock executor.pg_start_backup(label) call start_time = datetime.datetime.now() server.postgres.start_exclusive_backup.return_value = ( "A257/44B4C0D8", "000000060000A25700000044", 11845848, start_time) # Build a test empty backup info backup_info = BackupInfo(server=backup_manager.server, backup_id='fake_id') backup_manager.executor.strategy.start_backup(backup_info) # Check that all the values are correctly saved inside the BackupInfo assert backup_info.pgdata == '/pg/data' assert backup_info.config_file == "/etc/postgresql.conf" assert backup_info.hba_file == "/pg/pg_hba.conf" assert backup_info.ident_file == "/pg/pg_ident.conf" assert backup_info.tablespaces == tablespaces assert backup_info.status == 'STARTED' assert backup_info.timeline == 6 assert backup_info.begin_xlog == 'A257/44B4C0D8' assert backup_info.begin_wal == '000000060000A25700000044' assert backup_info.begin_offset == 11845848 assert backup_info.begin_time == start_time # Check that the correct call to pg_start_backup has been made server.postgres.start_exclusive_backup.assert_called_with( 'Barman backup main fake_id')
def test_pgespresso_start_backup(self): """ Test concurrent backup using pgespresso """ # Test: start concurrent backup # Build a backup_manager using a mocked server server = build_mocked_server(main_conf={ 'backup_options': BackupOptions.CONCURRENT_BACKUP }) backup_manager = build_backup_manager(server=server) # Mock server.get_pg_setting('data_directory') call backup_manager.server.postgres.get_setting.return_value = '/pg/data' # Mock server.get_pg_configuration_files() call server.postgres.get_configuration_files.return_value = dict( config_file="/etc/postgresql.conf", hba_file="/pg/pg_hba.conf", ident_file="/pg/pg_ident.conf", ) # Mock server.get_pg_tablespaces() call tablespaces = [Tablespace._make(('test_tbs', 1234, '/tbs/test'))] server.postgres.get_tablespaces.return_value = tablespaces server.postgres.server_version = 90500 # Mock executor._pgespresso_start_backup(label) call start_time = datetime.datetime.now(tz.tzlocal()).replace(microsecond=0) server.postgres.pgespresso_start_backup.return_value = { 'backup_label': "START WAL LOCATION: 266/4A9C1EF8 " "(file 00000010000002660000004A)\n" "START TIME: %s" % start_time.strftime('%Y-%m-%d %H:%M:%S %Z'), } # Build a test empty backup info backup_info = BackupInfo(server=backup_manager.server, backup_id='fake_id2') backup_manager.executor.strategy.start_backup(backup_info) # Check that all the values are correctly saved inside the BackupInfo assert backup_info.pgdata == '/pg/data' assert backup_info.config_file == "/etc/postgresql.conf" assert backup_info.hba_file == "/pg/pg_hba.conf" assert backup_info.ident_file == "/pg/pg_ident.conf" assert backup_info.tablespaces == tablespaces assert backup_info.status == 'STARTED' assert backup_info.timeline == 16 assert backup_info.begin_xlog == '266/4A9C1EF8' assert backup_info.begin_wal == '00000010000002660000004A' assert backup_info.begin_offset == 10231544 assert backup_info.begin_time == start_time # Check that the correct call to pg_start_backup has been made server.postgres.pgespresso_start_backup.assert_called_with( 'Barman backup main fake_id2')
def test_concurrent_start_backup(self): """ Test concurrent backup using 9.6 api """ # Test: start concurrent backup # Build a backup_manager using a mocked server server = build_mocked_server(main_conf={ 'backup_options': BackupOptions.CONCURRENT_BACKUP }) backup_manager = build_backup_manager(server=server) # Mock server.get_pg_setting('data_directory') call backup_manager.server.postgres.get_setting.return_value = '/pg/data' # Mock server.get_pg_configuration_files() call server.postgres.get_configuration_files.return_value = dict( config_file="/etc/postgresql.conf", hba_file="/pg/pg_hba.conf", ident_file="/pg/pg_ident.conf", ) # Mock server.get_pg_tablespaces() call tablespaces = [Tablespace._make(('test_tbs', 1234, '/tbs/test'))] server.postgres.get_tablespaces.return_value = tablespaces # this is a postgres 9.6 server.postgres.server_version = 90600 # Mock call to new api method start_time = datetime.datetime.now() server.postgres.start_concurrent_backup.return_value = { 'location': "A257/44B4C0D8", 'timeline': 6, 'timestamp': start_time, } # Build a test empty backup info backup_info = BackupInfo(server=backup_manager.server, backup_id='fake_id2') backup_manager.executor.strategy.start_backup(backup_info) # Check that all the values are correctly saved inside the BackupInfo assert backup_info.pgdata == '/pg/data' assert backup_info.config_file == "/etc/postgresql.conf" assert backup_info.hba_file == "/pg/pg_hba.conf" assert backup_info.ident_file == "/pg/pg_ident.conf" assert backup_info.tablespaces == tablespaces assert backup_info.status == 'STARTED' assert backup_info.timeline == 6 assert backup_info.begin_xlog == 'A257/44B4C0D8' assert backup_info.begin_wal == '000000060000A25700000044' assert backup_info.begin_offset == 11845848 assert backup_info.begin_time == start_time
def test_postgres_start_backup(self): """ Test concurrent backup using pg_basebackup """ # Test: start concurrent backup backup_manager = build_backup_manager(global_conf={ 'backup_method': 'postgres' }) # Mock server.get_pg_setting('data_directory') call postgres_mock = backup_manager.server.postgres postgres_mock.get_setting.side_effect = [ '/test/fake_data_dir', ] # Mock server.get_pg_configuration_files() call postgres_mock.get_configuration_files.return_value = dict( config_file="/etc/postgresql.conf", hba_file="/pg/pg_hba.conf", ident_file="/pg/pg_ident.conf", ) # Mock server.get_pg_tablespaces() call tablespaces = [Tablespace._make(('test_tbs', 1234, '/tbs/test'))] postgres_mock.get_tablespaces.return_value = tablespaces # this is a postgres 9.5 postgres_mock.server_version = 90500 # Mock call to new api method start_time = datetime.datetime.now() postgres_mock.current_xlog_info = { 'location': "A257/44B4C0D8", 'timestamp': start_time, } # Build a test empty backup info backup_info = BackupInfo(server=backup_manager.server, backup_id='fake_id2') backup_manager.executor.strategy.start_backup(backup_info) # Check that all the values are correctly saved inside the BackupInfo assert backup_info.pgdata == '/test/fake_data_dir' assert backup_info.config_file == "/etc/postgresql.conf" assert backup_info.hba_file == "/pg/pg_hba.conf" assert backup_info.ident_file == "/pg/pg_ident.conf" assert backup_info.tablespaces == tablespaces assert backup_info.status == 'STARTED' assert backup_info.timeline is None assert backup_info.begin_xlog == 'A257/44B4C0D8' assert backup_info.begin_wal is None assert backup_info.begin_offset is None assert backup_info.begin_time == start_time
def mock_backup_info(backup_id='1234567890', begin_offset=40, begin_time=None, begin_wal='000000010000000000000002', begin_xlog='0/2000028', config_file='/pgdata/location/postgresql.conf', end_offset=184, end_time=None, end_wal='000000010000000000000002', end_xlog='0/20000B8', error=None, hba_file='/pgdata/location/pg_hba.conf', ident_file='/pgdata/location/pg_ident.conf', mode='default', pgdata='/pgdata/location', server_name='test_server', size=12345, status=BackupInfo.DONE, tablespaces=[ ['tbs1', 16387, '/fake/location'], ['tbs2', 16405, '/another/location'], ], timeline=1, version=90302): if begin_time is None: begin_time = datetime.now(tz.tzlocal()) - timedelta(minutes=10) if end_time is None: end_time = datetime.now(tz.tzlocal()) # Generate a list of tablespace objects (don't use a list comprehension # or in python 2.x the 'item' variable will leak to the main context) tablespaces = list(Tablespace._make(item) for item in tablespaces) # make a dictionary with all the arguments to_dict = dict(locals()) # generate a property on the mock for every key in to_dict bi_mock = mock.Mock() for key in to_dict: setattr(bi_mock, key, to_dict[key]) bi_mock.to_dict.return_value = to_dict bi_mock.to_json.return_value = to_dict return bi_mock
def test_concurrent_start_backup(self, espresso_start_mock): """ :param espresso_start_mock: """ # Test: start concurrent backup # Build a backup_manager using a mocked server server = build_mocked_server(main_conf={"backup_options": BackupOptions.CONCURRENT_BACKUP}) backup_manager = build_backup_manager(server=server) # Mock server.get_pg_setting('data_directory') call backup_manager.server.get_pg_setting.return_value = "/pg/data" # Mock server.get_pg_configuration_files() call backup_manager.server.get_pg_configuration_files.return_value = dict( config_file="/etc/postgresql.conf", hba_file="/pg/pg_hba.conf", ident_file="/pg/pg_ident.conf" ) # Mock server.get_pg_tablespaces() call tablespaces = [Tablespace._make(("test_tbs", 1234, "/tbs/test"))] backup_manager.server.get_pg_tablespaces.return_value = tablespaces # Mock executor._pgespresso_start_backup(label) call start_time = datetime.datetime.now() espresso_start_mock.return_value = ( "START WAL LOCATION: 266/4A9C1EF8 " "(file 00000010000002660000004A)", start_time, ) # Build a test empty backup info backup_info = BackupInfo(server=backup_manager.server, backup_id="fake_id2") backup_manager.executor.strategy.start_backup(backup_info) # Check that all the values are correctly saved inside the BackupInfo assert backup_info.pgdata == "/pg/data" assert backup_info.config_file == "/etc/postgresql.conf" assert backup_info.hba_file == "/pg/pg_hba.conf" assert backup_info.ident_file == "/pg/pg_ident.conf" assert backup_info.tablespaces == tablespaces assert backup_info.status == "STARTED" assert backup_info.timeline == 16 assert backup_info.begin_xlog == "266/4A9C1EF8" assert backup_info.begin_wal == "00000010000002660000004A" assert backup_info.begin_offset == 10231544 assert backup_info.begin_time == start_time # Check that the correct call to pg_start_backup has been made espresso_start_mock.assert_called_with("Barman backup main fake_id2")
def get_tablespaces(self): """ Returns a list of tablespaces or None if not present """ try: cur = self._cursor() if self.server_version >= 90200: cur.execute("SELECT spcname, oid, " "pg_tablespace_location(oid) AS spclocation " "FROM pg_tablespace " "WHERE pg_tablespace_location(oid) != ''") else: cur.execute("SELECT spcname, oid, spclocation " "FROM pg_tablespace WHERE spclocation != ''") # Generate a list of tablespace objects return [Tablespace._make(item) for item in cur.fetchall()] except (PostgresConnectionError, psycopg2.Error) as e: _logger.debug("Error retrieving PostgreSQL tablespaces: %s", str(e).strip()) return None
def get_tablespaces(self): """ Returns a list of tablespaces or None if not present """ try: cur = self._cursor() if self.server_version >= 90200: cur.execute( "SELECT spcname, oid, " "pg_tablespace_location(oid) AS spclocation " "FROM pg_tablespace " "WHERE pg_tablespace_location(oid) != ''" ) else: cur.execute("SELECT spcname, oid, spclocation " "FROM pg_tablespace WHERE spclocation != ''") # Generate a list of tablespace objects return [Tablespace._make(item) for item in cur.fetchall()] except (PostgresConnectionError, psycopg2.Error) as e: _logger.debug("Error retrieving PostgreSQL tablespaces: %s", str(e).strip()) return None
def build_test_backup_info(backup_id='1234567890', begin_offset=40, begin_time=None, begin_wal='000000010000000000000002', begin_xlog='0/2000028', config_file='/pgdata/location/postgresql.conf', end_offset=184, end_time=None, end_wal='000000010000000000000002', end_xlog='0/20000B8', error=None, hba_file='/pgdata/location/pg_hba.conf', ident_file='/pgdata/location/pg_ident.conf', mode='default', pgdata='/pgdata/location', server_name='test_server', size=12345, status=BackupInfo.DONE, included_files=None, tablespaces=( ('tbs1', 16387, '/fake/location'), ('tbs2', 16405, '/another/location'), ), timeline=1, version=90302, server=None, copy_stats=None): """ Create an 'Ad Hoc' BackupInfo object for testing purposes. A BackupInfo object is the barman representation of a physical backup, for testing purposes is necessary to build a BackupInfo avoiding the usage of Mock/MagicMock classes as much as possible. :param str backup_id: the id of the backup :param int begin_offset: begin_offset of the backup :param datetime.datetime|None begin_time: begin_time of the backup :param str begin_wal: begin_wal of the backup :param str begin_xlog: begin_xlog of the backup :param str config_file: config file of the backup :param int end_offset: end_offset of the backup :param datetime.datetime|None end_time: end_time of the backup :param str end_wal: begin_xlog of the backup :param str end_xlog: end_xlog of the backup :param str|None error: error message for the backup :param str hba_file: hba_file for the backup :param str ident_file: ident_file for the backup :param str mode: mode of execution of the backup :param str pgdata: pg_data dir of the backup :param str server_name: server name for the backup :param int size: dimension of the backup :param str status: status of the execution of the backup :param list|None included_files: a list of extra configuration files :param list|tuple|None tablespaces: a list of tablespaces for the backup :param int timeline: timeline of the backup :param int version: postgres version of the backup :param barman.server.Server|None server: Server object for the backup :param dict|None: Copy stats dictionary :rtype: barman.infofile.BackupInfo """ if begin_time is None: begin_time = datetime.now(tz.tzlocal()) - timedelta(minutes=10) if end_time is None: end_time = datetime.now(tz.tzlocal()) # Generate a list of tablespace objects (don't use a list comprehension # or in python 2.x the 'item' variable will leak to the main context) if tablespaces is not None: tablespaces = list(Tablespace._make(item) for item in tablespaces) # Manage the server for the Backup info: if no server is provided # by the caller use a Mock with a basic configuration if server is None: server = mock.Mock(name=server_name) server.config = build_config_from_dicts().get_server('main') server.passive_node = False server.backup_manager.name = 'default' backup_info = BackupInfo(**locals()) return backup_info
def build_test_backup_info( backup_id='1234567890', begin_offset=40, begin_time=None, begin_wal='000000010000000000000002', begin_xlog='0/2000028', config_file='/pgdata/location/postgresql.conf', end_offset=184, end_time=None, end_wal='000000010000000000000002', end_xlog='0/20000B8', error=None, hba_file='/pgdata/location/pg_hba.conf', ident_file='/pgdata/location/pg_ident.conf', mode='default', pgdata='/pgdata/location', server_name='test_server', size=12345, status=BackupInfo.DONE, included_files=None, tablespaces=( ('tbs1', 16387, '/fake/location'), ('tbs2', 16405, '/another/location'), ), timeline=1, version=90302, server=None): """ Create an 'Ad Hoc' BackupInfo object for testing purposes. A BackupInfo object is the barman representation of a physical backup, for testing purposes is necessary to build a BackupInfo avoiding the usage of Mock/MagicMock classes as much as possible. :param str backup_id: the id of the backup :param int begin_offset: begin_offset of the backup :param datetime.datetime|None begin_time: begin_time of the backup :param str begin_wal: begin_wal of the backup :param str begin_xlog: begin_xlog of the backup :param str config_file: config file of the backup :param int end_offset: end_offset of the backup :param datetime.datetime|None end_time: end_time of the backup :param str end_wal: begin_xlog of the backup :param str end_xlog: end_xlog of the backup :param str|None error: error message for the backup :param str hba_file: hba_file for the backup :param str ident_file: ident_file for the backup :param str mode: mode of execution of the backup :param str pgdata: pg_data dir of the backup :param str server_name: server name for the backup :param int size: dimension of the backup :param str status: status of the execution of the backup :param list|None included_files: a list of extra configuration files :param list|tuple|None tablespaces: a list of tablespaces for the backup :param int timeline: timeline of the backup :param int version: postgres version of the backup :param barman.server.Server|None server: Server object for the backup :rtype: barman.infofile.BackupInfo """ if begin_time is None: begin_time = datetime.now(tz.tzlocal()) - timedelta(minutes=10) if end_time is None: end_time = datetime.now(tz.tzlocal()) # Generate a list of tablespace objects (don't use a list comprehension # or in python 2.x the 'item' variable will leak to the main context) if tablespaces is not None: tablespaces = list(Tablespace._make(item) for item in tablespaces) # Manage the server for the Backup info: if no server is provided # by the caller use a Mock with a basic configuration if server is None: server = mock.Mock(name=server_name) server.config = build_config_from_dicts().get_server('main') server.backup_manager.name = 'default' backup_info = BackupInfo(**locals()) return backup_info
def test_start_backup(self, espresso_start_mock, start_mock): """ Basic test for the start_backup method :param espresso_start_mock: mock for the pgespresso_start_backup :param start_mock: mock for the pg_start_backup """ # Build a backup_manager using a mocked server backup_manager = build_backup_manager(name='test-server') # Mock server.get_pg_setting('data_directory') call backup_manager.server.get_pg_setting.return_value = '/pg/data' # Mock server.get_pg_configuration_files() call backup_manager.server.get_pg_configuration_files.return_value = dict( config_file="/etc/postgresql.conf", hba_file="/pg/pg_hba.conf", ident_file="/pg/pg_ident.conf", ) # Mock server.get_pg_tablespaces() call tablespaces = [Tablespace._make(('test_tbs', 1234, '/tbs/test'))] backup_manager.server.get_pg_tablespaces.return_value = tablespaces # Test 1: start exclusive backup # Mock executor.pg_start_backup(label) call start_time = datetime.datetime.now() start_mock.return_value = ("A257/44B4C0D8", "000000060000A25700000044", 11845848, start_time) # Build a test empty backup info backup_info = BackupInfo(server=backup_manager.server, backup_id='fake_id') backup_manager.executor.start_backup(backup_info) # Check that all the values are correctly saved inside the BackupInfo assert backup_info.pgdata == '/pg/data' assert backup_info.config_file == "/etc/postgresql.conf" assert backup_info.hba_file == "/pg/pg_hba.conf" assert backup_info.ident_file == "/pg/pg_ident.conf" assert backup_info.tablespaces == tablespaces assert backup_info.status == 'STARTED' assert backup_info.timeline == 6 assert backup_info.begin_xlog == 'A257/44B4C0D8' assert backup_info.begin_wal == '000000060000A25700000044' assert backup_info.begin_offset == 11845848 assert backup_info.begin_time == start_time # Check that the correct call to pg_start_backup has been made start_mock.assert_called_with('Barman backup test-server fake_id') assert not espresso_start_mock.called # Test 2: start concurrent backup # change the configuration to concurrent backup backup_manager.executor.config.backup_options = [ BackupOptions.CONCURRENT_BACKUP] # Reset mock executor.pg_start_backup(label) call start_mock.reset_mock() # Mock executor.pgespresso_start_backup(label) call start_time = datetime.datetime.now() espresso_start_mock.return_value = ("START WAL LOCATION: 266/4A9C1EF8 " "(file 00000010000002660000004A)", start_time) # Build a test empty backup info backup_info = BackupInfo(server=backup_manager.server, backup_id='fake_id2') backup_manager.executor.start_backup(backup_info) # Check that all the values are correctly saved inside the BackupInfo assert backup_info.pgdata == '/pg/data' assert backup_info.config_file == "/etc/postgresql.conf" assert backup_info.hba_file == "/pg/pg_hba.conf" assert backup_info.ident_file == "/pg/pg_ident.conf" assert backup_info.tablespaces == tablespaces assert backup_info.status == 'STARTED' assert backup_info.timeline == 16 assert backup_info.begin_xlog == '266/4A9C1EF8' assert backup_info.begin_wal == '00000010000002660000004A' assert backup_info.begin_offset == 10231544 assert backup_info.begin_time == start_time # Check that the correct call to pg_start_backup has been made espresso_start_mock.assert_called_with( 'Barman backup test-server fake_id2') assert not start_mock.called