class TestModuleManager(AlignakTest): def setUp(self): self.setup_with_file([]) time_hacker.set_real_time() # Try to see if the module manager can manage modules def test_modulemanager(self): mod = Module({'module_alias': 'mod-example', 'python_name': 'alignak_module_example'}) self.modulemanager = ModulesManager('broker', None) self.modulemanager.load_and_init([mod]) # And start external ones, like our LiveStatus self.modulemanager.start_external_instances() print "I correctly loaded the modules: %s " % ([inst.get_name() for inst in self.modulemanager.instances]) print "*** First kill ****" # Now I will try to kill the livestatus module ls = self.modulemanager.instances[0] " :type: alignak.basemodule.BaseModule " ls.kill() time.sleep(0.1) print "Check alive?" print "Is alive?", ls.process.is_alive() # Should be dead self.assertFalse(ls.process.is_alive()) self.modulemanager.check_alive_instances() self.modulemanager.try_to_restart_deads() # In fact it's too early, so it won't do it # Here the inst should still be dead print "Is alive?", ls.process.is_alive() self.assertFalse(ls.process.is_alive()) # So we lie ls.last_init_try = -5 self.modulemanager.check_alive_instances() self.modulemanager.try_to_restart_deads() # In fact it's too early, so it won't do it # Here the inst should be alive again print "Is alive?", ls.process.is_alive() self.assertTrue(ls.process.is_alive()) # should be nothing more in to_restart of # the module manager self.assertEqual([], self.modulemanager.to_restart) # Now we look for time restart so we kill it again ls.kill() time.sleep(0.2) self.assertFalse(ls.process.is_alive()) # Should be too early self.modulemanager.check_alive_instances() self.modulemanager.try_to_restart_deads() print "Is alive or not", ls.process.is_alive() self.assertFalse(ls.process.is_alive()) # We lie for the test again ls.last_init_try = -5 self.modulemanager.check_alive_instances() self.modulemanager.try_to_restart_deads() # Here the inst should be alive again print "Is alive?", ls.process.is_alive() self.assertTrue(ls.process.is_alive()) # And we clear all now print "Ask to die" self.modulemanager.stop_all() print "Died"
class TestModules(AlignakTest): """ This class contains the tests for the module """ def test_module_loading(self): """ Test arbiter, broker, ... auto-generated modules Alignak module loading :return: """ self.print_header() self.setup_with_file('./cfg/cfg_default.cfg') self.assertTrue(self.conf_is_correct) self.show_configuration_logs() # No arbiter modules created modules = [m.module_alias for m in self.arbiter.myself.modules] self.assertListEqual(modules, []) # The only existing broker module is logs declared in the configuration modules = [m.module_alias for m in self.brokers['broker-master'].modules] self.assertListEqual(modules, []) # No poller module modules = [m.module_alias for m in self.pollers['poller-master'].modules] self.assertListEqual(modules, []) # No receiver module modules = [m.module_alias for m in self.receivers['receiver-master'].modules] self.assertListEqual(modules, ['web-services']) # No reactionner module modules = [m.module_alias for m in self.reactionners['reactionner-master'].modules] self.assertListEqual(modules, []) # No scheduler modules modules = [m.module_alias for m in self.schedulers['scheduler-master'].modules] self.assertListEqual(modules, []) def test_module_manager(self): """ Test if the module manager manages correctly all the modules :return: """ self.print_header() self.setup_with_file('cfg/cfg_default.cfg') self.assertTrue(self.conf_is_correct) time_hacker.set_real_time() # Create an Alignak module mod = Module({ 'module_alias': 'web-services', 'module_types': 'web-services', 'python_name': 'alignak_module_ws', # Set Arbiter address as empty to not poll the Arbiter else the test will fail! 'alignak_host': '', 'alignak_port': 7770, }) # Create the modules manager for a daemon type self.modulemanager = ModulesManager('receiver', None) # Load and initialize the modules: # - load python module # - get module properties and instances self.modulemanager.load_and_init([mod]) # Loading module logs self.assert_any_log_match(re.escape( "Importing Python module 'alignak_module_ws' for web-services..." )) self.assert_any_log_match(re.escape( "Module properties: {'daemons': ['receiver'], 'phases': ['running'], " "'type': 'web-services', 'external': True}" )) self.assert_any_log_match(re.escape( "Imported 'alignak_module_ws' for web-services" )) self.assert_any_log_match(re.escape( "Loaded Python module 'alignak_module_ws' (web-services)" )) self.assert_any_log_match(re.escape( "Give an instance of alignak_module_ws for alias: web-services" )) my_module = self.modulemanager.instances[0] # Get list of not external modules self.assertListEqual([], self.modulemanager.get_internal_instances()) for phase in ['configuration', 'late_configuration', 'running', 'retention']: self.assertListEqual([], self.modulemanager.get_internal_instances(phase)) # Get list of external modules self.assertListEqual([my_module], self.modulemanager.get_external_instances()) for phase in ['configuration', 'late_configuration', 'retention']: self.assertListEqual([], self.modulemanager.get_external_instances(phase)) for phase in ['running']: self.assertListEqual([my_module], self.modulemanager.get_external_instances(phase)) # Clear logs self.clear_logs() # Start external modules self.modulemanager.start_external_instances() # Starting external module logs self.assert_log_match("Trying to initialize module: web-services", 0) self.assert_log_match("Starting external module web-services", 1) self.assert_log_match("Starting external process for module web-services", 2) self.assert_log_match("web-services is now started", 3) # Check alive self.assertIsNotNone(my_module.process) self.assertTrue(my_module.process.is_alive()) # Clear logs self.clear_logs() # Kill the external module (normal stop is .stop_process) my_module.kill() time.sleep(0.1) self.assert_log_match("Killing external module", 0) self.assert_log_match("External module killed", 1) # Should be dead (not normally stopped...) but we still know a process for this module! self.assertIsNotNone(my_module.process) # Nothing special ... self.modulemanager.check_alive_instances() self.assert_log_match("The external module web-services died unexpectedly!", 2) self.assert_log_match("Setting the module web-services to restart", 3) # Try to restart the dead modules self.modulemanager.try_to_restart_deads() self.assert_log_match("Trying to initialize module: web-services", 4) # In fact it's too early, so it won't do it # The module instance is still dead self.assertFalse(my_module.process.is_alive()) # So we lie, on the restart tries ... my_module.last_init_try = -5 self.modulemanager.check_alive_instances() self.modulemanager.try_to_restart_deads() self.assert_log_match("Trying to initialize module: web-services", 5) # The module instance is now alive again self.assertTrue(my_module.process.is_alive()) self.assert_log_match("I'm stopping module 'web-services'", 6) self.assert_log_match("Starting external process for module web-services", 7) self.assert_log_match("web-services is now started", 8) # There is nothing else to restart in the module manager self.assertEqual([], self.modulemanager.to_restart) # Clear logs self.clear_logs() # Now we look for time restart so we kill it again my_module.kill() time.sleep(0.2) self.assertFalse(my_module.process.is_alive()) self.assert_log_match("Killing external module", 0) self.assert_log_match("External module killed", 1) # Should be too early self.modulemanager.check_alive_instances() self.assert_log_match("The external module web-services died unexpectedly!", 2) self.assert_log_match("Setting the module web-services to restart", 3) self.modulemanager.try_to_restart_deads() self.assert_log_match("Trying to initialize module: web-services", 4) # In fact it's too early, so it won't do it # The module instance is still dead self.assertFalse(my_module.process.is_alive()) # So we lie, on the restart tries ... my_module.last_init_try = -5 self.modulemanager.check_alive_instances() self.modulemanager.try_to_restart_deads() self.assert_log_match("Trying to initialize module: web-services", 5) # The module instance is now alive again self.assertTrue(my_module.process.is_alive()) self.assert_log_match("I'm stopping module 'web-services'", 6) self.assert_log_match("Starting external process for module web-services", 7) self.assert_log_match("web-services is now started", 8) # And we clear all now self.modulemanager.stop_all() # Stopping module logs self.assert_log_match("Request external process to stop for web-services", 9) self.assert_log_match(re.escape("I'm stopping module 'web-services' (pid="), 10) self.assert_log_match( re.escape("'web-services' is still alive after normal kill, I help it to die"), 11 ) self.assert_log_match("Killing external module ", 12) self.assert_log_match("External module killed", 13) self.assert_log_match("External process stopped.", 14) def test_module_start_default(self): """ Test the module initialization function, no parameters, using default :return: """ self.print_header() # Obliged to call to get a self.logger... self.setup_with_file('cfg/cfg_default.cfg') self.assertTrue(self.conf_is_correct) # ----- # Default initialization # ----- # Clear logs self.clear_logs() # Create an Alignak module mod = Module({ 'module_alias': 'web-services', 'module_types': 'web-services', 'python_name': 'alignak_module_ws' }) instance = alignak_module_ws.get_instance(mod) self.assertIsInstance(instance, BaseModule) self.assert_log_match( re.escape("Give an instance of alignak_module_ws for " "alias: web-services"), 0) self.assert_log_match( re.escape("configuration, Alignak Arbiter: 127.0.0.1:7770"), 1) self.assert_log_match( re.escape("configuration, listening on: 0.0.0.0:8888"), 2) self.assert_log_match( re.escape("SSL is not enabled, this is not recommended. " "You should consider enabling SSL!"), 3) def test_module_start_parameters(self): """ Test the module initialization function, no parameters, provide parameters :return: """ self.print_header() # Obliged to call to get a self.logger... self.setup_with_file('cfg/cfg_default.cfg') self.assertTrue(self.conf_is_correct) # ----- # Provide parameters # ----- # Clear logs self.clear_logs() # Create an Alignak module mod = Module({ 'module_alias': 'web-services', 'module_types': 'web-services', 'python_name': 'alignak_module_ws', 'use_ssl': '1', 'alignak_host': 'my_host', 'alignak_port': 80, 'host': 'me', 'port': 8080, }) instance = alignak_module_ws.get_instance(mod) self.assertIsInstance(instance, BaseModule) self.assert_log_match( re.escape("Give an instance of alignak_module_ws for " "alias: web-services"), 0) self.assert_log_match( re.escape("configuration, Alignak Arbiter: my_host:80"), 1) self.assert_log_match( re.escape("configuration, listening on: me:8080"), 2) self.assert_log_match( re.escape("Error : the CA certificate /usr/local/etc/alignak/certs/ca.pem is " "missing (ca_cert).Please fix it in your configuration"), 3) self.assert_log_match( re.escape("SSL is not enabled, this is not recommended. " "You should consider enabling SSL!"), 4) def test_module_zzz_run(self): """ Test the module API :return: """ self.print_header() # Obliged to call to get a self.logger... self.setup_with_file('cfg/cfg_default.cfg') self.assertTrue(self.conf_is_correct) # ----- # Provide parameters - logger configuration file (exists) # ----- # Clear logs self.clear_logs() # Create an Alignak module mod = Module({ 'module_alias': 'web-services', 'module_types': 'web-services', 'python_name': 'alignak_module_ws', # Set Arbiter address as empty to not poll the Arbiter else the test will fail! 'alignak_host': '', 'alignak_port': 7770, }) # Create the modules manager for a daemon type self.modulemanager = ModulesManager('receiver', None) # Load an initialize the modules: # - load python module # - get module properties and instances self.modulemanager.load_and_init([mod]) my_module = self.modulemanager.instances[0] # Clear logs self.clear_logs() # Start external modules self.modulemanager.start_external_instances() # Starting external module logs self.assert_log_match("Trying to initialize module: web-services", 0) self.assert_log_match("Starting external module web-services", 1) self.assert_log_match("Starting external process for module web-services", 2) self.assert_log_match("web-services is now started", 3) # Check alive self.assertIsNotNone(my_module.process) self.assertTrue(my_module.process.is_alive()) time.sleep(1) # Get the module API list and request on each endpoint response = requests.get('http://127.0.0.1:8888') api_list = response.json() for endpoint in api_list: print("Trying %s" % (endpoint)) response = requests.get('http://127.0.0.1:8888/' + endpoint) print("Response %d: %s" % (response.status_code, response.content)) self.assertEqual(response.status_code, 200) if response.status_code == 200: print("Got %s: %s" % (endpoint, response.json())) else: print("Error %s: %s" % (response.status_code, response.content)) time.sleep(1) # Do not allow GET request on /command response = requests.get('http://127.0.0.1:8888/command') self.assertEqual(response.status_code, 200) result = response.json() self.assertEqual(result['_status'], 'ko') self.assertEqual(result['_result'], 'You must only POST on this endpoint.') self.assertEqual(my_module.received_commands, 0) # You must have parameters when POSTing on /command headers = {'Content-Type': 'application/json'} data = {} response = requests.post('http://127.0.0.1:8888/command', json=data, headers=headers) self.assertEqual(response.status_code, 200) result = response.json() self.assertEqual(result['_status'], 'ko') self.assertEqual(result['_result'], 'You must POST parameters on this endpoint.') self.assertEqual(my_module.received_commands, 0) # Request to execute an external command headers = {'Content-Type': 'application/json'} data = { "command": "Command", "element": "test_host", "parameters": "abc;1" } self.assertEqual(my_module.received_commands, 0) response = requests.post('http://127.0.0.1:8888/command', json=data, headers=headers) self.assertEqual(response.status_code, 200) result = response.json() self.assertEqual(result['_status'], 'ok') # Result is uppercase command, parameters are ordered self.assertEqual(result['_result'], 'COMMAND;test_host;abc;1') # Not during unit tests ... because module queues are not functional! # time.sleep(1) # self.assertEqual(my_module.received_commands, 1) # Request to execute an external command headers = {'Content-Type': 'application/json'} data = { "command": "command_command", "element": "test_host;test_service", "parameters": "1;abc;2" } response = requests.post('http://127.0.0.1:8888/command', json=data, headers=headers) self.assertEqual(response.status_code, 200) result = response.json() self.assertEqual(result['_status'], 'ok') # Result is uppercase command, parameters are ordered self.assertEqual(result['_result'], 'COMMAND_COMMAND;test_host;test_service;1;abc;2') # Request to execute an external command headers = {'Content-Type': 'application/json'} data = { "command": "command_command", "element": "test_host/test_service", # Accept / as an host/service separator "parameters": "1;abc;2" } response = requests.post('http://127.0.0.1:8888/command', json=data, headers=headers) self.assertEqual(response.status_code, 200) result = response.json() self.assertEqual(result['_status'], 'ok') # Result is uppercase command, parameters are ordered self.assertEqual(result['_result'], 'COMMAND_COMMAND;test_host;test_service;1;abc;2') # Request to execute an external command (Alignak modern syntax) headers = {'Content-Type': 'application/json'} data = { "command": "command_command", "host": "test_host", "service": "test_service", "parameters": "1;abc;2" } response = requests.post('http://127.0.0.1:8888/command', json=data, headers=headers) self.assertEqual(response.status_code, 200) result = response.json() self.assertEqual(result['_status'], 'ok') # Result is uppercase command, parameters are ordered self.assertEqual(result['_result'], 'COMMAND_COMMAND;test_host;test_service;1;abc;2') # Request to execute an external command (Alignak modern syntax) headers = {'Content-Type': 'application/json'} data = { "command": "command_command", "host": "test_host", "service": "test_service", "user": "******", "parameters": "1;abc;2" } response = requests.post('http://127.0.0.1:8888/command', json=data, headers=headers) self.assertEqual(response.status_code, 200) result = response.json() self.assertEqual(result['_status'], 'ok') # Result is uppercase command, parameters are ordered self.assertEqual(result['_result'], 'COMMAND_COMMAND;test_host;test_service;test_user;1;abc;2') self.modulemanager.stop_all()
class TestModules(AlignakTest): """ This class contains the tests for the modules """ def setUp(self): super(TestModules, self).setUp() self.set_unit_tests_logger_level('INFO') def test_module_loading(self): """ Test arbiter, broker, ... detecting configured modules :return: """ self.setup_with_file('cfg/cfg_default_with_modules.cfg', 'cfg/default_with_modules/alignak.ini') assert self.conf_is_correct self.show_configuration_logs() self.show_logs() # arbiter modules modules = [m.module_alias for m in self._arbiter.link_to_myself.modules] assert modules == ['Example'] modules = [m.name for m in self._arbiter.link_to_myself.modules] assert modules == ['Example'] # broker modules modules = [m.module_alias for m in self._broker_daemon.modules] assert modules == ['Example'] modules = [m.name for m in self._broker_daemon.modules] assert modules == ['Example'] # # The only existing poller module is Example declared in the configuration # modules = [m.module_alias for m in self.pollers['poller-master'].modules] # assert modules == ['Example'] # # # The only existing receiver module is Example declared in the configuration # modules = [m.module_alias for m in self.receivers['receiver-master'].modules] # assert modules == ['Example'] # # # The only existing reactionner module is Example declared in the configuration # modules = [m.module_alias for m in self.reactionners['reactionner-master'].modules] # assert modules == ['Example'] # No scheduler modules created modules = [m.module_alias for m in self._scheduler_daemon.modules] assert modules == ['Example'] modules = [m.name for m in self._scheduler_daemon.modules] assert modules == ['Example'] self.show_logs() # Loading module logs self.assert_any_log_match(re.escape( u"Importing Python module 'alignak_module_example' for Example..." )) self.assert_any_log_match(re.escape( u"Imported 'alignak_module_example' for Example" )) self.assert_any_log_match(re.escape( u"Give an instance of alignak_module_example for alias: Example" )) self.assert_any_log_match(re.escape( u"I correctly loaded my modules: [Example]" )) def test_arbiter_configuration_module(self): """ Test arbiter configuration loading :return: """ self.setup_with_file('./cfg/modules/arbiter_modules.cfg') assert self.conf_is_correct self.show_configuration_logs() self.show_logs() # The arbiter module is 'backend_arbiter' declared in the configuration modules = [m.module_alias for m in self._arbiter.link_to_myself.modules] assert modules == ['Example'] def test_module_on_module(self): """ No module configuration for modules Check that the feature is detected as disabled :return: """ self.setup_with_file('cfg/modules/alignak_module_with_submodules.cfg') assert self.conf_is_correct self.show_configuration_logs() # arbiter modules modules = [m.module_alias for m in self._arbiter.link_to_myself.modules] assert modules == ['Example'] modules = [m.name for m in self._arbiter.link_to_myself.modules] assert modules == ['Example'] # broker modules modules = [m.module_alias for m in self._broker_daemon.modules] assert modules == ['Example'] modules = [m.name for m in self._broker_daemon.modules] assert modules == ['Example'] # # The only existing poller module is Example declared in the configuration # modules = [m.module_alias for m in self.pollers['poller-master'].modules] # assert modules == ['Example'] # # # The only existing receiver module is Example declared in the configuration # modules = [m.module_alias for m in self.receivers['receiver-master'].modules] # assert modules == ['Example'] # # # The only existing reactionner module is Example declared in the configuration # modules = [m.module_alias for m in self.reactionners['reactionner-master'].modules] # assert modules == ['Example'] # No scheduler modules created modules = [m.module_alias for m in self._scheduler_daemon.modules] assert modules == ['Example', 'inner-retention'] modules = [m.name for m in self._scheduler_daemon.modules] assert modules == ['Example', 'inner-retention'] def test_modulemanager_1(self): """ Module manager manages its modules - old form Test if the module manager manages correctly all the modules :return: """ self.setup_with_file('cfg/cfg_default_with_modules.cfg', 'cfg/default_with_modules/alignak.ini') assert self.conf_is_correct # Create an Alignak module mod = Module({ 'module_alias': 'mod-example', 'module_types': 'example', 'python_name': 'alignak_module_example' }) self.run_modulemanager(mod) def test_modulemanager_2(self): """ Module manager manages its modules - new form Test if the module manager manages correctly all the modules :return: """ self.setup_with_file('cfg/cfg_default_with_modules.cfg', 'cfg/default_with_modules/alignak.ini') assert self.conf_is_correct # Create an Alignak module mod = Module({ 'name': 'mod-example', 'type': 'example', 'python_name': 'alignak_module_example' }) self.run_modulemanager(mod) def run_modulemanager(self, mod): # Force the daemon SyncManager to None for unit tests! self._broker_daemon.sync_manager = None # Create the modules manager for a daemon type self.modules_manager = ModulesManager(self._broker_daemon) # Load an initialize the modules: # - load python module # - get module properties and instances self.modules_manager.load_and_init([mod]) # Loading module logs self.assert_any_log_match(re.escape( "Importing Python module 'alignak_module_example' for mod-example..." )) self.assert_any_log_match(re.escape( "Imported 'alignak_module_example' for mod-example" )) self.assert_any_log_match(re.escape( "Give an instance of alignak_module_example for alias: mod-example" )) self.clear_logs() my_module = self.modules_manager.instances[0] assert my_module.is_external # Get list of not external modules assert [] == self.modules_manager.get_internal_instances() for phase in ['configuration', 'late_configuration', 'running', 'retention']: assert [] == self.modules_manager.get_internal_instances(phase) # Get list of external modules assert [my_module] == self.modules_manager.get_external_instances() for phase in ['configuration', 'late_configuration', 'running', 'retention']: assert [my_module] == self.modules_manager.get_external_instances(phase) # Start external modules self.modules_manager.start_external_instances() self.show_logs() # Starting external module logs idx = 0 self.assert_log_match(re.escape( "Trying to initialize module: mod-example" ), idx) idx += 1 self.assert_log_match(re.escape( "Test - Example in init" ), idx) idx += 1 self.assert_log_match(re.escape( "Initialization of the example module" ), idx) idx += 1 self.assert_log_match(re.escape( "Module mod-example is initialized" ), idx) idx += 1 self.assert_log_match(re.escape( "Starting external module mod-example" ), idx) idx += 1 self.assert_log_match(re.escape( "Starting external process for module mod-example" ), idx) idx += 1 self.assert_log_match(re.escape( "mod-example is now started (pid=" ), idx) idx += 1 self.assert_log_count(7) # Check alive assert my_module.process is not None assert my_module.process.is_alive() self.clear_logs() # Check the alive module instances... self.modules_manager.check_alive_instances() # Try to restart the dead modules, if any self.modules_manager.try_to_restart_deads() self.assert_log_count(0) # Kill the external module (normal stop is .stop_process) self.clear_logs() my_module.kill() idx = 0 self.assert_log_match(re.escape( "Killing external module " ), idx) idx += 1 self.show_logs() # self.assert_log_match(re.escape( # "mod-example is still living " # ), idx) # idx += 1 # Specific case because sometimes the module is not killed within the expected 10s time normal_kill = True logger_ = logging.getLogger(ALIGNAK_LOGGER_NAME) for handler in logger_.handlers: if not isinstance(handler, CollectorHandler): continue regex = re.compile('mod-example is still living') log_num = 0 found = False for log in handler.collector: if idx == log_num: if regex.search(log): idx += 1 normal_kill = False break log_num += 1 break self.assert_log_match(re.escape( "External module killed" ), idx) idx += 1 self.assert_log_count(idx) # The module is dead (not normally stopped...) so this module inner # process reference is not None! assert my_module.process is not None # Check the alive module instances... self.clear_logs() idx = 0 self.modules_manager.check_alive_instances() self.show_logs() self.assert_log_match(re.escape( "The external module mod-example died unexpectedly!" ), idx) idx += 1 self.assert_log_match(re.escape( "Setting the module mod-example to restart" ), idx) self.assert_log_count(2) idx += 1 if normal_kill: # Try to restart the dead modules, if any # Indeed, it's too early, so it won't do it self.clear_logs() idx = 0 print("try init: %d" % my_module.init_try) self.modules_manager.try_to_restart_deads() self.show_logs() self.assert_log_match(re.escape( "Trying to restart module: mod-example" ), idx) idx += 1 self.assert_log_match(re.escape( "Too early to retry initialization, retry period is %d seconds" % MODULE_INIT_PERIOD ), idx) idx += 1 self.assert_log_count(2) # Here the module instance is still dead assert not my_module.process.is_alive() # Wait for a minimum delay time.sleep(MODULE_INIT_PERIOD + 1) # my_module.last_init_try = -5 self.clear_logs() self.modules_manager.check_alive_instances() self.show_logs() self.assert_log_count(0) # Try to restart the dead modules, if any # Now it is time... self.clear_logs() idx = 0 self.modules_manager.try_to_restart_deads() self.show_logs() self.assert_log_match(re.escape( "Trying to restart module: mod-example" ), idx) idx += 1 self.assert_log_match(re.escape( "Trying to initialize module: mod-example" ), idx) idx += 1 self.assert_log_match(re.escape( "Test - Example in init" ), idx) idx += 1 self.assert_log_match(re.escape( "Initialization of the example module" ), idx) idx += 1 self.assert_log_match(re.escape( "Module mod-example is initialized" ), idx) idx += 1 self.assert_log_match(re.escape( "Restarting mod-example..." ), idx) idx += 1 self.assert_log_match(re.escape( "Starting external process for module mod-example" ), idx) idx += 1 self.assert_log_match(re.escape( "mod-example is now started (pid=" ), idx) idx += 1 self.assert_log_count(8) # Here the module instance should be alive again assert my_module.process.is_alive() # No more module to restart... assert [] == self.modules_manager.to_restart # And we clear all now self.clear_logs() idx = 0 self.modules_manager.stop_all() self.show_logs() self.assert_log_match(re.escape( "Shutting down modules..." ), idx) idx += 1 self.assert_log_match(re.escape( "Request external process to stop for mod-example" ), idx) idx += 1 self.assert_log_match(re.escape( "I'm stopping module 'mod-example'" ), idx) idx += 1 self.assert_log_match(re.escape( "Killing external module " ), idx) idx += 1 # Specific case because sometimes the module is not killed within the expected 10s time logger_ = logging.getLogger(ALIGNAK_LOGGER_NAME) for handler in logger_.handlers: if not isinstance(handler, CollectorHandler): continue regex = re.compile('mod-example is still living') log_num = 0 found = False for log in handler.collector: if idx == log_num: if regex.search(log): idx += 1 break log_num += 1 break self.assert_log_match(re.escape( "External module killed" ), idx) idx += 1 self.assert_log_match(re.escape( "External process stopped." ), idx) idx += 1 # self.assert_log_count(6) def test_modulemanager_several_modules(self): """ Module manager manages its modules Test if the module manager manages correctly all the modules Configured with several modules :return: """ self.setup_with_file('cfg/cfg_default_with_modules.cfg', 'cfg/default_with_modules/alignak.ini') assert self.conf_is_correct # for mod in self._arbiter.conf.modules: # print (mod.__dict__) # Create an Alignak module mod = Module({ 'module_alias': 'mod-example', 'module_types': 'example', 'python_name': 'alignak_module_example', 'option1': 'foo', 'option2': 'bar', 'option3': 1 }) mod2 = Module({ 'module_alias': 'mod-example-2', 'module_types': 'example', 'python_name': 'alignak_module_example', 'option1': 'faa', 'option2': 'bor', 'option3': 1 }) # Force the daemon SyncManager to None for unit tests! self._broker_daemon.sync_manager = None # Create the modules manager for a daemon type self.modules_manager = ModulesManager(self._broker_daemon) print("Modules: %s" % self._broker_daemon.modules) # Load an initialize the modules: # - load python module # - get module properties and instances assert self.modules_manager.load_and_init([mod, mod2]) print("I correctly loaded my modules: [%s]" % ','.join([inst.name for inst in self.modules_manager.instances])) self.show_logs() self.assert_any_log_match(re.escape( "Importing Python module 'alignak_module_example' for mod-example..." )) self.assert_any_log_match(re.escape( "Imported 'alignak_module_example' for mod-example" )) self.assert_any_log_match(re.escape( "Loaded Python module 'alignak_module_example' (mod-example)" )) self.assert_any_log_match(re.escape( "Importing Python module 'alignak_module_example' for mod-example-2..." )) self.assert_any_log_match(re.escape( "Imported 'alignak_module_example' for mod-example-2" )) self.assert_any_log_match(re.escape( "Loaded Python module 'alignak_module_example' (mod-example-2)" )) self.assert_any_log_match(re.escape( "Give an instance of alignak_module_example for alias: mod-example" )) self.assert_any_log_match(re.escape( "configuration, foo, bar, 1" )) self.assert_any_log_match(re.escape( "Give an instance of alignak_module_example for alias: mod-example-2" )) self.assert_any_log_match(re.escape( "configuration, faa, bor, 1" )) # Loading module logs self.assert_any_log_match(re.escape( "Importing Python module 'alignak_module_example' for mod-example..." )) my_module = self.modules_manager.instances[0] my_module2 = self.modules_manager.instances[1] assert my_module.is_external assert my_module2.is_external # Get list of not external modules assert [] == self.modules_manager.get_internal_instances() for phase in ['configuration', 'late_configuration', 'running', 'retention']: assert [] == self.modules_manager.get_internal_instances(phase) # Get list of external modules assert [my_module, my_module2] == self.modules_manager.get_external_instances() for phase in ['configuration', 'late_configuration', 'running', 'retention']: assert [my_module, my_module2] == self.modules_manager.get_external_instances(phase) # Start external modules self.modules_manager.start_external_instances() self.modules_manager.start_external_instances() # Starting external module logs self.assert_any_log_match(re.escape( "Starting external module mod-example" )) self.assert_any_log_match(re.escape( "Starting external process for module mod-example" )) self.assert_any_log_match(re.escape( "mod-example is now started (pid=" )) # Check alive assert my_module.process is not None assert my_module.process.is_alive() assert my_module2.process is not None assert my_module2.process.is_alive() # Kill the external module (normal stop is .stop_process) self.clear_logs() print("Killing a module") my_module.kill() time.sleep(0.1) self.show_logs() # Stopping module logs self.assert_any_log_match(re.escape( "Killing external module " )) self.assert_any_log_match(re.escape( "External module killed" )) # Should be dead (not normally stopped...) but we still know a process for this module! assert my_module.process is not None self.clear_logs() print("Killing another module") my_module2.kill() time.sleep(0.1) self.show_logs() # Stopping module logs self.assert_any_log_match(re.escape( "Killing external module " )) self.assert_any_log_match(re.escape( "External module killed" )) # Should be dead (not normally stopped...) but we still know a process for this module! assert my_module.process is not None # Nothing special ... self.clear_logs() self.modules_manager.check_alive_instances() # Try to restart the dead modules print("Trying to restart dead modules") # We lie on the last restart try time my_module.last_init_try = time.time() my_module2.last_init_try = time.time() self.modules_manager.try_to_restart_deads() self.show_logs() # In fact it's too early, so it won't do it # Here the module instances should still be dead assert not my_module.process.is_alive() assert not my_module2.process.is_alive() # We lie on the last restart try time my_module.last_init_try = 0 my_module2.last_init_try = 0 self.modules_manager.check_alive_instances() self.modules_manager.try_to_restart_deads() # Here the module instances should be alive again assert my_module.process.is_alive() assert my_module2.process.is_alive() # Kill the module again self.clear_logs() my_module.kill() self.show_logs() time.sleep(0.2) assert not my_module.process.is_alive() # And we clear all now self.modules_manager.stop_all() # Stopping module logs self.assert_any_log_match(re.escape( "I'm stopping module " ))
class TestModules(AlignakTest): """ This class contains the tests for the module """ def test_module_loading(self): """ Test module loading Alignak module loading :return: """ self.setup_with_file('./cfg/alignak.cfg') self.assertTrue(self.conf_is_correct) self.show_configuration_logs() # No arbiter modules created modules = [ m.module_alias for m in self._arbiter.link_to_myself.modules ] self.assertListEqual(modules, []) # No broker modules modules = [m.module_alias for m in self._broker_daemon.modules] self.assertListEqual(modules, []) # No scheduler modules modules = [m.module_alias for m in self._scheduler_daemon.modules] self.assertListEqual(modules, ['inner-retention']) # A receiver module modules = [m.module_alias for m in self._receiver.modules] self.assertListEqual(modules, ['nsca']) def test_module_manager(self): """ Test if the module manager manages correctly all the modules :return: """ self.setup_with_file('./cfg/alignak.cfg') self.assertTrue(self.conf_is_correct) self.clear_logs() # Create an Alignak module mod = Module({ 'module_alias': 'nsca', 'module_types': 'nsca', 'python_name': 'alignak_module_nsca' }) # Create the modules manager for a daemon type self.modulemanager = ModulesManager(self._broker_daemon) # Load an initialize the modules: # - load python module # - get module properties and instances self.modulemanager.load_and_init([mod]) # Loading module nsca print("Load and init") self.show_logs() i = 0 self.assert_log_match( re.escape( "Importing Python module 'alignak_module_nsca' for nsca..."), i) i += 1 # Dict order is problematic :/ # self.assert_log_match(re.escape( # "Module properties: {'daemons': ['broker'], 'phases': ['running'], " # "'type': 'nsca', 'external': True}" # ), i) i += 1 self.assert_log_match( re.escape("Imported 'alignak_module_nsca' for nsca"), i) i += 1 self.assert_log_match( re.escape("Loaded Python module 'alignak_module_nsca' (nsca)"), i) i += 1 self.assert_log_match(re.escape("Alignak starting module 'nsca'"), i) i += 1 self.assert_log_match( re.escape( "Give an instance of alignak_module_nsca for alias: nsca"), i) i += 1 self.assert_log_match( re.escape( "configuration, allowed hosts : '127.0.0.1'(5667), buffer length: 4096, " "payload length: -1, encryption: 0, max packet age: 30, " "check future packet: True, backlog: 10"), i) time.sleep(1) # Reload the module print("Reload") self.modulemanager.load([mod]) self.modulemanager.get_instances() # # Loading module nsca self.show_logs() i = 0 self.assert_log_match( re.escape( "Importing Python module 'alignak_module_nsca' for nsca..."), i) i += 1 # self.assert_log_match(re.escape( # "Module properties: {'daemons': ['broker'], 'phases': ['running'], " # "'type': 'nsca', 'external': True}" # ), i) i += 1 self.assert_log_match( re.escape("Imported 'alignak_module_nsca' for nsca"), i) i += 1 self.assert_log_match( re.escape("Loaded Python module 'alignak_module_nsca' (nsca)"), i) i += 1 self.assert_log_match(re.escape("Alignak starting module 'nsca'"), i) i += 1 self.assert_log_match( re.escape( "Give an instance of alignak_module_nsca for alias: nsca"), i) i += 1 self.assert_log_match( re.escape( "configuration, allowed hosts : '127.0.0.1'(5667), buffer length: 4096, " "payload length: -1, encryption: 0, max packet age: 30, " "check future packet: True, backlog: 10"), i) i += 1 self.assert_log_match( re.escape( "Importing Python module 'alignak_module_nsca' for nsca..."), i) i += 1 # self.assert_log_match(re.escape( # "Module properties: {'daemons': ['broker'], 'phases': ['running'], " # "'type': 'nsca', 'external': True}" # ), i) i += 1 self.assert_log_match( re.escape("Imported 'alignak_module_nsca' for nsca"), i) i += 1 self.assert_log_match( re.escape("Loaded Python module 'alignak_module_nsca' (nsca)"), i) i += 1 self.assert_log_match( re.escape("Request external process to stop for nsca"), i) i += 1 self.assert_log_match(re.escape("External process stopped."), i) i += 1 self.assert_log_match(re.escape("Alignak starting module 'nsca'"), i) i += 1 # self.assert_log_match(re.escape( # "Give an instance of alignak_module_nsca for alias: nsca" # ), i) # i += 1 self.assert_log_match( re.escape( "Give an instance of alignak_module_nsca for alias: nsca"), i) i += 1 self.assert_log_match( re.escape( "configuration, allowed hosts : '127.0.0.1'(5667), buffer length: 4096, " "payload length: -1, encryption: 0, max packet age: 30, " "check future packet: True, backlog: 10"), i) my_module = self.modulemanager.instances[0] # Get list of not external modules self.assertListEqual([], self.modulemanager.get_internal_instances()) for phase in [ 'configuration', 'late_configuration', 'running', 'retention' ]: self.assertListEqual( [], self.modulemanager.get_internal_instances(phase)) # Get list of external modules self.assertListEqual([my_module], self.modulemanager.get_external_instances()) for phase in ['configuration', 'late_configuration', 'retention']: self.assertListEqual( [], self.modulemanager.get_external_instances(phase)) for phase in ['running']: self.assertListEqual( [my_module], self.modulemanager.get_external_instances(phase)) # Clear nsca self.clear_logs() # Start external modules self.modulemanager.start_external_instances() # Starting external module nsca self.assert_log_match("Trying to initialize module: nsca", 0) self.assert_log_match("Starting external module nsca", 1) self.assert_log_match("Starting external process for module nsca", 2) self.assert_log_match("nsca is now started", 3) # Check alive self.assertIsNotNone(my_module.process) self.assertTrue(my_module.process.is_alive()) # Clear nsca self.clear_logs() # Kill the external module (normal stop is .stop_process) my_module.kill() time.sleep(0.1) index = 0 self.assert_log_match("Killing external module", index) index = index + 1 # todo: This log is not expected! But it is probably because of the py.test ... # Indeed the receiver daemon that the module is attached to is receiving a SIGTERM !!! self.assert_log_match( re.escape( "nsca is still living 10 seconds after a normal kill, I help it to die" ), index) index = index + 1 self.assert_log_match("External module killed", index) index = index + 1 # Should be dead (not normally stopped...) but we still know a process for this module! self.assertIsNotNone(my_module.process) # Nothing special ... self.modulemanager.check_alive_instances() self.assert_log_match("The external module nsca died unexpectedly!", index) index = index + 1 self.assert_log_match("Setting the module nsca to restart", index) index = index + 1 # # Try to restart the dead modules # self.modulemanager.try_to_restart_deads() # self.assert_log_match("Trying to restart module: nsca", index) # index = index +1 # self.assert_log_match("Too early to retry initialization, retry period is 5 seconds", index) # index = index +1 # # # In fact it's too early, so it won't do it # # The module instance is still dead # self.assertFalse(my_module.process.is_alive()) # So we lie, on the restart tries ... my_module.last_init_try = -5 self.modulemanager.check_alive_instances() self.modulemanager.try_to_restart_deads() self.assert_log_match("Trying to restart module: nsca", index) index = index + 1 self.assert_log_match("Trying to initialize module: nsca", index) index = index + 1 self.assert_log_match("Restarting nsca...", index) index = index + 1 # The module instance is now alive again self.assertTrue(my_module.process.is_alive()) self.assert_log_match("Starting external process for module nsca", index) index = index + 1 self.assert_log_match("nsca is now started", index) index = index + 1 # There is nothing else to restart in the module manager self.assertEqual([], self.modulemanager.to_restart) # Clear nsca self.clear_logs() # Let the module start and then kill it again time.sleep(3.0) my_module.kill() # time.sleep(5.0) self.show_logs() print("My module PID 2: %s" % my_module.process.pid) time.sleep(0.2) self.assertFalse(my_module.process.is_alive()) index = 0 self.assert_log_match("Killing external module", index) index = index + 1 # # todo: This log is not expected! But it is probably because of the py.test ... # # Indeed the receiver daemon that the module is attached to is receiving a SIGTERM !!! # self.assert_log_match(re.escape("'web-services' is still living 10 seconds after a normal kill, I help it to die"), index) # index = index +1 self.assert_log_match("External module killed", index) index = index + 1 # The module is dead but the modules manager do not know yet! self.modulemanager.check_alive_instances() self.assert_log_match("The external module nsca died unexpectedly!", index) index = index + 1 self.assert_log_match("Setting the module nsca to restart", index) index = index + 1 self.modulemanager.try_to_restart_deads() self.assert_log_match("Trying to restart module: nsca", index) index = index + 1 self.assert_log_match( "Too early to retry initialization, retry period is 5 seconds", index) index = index + 1 # In fact it's too early, so it won't do it # The module instance is still dead self.assertFalse(my_module.process.is_alive()) # So we lie, on the restart tries ... my_module.last_init_try = -5 self.modulemanager.check_alive_instances() self.modulemanager.try_to_restart_deads() self.assert_log_match("Trying to restart module: nsca", index) index = index + 1 self.assert_log_match("Trying to initialize module: nsca", index) index = index + 1 self.assert_log_match("Restarting nsca...", index) index = index + 1 # The module instance is now alive again self.assertTrue(my_module.process.is_alive()) self.assert_log_match("Starting external process for module nsca", index) index = index + 1 self.assert_log_match("nsca is now started", index) index = index + 1 time.sleep(1.0) print("My module PID: %s" % my_module.process.pid) # Clear nsca self.clear_logs() # And we clear all now self.modulemanager.stop_all() # Stopping module nsca index = 0 self.assert_log_match("Shutting down modules...", index) index = index + 1 self.assert_log_match("Request external process to stop for nsca", index) index = index + 1 self.assert_log_match(re.escape("I'm stopping module 'nsca' (pid="), index) index = index + 1 # self.assert_log_match(re.escape("'nsca' is still living after a normal kill, I help it to die"), index) # index = index +1 self.assert_log_match(re.escape("Killing external module (pid"), index) index = index + 1 self.assert_log_match(re.escape("External module killed"), index) index = index + 1 self.assert_log_match("External process stopped.", index) index = index + 1 def test_module_start_default(self): """Test the module initialization function, no parameters, using default :return: """ # Obliged to call to get a self.logger... self.setup_with_file('./cfg/alignak.cfg') self.assertTrue(self.conf_is_correct) # Clear nsca self.clear_logs() # ----- # Default initialization # ----- # Create an Alignak module mod = Module({ 'module_alias': 'nsca', 'module_types': 'passive', 'python_name': 'alignak_module_nsca' }) instance = alignak_module_nsca.get_instance(mod) self.assertIsInstance(instance, BaseModule) self.show_logs() # self.assert_log_match( # re.escape("Give an instance of alignak_module_nsca for alias: nsca"), 0) self.assert_log_match( re.escape( "Give an instance of alignak_module_nsca for alias: nsca"), 0) self.assert_log_match( re.escape( "configuration, allowed hosts : '127.0.0.1'(5667), buffer length: 4096, " "payload length: -1, encryption: 0, max packet age: 30, " "check future packet: True, backlog: 10"), 1)
class TestModules(AlignakTest): """ This class contains the tests for the modules """ def setUp(self): super(TestModules, self).setUp() self.set_unit_tests_logger_level('INFO') def test_module_loading(self): """ Test arbiter, broker, ... detecting configured modules :return: """ self.setup_with_file('cfg/cfg_default_with_modules.cfg', 'cfg/default_with_modules/alignak.ini') assert self.conf_is_correct self.show_configuration_logs() self.show_logs() # arbiter modules modules = [ m.module_alias for m in self._arbiter.link_to_myself.modules ] assert modules == ['Example'] modules = [m.name for m in self._arbiter.link_to_myself.modules] assert modules == ['Example'] # broker modules modules = [m.module_alias for m in self._broker_daemon.modules] assert modules == ['Example'] modules = [m.name for m in self._broker_daemon.modules] assert modules == ['Example'] # # The only existing poller module is Example declared in the configuration # modules = [m.module_alias for m in self.pollers['poller-master'].modules] # assert modules == ['Example'] # # # The only existing receiver module is Example declared in the configuration # modules = [m.module_alias for m in self.receivers['receiver-master'].modules] # assert modules == ['Example'] # # # The only existing reactionner module is Example declared in the configuration # modules = [m.module_alias for m in self.reactionners['reactionner-master'].modules] # assert modules == ['Example'] # No scheduler modules created modules = [m.module_alias for m in self._scheduler_daemon.modules] assert modules == ['Example'] modules = [m.name for m in self._scheduler_daemon.modules] assert modules == ['Example'] self.show_logs() # Loading module logs self.assert_any_log_match( re.escape( u"Importing Python module 'alignak_module_example' for Example..." )) self.assert_any_log_match( re.escape(u"Imported 'alignak_module_example' for Example")) self.assert_any_log_match( re.escape( u"Give an instance of alignak_module_example for alias: Example" )) self.assert_any_log_match( re.escape(u"I correctly loaded my modules: [Example]")) def test_arbiter_configuration_module(self): """ Test arbiter configuration loading :return: """ self.setup_with_file('./cfg/modules/arbiter_modules.cfg') assert self.conf_is_correct self.show_configuration_logs() self.show_logs() # The arbiter module is 'backend_arbiter' declared in the configuration modules = [ m.module_alias for m in self._arbiter.link_to_myself.modules ] assert modules == ['Example'] def test_module_on_module(self): """ No module configuration for modules Check that the feature is detected as disabled :return: """ self.setup_with_file('cfg/modules/alignak_module_with_submodules.cfg') assert self.conf_is_correct self.show_configuration_logs() # arbiter modules modules = [ m.module_alias for m in self._arbiter.link_to_myself.modules ] assert modules == ['Example'] modules = [m.name for m in self._arbiter.link_to_myself.modules] assert modules == ['Example'] # broker modules modules = [m.module_alias for m in self._broker_daemon.modules] assert modules == ['Example'] modules = [m.name for m in self._broker_daemon.modules] assert modules == ['Example'] # # The only existing poller module is Example declared in the configuration # modules = [m.module_alias for m in self.pollers['poller-master'].modules] # assert modules == ['Example'] # # # The only existing receiver module is Example declared in the configuration # modules = [m.module_alias for m in self.receivers['receiver-master'].modules] # assert modules == ['Example'] # # # The only existing reactionner module is Example declared in the configuration # modules = [m.module_alias for m in self.reactionners['reactionner-master'].modules] # assert modules == ['Example'] # No scheduler modules created modules = [m.module_alias for m in self._scheduler_daemon.modules] assert modules == ['Example', 'inner-retention'] modules = [m.name for m in self._scheduler_daemon.modules] assert modules == ['Example', 'inner-retention'] def test_modulemanager_1(self): """ Module manager manages its modules - old form Test if the module manager manages correctly all the modules :return: """ self.setup_with_file('cfg/cfg_default_with_modules.cfg', 'cfg/default_with_modules/alignak.ini') assert self.conf_is_correct # Create an Alignak module mod = Module({ 'module_alias': 'mod-example', 'module_types': 'example', 'python_name': 'alignak_module_example' }) self.run_modulemanager(mod) def test_modulemanager_2(self): """ Module manager manages its modules - new form Test if the module manager manages correctly all the modules :return: """ self.setup_with_file('cfg/cfg_default_with_modules.cfg', 'cfg/default_with_modules/alignak.ini') assert self.conf_is_correct # Create an Alignak module mod = Module({ 'name': 'mod-example', 'type': 'example', 'python_name': 'alignak_module_example' }) self.run_modulemanager(mod) def run_modulemanager(self, mod): # Force the daemon SyncManager to None for unit tests! self._broker_daemon.sync_manager = None # Create the modules manager for a daemon type self.modules_manager = ModulesManager(self._broker_daemon) # Load an initialize the modules: # - load python module # - get module properties and instances self.modules_manager.load_and_init([mod]) # Loading module logs self.assert_any_log_match( re.escape( "Importing Python module 'alignak_module_example' for mod-example..." )) self.assert_any_log_match( re.escape("Imported 'alignak_module_example' for mod-example")) self.assert_any_log_match( re.escape( "Give an instance of alignak_module_example for alias: mod-example" )) self.clear_logs() my_module = self.modules_manager.instances[0] assert my_module.is_external # Get list of not external modules assert [] == self.modules_manager.get_internal_instances() for phase in [ 'configuration', 'late_configuration', 'running', 'retention' ]: assert [] == self.modules_manager.get_internal_instances(phase) # Get list of external modules assert [my_module] == self.modules_manager.get_external_instances() for phase in [ 'configuration', 'late_configuration', 'running', 'retention' ]: assert [my_module ] == self.modules_manager.get_external_instances(phase) # Start external modules self.modules_manager.start_external_instances() self.show_logs() # Starting external module logs idx = 0 self.assert_log_match( re.escape("Trying to initialize module: mod-example"), idx) idx += 1 self.assert_log_match(re.escape("Test - Example in init"), idx) idx += 1 self.assert_log_match( re.escape("Initialization of the example module"), idx) idx += 1 self.assert_log_match(re.escape("Module mod-example is initialized"), idx) idx += 1 self.assert_log_match( re.escape("Starting external module mod-example"), idx) idx += 1 self.assert_log_match( re.escape("Starting external process for module mod-example"), idx) idx += 1 self.assert_log_match(re.escape("mod-example is now started (pid="), idx) idx += 1 self.assert_log_count(7) # Check alive assert my_module.process is not None assert my_module.process.is_alive() self.clear_logs() # Check the alive module instances... self.modules_manager.check_alive_instances() # Try to restart the dead modules, if any self.modules_manager.try_to_restart_deads() self.assert_log_count(0) # Kill the external module (normal stop is .stop_process) self.clear_logs() my_module.kill() idx = 0 self.assert_log_match(re.escape("Killing external module "), idx) idx += 1 self.show_logs() # self.assert_log_match(re.escape( # "mod-example is still living " # ), idx) # idx += 1 # Specific case because sometimes the module is not killed within the expected 10s time normal_kill = True logger_ = logging.getLogger(ALIGNAK_LOGGER_NAME) for handler in logger_.handlers: if not isinstance(handler, CollectorHandler): continue regex = re.compile('mod-example is still living') log_num = 0 found = False for log in handler.collector: if idx == log_num: if regex.search(log): idx += 1 normal_kill = False break log_num += 1 break self.assert_log_match(re.escape("External module killed"), idx) idx += 1 self.assert_log_count(idx) # The module is dead (not normally stopped...) so this module inner # process reference is not None! assert my_module.process is not None # Check the alive module instances... self.clear_logs() idx = 0 self.modules_manager.check_alive_instances() self.show_logs() self.assert_log_match( re.escape("The external module mod-example died unexpectedly!"), idx) idx += 1 self.assert_log_match( re.escape("Setting the module mod-example to restart"), idx) self.assert_log_count(2) idx += 1 if normal_kill: # Try to restart the dead modules, if any # Indeed, it's too early, so it won't do it self.clear_logs() idx = 0 print("try init: %d" % my_module.init_try) self.modules_manager.try_to_restart_deads() self.show_logs() self.assert_log_match( re.escape("Trying to restart module: mod-example"), idx) idx += 1 self.assert_log_match( re.escape( "Too early to retry initialization, retry period is %d seconds" % MODULE_INIT_PERIOD), idx) idx += 1 self.assert_log_count(2) # Here the module instance is still dead assert not my_module.process.is_alive() # Wait for a minimum delay time.sleep(MODULE_INIT_PERIOD + 1) # my_module.last_init_try = -5 self.clear_logs() self.modules_manager.check_alive_instances() self.show_logs() self.assert_log_count(0) # Try to restart the dead modules, if any # Now it is time... self.clear_logs() idx = 0 self.modules_manager.try_to_restart_deads() self.show_logs() self.assert_log_match( re.escape("Trying to restart module: mod-example"), idx) idx += 1 self.assert_log_match( re.escape("Trying to initialize module: mod-example"), idx) idx += 1 self.assert_log_match(re.escape("Test - Example in init"), idx) idx += 1 self.assert_log_match( re.escape("Initialization of the example module"), idx) idx += 1 self.assert_log_match(re.escape("Module mod-example is initialized"), idx) idx += 1 self.assert_log_match(re.escape("Restarting mod-example..."), idx) idx += 1 self.assert_log_match( re.escape("Starting external process for module mod-example"), idx) idx += 1 self.assert_log_match(re.escape("mod-example is now started (pid="), idx) idx += 1 self.assert_log_count(8) # Here the module instance should be alive again assert my_module.process.is_alive() # No more module to restart... assert [] == self.modules_manager.to_restart # And we clear all now self.clear_logs() idx = 0 self.modules_manager.stop_all() self.show_logs() self.assert_log_match(re.escape("Shutting down modules..."), idx) idx += 1 self.assert_log_match( re.escape("Request external process to stop for mod-example"), idx) idx += 1 self.assert_log_match(re.escape("I'm stopping module 'mod-example'"), idx) idx += 1 self.assert_log_match(re.escape("Killing external module "), idx) idx += 1 # Specific case because sometimes the module is not killed within the expected 10s time logger_ = logging.getLogger(ALIGNAK_LOGGER_NAME) for handler in logger_.handlers: if not isinstance(handler, CollectorHandler): continue regex = re.compile('mod-example is still living') log_num = 0 found = False for log in handler.collector: if idx == log_num: if regex.search(log): idx += 1 break log_num += 1 break self.assert_log_match(re.escape("External module killed"), idx) idx += 1 self.assert_log_match(re.escape("External process stopped."), idx) idx += 1 # self.assert_log_count(6) def test_modulemanager_several_modules(self): """ Module manager manages its modules Test if the module manager manages correctly all the modules Configured with several modules :return: """ self.setup_with_file('cfg/cfg_default_with_modules.cfg', 'cfg/default_with_modules/alignak.ini') assert self.conf_is_correct # for mod in self._arbiter.conf.modules: # print (mod.__dict__) # Create an Alignak module mod = Module({ 'module_alias': 'mod-example', 'module_types': 'example', 'python_name': 'alignak_module_example', 'option1': 'foo', 'option2': 'bar', 'option3': 1 }) mod2 = Module({ 'module_alias': 'mod-example-2', 'module_types': 'example', 'python_name': 'alignak_module_example', 'option1': 'faa', 'option2': 'bor', 'option3': 1 }) # Force the daemon SyncManager to None for unit tests! self._broker_daemon.sync_manager = None # Create the modules manager for a daemon type self.modules_manager = ModulesManager(self._broker_daemon) print("Modules: %s" % self._broker_daemon.modules) # Load an initialize the modules: # - load python module # - get module properties and instances assert self.modules_manager.load_and_init([mod, mod2]) print("I correctly loaded my modules: [%s]" % ','.join([inst.name for inst in self.modules_manager.instances])) self.show_logs() self.assert_any_log_match( re.escape( "Importing Python module 'alignak_module_example' for mod-example..." )) self.assert_any_log_match( re.escape("Imported 'alignak_module_example' for mod-example")) self.assert_any_log_match( re.escape( "Loaded Python module 'alignak_module_example' (mod-example)")) self.assert_any_log_match( re.escape( "Importing Python module 'alignak_module_example' for mod-example-2..." )) self.assert_any_log_match( re.escape("Imported 'alignak_module_example' for mod-example-2")) self.assert_any_log_match( re.escape( "Loaded Python module 'alignak_module_example' (mod-example-2)" )) self.assert_any_log_match( re.escape( "Give an instance of alignak_module_example for alias: mod-example" )) self.assert_any_log_match(re.escape("configuration, foo, bar, 1")) self.assert_any_log_match( re.escape( "Give an instance of alignak_module_example for alias: mod-example-2" )) self.assert_any_log_match(re.escape("configuration, faa, bor, 1")) # Loading module logs self.assert_any_log_match( re.escape( "Importing Python module 'alignak_module_example' for mod-example..." )) my_module = self.modules_manager.instances[0] my_module2 = self.modules_manager.instances[1] assert my_module.is_external assert my_module2.is_external # Get list of not external modules assert [] == self.modules_manager.get_internal_instances() for phase in [ 'configuration', 'late_configuration', 'running', 'retention' ]: assert [] == self.modules_manager.get_internal_instances(phase) # Get list of external modules assert [my_module, my_module2] == self.modules_manager.get_external_instances() for phase in [ 'configuration', 'late_configuration', 'running', 'retention' ]: assert [my_module, my_module2 ] == self.modules_manager.get_external_instances(phase) # Start external modules self.modules_manager.start_external_instances() self.modules_manager.start_external_instances() # Starting external module logs self.assert_any_log_match( re.escape("Starting external module mod-example")) self.assert_any_log_match( re.escape("Starting external process for module mod-example")) self.assert_any_log_match( re.escape("mod-example is now started (pid=")) # Check alive assert my_module.process is not None assert my_module.process.is_alive() assert my_module2.process is not None assert my_module2.process.is_alive() # Kill the external module (normal stop is .stop_process) self.clear_logs() print("Killing a module") my_module.kill() time.sleep(0.1) self.show_logs() # Stopping module logs self.assert_any_log_match(re.escape("Killing external module ")) self.assert_any_log_match(re.escape("External module killed")) # Should be dead (not normally stopped...) but we still know a process for this module! assert my_module.process is not None self.clear_logs() print("Killing another module") my_module2.kill() time.sleep(0.1) self.show_logs() # Stopping module logs self.assert_any_log_match(re.escape("Killing external module ")) self.assert_any_log_match(re.escape("External module killed")) # Should be dead (not normally stopped...) but we still know a process for this module! assert my_module.process is not None # Nothing special ... self.clear_logs() self.modules_manager.check_alive_instances() # Try to restart the dead modules print("Trying to restart dead modules") # We lie on the last restart try time my_module.last_init_try = time.time() my_module2.last_init_try = time.time() self.modules_manager.try_to_restart_deads() self.show_logs() # In fact it's too early, so it won't do it # Here the module instances should still be dead assert not my_module.process.is_alive() assert not my_module2.process.is_alive() # We lie on the last restart try time my_module.last_init_try = 0 my_module2.last_init_try = 0 self.modules_manager.check_alive_instances() self.modules_manager.try_to_restart_deads() # Here the module instances should be alive again assert my_module.process.is_alive() assert my_module2.process.is_alive() # Kill the module again self.clear_logs() my_module.kill() self.show_logs() time.sleep(0.2) assert not my_module.process.is_alive() # And we clear all now self.modules_manager.stop_all() # Stopping module logs self.assert_any_log_match(re.escape("I'm stopping module "))
class TestModules(AlignakTest): """ This class contains the tests for the modules """ def test_module_loading(self): """ Test arbiter, broker, ... detecting configured modules :return: """ self.print_header() self.setup_with_file('./cfg/cfg_default_with_modules.cfg') assert self.conf_is_correct self.show_configuration_logs() # The only existing arbiter module is Example declared in the configuration modules = [m.module_alias for m in self.arbiter.myself.modules] assert modules == ['Example'] # The only existing broker module is Example declared in the configuration modules = [ m.module_alias for m in self.brokers['broker-master'].modules ] assert modules == ['Example'] # The only existing poller module is Example declared in the configuration modules = [ m.module_alias for m in self.pollers['poller-master'].modules ] assert modules == ['Example'] # The only existing receiver module is Example declared in the configuration modules = [ m.module_alias for m in self.receivers['receiver-master'].modules ] assert modules == ['Example'] # The only existing reactionner module is Example declared in the configuration modules = [ m.module_alias for m in self.reactionners['reactionner-master'].modules ] assert modules == ['Example'] # No scheduler modules created modules = [ m.module_alias for m in self.schedulers['scheduler-master'].modules ] assert modules == ['Example'] # Loading module logs self.assert_any_log_match( re.escape( "Importing Python module 'alignak_module_example' for Example..." )) self.assert_any_log_match( re.escape( "Module properties: {'daemons': ['arbiter', 'broker', 'scheduler', 'poller', " "'receiver', 'reactionner'], 'phases': ['configuration', 'late_configuration', " "'running', 'retention'], 'type': 'example', 'external': True}" )) self.assert_any_log_match( re.escape("Imported 'alignak_module_example' for Example")) self.assert_any_log_match( re.escape( "Give an instance of alignak_module_example for alias: Example" )) self.assert_any_log_match( re.escape("I correctly loaded my modules: [Example]")) def test_arbiter_configuration_module(self): """ Test arbiter configuration loading :return: """ self.print_header() self.setup_with_file('./cfg/cfg_arbiter_configuration_module.cfg') assert self.conf_is_correct self.show_configuration_logs() self.show_logs() # The arbiter module is 'backend_arbiter' declared in the configuration modules = [m.module_alias for m in self.arbiter.myself.modules] assert modules == ['backend_arbiter'] def test_missing_module_detection(self): """ Detect missing module configuration Alignak configuration parser detects that some modules are required because some specific parameters are included in the configuration files. If the modules are not present in the configuration, it logs warning message to alert the user about this! :return: """ self.print_header() with pytest.raises(SystemExit): self.setup_with_file( 'cfg/modules/alignak_modules_nagios_parameters.cfg') assert not self.conf_is_correct self.show_configuration_logs() # Log missing module self.assert_any_log_match( re.escape( "Your configuration parameters 'status_file = /var/status.dat' and " "'object_cache_file = /var/status.dat' need to use an external module such " "as 'retention' but I did not found one!")) self.assert_any_log_match( re.escape( "Your configuration parameter 'log_file = /test/file' needs to use an external " "module such as 'logs' but I did not found one!")) self.assert_any_log_match( re.escape( "Your configuration parameter 'use_syslog = True' needs to use an external " "module such as 'logs' but I did not found one!")) self.assert_any_log_match( re.escape( "Your configuration parameters 'host_perfdata_file = /test/file' and " "'service_perfdata_file = /test/file' need to use an external module such as " "'retention' but I did not found one!")) self.assert_any_log_match( re.escape( "Your configuration parameters 'state_retention_file = /test/file' and " "'retention_update_interval = 100' need to use an external module such as " "'retention' but I did not found one!")) self.assert_any_log_match( re.escape( "Your configuration parameter 'command_file = /var/alignak.cmd' needs to use " "an external module such as 'logs' but I did not found one!")) def test_module_on_module(self): """ No module configuration for modules Check that the feature is detected as disabled :return: """ self.print_header() self.setup_with_file('cfg/modules/alignak_module_with_submodules.cfg') assert self.conf_is_correct self.show_configuration_logs() # No arbiter modules created modules = [m.module_alias for m in self.arbiter.myself.modules] assert modules == ['Example'] # The only existing broker module is Example declared in the configuration modules = [ m.module_alias for m in self.brokers['broker-master'].modules ] assert modules == ['Example'] # The only existing poller module is Example declared in the configuration modules = [ m.module_alias for m in self.pollers['poller-master'].modules ] assert modules == ['Example'] # The only existing receiver module is Example declared in the configuration modules = [ m.module_alias for m in self.receivers['receiver-master'].modules ] assert modules == ['Example'] # The only existing reactionner module is Example declared in the configuration modules = [ m.module_alias for m in self.reactionners['reactionner-master'].modules ] assert modules == ['Example'] # No scheduler modules created modules = [ m.module_alias for m in self.schedulers['scheduler-master'].modules ] assert modules == ['Example'] def test_modulemanager(self): """ Module manager manages its modules Test if the module manager manages correctly all the modules :return: """ self.print_header() self.setup_with_file('cfg/cfg_default_with_modules.cfg') assert self.conf_is_correct time_hacker.set_real_time() # Create an Alignak module mod = Module({ 'module_alias': 'mod-example', 'module_types': 'example', 'python_name': 'alignak_module_example' }) # Create the modules manager for a daemon type self.modulemanager = ModulesManager('receiver', None) # Load an initialize the modules: # - load python module # - get module properties and instances self.modulemanager.load_and_init([mod]) # Loading module logs self.assert_any_log_match( re.escape( "Importing Python module 'alignak_module_example' for Example..." )) self.assert_any_log_match( re.escape( "Module properties: {'daemons': ['arbiter', 'broker', 'scheduler', 'poller', " "'receiver', 'reactionner'], 'phases': ['configuration', 'late_configuration', " "'running', 'retention'], 'type': 'example', 'external': True}" )) self.assert_any_log_match( re.escape("Imported 'alignak_module_example' for Example")) self.assert_any_log_match( re.escape( "Give an instance of alignak_module_example for alias: Example" )) self.assert_any_log_match( re.escape("I correctly loaded my modules: [Example]")) my_module = self.modulemanager.instances[0] assert my_module.is_external # Get list of not external modules assert [] == self.modulemanager.get_internal_instances() for phase in [ 'configuration', 'late_configuration', 'running', 'retention' ]: assert [] == self.modulemanager.get_internal_instances(phase) # Get list of external modules assert [my_module] == self.modulemanager.get_external_instances() for phase in [ 'configuration', 'late_configuration', 'running', 'retention' ]: assert [my_module ] == self.modulemanager.get_external_instances(phase) # Start external modules self.modulemanager.start_external_instances() # Starting external module logs self.assert_any_log_match( re.escape("Starting external module mod-example")) self.assert_any_log_match( re.escape("Starting external process for module mod-example")) self.assert_any_log_match( re.escape("mod-example is now started (pid=")) # Check alive assert my_module.process is not None assert my_module.process.is_alive() # Kill the external module (normal stop is .stop_process) my_module.kill() time.sleep(0.1) # Should be dead (not normally stopped...) but we still know a process for this module! assert my_module.process is not None # Stopping module logs self.assert_any_log_match(re.escape("Killing external module ")) self.assert_any_log_match(re.escape("External module killed")) # Nothing special ... self.modulemanager.check_alive_instances() # Try to restart the dead modules self.modulemanager.try_to_restart_deads() # In fact it's too early, so it won't do it # Here the inst should still be dead assert not my_module.process.is_alive() # So we lie my_module.last_init_try = -5 self.modulemanager.check_alive_instances() self.modulemanager.try_to_restart_deads() # In fact it's too early, so it won't do it # Here the inst should be alive again assert my_module.process.is_alive() # should be nothing more in to_restart of # the module manager assert [] == self.modulemanager.to_restart # Now we look for time restart so we kill it again my_module.kill() time.sleep(0.2) assert not my_module.process.is_alive() # Should be too early self.modulemanager.check_alive_instances() self.modulemanager.try_to_restart_deads() assert not my_module.process.is_alive() # We lie for the test again my_module.last_init_try = -5 self.modulemanager.check_alive_instances() self.modulemanager.try_to_restart_deads() # Here the inst should be alive again assert my_module.process.is_alive() # And we clear all now self.modulemanager.stop_all() # Stopping module logs self.assert_any_log_match(re.escape("I'm stopping module "))
class TestModuleManager(AlignakTest): def setUp(self): self.setup_with_file([]) time_hacker.set_real_time() # Try to see if the module manager can manage modules def test_modulemanager(self): mod = Module({ 'module_alias': 'mod-example', 'python_name': 'alignak_module_example' }) self.modulemanager = ModulesManager('broker', None) self.modulemanager.load_and_init([mod]) # And start external ones, like our LiveStatus self.modulemanager.start_external_instances() print "I correctly loaded the modules: %s " % ( [inst.get_name() for inst in self.modulemanager.instances]) print "*** First kill ****" # Now I will try to kill the livestatus module ls = self.modulemanager.instances[0] " :type: alignak.basemodule.BaseModule " ls.kill() time.sleep(0.1) print "Check alive?" print "Is alive?", ls.process.is_alive() # Should be dead self.assertFalse(ls.process.is_alive()) self.modulemanager.check_alive_instances() self.modulemanager.try_to_restart_deads() # In fact it's too early, so it won't do it # Here the inst should still be dead print "Is alive?", ls.process.is_alive() self.assertFalse(ls.process.is_alive()) # So we lie ls.last_init_try = -5 self.modulemanager.check_alive_instances() self.modulemanager.try_to_restart_deads() # In fact it's too early, so it won't do it # Here the inst should be alive again print "Is alive?", ls.process.is_alive() self.assertTrue(ls.process.is_alive()) # should be nothing more in to_restart of # the module manager self.assertEqual([], self.modulemanager.to_restart) # Now we look for time restart so we kill it again ls.kill() time.sleep(0.2) self.assertFalse(ls.process.is_alive()) # Should be too early self.modulemanager.check_alive_instances() self.modulemanager.try_to_restart_deads() print "Is alive or not", ls.process.is_alive() self.assertFalse(ls.process.is_alive()) # We lie for the test again ls.last_init_try = -5 self.modulemanager.check_alive_instances() self.modulemanager.try_to_restart_deads() # Here the inst should be alive again print "Is alive?", ls.process.is_alive() self.assertTrue(ls.process.is_alive()) # And we clear all now print "Ask to die" self.modulemanager.stop_all() print "Died"