def test_update_sequences(self):
     """ Test the sequencing of the update_sequences method. """
     from supvisors.application import ApplicationStatus
     from supvisors.process import ProcessStatus
     application = ApplicationStatus('ApplicationTest', self.supvisors.logger)
     # add processes to the application
     for info in database_copy():
         process = ProcessStatus(info['group'], info['name'], self.supvisors)
         process.add_info('10.0.0.1', info)
         # set random sequence to process
         process.rules.start_sequence = random.randint(0, 2)
         process.rules.stop_sequence = random.randint(0, 2)
         application.add_process(process)
     # call the sequencer
     application.update_sequences()
     # check the sequencing of the starting
     sequences = sorted({process.rules.start_sequence for process in application.processes.values()})
     # as key is an integer, the sequence dictionary should be sorted but pypy doesn't...
     for sequence, processes in sorted(application.start_sequence.items()):
         self.assertEqual(sequence, sequences.pop(0))
         self.assertListEqual(sorted(processes, key=lambda x: x.process_name),
             sorted([proc for proc in application.processes.values() if sequence == proc.rules.start_sequence], key=lambda x: x.process_name))
     # check the sequencing of the stopping
     sequences = sorted({process.rules.stop_sequence for process in application.processes.values()})
     # as key is an integer, the sequence dictionary should be sorted but pypy doesn't...
     for sequence, processes in sorted(application.stop_sequence.items()):
         self.assertEqual(sequence, sequences.pop(0))
         self.assertListEqual(sorted(processes, key=lambda x: x.process_name),
             sorted([proc for proc in application.processes.values() if sequence == proc.rules.stop_sequence], key=lambda x: x.process_name))
Beispiel #2
0
 def test_add_process(self):
     """ Test the add_process method. """
     from supvisors.application import ApplicationStatus
     from supvisors.process import ProcessStatus
     application = ApplicationStatus('ApplicationTest', self.supvisors.logger)
     # add a process to the application
     info = any_process_info()
     process = ProcessStatus(info['group'], info['name'], self.supvisors)
     process.add_info('10.0.0.1', info)
     application.add_process(process)
     # check that process is stored
     self.assertIn(process.process_name, application.processes.keys())
     self.assertIs(process, application.processes[process.process_name])
 def test_add_process(self):
     """ Test the add_process method. """
     from supvisors.application import ApplicationStatus
     from supvisors.process import ProcessStatus
     application = ApplicationStatus('ApplicationTest', self.supvisors.logger)
     # add a process to the application
     info = any_process_info()
     process = ProcessStatus(info['group'], info['name'], self.supvisors)
     process.add_info('10.0.0.1', info)
     application.add_process(process)
     # check that process is stored
     self.assertIn(process.process_name, application.processes.keys())
     self.assertIs(process, application.processes[process.process_name])
Beispiel #4
0
 def load_processes(self, address, all_info):
     """ Load application dictionary from process info got from Supervisor on address. """
     # get all processes and sort them by group (application)
     # first store applications in a set
     application_list = {x['group'] for x in all_info}
     self.logger.debug('applicationList={} from {}'.format(
         application_list, address))
     # add unknown applications
     for application_name in application_list:
         if application_name not in self.applications.keys():
             application = ApplicationStatus(application_name, self.logger)
             if self.supvisors.parser:
                 self.supvisors.parser.load_application_rules(application)
             self.applications[application_name] = application
     # get AddressStatus corresponding to address
     status = self.addresses[address]
     # store processes into their application entry
     for info in all_info:
         try:
             process = self.process_from_info(info)
         except KeyError:
             # not found. add new ProcessStatus instance to dictionary and application
             process = ProcessStatus(info['group'], info['name'],
                                     self.supvisors)
             if self.supvisors.parser:
                 self.supvisors.parser.load_process_rules(process)
             self.processes[process.namespec()] = process
             self.applications[process.application_name].add_process(
                 process)
         # update the current entry
         process.add_info(address, info)
         # share the instance to the Supervisor instance that holds it
         status.add_process(process)
 def test_serialization(self):
     """ Test the serial method used to get a serializable form of Application. """
     import pickle
     from supvisors.application import ApplicationStatus
     from supvisors.ttypes import ApplicationStates
     # create address status instance
     application = ApplicationStatus('ApplicationTest', self.supvisors.logger)
     application._state = ApplicationStates.RUNNING
     application.major_failure = False
     application.minor_failure = True
     # test to_json method
     serialized = application.serial()
     self.assertDictEqual(serialized, {'application_name': 'ApplicationTest',
         'statecode': 2, 'statename': 'RUNNING',
         'major_failure': False, 'minor_failure':True})
     # test that returned structure is serializable using pickle
     dumped = pickle.dumps(serialized)
     loaded = pickle.loads(dumped)
     self.assertDictEqual(serialized, loaded)
Beispiel #6
0
 def test_serialization(self):
     """ Test the serial method used to get a serializable form of Application. """
     import pickle
     from supvisors.application import ApplicationStatus
     from supvisors.ttypes import ApplicationStates
     # create address status instance
     application = ApplicationStatus('ApplicationTest',
                                     self.supvisors.logger)
     application._state = ApplicationStates.RUNNING
     application.major_failure = False
     application.minor_failure = True
     # test to_json method
     serialized = application.serial()
     self.assertDictEqual(
         serialized, {
             'application_name': 'ApplicationTest',
             'statecode': 2,
             'statename': 'RUNNING',
             'major_failure': False,
             'minor_failure': True
         })
     # test that returned structure is serializable using pickle
     dumped = pickle.dumps(serialized)
     loaded = pickle.loads(dumped)
     self.assertDictEqual(serialized, loaded)
Beispiel #7
0
 def test_update_sequences(self):
     """ Test the sequencing of the deployment method. """
     from supvisors.application import ApplicationStatus
     from supvisors.process import ProcessStatus
     application = ApplicationStatus('ApplicationTest', self.supvisors.logger)
     # add processes to the application
     for info in ProcessInfoDatabase:
         process = ProcessStatus(info['group'], info['name'], self.supvisors)
         process.add_info('10.0.0.1', info.copy())
         # set random sequence to process
         process.rules.start_sequence = random.randint(0, 2)
         process.rules.stop_sequence = random.randint(0, 2)
         application.add_process(process)
     # call the sequencer
     application.update_sequences()
     # check the sequencing of the starting
     sequences = sorted({process.rules.start_sequence for process in application.processes.values()})
     # as key is an integer, the sequence dictionary should be sorted but pypy doesn't...
     for sequence, processes in sorted(application.start_sequence.items()):
         self.assertEqual(sequence, sequences.pop(0))
         self.assertListEqual(sorted(processes, key=lambda x: x.process_name),
             sorted([proc for proc in application.processes.values() if sequence == proc.rules.start_sequence], key=lambda x: x.process_name))
     # check the sequencing of the stopping
     sequences = sorted({process.rules.stop_sequence for process in application.processes.values()})
     # as key is an integer, the sequence dictionary should be sorted but pypy doesn't...
     for sequence, processes in sorted(application.stop_sequence.items()):
         self.assertEqual(sequence, sequences.pop(0))
         self.assertListEqual(sorted(processes, key=lambda x: x.process_name),
             sorted([proc for proc in application.processes.values() if sequence == proc.rules.stop_sequence], key=lambda x: x.process_name))
Beispiel #8
0
 def setdefault_application(self, application_name):
     """ Return the application corresponding to application_name if found.
     Otherwise return a new application for application_name.
     Related application rules are loaded from the rules file. """
     try:
         # find existing application
         application = self.applications[application_name]
     except KeyError:
         # create new instance
         application = ApplicationStatus(application_name, self.logger)
         # load rules from rules file
         self.supvisors.parser.load_application_rules(application)
         # add new application to context
         self.applications[application_name] = application
     return application
Beispiel #9
0
 def test_create(self):
     """ Test the values set at construction. """
     from supvisors.application import ApplicationStatus
     from supvisors.ttypes import ApplicationStates, StartingFailureStrategies, RunningFailureStrategies
     application = ApplicationStatus('ApplicationTest', self.supvisors.logger)
     # check application default attributes
     self.assertEqual('ApplicationTest', application.application_name)
     self.assertEqual(ApplicationStates.STOPPED, application.state)
     self.assertFalse(application.major_failure)
     self.assertFalse(application.minor_failure)
     self.assertFalse(application.processes)
     self.assertFalse(application.start_sequence)
     self.assertFalse(application.stop_sequence)
     # check application default rules
     self.assertEqual(0, application.rules.start_sequence)
     self.assertEqual(0, application.rules.stop_sequence)
     self.assertEqual(StartingFailureStrategies.ABORT, application.rules.starting_failure_strategy)
     self.assertEqual(RunningFailureStrategies.CONTINUE, application.rules.running_failure_strategy)
Beispiel #10
0
 def check_valid(self, parser):
     """ Test the parsing of a valid XML. """
     from supvisors.application import ApplicationStatus
     from supvisors.process import ProcessStatus
     from supvisors.ttypes import RunningFailureStrategies, StartingFailureStrategies
     # test models & patterns
     self.assertItemsEqual([
         'dummy_model_01', 'dummy_model_02', 'dummy_model_03',
         'dummy_model_04'
     ], parser.models.keys())
     self.assertItemsEqual(['dummies_', 'dummies_01_', 'dummies_02_'],
                           parser.patterns.keys())
     # check unknown application
     application = ApplicationStatus('dummy_application_X',
                                     self.supvisors.logger)
     parser.load_application_rules(application)
     self.assert_default_application_rules(application.rules)
     # check first application
     application = ApplicationStatus('dummy_application_A',
                                     self.supvisors.logger)
     parser.load_application_rules(application)
     self.assert_default_application_rules(application.rules)
     # check second application
     application = ApplicationStatus('dummy_application_B',
                                     self.supvisors.logger)
     parser.load_application_rules(application)
     self.assert_application_rules(application.rules, 1, 4,
                                   StartingFailureStrategies.STOP,
                                   RunningFailureStrategies.RESTART_PROCESS)
     # check third application
     application = ApplicationStatus('dummy_application_C',
                                     self.supvisors.logger)
     parser.load_application_rules(application)
     self.assert_application_rules(
         application.rules, 20, 0, StartingFailureStrategies.ABORT,
         RunningFailureStrategies.STOP_APPLICATION)
     # check fourth application
     application = ApplicationStatus('dummy_application_D',
                                     self.supvisors.logger)
     parser.load_application_rules(application)
     self.assert_application_rules(
         application.rules, 0, 100, StartingFailureStrategies.CONTINUE,
         RunningFailureStrategies.RESTART_APPLICATION)
     # check program from unknown application: all default
     process = ProcessStatus('dummy_application_X', 'dummy_program_X0',
                             self.supvisors)
     parser.load_process_rules(process)
     self.assert_default_process_rules(process.rules)
     # check unknown program from known application: all default
     process = ProcessStatus('dummy_application_A', 'dummy_program_A0',
                             self.supvisors)
     parser.load_process_rules(process)
     self.assert_default_process_rules(process.rules)
     # check known program from known but not related application: all default
     process = ProcessStatus('dummy_application_A', 'dummy_program_B1',
                             self.supvisors)
     parser.load_process_rules(process)
     self.assert_default_process_rules(process.rules)
     # check known empty program
     process = ProcessStatus('dummy_application_B', 'dummy_program_B0',
                             self.supvisors)
     parser.load_process_rules(process)
     self.assert_default_process_rules(process.rules)
     # check dash addresses and valid other values
     process = ProcessStatus('dummy_application_B', 'dummy_program_B1',
                             self.supvisors)
     parser.load_process_rules(process)
     self.assert_process_rules(process.rules, ['#'], 3, 50, True, False, 5,
                               RunningFailureStrategies.CONTINUE)
     # check single address with required not applicable and out of range loading
     process = ProcessStatus('dummy_application_B', 'dummy_program_B2',
                             self.supvisors)
     parser.load_process_rules(process)
     self.assert_process_rules(process.rules, ['10.0.0.3'], 0, 0, False,
                               False, 1,
                               RunningFailureStrategies.RESTART_PROCESS)
     # check wildcard address, optional and max loading
     process = ProcessStatus('dummy_application_B', 'dummy_program_B3',
                             self.supvisors)
     parser.load_process_rules(process)
     self.assert_process_rules(process.rules, ['*'], 0, 0, False, False,
                               100,
                               RunningFailureStrategies.STOP_APPLICATION)
     # check multiple addresses, all other incorrect values
     process = ProcessStatus('dummy_application_B', 'dummy_program_B4',
                             self.supvisors)
     parser.load_process_rules(process)
     self.assert_process_rules(process.rules,
                               ['10.0.0.3', '10.0.0.1', '10.0.0.5'], 0, 0,
                               False, False, 1,
                               RunningFailureStrategies.RESTART_APPLICATION)
     # check empty reference
     process = ProcessStatus('dummy_application_C', 'dummy_program_C0',
                             self.supvisors)
     parser.load_process_rules(process)
     self.assert_default_process_rules(process.rules)
     # check unknown reference
     process = ProcessStatus('dummy_application_C', 'dummy_program_C1',
                             self.supvisors)
     parser.load_process_rules(process)
     self.assert_default_process_rules(process.rules)
     # check known reference
     process = ProcessStatus('dummy_application_C', 'dummy_program_C2',
                             self.supvisors)
     parser.load_process_rules(process)
     self.assert_process_rules(process.rules, ['*'], 0, 0, False, False, 25,
                               RunningFailureStrategies.STOP_APPLICATION)
     # check other known reference
     process = ProcessStatus('dummy_application_C', 'dummy_program_C3',
                             self.supvisors)
     parser.load_process_rules(process)
     self.assert_process_rules(process.rules, ['#'], 1, 0, True, True, 1,
                               RunningFailureStrategies.CONTINUE)
     # check pattern with single matching and reference
     process = ProcessStatus('dummy_application_D', 'dummies_any',
                             self.supvisors)
     parser.load_process_rules(process)
     self.assert_process_rules(process.rules, ['10.0.0.4', '10.0.0.2'], 0,
                               100, False, False, 10,
                               RunningFailureStrategies.CONTINUE)
     # check pattern with multiple matching and configuration
     process = ProcessStatus('dummy_application_D', 'dummies_01_any',
                             self.supvisors)
     parser.load_process_rules(process)
     self.assert_process_rules(process.rules, ['#'], 1, 1, False, True, 75,
                               RunningFailureStrategies.CONTINUE)
     # check pattern with multiple matching and incorrect reference
     process = ProcessStatus('dummy_application_D', 'any_dummies_02_',
                             self.supvisors)
     parser.load_process_rules(process)
     self.assert_default_process_rules(process.rules)
 def test_running(self):
     """ Test the running method. """
     from supvisors.application import ApplicationStatus
     from supvisors.process import ProcessStatus
     application = ApplicationStatus('ApplicationTest', self.supvisors.logger)
     self.assertFalse(application.running())
     # add a stopped process
     info = any_stopped_process_info()
     process = ProcessStatus(info['group'], info['name'], self.supvisors)
     process.add_info('10.0.0.1', info)
     application.add_process(process)
     application.update_status()
     self.assertFalse(application.running())
     # add a running process
     info = any_running_process_info()
     process = ProcessStatus(info['group'], info['name'], self.supvisors)
     process.add_info('10.0.0.1', info)
     application.add_process(process)
     application.update_status()
     self.assertTrue(application.running())
 def test_update_status(self):
     """ Test the rules to update the status of the application method. """
     from supervisor.states import ProcessStates
     from supvisors.application import ApplicationStatus
     from supvisors.process import ProcessStatus
     from supvisors.ttypes import ApplicationStates
     application = ApplicationStatus('ApplicationTest', self.supvisors.logger)
     # add processes to the application
     for info in database_copy():
         process = ProcessStatus(info['group'], info['name'], self.supvisors)
         process.add_info('10.0.0.1', info)
         application.add_process(process)
     # init status
     # there are lots of states but the 'strongest' is STARTING
     # STARTING is a 'running' state so major/minor failures are applicable
     application.update_status()
     self.assertEqual(ApplicationStates.STARTING, application.state)
     # there is a FATAL state in the process database
     # no rule is set for processes, so there are only minor failures
     self.assertFalse(application.major_failure)
     self.assertTrue(application.minor_failure)
     # set FATAL process to major
     fatal_process = next((process for process in application.processes.values() if process.state == ProcessStates.FATAL), None)
     fatal_process.rules.required = True
     # update status. major failure is now expected
     application.update_status()
     self.assertEqual(ApplicationStates.STARTING, application.state)
     self.assertTrue(application.major_failure)
     self.assertFalse(application.minor_failure)
     # set STARTING process to RUNNING
     starting_process = next((process for process in application.processes.values() if process.state == ProcessStates.STARTING), None)
     starting_process.state = ProcessStates.RUNNING
     # update status. there is still one BACKOFF process leading to STARTING application
     application.update_status()
     self.assertEqual(ApplicationStates.STARTING, application.state)
     self.assertTrue(application.major_failure)
     self.assertFalse(application.minor_failure)
     # set BACKOFF process to EXITED
     backoff_process = next((process for process in application.processes.values() if process.state == ProcessStates.BACKOFF), None)
     backoff_process.state = ProcessStates.EXITED
     # update status. the 'strongest' state is now STOPPING
     # as STOPPING is not a 'running' state, failures are not applicable
     application.update_status()
     self.assertEqual(ApplicationStates.STOPPING, application.state)
     self.assertFalse(application.major_failure)
     self.assertFalse(application.minor_failure)
     # set STOPPING process to STOPPED
     stopping_process = next((process for process in application.processes.values() if process.state == ProcessStates.STOPPING), None)
     stopping_process.state = ProcessStates.STOPPED
     # update status. the 'strongest' state is now RUNNING
     # failures are applicable again
     application.update_status()
     self.assertEqual(ApplicationStates.RUNNING, application.state)
     self.assertTrue(application.major_failure)
     self.assertFalse(application.minor_failure)
     # set RUNNING processes to STOPPED
     for process in application.processes.values():
         if process.state == ProcessStates.RUNNING:
             process.state = ProcessStates.STOPPED
     # update status. the 'strongest' state is now RUNNING
     # failures are not applicable anymore
     application.update_status()
     self.assertEqual(ApplicationStates.STOPPED, application.state)
     self.assertFalse(application.major_failure)
     self.assertFalse(application.minor_failure)
Beispiel #13
0
 def test_deployment_state(self):
     """ Test the Deployment state of the FSM. """
     from supvisors.application import ApplicationStatus
     from supvisors.process import ProcessStatus
     from supvisors.statemachine import AbstractState, DeploymentState
     from supvisors.ttypes import ApplicationStates, SupvisorsStates
     state = DeploymentState(self.supvisors)
     self.assertIsInstance(state, AbstractState)
     # test enter method
     # test that start_applications is  called only when local address is the master address
     with patch.object(self.supvisors.starter,
                       'start_applications') as mocked_starter:
         self.supvisors.context.master = False
         state.enter()
         self.assertEqual(0, mocked_starter.call_count)
         # now master address is local
         self.supvisors.context.master = True
         state.enter()
         self.assertEqual(1, mocked_starter.call_count)
     # create application context
     application = ApplicationStatus('sample_test_2', self.supvisors.logger)
     self.supvisors.context.applications['sample_test_2'] = application
     for info in database_copy():
         if info['group'] == 'sample_test_2':
             process = ProcessStatus(info['group'], info['name'],
                                     self.supvisors)
             process.rules.start_sequence = len(process.namespec()) % 3
             process.rules.stop_sequence = len(process.namespec()) % 3 + 1
             process.add_info('10.0.0.1', info)
             application.add_process(process)
     # test application updates
     self.supvisors.context.master = False
     self.assertEqual(ApplicationStates.STOPPED, application.state)
     self.assertFalse(application.minor_failure)
     self.assertFalse(application.major_failure)
     self.assertDictEqual({}, application.start_sequence)
     self.assertDictEqual({}, application.stop_sequence)
     state.enter()
     application = self.supvisors.context.applications['sample_test_2']
     self.assertEqual(ApplicationStates.RUNNING, application.state)
     self.assertTrue(application.minor_failure)
     self.assertFalse(application.major_failure)
     # list order may differ, so break down
     self.assertItemsEqual([0, 1], application.start_sequence.keys())
     self.assertItemsEqual([
         application.processes['yeux_01'], application.processes['yeux_00']
     ], application.start_sequence[0])
     self.assertItemsEqual([application.processes['sleep']],
                           application.start_sequence[1])
     self.assertItemsEqual([1, 2], application.stop_sequence.keys())
     self.assertItemsEqual([
         application.processes['yeux_01'], application.processes['yeux_00']
     ], application.stop_sequence[1])
     self.assertItemsEqual([application.processes['sleep']],
                           application.stop_sequence[2])
     # test next method
     # stay in DEPLOYMENT if local is master and a deployment is in progress, whatever the conflict status
     with patch.object(self.supvisors.starter,
                       'check_starting',
                       return_value=False):
         for conflict in [True, False]:
             with patch.object(self.supvisors.context,
                               'conflicting',
                               return_value=conflict):
                 self.supvisors.context.master = True
                 result = state.next()
                 self.assertEqual(SupvisorsStates.DEPLOYMENT, result)
     # return OPERATION if local is not master and no conflict, whatever the starting status
     self.supvisors.context.master = False
     with patch.object(self.supvisors.context,
                       'conflicting',
                       return_value=False):
         for starting in [True, False]:
             with patch.object(self.supvisors.starter,
                               'check_starting',
                               return_value=starting):
                 result = state.next()
                 self.assertEqual(SupvisorsStates.OPERATION, result)
     # return OPERATION if a deployment is in progress and no conflict, whatever the master status
     with patch.object(self.supvisors.starter,
                       'check_starting',
                       return_value=True):
         with patch.object(self.supvisors.context,
                           'conflicting',
                           return_value=False):
             for master in [True, False]:
                 self.supvisors.context.master = master
                 result = state.next()
                 self.assertEqual(SupvisorsStates.OPERATION, result)
     # return CONCILIATION if local is not master and conflict detected, whatever the starting status
     self.supvisors.context.master = False
     with patch.object(self.supvisors.context,
                       'conflicting',
                       return_value=True):
         for starting in [True, False]:
             with patch.object(self.supvisors.starter,
                               'check_starting',
                               return_value=starting):
                 result = state.next()
                 self.assertEqual(SupvisorsStates.CONCILIATION, result)
     # return CONCILIATION if a deployment is in progress and conflict detected, whatever the master status
     with patch.object(self.supvisors.starter,
                       'check_starting',
                       return_value=True):
         with patch.object(self.supvisors.context,
                           'conflicting',
                           return_value=True):
             for master in [True, False]:
                 self.supvisors.context.master = master
                 result = state.next()
                 self.assertEqual(SupvisorsStates.CONCILIATION, result)
     # no exit implementation. just call it without test
     state.exit()
 def test_deployment_state(self):
     """ Test the Deployment state of the FSM. """
     from supvisors.application import ApplicationStatus
     from supvisors.process import ProcessStatus
     from supvisors.statemachine import AbstractState, DeploymentState
     from supvisors.ttypes import ApplicationStates, SupvisorsStates
     state = DeploymentState(self.supvisors)
     self.assertIsInstance(state, AbstractState)
     # test enter method
     # test that start_applications is  called only when local address is the master address
     with patch.object(self.supvisors.starter, 'start_applications') as mocked_starter:
         self.supvisors.context.master = False
         state.enter()
         self.assertEqual(0, mocked_starter.call_count)
         # now master address is local
         self.supvisors.context.master = True
         state.enter()
         self.assertEqual(1, mocked_starter.call_count)
     # create application context
     application = ApplicationStatus('sample_test_2', self.supvisors.logger)
     self.supvisors.context.applications['sample_test_2'] = application
     for info in database_copy():
         if info['group'] == 'sample_test_2':
             process = ProcessStatus(info['group'], info['name'], self.supvisors)
             process.rules.start_sequence = len(process.namespec()) % 3
             process.rules.stop_sequence = len(process.namespec()) % 3 + 1
             process.add_info('10.0.0.1', info)
             application.add_process(process)
     # test application updates
     self.supvisors.context.master = False
     self.assertEqual(ApplicationStates.STOPPED, application.state)
     self.assertFalse(application.minor_failure)
     self.assertFalse(application.major_failure)
     self.assertDictEqual({}, application.start_sequence)
     self.assertDictEqual({}, application.stop_sequence)
     state.enter()
     application = self.supvisors.context.applications['sample_test_2']
     self.assertEqual(ApplicationStates.RUNNING, application.state)
     self.assertTrue(application.minor_failure)
     self.assertFalse(application.major_failure)
     # list order may differ, so break down
     self.assertItemsEqual([0, 1], application.start_sequence.keys())
     self.assertItemsEqual([application.processes['yeux_01'], application.processes['yeux_00']], application.start_sequence[0])
     self.assertItemsEqual([application.processes['sleep']], application.start_sequence[1])
     self.assertItemsEqual([1, 2], application.stop_sequence.keys())
     self.assertItemsEqual([application.processes['yeux_01'], application.processes['yeux_00']], application.stop_sequence[1])
     self.assertItemsEqual([application.processes['sleep']], application.stop_sequence[2])
     # test next method
     # stay in DEPLOYMENT if local is master and a starting is in progress, whatever the conflict status
     with patch.object(self.supvisors.starter, 'check_starting', return_value=False):
         for conflict in [True, False]:
             with patch.object(self.supvisors.context, 'conflicting', return_value=conflict):
                 self.supvisors.context.master = True
                 result = state.next()
                 self.assertEqual(SupvisorsStates.DEPLOYMENT, result)
     # return OPERATION if local is not master and no conflict, whatever the starting status
     self.supvisors.context.master = False
     with patch.object(self.supvisors.context, 'conflicting', return_value=False):
         for starting in [True, False]:
             with patch.object(self.supvisors.starter, 'check_starting', return_value=starting):
                 result = state.next()
                 self.assertEqual(SupvisorsStates.OPERATION, result)
     # return OPERATION if a starting is in progress and no conflict, whatever the master status
     with patch.object(self.supvisors.starter, 'check_starting', return_value=True):
         with patch.object(self.supvisors.context, 'conflicting', return_value=False):
             for master in [True, False]:
                 self.supvisors.context.master = master
                 result = state.next()
                 self.assertEqual(SupvisorsStates.OPERATION, result)
      # return CONCILIATION if local is not master and conflict detected, whatever the starting status
     self.supvisors.context.master = False
     with patch.object(self.supvisors.context, 'conflicting', return_value=True):
         for starting in [True, False]:
             with patch.object(self.supvisors.starter, 'check_starting', return_value=starting):
                 result = state.next()
                 self.assertEqual(SupvisorsStates.CONCILIATION, result)
     # return CONCILIATION if a starting is in progress and conflict detected, whatever the master status
     with patch.object(self.supvisors.starter, 'check_starting', return_value=True):
         with patch.object(self.supvisors.context, 'conflicting', return_value=True):
             for master in [True, False]:
                 self.supvisors.context.master = master
                 result = state.next()
                 self.assertEqual(SupvisorsStates.CONCILIATION, result)
     # no exit implementation. just call it without test
     state.exit()
Beispiel #15
0
 def test_stopped(self):
     """ Test the stopped method. """
     from supvisors.application import ApplicationStatus
     from supvisors.process import ProcessStatus
     application = ApplicationStatus('ApplicationTest',
                                     self.supvisors.logger)
     self.assertTrue(application.stopped())
     # add a stopped process
     info = any_stopped_process_info()
     process = ProcessStatus(info['group'], info['name'], self.supvisors)
     process.add_info('10.0.0.1', info)
     application.add_process(process)
     application.update_status()
     self.assertTrue(application.stopped())
     # add a running process
     info = any_running_process_info()
     process = ProcessStatus(info['group'], info['name'], self.supvisors)
     process.add_info('10.0.0.1', info)
     application.add_process(process)
     application.update_status()
     self.assertFalse(application.stopped())
Beispiel #16
0
 def test_update_status(self):
     """ Test the rules to update the status of the application method. """
     from supervisor.states import ProcessStates
     from supvisors.application import ApplicationStatus
     from supvisors.process import ProcessStatus
     from supvisors.ttypes import ApplicationStates
     application = ApplicationStatus('ApplicationTest',
                                     self.supvisors.logger)
     # add processes to the application
     for info in ProcessInfoDatabase:
         process = ProcessStatus(info['group'], info['name'],
                                 self.supvisors)
         process.add_info('10.0.0.1', info.copy())
         application.add_process(process)
     # init status
     # there are lots of states but the 'strongest' is STARTING
     # STARTING is a 'running' state so major/minor failures are applicable
     application.update_status()
     self.assertEqual(ApplicationStates.STARTING, application.state)
     # there is a FATAL state in the process database
     # no rule is set for processes, so there are only minor failures
     self.assertFalse(application.major_failure)
     self.assertTrue(application.minor_failure)
     # set FATAL process to major
     fatal_process = next((process
                           for process in application.processes.values()
                           if process.state == ProcessStates.FATAL), None)
     fatal_process.rules.required = True
     # update status. major failure is now expected
     application.update_status()
     self.assertEqual(ApplicationStates.STARTING, application.state)
     self.assertTrue(application.major_failure)
     self.assertFalse(application.minor_failure)
     # set STARTING process to RUNNING
     starting_process = next(
         (process for process in application.processes.values()
          if process.state == ProcessStates.STARTING), None)
     starting_process.state = ProcessStates.RUNNING
     # update status. there is still one BACKOFF process leading to STARTING application
     application.update_status()
     self.assertEqual(ApplicationStates.STARTING, application.state)
     self.assertTrue(application.major_failure)
     self.assertFalse(application.minor_failure)
     # set BACKOFF process to EXITED
     backoff_process = next(
         (process for process in application.processes.values()
          if process.state == ProcessStates.BACKOFF), None)
     backoff_process.state = ProcessStates.EXITED
     # update status. the 'strongest' state is now STOPPING
     # as STOPPING is not a 'running' state, failures are not applicable
     application.update_status()
     self.assertEqual(ApplicationStates.STOPPING, application.state)
     self.assertFalse(application.major_failure)
     self.assertFalse(application.minor_failure)
     # set STOPPING process to STOPPED
     stopping_process = next(
         (process for process in application.processes.values()
          if process.state == ProcessStates.STOPPING), None)
     stopping_process.state = ProcessStates.STOPPED
     # update status. the 'strongest' state is now RUNNING
     # failures are applicable again
     application.update_status()
     self.assertEqual(ApplicationStates.RUNNING, application.state)
     self.assertTrue(application.major_failure)
     self.assertFalse(application.minor_failure)
     # set RUNNING processes to STOPPED
     for process in application.processes.values():
         if process.state == ProcessStates.RUNNING:
             process.state = ProcessStates.STOPPED
     # update status. the 'strongest' state is now RUNNING
     # failures are not applicable anymore
     application.update_status()
     self.assertEqual(ApplicationStates.STOPPED, application.state)
     self.assertFalse(application.major_failure)
     self.assertFalse(application.minor_failure)