Exemple #1
0
    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
Exemple #5
0
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
Exemple #6
0
    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")
Exemple #7
0
 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
Exemple #8
0
 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
Exemple #10
0
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
Exemple #11
0
    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