def test_get_version_info(self, find_command_mock): """ Test the `get_version_info` class method """ command_mock = find_command_mock.return_value command_mock.cmd = '/some/path/pg_receivewal' command_mock.out = \ 'pg_receivewal (PostgreSQL) 11.7 (ev1 12) (ev2 2:3.4)' # Test with normal output version_info = PgReceiveXlog.get_version_info() assert version_info['full_path'] == '/some/path/pg_receivewal' assert version_info['full_version'] == '11.7' assert version_info['major_version'] == '11' # Test with development branch command_mock.out = 'pg_receivewal 13devel' version_info = PgReceiveXlog.get_version_info() assert version_info['full_version'] == '13devel' assert version_info['major_version'] == '13' # Test with bad output command_mock.out = 'pg_receivewal' version_info = PgReceiveXlog.get_version_info() assert version_info['full_path'] == '/some/path/pg_receivewal' assert version_info['full_version'] is None assert version_info['major_version'] is None # Test with invocation error find_command_mock.side_effect = CommandFailedException version_info = PgReceiveXlog.get_version_info() assert version_info['full_path'] is None assert version_info['full_version'] is None assert version_info['major_version'] is None
def fetch_remote_status(self): """ Execute checks for replication-based wal archiving This method does not raise any exception in case of errors, but set the missing values to None in the resulting dictionary. :rtype: dict[str, None|str] """ remote_status = dict.fromkeys( ('pg_receivexlog_compatible', 'pg_receivexlog_installed', 'pg_receivexlog_path', 'pg_receivexlog_version'), None) # Test pg_receivexlog existence version_info = PgReceiveXlog.get_version_info( self.backup_manager.server.path) if version_info['full_path']: remote_status["pg_receivexlog_installed"] = True remote_status["pg_receivexlog_path"] = version_info['full_path'] remote_status["pg_receivexlog_version"] = ( version_info['full_version']) pgreceivexlog_version = version_info['major_version'] else: remote_status["pg_receivexlog_installed"] = False return remote_status # Retrieve the PostgreSQL version pg_version = None if self.server.streaming is not None: pg_version = self.server.streaming.server_major_version # If one of the version is unknown we cannot compare them if pgreceivexlog_version is None or pg_version is None: return remote_status # pg_version is not None so transform into a Version object # for easier comparison between versions pg_version = Version(pg_version) # pg_receivexlog 9.2 is compatible only with PostgreSQL 9.2. if "9.2" == pg_version == pgreceivexlog_version: remote_status["pg_receivexlog_compatible"] = True # other versions are compatible with lesser versions of PostgreSQL # WARNING: The development versions of `pg_receivexlog` are considered # higher than the stable versions here, but this is not an issue # because it accepts everything that is less than # the `pg_receivexlog` version(e.g. '9.6' is less than '9.6devel') elif "9.2" < pg_version <= pgreceivexlog_version: remote_status["pg_receivexlog_compatible"] = True else: remote_status["pg_receivexlog_compatible"] = False return remote_status
def fetch_remote_status(self): """ Execute checks for replication-based wal archiving This method does not raise any exception in case of errors, but set the missing values to None in the resulting dictionary. :rtype: dict[str, None|str] """ remote_status = dict.fromkeys( ('pg_receivexlog_compatible', 'pg_receivexlog_installed', 'pg_receivexlog_path', 'pg_receivexlog_supports_slots', 'pg_receivexlog_synchronous', 'pg_receivexlog_version'), None) # Test pg_receivexlog existence version_info = PgReceiveXlog.get_version_info(self.server.path) if version_info['full_path']: remote_status["pg_receivexlog_installed"] = True remote_status["pg_receivexlog_path"] = version_info['full_path'] remote_status["pg_receivexlog_version"] = ( version_info['full_version']) pgreceivexlog_version = version_info['major_version'] else: remote_status["pg_receivexlog_installed"] = False return remote_status # Retrieve the PostgreSQL version pg_version = None if self.server.streaming is not None: pg_version = self.server.streaming.server_major_version # If one of the version is unknown we cannot compare them if pgreceivexlog_version is None or pg_version is None: return remote_status # pg_version is not None so transform into a Version object # for easier comparison between versions pg_version = Version(pg_version) # Set conservative default values (False) for modern features remote_status["pg_receivexlog_compatible"] = False remote_status['pg_receivexlog_supports_slots'] = False remote_status["pg_receivexlog_synchronous"] = False # pg_receivexlog 9.2 is compatible only with PostgreSQL 9.2. if "9.2" == pg_version == pgreceivexlog_version: remote_status["pg_receivexlog_compatible"] = True # other versions are compatible with lesser versions of PostgreSQL # WARNING: The development versions of `pg_receivexlog` are considered # higher than the stable versions here, but this is not an issue # because it accepts everything that is less than # the `pg_receivexlog` version(e.g. '9.6' is less than '9.6devel') elif "9.2" < pg_version <= pgreceivexlog_version: # At least PostgreSQL 9.3 is required here remote_status["pg_receivexlog_compatible"] = True # replication slots are supported starting from version 9.4 if "9.4" <= pg_version <= pgreceivexlog_version: remote_status['pg_receivexlog_supports_slots'] = True # Synchronous WAL streaming requires replication slots # and pg_receivexlog >= 9.5 if "9.4" <= pg_version and "9.5" <= pgreceivexlog_version: remote_status["pg_receivexlog_synchronous"] = ( self._is_synchronous()) return remote_status