def test_failed_recover(self, _): self.gpArrayMock.get_unbalanced_segdbs.return_value = [self.primary0] options = Options() options.coordinatorDataDirectory = self.temp_dir options.spareDataDirectoryFile = None options.showProgress = True options.showProgressInplace = True # import HERE so that patches are already in place! from gppylib.programs.clsRecoverSegment import GpRecoverSegmentProgram self.subject = GpRecoverSegmentProgram(options) self.subject.logger = Mock( spec=['log', 'warn', 'info', 'debug', 'error', 'warning', 'fatal']) self.mock_get_mirrors_to_build.side_effect = self._get_test_mirrors self.primary0.heap_checksum = 1 self.mock_check_segment_consistency.return_value = ([self.primary0], [], 1) self.mock_get_segments_checksum_settings.return_value = ([ self.mirror0 ], []) self.return_one = True self.mock_build_mirrors.return_value = False with self.assertRaises(SystemExit) as cm: self.subject.run() self.assertEqual(cm.exception.code, 1)
def test_check_segment_state(self): options = Mock() mock_pool = Mock() m1 = Mock() m1.get_results.return_value = CommandResult(1, 'Failed to connect', '', False, True) m2 = Mock() m2.get_results.return_value = CommandResult(0, 'segmentState: Ready', '', False, True) mock_pool.getCompletedItems.return_value = [] confProvider = Mock() m1 = Mock() m1.getSegmentHostName.return_value = 'foo1' m1.isSegmentUp.return_value = True m1.isSegmentMaster.return_value = False m2 = Mock() m2.getSegmentHostName.return_value = 'foo2' m2.isSegmentUp.return_value = True m2.isSegmentMaster.return_value = False gparray = Mock() gparray.getDbList.return_value = [m1, m2] confProvider.loadSystemConfig.return_value = gparray gprecover_prog = GpRecoverSegmentProgram(options) gprecover_prog._GpRecoverSegmentProgram__pool = mock_pool gprecover_prog._check_segment_state(confProvider)
def test_successful_recover(self, _): self.gpArrayMock.get_unbalanced_segdbs.return_value = [self.primary0] options = Options() options.coordinatorDataDirectory = self.temp_dir options.spareDataDirectoryFile = None options.showProgress = True options.showProgressInplace = True # import HERE so that patches are already in place! from gppylib.programs.clsRecoverSegment import GpRecoverSegmentProgram self.subject = GpRecoverSegmentProgram(options) self.subject.logger = Mock( spec=['log', 'warn', 'info', 'debug', 'error', 'warning', 'fatal']) self.mock_get_mirrors_to_build.side_effect = self._get_test_mirrors self.primary0.heap_checksum = 1 self.mock_check_segment_consistency.return_value = ([self.primary0], [], 1) self.mock_get_segments_checksum_settings.return_value = ([ self.mirror0 ], []) self.return_one = True self.mock_build_mirrors.return_value = True with self.assertRaises(SystemExit) as cm: # XXX Disable live FTS probes. The fact that we have to do this # indicates that these are not really unit tests. with patch.object(self.subject, 'trigger_fts_probe'): self.subject.run() self.assertEqual(cm.exception.code, 0)
def test_check_segment_state_ready_for_recovery_with_segment_in_change_tracking_disabled( self, mock_results): options = Mock() mock_results.return_value = CommandResult( 0, '', 'mode: PrimarySegment\nsegmentState: ChangeTrackingDisabled\ndataState: InChangeTracking\n', False, True) m2 = Mock() m2.isSegmentQD.return_value = False m2.isSegmentModeInChangeLogging.return_value = True m2.getSegmentHostName.return_value = 'foo1' m2.getSegmentDataDirectory.return_value = 'bar' m2.getSegmentPort.return_value = 5555 m2.getSegmentDbId.return_value = 2 m2.getSegmentRole.return_value = 'p' m2.getSegmentMode.return_value = 'c' segmentList = [m2] dbsMap = {2: m2} gprecover_prog = GpRecoverSegmentProgram(options) mock_pool = Mock() mock_pool.addCommand = Mock() mock_pool.join = Mock() gprecover_prog._GpRecoverSegmentProgram__pool = mock_pool segmentStates = gprecover_prog.check_segment_state_ready_for_recovery( segmentList, dbsMap) self.assertEquals(segmentStates, {2: 'ChangeTrackingDisabled'})
def test_check_segment_state_ready_for_recovery_ignores_initial_stdout_warnings( self, mock_results): options = Mock() gprecover_prog = GpRecoverSegmentProgram(options) gprecover_prog.logger.info = Mock() mock_results.return_value = CommandResult( 0, '', 'Warning: Permanently added "a4eb06fc188f,172.17.0.2" (RSA) to the list of \nmode: PrimarySegment\nsegmentState: ChangeTrackingDisabled\ndataState: InChangeTracking\n', False, True) segment_mock = Mock() segment_mock.isSegmentQD.return_value = False segment_mock.isSegmentModeInChangeLogging.return_value = True segment_mock.getSegmentHostName.return_value = 'foo1' segment_mock.getSegmentDataDirectory.return_value = 'bar' segment_mock.getSegmentPort.return_value = 5555 segment_mock.getSegmentDbId.return_value = 2 segment_mock.getSegmentRole.return_value = 'p' segment_mock.getSegmentMode.return_value = 'c' segmentList = [segment_mock] dbsMap = {2: segment_mock} mock_pool = Mock() mock_pool.addCommand = Mock() mock_pool.join = Mock() gprecover_prog._GpRecoverSegmentProgram__pool = mock_pool segmentStates = gprecover_prog.check_segment_state_ready_for_recovery( segmentList, dbsMap) self.assertEquals(segmentStates, {2: 'ChangeTrackingDisabled'}) gprecover_prog.logger.info.assert_called_once_with( 'Warning: Permanently added "a4eb06fc188f,172.17.0.2" (RSA) to the list of ' )
def test_check_segment_state_with_segment_not_ready(self): options = Mock() m1 = Mock() m1.get_results.return_value = CommandResult(0, 'Failed to connect', '', False, True) m2 = Mock() m2.get_results.return_value = CommandResult(0, 'segmentState: Not Ready', '', False, True) mock_pool = Mock() mock_pool.getCompletedItems.return_value = [m1, m2] m1 = Mock() m1.getSegmentHostName.return_value = 'foo1' m1.isSegmentUp.return_value = True m1.isSegmentMaster.return_value = False m2 = Mock() m2.getSegmentHostName.return_value = 'foo2' m2.isSegmentUp.return_value = True m2.isSegmentMaster.return_value = False gparray = Mock() gparray.getDbList.return_value = [m1, m2] confProvider = Mock() confProvider.loadSystemConfig.return_value = gparray gprecover_prog = GpRecoverSegmentProgram(options) gprecover_prog._GpRecoverSegmentProgram__pool = mock_pool with self.assertRaisesRegexp(Exception, 'Not ready to connect to database'): gprecover_prog._check_segment_state(confProvider)
def test_check_persistent_tables_no_segments(self, mock1): options = Mock() segments = [] mock_pool = Mock() mock_pool.getCompletedItems.return_value = [] gprecover_prog = GpRecoverSegmentProgram(options) gprecover_prog._GpRecoverSegmentProgram__pool = mock_pool gprecover_prog._check_persistent_tables(segments)
def test_output_segments_with_persistent_mirroring_disabled_should_not_print_if_no_segments( self): segs_with_persistent_mirroring_disabled = [] options = Mock() gprecover_prog = GpRecoverSegmentProgram(options) gprecover_prog.logger.warn = Mock() gprecover_prog._output_segments_with_persistent_mirroring_disabled( segs_with_persistent_mirroring_disabled) assert not gprecover_prog.logger.warn.called
def setUp(self): raw_options = GpRecoverSegmentProgram.createParser() (options, _) = raw_options.parse_args(args=[]) options.spareDataDirectoryFile = None options.newRecoverHosts = None self.subject = GpRecoverSegmentProgram(options) self.execSqlResult = Mock(spec=['fetchall']) self.gp_env = Mock() GpCoordinatorEnvironmentMock = Mock(return_value=self.gp_env) self.gparray = Mock(spec=GpArray) self.gparray.getDbList.return_value = self._segments_mock() configProviderMock = Mock(spec=GpConfigurationProvider) configProviderMock.initializeProvider.return_value = configProviderMock configProviderMock.loadSystemConfig.return_value = self.gparray self.getConfigProviderFunctionMock = Mock(GpConfigurationProvider) self.getConfigProviderFunctionMock.return_value = configProviderMock self.subject.logger = Mock() self.worker_pool = Mock(spec=WorkerPool, return_value=None) self.worker_pool.getCompletedItems.return_value = [] self.worker_pool.logger = self.subject.logger self.worker_pool.addCommand.return_value = None self.pool_completed = [] self.apply_patches([ patch("gppylib.db.dbconn.connect"), patch("gppylib.db.dbconn.DbURL"), patch("gppylib.db.dbconn.execSQL", return_value=self.execSqlResult), patch('time.sleep'), patch( 'gppylib.programs.clsRecoverSegment.GpCoordinatorEnvironment', GpCoordinatorEnvironmentMock), # patch('gppylib.system.environment.GpCoordinatorEnvironment.__init__', self.gp_env), # patch('gppylib.system.environment.GpCoordinatorEnvironment.getCoordinatorPort'), patch('gppylib.system.faultProberInterface.getFaultProber'), patch( 'gppylib.system.configurationInterface.getConfigurationProvider', self.getConfigProviderFunctionMock), patch('gppylib.commands.base.WorkerPool.__init__', self.worker_pool), patch('gppylib.commands.base.WorkerPool.getCompletedItems', return_value=self.pool_completed), patch('gppylib.commands.base.WorkerPool.addCommand'), patch('gppylib.commands.base.WorkerPool.join'), ]) # tests make use of a workaround to access a python attribute that is normally # name mangled when specified with a "__" prefix. That workaround is to use _<class>__<attribute> # such as self.subject._GpRecoverSegmentProgram__pool = mock_pool self.subject._GpRecoverSegmentProgram__pool = self.worker_pool
def test_output_segments_with_persistent_mirroring_disabled_should_print_failed_segments( self): segs_with_persistent_mirroring_disabled = [0, 1] options = Mock() gprecover_prog = GpRecoverSegmentProgram(options) gprecover_prog.logger.warn = Mock() gprecover_prog._output_segments_with_persistent_mirroring_disabled( segs_with_persistent_mirroring_disabled) gprecover_prog.logger.warn.assert_called_once_with( 'Segments with dbid 0, 1 not recovered; persistent mirroring state is disabled.' )
def test_is_segment_mirror_state_mismatched_cluster_and_segments_mirroring_disabled( self, mock_sql): options = Mock() gprecover_prog = GpRecoverSegmentProgram(options) gparray_mock = Mock() gparray_mock.getFaultStrategy.return_value = gparray.FAULT_STRATEGY_NONE segment_mock = Mock() segment_mock.getSegmentDbId.return_value = 0 result = gprecover_prog.is_segment_mirror_state_mismatched( gparray_mock, segment_mock) self.assertFalse(result)
def test_is_segment_mirror_state_mismatched_cluster_mirroring_enabled_segment_mirroring_disabled( self, mock_sql): options = Mock() gprecover_prog = GpRecoverSegmentProgram(options) gparray_mock = Mock() gparray_mock.getFaultStrategy.return_value = gparray.FAULT_STRATEGY_FILE_REPLICATION segment_mock = Mock() segment_mock.getSegmentContentId.return_value = 0 result = gprecover_prog.is_segment_mirror_state_mismatched( gparray_mock, segment_mock) self.assertTrue(result)
def test_output_segments_in_change_tracking_disabled_should_print_failed_segments( self): segs_in_change_tracking_disabled = { 2: 'ChangeTrackingDisabled', 4: 'ChangeTrackingDisabled' } options = Mock() gprecover_prog = GpRecoverSegmentProgram(options) gprecover_prog.logger.warn = Mock() gprecover_prog._output_segments_in_change_tracking_disabled( segs_in_change_tracking_disabled) gprecover_prog.logger.warn.assert_called_once_with( 'Segments with dbid 2 ,4 in change tracking disabled state, need to run recoverseg with -F option.' )
def test_check_persistent_tables(self, mock1): options = Mock() segments = [ self._get_mock_segment('seg1', '1234', 'seg1', '/tmp/seg1'), self._get_mock_segment('seg2', '2345', 'seg2', '/tmp/seg2') ] mock_pool = Mock() m1 = Mock() m1.get_results.return_value = '' m2 = Mock() m2.get_results.return_value = '' mock_pool.getCompletedItems.return_value = [m1, m2] gprecover_prog = GpRecoverSegmentProgram(options) gprecover_prog._GpRecoverSegmentProgram__pool = mock_pool gprecover_prog._check_persistent_tables(segments)
def test_check_persistent_tables_error(self, mock1): options = Mock() segments = [ self._get_mock_segment('seg1', '1234', 'seg1', '/tmp/seg1'), self._get_mock_segment('seg2', '2345', 'seg2', '/tmp/seg2') ] mock_pool = Mock() m1 = Mock() m1.get_results.return_value = ['sdfsdf'] m2 = Mock() m2.get_results.return_value = ['asdfas'] mock_pool.getCompletedItems.return_value = [m1, m2] gprecover_prog = GpRecoverSegmentProgram(options) gprecover_prog._GpRecoverSegmentProgram__pool = mock_pool with self.assertRaisesRegexp(Exception, 'Please fix the persistent tables issue'): gprecover_prog._check_persistent_tables(segments)
def test_successful_rebalance(self, _, __, ___): self.gpArrayMock.get_unbalanced_segdbs.return_value = [self.primary0] options = Options() options.masterDataDirectory = self.temp_dir options.rebalanceSegments = True options.spareDataDirectoryFile = None options.showProgress = True options.showProgressInplace = True # import HERE so that patches are already in place! from gppylib.programs.clsRecoverSegment import GpRecoverSegmentProgram self.subject = GpRecoverSegmentProgram(options) self.subject.logger = Mock(spec=['log', 'warn', 'info', 'debug', 'error', 'warning', 'fatal']) with self.assertRaises(SystemExit): self.subject.run() self.subject.logger.info.assert_any_call('The rebalance operation has completed successfully.')
def test_failed_rebalance(self, _, __, ___): self.gpArrayMock.get_unbalanced_segdbs.return_value = [self.primary0] options = Options() options.coordinatorDataDirectory = self.temp_dir options.rebalanceSegments = True options.spareDataDirectoryFile = None options.showProgress = True options.showProgressInplace = True # import HERE so that patches are already in place! from gppylib.programs.clsRecoverSegment import GpRecoverSegmentProgram self.subject = GpRecoverSegmentProgram(options) self.subject.logger = Mock(spec=['log', 'warn', 'info', 'debug', 'error', 'warning', 'fatal']) with self.assertRaises(SystemExit) as cm: self.subject.run() self.assertEqual(cm.exception.code, 0) self.subject.logger.info.assert_any_call('The rebalance operation has completed with WARNINGS. ' 'Please review the output in the gprecoverseg log.')
def setUp(self): self.temp_dir = tempfile.mkdtemp() self.config_file_path = os.path.join(self.temp_dir, "foo") with open(self.config_file_path, "w") as config_file: config_file.write("") self.conn = Mock() self.conn.__enter__ = Mock(return_value=(Mock(), None)) self.conn.__exit__ = Mock(return_value=None) self.cursor = FakeCursor() self.db_singleton = Mock() self.os_env = dict(USER="******") self.os_env["COORDINATOR_DATA_DIRECTORY"] = self.temp_dir self.os_env["GPHOME"] = self.temp_dir self.gparray = self._create_gparray_with_2_primary_2_mirrors() self.pool = Mock() self.pool.getCompletedItems.return_value = [] self.pgconf_dict = gucdict() self.pgconf_dict["port"] = setting("port", "123", None, None, None) self.pgconf_dict["max_connection"] = setting("max_connections", "1", None, None, None) self.config_provider_mock = MagicMock(spec=GpConfigurationProvider) self.config_provider_mock.initializeProvider.return_value = self.config_provider_mock self.gpArrayMock = MagicMock(spec=GpArray) self.gpArrayMock.getDbList.side_effect = [[self.primary0], [self.primary0], [self.primary0]] self.gpArrayMock.segmentPairs = [] self.gpArrayMock.hasMirrors = True self.gpArrayMock.isStandardArray.return_value = (True, None) self.gpArrayMock.coordinator = self.gparray.coordinator self.config_provider_mock.loadSystemConfig.return_value = self.gpArrayMock self.mirror_to_build = GpMirrorToBuild(self.mirror0, self.primary0, None, False) self.apply_patches([ patch('os.environ', new=self.os_env), patch('gppylib.db.dbconn.connect', return_value=self.conn), patch('gppylib.db.dbconn.query', return_value=self.cursor), patch('gppylib.db.dbconn.queryRow', return_value=["foo"]), patch('gppylib.pgconf.readfile', return_value=self.pgconf_dict), patch('gppylib.commands.gp.GpVersion'), patch('gppylib.system.faultProberInterface.getFaultProber'), patch( 'gppylib.system.configurationInterface.getConfigurationProvider', return_value=self.config_provider_mock), patch('gppylib.commands.base.WorkerPool', return_value=self.pool), patch('gppylib.gparray.GpArray.getSegmentsByHostName', return_value={}), patch('gppylib.gplog.get_default_logger'), patch.object(GpMirrorListToBuild, "__init__", return_value=None), patch.object(GpMirrorListToBuild, "buildMirrors"), patch.object(GpMirrorListToBuild, "getAdditionalWarnings"), patch.object(GpMirrorListToBuild, "getMirrorsToBuild"), patch.object(HeapChecksum, "check_segment_consistency"), patch.object(HeapChecksum, "get_segments_checksum_settings"), ]) self.call_count = 0 self.return_one = True self.mock_build_mirrors = self.get_mock_from_apply_patch( "buildMirrors") self.mock_get_mirrors_to_build = self.get_mock_from_apply_patch( 'getMirrorsToBuild') self.mock_heap_checksum_init = self.get_mock_from_apply_patch( "__init__") self.mock_check_segment_consistency = self.get_mock_from_apply_patch( 'check_segment_consistency') self.mock_get_segments_checksum_settings = self.get_mock_from_apply_patch( 'get_segments_checksum_settings') sys.argv = ["gprecoverseg"] # reset to relatively empty args list options = Options() options.coordinatorDataDirectory = self.temp_dir options.spareDataDirectoryFile = self.config_file_path options.showProgress = True options.showProgressInplace = True # import HERE so that patches are already in place! from gppylib.programs.clsRecoverSegment import GpRecoverSegmentProgram self.subject = GpRecoverSegmentProgram(options) self.subject.logger = Mock( spec=['log', 'warn', 'info', 'debug', 'error', 'warning', 'fatal']) faultProberInterface.gFaultProber = Mock()
def test_check_segment_change_tracking_disabled_state_return_true(self): options = Mock() gprecover_prog = GpRecoverSegmentProgram(options) res = gprecover_prog.check_segment_change_tracking_disabled_state( gparray.SEGMENT_STATE_CHANGE_TRACKING_DISABLED) self.assertEquals(res, True)
def test_check_segment_change_tracking_disabled_state_return_false(self): options = Mock() gprecover_prog = GpRecoverSegmentProgram(options) res = gprecover_prog.check_segment_change_tracking_disabled_state( gparray.SEGMENT_STATE_READY) self.assertEquals(res, False)
def test_check_database_connection_exceed_max_retries(self, mock1, mock2): options = Mock() confProvider = Mock() gprecover_prog = GpRecoverSegmentProgram(options) self.assertFalse( gprecover_prog._check_database_connection(confProvider))
def test_check_database_connection(self, mock1, mock2): options = Mock() confProvider = Mock() gprecover_prog = GpRecoverSegmentProgram(options) self.assertTrue( gprecover_prog._check_database_connection(confProvider))