Ejemplo n.º 1
0
    def signalControllerStart(self, signal, sender, **data):
        """
        Called to handle the EVT_DIRECTOR_CTRLSTART signal, which
        is used to return the result of a start command.

        :param data['data]: This will contain the name of the
        controller to be started. This name is the same name
        as that in the configuration section.

        :returns: a call result dict.

            rc['result'] = 'ok' | 'error'

            For ok result:

            rc['data'] = ''

            For error result:

            rc['data'] = 'Error / Exception message'

        Note: this will contain every controller except the
        director controller.

        Event Dispatched: EVT_DIRECTOR_CTRLSTART

        """
        msg = ''
        try:
            self.log.debug("signalControllerStart: received request (sig id %s)." % signal.uid)
            name = data['data']

            c = config.get_cfg()
            for ctrl in c.cfg:
                if ctrl.name == name:
                    if ctrl.disabled == "yes":
                        msg = "The controller '%s' is disabled and cannot be started" % name
                    else:
                        # indicate we're that the process should be start
                        # if it stops or exits.
                        #
                        ctrl.wasStopped = False
                        ctrl.mod.start()
                        msg = "Service '%s' start called." % ctrl.name

                    break

        except:
            self.log.exception("signalControllerStart: error handling signal (sig id %s) - " % signal.uid)
            msg = self.formatError()
            rc = self.resultDict(msg, 'error')

        else:
            rc = self.resultDict(msg)

        self.log.debug("signalControllerStart: replying to request (sig id %s) - " % signal.uid)
        messenger.reply(signal, rc)
    def testdirectorConfig(self):
        """Test the configuration set and machinery
        """
        test_config = """
        [director]
        disabled = 'no'
        
        [broker]
        disabled = 'no'
        
        [agency]
        disabled = 'no'

            [aardvark]
            order = 1
            cat = swipe
            agent = myswipe

            [bat]
            order = 0
            cat = swipe
            agent = myswipe
            
        """
        
        # Reset and Check that no setup done is caught:
        config.clear()
        
        self.assertRaises(config.ConfigNotSetup, config.get_cfg)

        # Check we don't get and problems with files...
        config.set_cfg(test_config)
        
        c = config.get_cfg()
        
        # This should only contain 5 as the agents should be part of 
        # the agency.agents member:
        self.assertEquals(len(c.cfg), 3)
        
        # This is the default order in which the objects should be recovered:
        self.assertEquals(c.cfg[0].name, 'director')
        self.assertEquals(c.cfg[0].order, 0)
        self.assertEquals(c.cfg[1].name, 'broker')
        self.assertEquals(c.cfg[1].order, 1)
        self.assertEquals(c.cfg[2].name, 'agency')
        self.assertEquals(c.cfg[2].order, 2)
        
        # Check the agents are present:
        agents = c.cfg[2].agents
        self.assertEquals(len(agents), 2)
        
        # Check the default ordering of the recovered agents:
        self.assertEquals(agents[0].name, 'bat')
        self.assertEquals(agents[0].order, 0)
        self.assertEquals(agents[1].name, 'aardvark')
        self.assertEquals(agents[1].order, 1)
    def testdirectorConfigByNameRecovery(self):
        """Test that I can get named config objects from the global configuration.
        """
        test_config = """
        [director]
        disabled = 'no'
        
        [broker]
        disabled = 'no'
        
        [agency]
        disabled = 'no'

            [aardvark]
            order = 1
            cat = swipe
            agent = myswipe

            [bat]
            order = 0
            cat = swipe
            agent = myswipe
            
        """
        config.clear()
        config.set_cfg(test_config)
        c = config.get_cfg()
        
        self.assertEquals(c.director is None, False)
        self.assertEquals(c.broker is None, False)
        self.assertEquals(c.agency is None, False)
        self.assertEquals(c.webadmin is None, True)
        
        # This is the default order in which the objects should be recovered:
        self.assertEquals(c.director.name, 'director')
        self.assertEquals(c.director.order, 0)
        
        # Check the agents are present:
        agents = c.agency.agents
        self.assertEquals(len(agents), 2)
        
        # Check the default ordering of the recovered agents:
        self.assertEquals(agents[0].name, 'bat')
        self.assertEquals(agents[0].order, 0)
        self.assertEquals(agents[1].name, 'aardvark')
        self.assertEquals(agents[1].order, 1)
Ejemplo n.º 4
0
    def controllerSetup(self):
        """
        Called to load the director configuration from the raw config data.
        This will then recover and load only the relevant controller
        sections.

        After loading the controllers each one's setUp will be called, passing
        it its own local section of the configuration.

        The controllers recovered will be stored in the internal controllers
        member variable.

        :returns: None.

        """
        self.log.info("controllerSetup: loading controllers from config.")
        c = config.get_cfg()

        # Recover and import the controllers:
        self.controllers = config.load_controllers(c.cfg,
                                                   ignore_exceptions=True)
        self.log.info("controllerSetup: %s controller(s) recovered." %
                      len(self.controllers))

        if self.controllers:
            # Setup all enabled controllers:
            for ctl in self.controllers:
                self.nameLookup[ctl.name] = ctl
                controller = ctl.mod
                if not controller:
                    self.log.warn("controllerSetup: %s module isn't loaded!" %
                                  ctl)
                    continue
                try:
                    if ctl.disabled == 'no':
                        controller.setUp(ctl.config)
                except Exception as e:
                    self.log.error("'%s' setUp error: %s" % (ctl, str(e)))
                    #sys.stderr.write("%s setUp error: %s" % (ctl, self.formatError()))
                    if not self.keep_going_on_exceptions():
                        # Stop!
                        raise
        else:
            self.log.warn("controllerSetup: no controllers found in config.")
Ejemplo n.º 5
0
    def appmainSetup(self):
        """
        Called from appmain or from testing to set up the signal
        handling and other items ready for a run / test run.

        :returns: poll_time used by the director as a sleep
        between controller checks.

        """
        c = config.get_cfg()
        poll_time = float(c.director.poll_time)

        if not c.director.messaging == 'no':
            # Set up all signals handlers provided by the director:
            self.signals.setup()

        # Recover the controllers from director configuration.
        self.controllerSetup()

        return poll_time
Ejemplo n.º 6
0
    def appmainSetup(self):
        """
        Called from appmain or from testing to set up the signal
        handling and other items ready for a run / test run.

        :returns: poll_time used by the director as a sleep
        between controller checks.

        """
        c = config.get_cfg()
        poll_time = float(c.director.poll_time)

        if not c.director.messaging == 'no':
            # Set up all signals handlers provided by the director:
            self.signals.setup()

        # Recover the controllers from director configuration.
        self.controllerSetup()

        return poll_time
Ejemplo n.º 7
0
    def controllerSetup(self):
        """
        Called to load the director configuration from the raw config data.
        This will then recover and load only the relevant controller
        sections.

        After loading the controllers each one's setUp will be called, passing
        it its own local section of the configuration.

        The controllers recovered will be stored in the internal controllers
        member variable.

        :returns: None.

        """
        self.log.info("controllerSetup: loading controllers from config.")
        c = config.get_cfg()

        # Recover and import the controllers:
        self.controllers = config.load_controllers(c.cfg, ignore_exceptions=True)
        self.log.info("controllerSetup: %s controller(s) recovered." % len(self.controllers))

        if self.controllers:
            # Setup all enabled controllers:
            for ctl in self.controllers:
                self.nameLookup[ctl.name] = ctl
                controller = ctl.mod
                if not controller:
                    self.log.warn("controllerSetup: %s module isn't loaded!" % ctl)
                    continue
                try:
                    if ctl.disabled == 'no':
                        controller.setUp(ctl.config)
                except Exception as e:
                    self.log.error("'%s' setUp error: %s" % (ctl, str(e)))
                    #sys.stderr.write("%s setUp error: %s" % (ctl, self.formatError()))
                    if not self.keep_going_on_exceptions():
                        # Stop!
                        raise
        else:
            self.log.warn("controllerSetup: no controllers found in config.")
Ejemplo n.º 8
0
        def testmain(tc):
            """"""
            c = config.get_cfg()
            self.assertNotEquals(c.director, None)
            self.assertNotEquals(c.agency, None)
            self.assertEquals(len(c.cfg), 3)
            self.assertEquals(len(c.agency.agents), 1)

            # Quick ping to see if messaging is up and running:
            d = signals.SignalsSender()
            get_log().info("testControllerConfigReload: calling ping")
            d.ping()

            # Check the initial state of our test controller.
            #
            ctrl = c.cfg[2]
            self.assertEquals(ctrl.disabled, 'no')
            self.assertEquals(ctrl.order, 4)
            self.assertEquals(ctrl.controller, 'mypackage.mycontroller')
            self.assertNotEquals(ctrl.mod, None)
            self.assertEquals(ctrl.extra_arg, 'hello there')

            # Called to return a version of the config that
            # could be pickled and transported externally.
            # The main difference will be no module code will
            # be exported as it won't pickle.
            #
            rc = d.configuration()
            self.assertEquals(rc['result'], 'ok')

            import pprint
            get_log().debug("""


            rc['data']

            %s


            """ % (pprint.pformat(rc['data'])))
        def testmain(tc):
            """"""
            c = config.get_cfg()
            self.assertNotEquals(c.director, None)
            self.assertNotEquals(c.agency, None)
            self.assertEquals(len(c.cfg), 3)
            self.assertEquals(len(c.agency.agents), 1)

            # Quick ping to see if messaging is up and running:
            d = signals.SignalsSender()
            get_log().info("testControllerConfigReload: calling ping")
            d.ping()

            # Check the initial state of our test controller.
            #
            ctrl = c.cfg[2]
            self.assertEquals(ctrl.disabled, 'no')
            self.assertEquals(ctrl.order, 4)
            self.assertEquals(ctrl.controller, 'mypackage.mycontroller')
            self.assertNotEquals(ctrl.mod, None)
            self.assertEquals(ctrl.extra_arg, 'hello there')

            # Called to return a version of the config that
            # could be pickled and transported externally.
            # The main difference will be no module code will
            # be exported as it won't pickle.
            #
            rc = d.configuration()
            self.assertEquals(rc['result'], 'ok')

            import pprint
            get_log().debug("""


            rc['data']

            %s


            """ % (pprint.pformat(rc['data'])))
Ejemplo n.º 10
0
    def main(self, director_testing=False):
        """
        The main thread in which twisted and the messagin system runs. The
        manager main run inside its own thread. The appman(...) is the
        main of the director.

        """
        self.log.info("main: running.")
        c = config.get_cfg()

        class ExitTime(object):
            def __init__(self):
                self.exitTime = False

            def isExit(self):
                return self.exitTime

        et = ExitTime()

        # Allow twisted to be disable if no messaging is used or an alternative
        # approach is used.
        if NO_MESSAGING or c.director.messaging == 'no':
            try:
                self.appmain(et.isExit)

            except KeyboardInterrupt:
                self.log.warn("Ctrl-C, Exiting.")

            except:
                self.log.exception("Exiting on exception: ")

            finally:
                # Indicate the director should exit then call shutdown to
                # cleanly tell all controllers to shutdown as well
                et.exitTime = True
                self.shutdown()

        else:
            disable_broker = c.director.disable_broker
            if disable_broker == 'no':
                # Set up the messenger protocols where using:
                self.log.info("main: setting up stomp connection to broker.")

                messenger.stompprotocol.setup(
                    dict(
                        host=c.director.msg_host,
                        port=int(c.director.msg_port),
                        username=c.director.msg_username,
                        password=c.director.msg_password,
                        channel=c.director.msg_channel,
                    ))

            else:
                self.log.warn(
                    "main: the director's broker connection is disabled (disable_broker = 'yes')."
                )

            # Use internal broker? This allow simplifies things and
            # means we don't have to run a morbid/other program as
            # a child process.
            #
            if c.director.internal_broker == 'yes':
                self.log.warn(
                    "main: Starting the interal light weight broker (internal_broker = 'yes')."
                )
                from evasion.director import testing
                testing.setup_broker(int(c.director.msg_port),
                                     c.director.msg_interface)

            noproxydispatchbroker = c.director.noproxydispatch
            if noproxydispatchbroker == 'no':
                from evasion.director import proxydispatch

                port = int(c.director.proxy_dispatch_port)
                self.log.info(
                    "main: setting up reply proxy dispatch http://127.0.0.1:%s/ ."
                    % port)
                proxydispatch.setup(port)

            else:
                self.log.warn(
                    "main: the director's proxydispatch is disabled (noproxydispatch = 'yes')."
                )

            if director_testing:
                self.log.warn(
                    "main: testing active! The main loop is running elsewhere."
                )

            else:
                try:
                    self.log.info("main: Running.")
                    messenger.run(self.appmain)

                finally:
                    self.log.info("main: shutdown!")
                    self.shutdown()
                    self.exit()
Ejemplo n.º 11
0
    def main(self, director_testing=False):
        """
        The main thread in which twisted and the messagin system runs. The
        manager main run inside its own thread. The appman(...) is the
        main of the director.

        """
        self.log.info("main: running.")
        c = config.get_cfg()

        class ExitTime(object):
            def __init__(self):
                self.exitTime = False

            def isExit(self):
                return self.exitTime

        et = ExitTime()

        # Allow twisted to be disable if no messaging is used or an alternative
        # approach is used.
        if NO_MESSAGING or c.director.messaging == 'no':
            try:
                self.appmain(et.isExit)

            except KeyboardInterrupt:
                self.log.warn("Ctrl-C, Exiting.")

            except:
                self.log.exception("Exiting on exception: ")

            finally:
                # Indicate the director should exit then call shutdown to
                # cleanly tell all controllers to shutdown as well
                et.exitTime = True
                self.shutdown()

        else:
            disable_broker = c.director.disable_broker
            if disable_broker == 'no':
                # Set up the messenger protocols where using:
                self.log.info("main: setting up stomp connection to broker.")

                messenger.stompprotocol.setup(dict(
                        host=c.director.msg_host,
                        port=int(c.director.msg_port),
                        username=c.director.msg_username,
                        password=c.director.msg_password,
                        channel=c.director.msg_channel,
                ))

            else:
                self.log.warn("main: the director's broker connection is disabled (disable_broker = 'yes').")

            # Use internal broker? This allow simplifies things and
            # means we don't have to run a morbid/other program as
            # a child process.
            #
            if c.director.internal_broker == 'yes':
                self.log.warn("main: Starting the interal light weight broker (internal_broker = 'yes').")
                from evasion.director import testing
                testing.setup_broker(
                    int(c.director.msg_port),
                    c.director.msg_interface
                )

            noproxydispatchbroker = c.director.noproxydispatch
            if noproxydispatchbroker == 'no':
                from evasion.director import proxydispatch

                port = int(c.director.proxy_dispatch_port)
                self.log.info("main: setting up reply proxy dispatch http://127.0.0.1:%s/ ." % port)
                proxydispatch.setup(port)

            else:
                self.log.warn("main: the director's proxydispatch is disabled (noproxydispatch = 'yes').")

            if director_testing:
                self.log.warn("main: testing active! The main loop is running elsewhere.")

            else:
                try:
                    self.log.info("main: Running.")
                    messenger.run(self.appmain)

                finally:
                    self.log.info("main: shutdown!")
                    self.shutdown()
                    self.exit()
Ejemplo n.º 12
0
        def testmain(tc):
            """Start-Stop-Restart"""
            # The configuration should contain the director and
            # controller with the load module instance from our
            # test controller
            #
            c = config.get_cfg()
            self.assertNotEquals(c.director, None)
            self.assertEquals(len(c.cfg), 2)

            # Quick ping to see if messaging is up and running:
            d = signals.SignalsSender()
            d.ping()

            # Check the initial state of our test controller. Its
            # loaded under a partial director. This is missing the
            # start although each controller will have had its setUp
            # called. We'll take card of running the controller via
            # signalling.
            #
            ctrl = c.cfg[1]
            self.assertEquals(ctrl.disabled, 'no')
            self.assertEquals(ctrl.order, 8)
            self.assertEquals(ctrl.controller, 'mypackage.mycontroller')
            self.assertNotEquals(ctrl.mod, None)
            self.assertEquals(ctrl.extra_arg, 'hello there')

            self.assertEquals(ctrl.mod.startCalled, False)
            self.assertEquals(ctrl.mod.stopCalled, False)
            self.assertEquals(ctrl.mod.tearDownCalled, False)
            self.assertEquals(ctrl.mod.isStartedCheck, False)
            self.assertEquals(ctrl.mod.isStoppedCheck, False)
            self.assertEquals(ctrl.mod.extraArg, 'hello there')

            # Recover the current state of the controllers:
            #
            print "Calling controllerState..."
            rc = d.controllerState()
            self.assertEquals(rc['result'], 'ok')

            correct = [
                # The director won't appear in this list although its technically
                # a controller.
                dict(name='mycontroller',
                     disabled='no',
                     started=False,
                     config=ctrl.mod.config),
            ]

            self.assertEquals(len(rc['data']), 1)
            self.assertEquals(rc['data'], correct,
                              err_msg(correct, rc['data']))

            # Tell the controller to start and check it is:
            #
            print "Calling controllerStart..."
            rc = d.controllerStart('mycontroller')
            self.assertEquals(rc['result'], 'ok')
            self.assertEquals(rc['data'], True)

            print "Calling controllerState..."
            rc = d.controllerState()
            self.assertEquals(rc['result'], 'ok')

            correct = [
                dict(name='mycontroller',
                     disabled='no',
                     started=True,
                     config=ctrl.mod.config),
            ]

            self.assertEquals(rc['data'], correct,
                              err_msg(correct, rc['data']))

            c = config.get_cfg()
            self.assertEquals(ctrl.mod.startCalled, True)
            self.assertEquals(ctrl.mod.stopCalled, False)

            # Tell the controller to stop and check it is:
            #
            print "Calling controllerStop..."
            rc = d.controllerStop('mycontroller')
            self.assertEquals(rc['result'], 'ok')
            self.assertEquals(rc['data'], True)

            print "Calling controllerState..."
            rc = d.controllerState()
            self.assertEquals(rc['result'], 'ok')

            correct = [
                dict(name='mycontroller',
                     disabled='no',
                     started=True,
                     config=ctrl.mod.config),
            ]

            self.assertEquals(rc['data'], correct,
                              err_msg(correct, rc['data']))

            c = config.get_cfg()
            self.assertEquals(ctrl.mod.startCalled, True)
            self.assertEquals(ctrl.mod.stopCalled, True)
    def testAgentControllerImport(self):
        """Test I can import Agent or Controller classes using the import_module
        """
        p = tempfile.mkdtemp()
        sys.path.append(p)
        try:
            # Create an agent inside a package so I can then test 
            # the absolute import on which the system is based.
            #
            # mypackage.myagent
            #
            mypkg = os.path.join(p,'mypackage')
            os.mkdir(mypkg)
            
            f = os.path.join(mypkg, '__init__.py')
            fd = open(f, 'wb')
            fd.write("\n")
            fd.close()
            
            # Create an agent module that import_module should find and load.
            #
            f = os.path.join(mypkg, 'myagent.py')
            fd = open(f, 'wb')
            fd.write("""

class Agent(object):
    pass
        
            """)
            fd.close()
            
            # This shouldn't create any import exceptions: 
            class Obj:
                type = 'agent'
                agent = 'mypackage.myagent'
            config.import_module(Obj.type, Obj())
            
            # Try this from configuration file:
            test_config = """
            [director]
            
            [agency]
            order = 1
            disabled = 'no'
            
            [fancyagent]
            order = 2
            cat = 'misc'
            agent = 'mypackage.myagent'
            
            [willnotshowup]
            disabled = 'yes'
            order = 3
            cat = 'misc'
            agent = 'mypackage.myagent'
            bob = '1234'
            port = 59876
            
            """
            config.set_cfg(test_config)
            c = config.get_cfg()
            
            objs = config.load_agents(c.cfg)

            # The agency will be in position 1 (order 1). There should be
            # two agents present, even though the second one is disabled.
            self.assertEquals(len(objs[1].agents), 2)
            
            # Check the config section is stored as part of the config 
            # attribute:
            a = objs[1].agents[1]
            self.assertEquals(a.config['disabled'], 'yes')
            self.assertEquals(a.config['order'], '3')
            self.assertEquals(a.config['cat'], 'misc')
            self.assertEquals(a.config['agent'], 'mypackage.myagent')
            self.assertEquals(a.config['bob'], '1234')
            self.assertEquals(a.config['port'], '59876')
            
            m = __import__('mypackage.myagent', fromlist=['mypackage',])
            self.assertEquals(isinstance(objs[1].agents[0].mod, m.Agent), True, "Agent not recovered correctly!")
            
            # The disabled agent should not be imported.
            m = __import__('mypackage.myagent', fromlist=['mypackage',])
            self.assertEquals(objs[1].agents[1].mod, None, "Agent was imported when it should not have been!")
            
            # try updating the config_objs and recheck that the change has been stored.
            config.update_objs(objs)
            c = config.get_cfg()
            self.assertEquals(isinstance(objs[1].agents[0].mod, m.Agent), True, "Agent not stored+updated correctly!")
            self.assertEquals(isinstance(c.agency.agents[0].mod, m.Agent), True, "Agent not stored+updated correctly!")
            
            
            # Create an controller module that import_module should find and load.
            #
            f = os.path.join(mypkg, 'mycontroller.py')
            fd = open(f, 'wb')
            fd.write("""

class Controller(object):
    pass
        
            """)
            fd.close()
            
            # This shouldn't create any import exceptions: 
            class Obj:
                type = 'controller'
                controller = 'mypackage.mycontroller'
            config.import_module(Obj.type, Obj())
            
            # Try this from configuration file:
            test_config = """
            [director]

            [agency]
            order = 1
            disabled = 'yes'
            
            [supercontroller]
            order = 2
            controller = 'mypackage.mycontroller'
            
            """
            config.set_cfg(test_config)
            c = config.get_cfg()
            
            self.assertEquals(len(c.cfg), 3)
            objs = config.load_controllers(c.cfg)
            
            msg = """
            Inital config != result from load_controllers
            
            c.objs:            
            %s
            
            loaded objs:
            %s
            
            """ % (c.cfg, objs)
            
            self.assertEquals(len(objs), 3, msg)
            
            m = __import__('mypackage.mycontroller', fromlist=['mypackage',])
            
            # The supercontroller will be in this position:
            self.assertEquals(isinstance(objs[2].mod, m.Controller), True, "Controller not recovered correctly!")

            # try updating the config_objs and recheck that the change has been stored.
            config.update_objs(objs)
            c = config.get_cfg()
            self.assertEquals(len(objs), 3)
            m = __import__('mypackage.mycontroller', fromlist=['mypackage',])
            self.assertEquals(isinstance(objs[2].mod, m.Controller), True, "Controller not recovered correctly!")
            
            
        finally:
            self.cleanUp(p)
Ejemplo n.º 14
0
        def testmain(tc):
            """Start-Stop-Restart"""
            # The configuration should contain the director and
            # controller with the load module instance from our
            # test controller
            #
            c = config.get_cfg()
            self.assertNotEquals(c.director, None)
            self.assertEquals(len(c.cfg), 2)

            # Quick ping to see if messaging is up and running:
            d = signals.SignalsSender()
            get_log().info("testControllerConfigReload: calling ping")
            d.ping()

            # Check the initial state of our test controller.
            #
            ctrl = c.cfg[1]
            self.assertEquals(ctrl.disabled, 'no')
            self.assertEquals(ctrl.order, 8)
            self.assertEquals(ctrl.controller, 'mypackage.mycontroller')
            self.assertNotEquals(ctrl.mod, None)
            self.assertEquals(ctrl.extra_arg, 'hello there')

            original_ctrl = ctrl.mod
            self.assertEquals(ctrl.mod.startCalled, False)
            self.assertEquals(ctrl.mod.stopCalled, False)
            self.assertEquals(ctrl.mod.tearDownCalled, False)
            self.assertEquals(ctrl.mod.isStartedCheck, False)
            self.assertEquals(ctrl.mod.isStoppedCheck, False)
            self.assertEquals(ctrl.mod.extraArg, 'hello there')

            # Start the controller before we do a reload
            #
            get_log().info(
                "testControllerConfigReload 0. Calling controllerStart...")
            rc = d.controllerStart('mycontroller')
            self.assertEquals(rc['result'], 'ok')
            self.assertEquals(rc['data'], True)

            # Create the new configuration and then tell the
            # controller to reload it. This should cause the
            # running controller to be stopped. The tearDown
            # method will also be called. The controller
            # name cannot be changed. This is used to refer to
            # the original configuration section. It is needed
            # when saving the configuration to disk.
            #
            # This configuration replaces what was there.
            new_config = dict(order=4,
                              name="mycontroller",
                              disabled='no',
                              controller='mypackage.mycontroller2')

            # Do the reload:
            rc = d.controllerReload('mycontroller', new_config)
            self.assertEquals(rc['result'], 'ok')
            self.assertEquals(rc['data'], True)

            # Check controller is different and that the original
            # controller got shutdown correctly:
            self.assertEquals(original_ctrl.startCalled, True)
            self.assertEquals(original_ctrl.stopCalled, True)
            self.assertEquals(original_ctrl.tearDownCalled, True)

            # Get the newly updated configuration and check the
            # new controllers state.
            #
            c = config.get_cfg()
            ctrl = c.cfg[1]
            self.assertNotEquals(ctrl, original_ctrl)
            self.assertNotEquals(c.director, None)
            self.assertEquals(len(c.cfg), 2)

            # Check out the new controller state:
            #
            self.assertEquals(ctrl.mod.startCalled, False)
            self.assertEquals(ctrl.mod.stopCalled, False)
            self.assertEquals(ctrl.mod.tearDownCalled, False)
            self.assertEquals(ctrl.mod.isStartedCheck, False)
            self.assertEquals(ctrl.mod.isStoppedCheck, False)
            self.assertEquals(hasattr(ctrl.mod, 'extraArg'), False)
Ejemplo n.º 15
0
        def testmain(tc):
            """Start-Stop-Restart"""
            # The configuration should contain the director and
            # controller with the load module instance from our
            # test controller
            #
            c = config.get_cfg()
            self.assertNotEquals(c.director, None)
            self.assertEquals(len(c.cfg), 2)

            # Quick ping to see if messaging is up and running:
            d = signals.SignalsSender()
            d.ping()

            # Check the initial state of our test controller. Its
            # loaded under a partial director. This is missing the
            # start although each controller will have had its setUp
            # called. We'll take card of running the controller via
            # signalling.
            #
            ctrl = c.cfg[1]
            self.assertEquals(ctrl.disabled, 'no')
            self.assertEquals(ctrl.order, 8)
            self.assertEquals(ctrl.controller, 'mypackage.mycontroller')
            self.assertNotEquals(ctrl.mod, None)
            self.assertEquals(ctrl.extra_arg, 'hello there')

            self.assertEquals(ctrl.mod.startCalled, False)
            self.assertEquals(ctrl.mod.stopCalled, False)
            self.assertEquals(ctrl.mod.tearDownCalled, False)
            self.assertEquals(ctrl.mod.isStartedCheck, False)
            self.assertEquals(ctrl.mod.isStoppedCheck, False)
            self.assertEquals(ctrl.mod.extraArg, 'hello there')

            # Recover the current state of the controllers:
            #
            print "Calling controllerState..."
            rc = d.controllerState()
            self.assertEquals(rc['result'], 'ok')

            correct = [
                # The director won't appear in this list although its technically
                # a controller.
                dict(name='mycontroller', disabled='no', started=False, config=ctrl.mod.config),
            ]

            self.assertEquals(len(rc['data']), 1)
            self.assertEquals(rc['data'], correct, err_msg(correct, rc['data']))

            # Tell the controller to start and check it is:
            #
            print "Calling controllerStart..."
            rc = d.controllerStart('mycontroller')
            self.assertEquals(rc['result'], 'ok')
            self.assertEquals(rc['data'], True)

            print "Calling controllerState..."
            rc = d.controllerState()
            self.assertEquals(rc['result'], 'ok')

            correct = [
                dict(name='mycontroller', disabled='no', started=True, config=ctrl.mod.config),
            ]

            self.assertEquals(rc['data'], correct, err_msg(correct, rc['data']))

            c = config.get_cfg()
            self.assertEquals(ctrl.mod.startCalled, True)
            self.assertEquals(ctrl.mod.stopCalled, False)

            # Tell the controller to stop and check it is:
            #
            print "Calling controllerStop..."
            rc = d.controllerStop('mycontroller')
            self.assertEquals(rc['result'], 'ok')
            self.assertEquals(rc['data'], True)

            print "Calling controllerState..."
            rc = d.controllerState()
            self.assertEquals(rc['result'], 'ok')

            correct = [
                dict(name='mycontroller', disabled='no', started=True, config=ctrl.mod.config),
            ]

            self.assertEquals(rc['data'], correct, err_msg(correct, rc['data']))

            c = config.get_cfg()
            self.assertEquals(ctrl.mod.startCalled, True)
            self.assertEquals(ctrl.mod.stopCalled, True)
Ejemplo n.º 16
0
        def testmain(tc):
            """Start-Stop-Restart"""
            # The configuration should contain the director and
            # controller with the load module instance from our
            # test controller
            #
            c = config.get_cfg()
            self.assertNotEquals(c.director, None)
            self.assertEquals(len(c.cfg), 2)

            # Quick ping to see if messaging is up and running:
            d = signals.SignalsSender()
            get_log().info("testControllerConfigReload: calling ping")
            d.ping()

            # Check the initial state of our test controller.
            #
            ctrl = c.cfg[1]
            self.assertEquals(ctrl.disabled, 'no')
            self.assertEquals(ctrl.order, 8)
            self.assertEquals(ctrl.controller, 'mypackage.mycontroller')
            self.assertNotEquals(ctrl.mod, None)
            self.assertEquals(ctrl.extra_arg, 'hello there')

            original_ctrl = ctrl.mod
            self.assertEquals(ctrl.mod.startCalled, False)
            self.assertEquals(ctrl.mod.stopCalled, False)
            self.assertEquals(ctrl.mod.tearDownCalled, False)
            self.assertEquals(ctrl.mod.isStartedCheck, False)
            self.assertEquals(ctrl.mod.isStoppedCheck, False)
            self.assertEquals(ctrl.mod.extraArg, 'hello there')

            # Start the controller before we do a reload
            #
            get_log().info("testControllerConfigReload 0. Calling controllerStart...")
            rc = d.controllerStart('mycontroller')
            self.assertEquals(rc['result'], 'ok')
            self.assertEquals(rc['data'], True)

            # Create the new configuration and then tell the
            # controller to reload it. This should cause the
            # running controller to be stopped. The tearDown
            # method will also be called. The controller
            # name cannot be changed. This is used to refer to
            # the original configuration section. It is needed
            # when saving the configuration to disk.
            #
            # This configuration replaces what was there.
            new_config = dict(
                order=4,
                name="mycontroller",
                disabled='no',
                controller='mypackage.mycontroller2'
            )

            # Do the reload:
            rc = d.controllerReload('mycontroller', new_config)
            self.assertEquals(rc['result'], 'ok')
            self.assertEquals(rc['data'], True)

            # Check controller is different and that the original
            # controller got shutdown correctly:
            self.assertEquals(original_ctrl.startCalled, True)
            self.assertEquals(original_ctrl.stopCalled, True)
            self.assertEquals(original_ctrl.tearDownCalled, True)

            # Get the newly updated configuration and check the
            # new controllers state.
            #
            c = config.get_cfg()
            ctrl = c.cfg[1]
            self.assertNotEquals(ctrl, original_ctrl)
            self.assertNotEquals(c.director, None)
            self.assertEquals(len(c.cfg), 2)

            # Check out the new controller state:
            #
            self.assertEquals(ctrl.mod.startCalled, False)
            self.assertEquals(ctrl.mod.stopCalled, False)
            self.assertEquals(ctrl.mod.tearDownCalled, False)
            self.assertEquals(ctrl.mod.isStartedCheck, False)
            self.assertEquals(ctrl.mod.isStoppedCheck, False)
            self.assertEquals(hasattr(ctrl.mod, 'extraArg'), False)
Ejemplo n.º 17
0
    def signalControllerState(self, signal, sender, **data):
        """
        Called to handle the EVT_DIRECTOR_CTRLSTATE signal, which
        is used to return the state of all controllers listed in
        the configuration.

        :param: None

        :returns: a call result dict.

            rc['result'] = 'ok' | 'error'

            For ok result:

            rc['data'] = [
                dict(name='..name..', disabled='no'|'yes', started=False | True, config={...}),
                :
                etc
            ]

            For error result:

            rc['data'] = 'Error / Exception message'

        Note: this will contain every controller except the
        director controller.

        Event Dispatched: EVT_DIRECTOR_CTRLSTATE

        """
        controller_state = []
        try:
            self.log.debug("controllerState: received request (sig id %s)." % signal.uid)

            c = config.get_cfg()

            for ctrl in c.cfg:
                if ctrl.name == 'director':
                    # skip the director as its not a normal controller.
                    continue

                # Recover the config for just this controller:
                ctrl_config = {}
                if ctrl.config:
                    ctrl_config = ctrl.config

                # Check if the controller module is present and actually running.
                started = False
                if ctrl.mod:
                    started = ctrl.mod.isStarted()

                controller_state.append(dict(
                    name=ctrl.name,
                    disabled=ctrl.disabled,
                    started=started,
                    config=ctrl_config,
                ))

        except:
            self.log.exception("controllerState: error handling signal (sig id %s) - " % signal.uid)
            msg = self.formatError()
            rc = self.resultDict(msg, 'error')

        else:
            rc = self.resultDict(controller_state)

        self.log.debug("controllerState: replying to request (sig id %s) - " % signal.uid)
        messenger.reply(signal, rc)