class TestModuleSnmpBooster(AlignakTest):
    """
    This class contains the tests for the module
    """
    def test_module_loading(self):
        """
        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()

        # An arbiter module
        modules = [m.module_alias for m in self.arbiter.myself.modules]
        self.assertListEqual(modules, ['SnmpBoosterArbiter'])

        # No broker module
        modules = [
            m.module_alias for m in self.brokers['broker-master'].modules
        ]
        self.assertListEqual(modules, [])

        # A poller module
        modules = [
            m.module_alias for m in self.pollers['poller-master'].modules
        ]
        self.assertListEqual(modules, ['SnmpBoosterPoller'])

        # No receiver module
        modules = [
            m.module_alias for m in self.receivers['receiver-master'].modules
        ]
        self.assertListEqual(modules, [])

        # No reactionner module
        modules = [
            m.module_alias
            for m in self.reactionners['reactionner-master'].modules
        ]
        self.assertListEqual(modules, [])

        # A scheduler module
        modules = [
            m.module_alias for m in self.schedulers['scheduler-master'].modules
        ]
        self.assertListEqual(modules, ['SnmpBoosterScheduler'])

    def test_module_manager_arbiter(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': 'SnmpBoosterArbiter',
            'module_types': 'checks',
            'python_name': 'alignak_module_snmp_booster.snmpbooster_arbiter',
            'loaded_by': 'arbiter',
            'datasource': './cfg/genDevConfig/example.ini',
            'db_host': 'localhost',
            'db_port': 6379
        })

        # Create the modules manager for a daemon type
        self.modulemanager = ModulesManager('arbiter', None)

        # Clear logs
        self.clear_logs()

        # Load and initialize the modules:
        #  - load python module
        #  - get module properties and instances
        self.modulemanager.load_and_init([mod])

        # Loading module logs
        self.assert_log_match(
            re.escape(
                "Importing Python module 'alignak_module_snmp_booster.snmpbooster_arbiter' for "
                "SnmpBoosterArbiter..."), 0)
        self.assert_log_match(
            re.escape(
                "Module properties: {'daemons': ['arbiter'], 'phases': ['running', "
                "'late_configuration'], 'type': 'snmp_booster', 'external': False, "
                "'worker_capable': True}"), 1)
        self.assert_log_match(
            re.escape(
                "Imported 'alignak_module_snmp_booster.snmpbooster_arbiter' for SnmpBoosterArbiter"
            ), 2)
        self.assert_log_match(
            re.escape(
                "Loaded Python module 'alignak_module_snmp_booster.snmpbooster_arbiter' "
                "(SnmpBoosterArbiter)"), 3)
        self.assert_log_match(
            re.escape(
                "Give an instance of alignak_module_snmp_booster.snmpbooster_arbiter "
                "for alias: SnmpBoosterArbiter"), 4)

        self.assert_log_match(
            re.escape(
                "[SnmpBooster] [code 0101] Loading SNMP Booster module for plugin SnmpBoosterArbiter"
            ), 5)
        self.assert_log_match(
            re.escape(
                "[SnmpBooster] [code 0902] Reading input configuration file: "
                "./cfg/genDevConfig/example.ini"), 6)

        # Starting internal module logs
        self.assert_log_match(
            re.escape("Trying to initialize module: SnmpBoosterArbiter"), 7)
        self.assert_log_match(
            re.escape(
                "[SnmpBooster] [code 1101] Initialization of the SNMP Booster 2.0.0"
            ), 8)

        my_module = self.modulemanager.instances[0]

        # Get list of not external modules
        self.assertListEqual([my_module],
                             self.modulemanager.get_internal_instances())
        for phase in ['configuration', 'retention']:
            self.assertListEqual(
                [], self.modulemanager.get_internal_instances(phase))
        for phase in ['late_configuration', 'running']:
            self.assertListEqual(
                [my_module], self.modulemanager.get_internal_instances(phase))

        # Get list of external modules
        self.assertListEqual([], self.modulemanager.get_external_instances())
        for phase in [
                'configuration', 'late_configuration', 'running', 'retention'
        ]:
            self.assertListEqual(
                [], self.modulemanager.get_external_instances(phase))

        # Clear logs
        self.clear_logs()

        # Nothing special ...
        self.modulemanager.check_alive_instances()

        # And we clear all now
        self.modulemanager.stop_all()

    def test_module_manager_scheduler(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': 'SnmpBoosterScheduler',
            'module_types': 'checks',
            'python_name': 'alignak_module_snmp_booster.snmpbooster_scheduler',
            'loaded_by': 'scheduler',
            'datasource': './cfg/genDevConfig/example.ini',
            'db_host': 'localhost',
            'db_port': 6379
        })

        # Create the modules manager for a daemon type
        self.modulemanager = ModulesManager('scheduler', None)

        # Clear logs
        self.clear_logs()

        # Load and initialize the modules:
        #  - load python module
        #  - get module properties and instances
        self.modulemanager.load_and_init([mod])

        # Loading module logs
        self.assert_log_match(
            re.escape(
                "Importing Python module 'alignak_module_snmp_booster.snmpbooster_scheduler' "
                "for SnmpBoosterScheduler..."), 0)
        self.assert_log_match(
            re.escape(
                "Module properties: {'daemons': ['scheduler'], 'phases': ['running', "
                "'late_configuration'], 'type': 'snmp_booster', 'external': False, "
                "'worker_capable': True}"), 1)
        self.assert_log_match(
            re.escape(
                "Imported 'alignak_module_snmp_booster.snmpbooster_scheduler' for SnmpBoosterScheduler"
            ), 2)
        self.assert_log_match(
            re.escape(
                "Loaded Python module 'alignak_module_snmp_booster.snmpbooster_scheduler' "
                "(SnmpBoosterScheduler)"), 3)
        self.assert_log_match(
            re.escape(
                "Give an instance of alignak_module_snmp_booster.snmpbooster_scheduler "
                "for alias: SnmpBoosterScheduler"), 4)

        self.assert_log_match(
            re.escape(
                "[SnmpBooster] [code 0101] Loading SNMP Booster module for plugin SnmpBoosterScheduler"
            ), 5)

        # Starting internal module logs
        self.assert_log_match(
            re.escape("Trying to initialize module: SnmpBoosterScheduler"), 6)
        self.assert_log_match(
            re.escape(
                "[SnmpBooster] [code 1101] Initialization of the SNMP Booster 2.0.0"
            ), 7)

        my_module = self.modulemanager.instances[0]

        # Get list of not external modules
        self.assertListEqual([my_module],
                             self.modulemanager.get_internal_instances())
        for phase in ['configuration', 'retention']:
            self.assertListEqual(
                [], self.modulemanager.get_internal_instances(phase))
        for phase in ['late_configuration', 'running']:
            self.assertListEqual(
                [my_module], self.modulemanager.get_internal_instances(phase))

        # Get list of external modules
        self.assertListEqual([], self.modulemanager.get_external_instances())
        for phase in [
                'configuration', 'late_configuration', 'running', 'retention'
        ]:
            self.assertListEqual(
                [], self.modulemanager.get_external_instances(phase))

        # Clear logs
        self.clear_logs()

        # Nothing special ...
        self.modulemanager.check_alive_instances()

        # And we clear all now
        self.modulemanager.stop_all()

    def test_module_manager_poller(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': 'SnmpBoosterPoller',
            'module_types': 'checks',
            'python_name': 'alignak_module_snmp_booster.snmpbooster_poller',
            'loaded_by': 'poller',
            'datasource': './cfg/genDevConfig/example.ini',
            'db_host': 'localhost',
            'db_port': 6379
        })

        # Create the modules manager for a daemon type
        self.modulemanager = ModulesManager('poller', None)

        # Clear logs
        self.clear_logs()

        # Load and initialize the modules:
        #  - load python module
        #  - get module properties and instances
        self.modulemanager.load_and_init([mod])

        # Loading module logs
        self.assert_log_match(
            re.escape(
                "Importing Python module 'alignak_module_snmp_booster.snmpbooster_poller' "
                "for SnmpBoosterPoller..."), 0)
        self.assert_log_match(
            re.escape(
                "Module properties: {'daemons': ['poller'], 'phases': ['running', "
                "'late_configuration'], 'type': 'snmp_booster', 'external': False, "
                "'worker_capable': True}"), 1)
        self.assert_log_match(
            re.escape(
                "Imported 'alignak_module_snmp_booster.snmpbooster_poller' for SnmpBoosterPoller"
            ), 2)
        self.assert_log_match(
            re.escape(
                "Loaded Python module 'alignak_module_snmp_booster.snmpbooster_poller' "
                "(SnmpBoosterPoller)"), 3)
        self.assert_log_match(
            re.escape(
                "Give an instance of alignak_module_snmp_booster.snmpbooster_poller "
                "for alias: SnmpBoosterPoller"), 4)

        self.assert_log_match(
            re.escape(
                "[SnmpBooster] [code 0101] Loading SNMP Booster module for plugin SnmpBoosterPoller"
            ), 5)

        # Starting internal module logs
        self.assert_log_match(
            re.escape("Trying to initialize module: SnmpBoosterPoller"), 6)
        self.assert_log_match(
            re.escape(
                "[SnmpBooster] [code 1101] Initialization of the SNMP Booster 2.0.0"
            ), 7)

        my_module = self.modulemanager.instances[0]

        # Get list of not external modules
        self.assertListEqual([my_module],
                             self.modulemanager.get_internal_instances())
        for phase in ['configuration', 'retention']:
            self.assertListEqual(
                [], self.modulemanager.get_internal_instances(phase))
        for phase in ['late_configuration', 'running']:
            self.assertListEqual(
                [my_module], self.modulemanager.get_internal_instances(phase))

        # Get list of external modules
        self.assertListEqual([], self.modulemanager.get_external_instances())
        for phase in [
                'configuration', 'late_configuration', 'running', 'retention'
        ]:
            self.assertListEqual(
                [], self.modulemanager.get_external_instances(phase))

        # Clear logs
        self.clear_logs()

        # Nothing special ...
        self.modulemanager.check_alive_instances()

        # And we clear all now
        self.modulemanager.stop_all()
Example #2
0
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 "
        ))
Example #4
0
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)
Example #5
0
class TestModuleNrpeBooster(AlignakTest):
    """
    This class contains the tests for the module
    """
    def test_module_loading(self):
        """
        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, ['nrpe-booster'])

        # No receiver module
        modules = [
            m.module_alias for m in self.receivers['receiver-master'].modules
        ]
        self.assertListEqual(modules, [])

        # 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': 'nrpe-booster',
            'module_types': 'nrpe-booster',
            'python_name': 'alignak_module_nrpe_booster'
        })

        # Create the modules manager for a daemon type
        self.modulemanager = ModulesManager('poller', None)

        # Clear logs
        self.clear_logs()

        # Load and initialize the modules:
        #  - load python module
        #  - get module properties and instances
        self.modulemanager.load_and_init([mod])

        # Loading module logs
        self.assert_log_match(
            re.escape(
                "Importing Python module 'alignak_module_nrpe_booster' for nrpe-booster..."
            ), 0)
        self.assert_log_match(
            re.escape(
                "Module properties: {'daemons': ['poller'], 'phases': ['running'], "
                "'type': 'nrpe_poller', 'external': False, 'worker_capable': True}"
            ), 1)
        self.assert_log_match(
            re.escape(
                "Imported 'alignak_module_nrpe_booster' for nrpe-booster"), 2)
        self.assert_log_match(
            re.escape(
                "Loaded Python module 'alignak_module_nrpe_booster' (nrpe-booster)"
            ), 3)
        self.assert_log_match(
            re.escape(
                "Give an instance of alignak_module_nrpe_booster for alias: nrpe-booster"
            ), 4)

        # Starting internal module logs
        self.assert_log_match("Trying to initialize module: nrpe-booster", 5)
        self.assert_log_match("Initialization of the NRPE poller module", 6)

        my_module = self.modulemanager.instances[0]

        # Get list of not external modules
        self.assertListEqual([my_module],
                             self.modulemanager.get_internal_instances())
        for phase in ['configuration', 'late_configuration', 'retention']:
            self.assertListEqual(
                [], self.modulemanager.get_internal_instances(phase))
        for phase in ['running']:
            self.assertListEqual(
                [my_module], self.modulemanager.get_internal_instances(phase))

        # Get list of external modules
        self.assertListEqual([], self.modulemanager.get_external_instances())
        for phase in [
                'configuration', 'late_configuration', 'running', 'retention'
        ]:
            self.assertListEqual(
                [], self.modulemanager.get_external_instances(phase))

        # Clear logs
        self.clear_logs()

        # Nothing special ...
        self.modulemanager.check_alive_instances()

        # And we clear all now
        self.modulemanager.stop_all()
        # Stopping module logs

        self.assert_log_match("Ending the NRPE poller module", 0)

    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': 'nrpe-booster',
            'module_types': 'nrpe-booster',
            'python_name': 'alignak_module_nrpe_booster'
        })

        instance = alignak_module_nrpe_booster.get_instance(mod)
        self.assertIsInstance(instance, BaseModule)

        self.assert_log_match(
            re.escape("Give an instance of alignak_module_nrpe_booster for "
                      "alias: nrpe-booster"), 0)
Example #6
0
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 "))
Example #7
0
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 "))