From 38f7c57d6008882e5036aac6b1aec413ce6b2f8b Mon Sep 17 00:00:00 2001 From: Stefan Hacker Date: Sat, 18 Dec 2010 03:18:46 +0100 Subject: [PATCH] Make mumo_manager.py usable. Extend test coverage (still very patchy) --- mumo_manager.py | 89 ++++++++++++++++++++++++++++++++++++++++---- mumo_manager_test.py | 56 ++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 7 deletions(-) diff --git a/mumo_manager.py b/mumo_manager.py index 644e7db..b914977 100644 --- a/mumo_manager.py +++ b/mumo_manager.py @@ -213,19 +213,94 @@ class MumoManager(Worker): @param kwargs: Keyword arguments for the function """ # Announce to all handlers registered to all events - for queue, handlers in mdict[self.MAGIC_ALL].iteritems(): - for handler in handlers: - self.__call_remote(queue, handler, args, kwargs) + try: + for queue, handlers in mdict[self.MAGIC_ALL].iteritems(): + for handler in handlers: + self.__call_remote(queue, handler, function, args, kwargs) + except KeyError: + # No handler registered for MAGIC_ALL + pass # Announce to all handlers of the given serverlist for server in servers: - for queue, handler in mdict[server].iteritems(): - self.__call_remote(queue, handler, args, kwargs) + try: + for queue, handler in mdict[server].iteritems(): + self.__call_remote(queue, handler, function, args, kwargs) + except KeyError: + # No handler registered for that server + pass - def __call_remote(self, queue, handler, *args, **kwargs): - queue.put((None, handler, args, kwargs)) + def __call_remote(self, queue, handler, function, *args, **kwargs): + try: + func = getattr(handler, function) # Find out what to call on target + except AttributeError, e: + mod = self.queues.get(queue, None) + myname = "" + for name, mymod in self.modules.iteritems(): + if mod == mymod: + myname = name + if myname: + self.log.error("Handler class registered by module '%s' does not handle function '%s'. Call failed.", myname, function) + else: + self.log().exception(e) + queue.put((None, func, args, kwargs)) # + #-- Module multiplexing functionality + # + + @local_thread + def announceConnected(self): + """ + Call connected handler on all handlers + """ + for queue, module in self.queues.iteritems(): + self.__call_remote(queue, module, "connected") + + @local_thread + def announceDisconnected(self): + """ + Call disconnected handler on all handlers + """ + for queue, module in self.queues.iteritems(): + self.__call_remote(queue, module, "disconnected") + + @local_thread + def announceMeta(self, servers, function, *args, **kwargs): + """ + Call a function on the meta handlers + + @param servers Servers to announce to + @param function Name of the function to call on the handler + @param args List of arguments + @param kwargs List of keyword arguments + """ + self.__announce_to_dict(self.metaCallbacks, servers, function, *args, **kwargs) + + @local_thread + def announceServer(self, servers, function, *args, **kwargs): + """ + Call a function on the server handlers + + @param servers Servers to announce to + @param function Name of the function to call on the handler + @param args List of arguments + @param kwargs List of keyword arguments + """ + self.__announce_to_dict(self.serverCallbacks, servers, function, *args, **kwargs) + + @local_thread + def announceContext(self, servers, function, *args, **kwargs): + """ + Call a function on the context handlers + + @param servers Servers to announce to + @param function Name of the function to call on the handler + @param args List of arguments + @param kwargs List of keyword arguments + """ + self.__announce_to_dict(self.serverCallbacks, servers, function, *args, **kwargs) + # #--- Module self management functionality # diff --git a/mumo_manager_test.py b/mumo_manager_test.py index 07a89f9..6041f54 100644 --- a/mumo_manager_test.py +++ b/mumo_manager_test.py @@ -33,12 +33,15 @@ import unittest import Queue from mumo_manager import MumoManager, MumoManagerRemote from mumo_module import MumoModule +from logging import basicConfig, ERROR import logging from threading import Event class MumoManagerTest(unittest.TestCase): def setUp(self): + basicConfig(level = ERROR) + class MyModule(MumoModule): def __init__(self, name, manager, configuration = None): MumoModule.__init__(self, name, manager, configuration) @@ -47,6 +50,10 @@ class MumoManagerTest(unittest.TestCase): self.estopped = Event() self.econnected = Event() self.edisconnected = Event() + + self.emeta = Event() + self.econtext = Event() + self.eserver = Event() def onStart(self): self.estarted.set() @@ -55,10 +62,26 @@ class MumoManagerTest(unittest.TestCase): self.estopped.set() def connected(self): + man = self.manager() + man.subscribeMetaCallbacks(self) + man.subscribeServerCallbacks(self) + man.subscribeContextCallbacks(self) self.econnected.set() def disconnected(self): self.edisconnected.set() + + def metaCallMe(self, arg1, arg2): + if arg1 == "arg1" and arg2 == "arg2": + self.emeta.set() + + def contextCallMe(self, arg1, arg2): + if arg1 == "arg1" and arg2 == "arg2": + self.econtext.set() + + def serverCallMe(self, arg1, arg2): + if arg1 == "arg1" and arg2 == "arg2": + self.eserver.set() self.mymod = MyModule @@ -106,6 +129,39 @@ class MumoManagerTest(unittest.TestCase): self.down(man, mod) + def testModuleConnectAndDisconnect(self): + man, mod = self.up() + + man.announceConnected() + mod.econnected.wait(timeout=1) + assert(mod.econnected.is_set()) + man.announceDisconnected() + mod.edisconnected.wait(timeout=1) + assert(mod.edisconnected.is_set()) + + self.down(man, mod) + + def testMetaCallback(self): + man, mod = self.up() + man.announceConnected() + man.announceMeta([], "metaCallMe", ["arg1"], {"arg2":"arg2"}) + man.announceDisconnected() + self.down(man, mod) + + def testContextCallback(self): + man, mod = self.up() + man.announceConnected() + man.announceContext([], "contextCallMe", ["arg1"], {"arg2":"arg2"}) + man.announceDisconnected() + self.down(man, mod) + + def testServerCallback(self): + man, mod = self.up() + man.announceConnected() + man.announceServer([], "serverCallMe", ["arg1"], {"arg2":"arg2"}) + man.announceDisconnected() + self.down(man, mod) + def tearDown(self): pass