def __init__(self, constraints): '''Initializer for AssimEventObserver class. Parameters: ----------- constraints: dict-like *or* callable() returning bool A dict describing our desired events. The constraints in the dict are effectively ANDed together. Each key is an attribute name in either the event itself or its associated object. The value associated with each attribute is either a list or a scalar value or something implementing __contains__. A scalar value implies that it *must* have exactly that value, otherwise it must be *in* the associated list/tuple/etc. This should be able to constrain the type of event we're looking at, the type of event-object we're looking at, and the domain of the event-object - and lots of other potentially useful things. See the "is_interesting" method below for implementation details... If 'constraints' is a callable (that is, callable(constraints) is True), then we will just call constraints(event) to see if the event is interesting to this observer. Whatever 'constraints' returns will be interpreted in a boolean context - so returning a bool would be a good idea... ''' self.constraints = constraints AssimEvent.registerobserver(self)
def __init__(self, constraints): '''Initializer for AssimEventObserver class. Parameters: ----------- constraints: dict-like *or* callable() returning bool A dict describing our desired events. The constraints in the dict are effectively ANDed together. Each key is an attribute name in either the event itself or its associated object. The value associated with each attribute is either a list or a scalar value or something implementing __contains__. A scalar value implies that it *must* have exactly that value, otherwise it must be *in* the associated list/tuple/etc. This should be able to constrain the type of event we're looking at, the type of event-object we're looking at, and the domain of the event-object - and lots of other potentially useful things. See the "is_interesting" method below for implementation details... If 'constraints' is a callable (that is, callable(constraints) is True), then we will just call constraints(event) to see if the event is interesting to this observer. Whatever 'constraints' returns will be interpreted in a boolean context - so returning a bool would be a good idea... ''' self.constraints = constraints AssimEvent.registerobserver(self)
def test_simple_init_bad(self): 'Perform a few simple AssimEvent bad initializations' AssimEvent.observers = [] observer=DummyObserver() badobserver=BadObserver() AssimEvent.registerobserver(observer) self.assertRaises(ValueError, AssimEvent, 'first', 999) self.assertRaises(AttributeError, AssimEvent.registerobserver, badobserver)
def test_simple_init_bad(self): 'Perform a few simple AssimEvent bad initializations' AssimEvent.enable_all_observers() AssimEvent.observers = [] observer=DummyObserver() badobserver=BadObserver() AssimEvent.registerobserver(observer) self.assertRaises(ValueError, AssimEvent, 'first', 999) self.assertRaises(AttributeError, AssimEvent.registerobserver, badobserver)
def test_fork_exec_event(self): '''This test will create a fork/exec event observer script and then test to see if its getting invoked properly... ''' AssimEvent.enable_all_observers() tmpdir = tempfile.mkdtemp('.d', 'testexec_') (fd, pathname) = tempfile.mkstemp('.out.txt') execscript = os.path.join(tmpdir, 'observer.sh') makescript(execscript, pathname) AssimEvent.observers = [] observer = ForkExecObserver(scriptdir=tmpdir) dummyclient = ClientClass() dummyclient.fred = 'fred' dummyclient.sevenofnine = 'Annika' dummyclient.foo = {'foo': 'bar'} self.assertEqual(observer.listscripts(), [ execscript, ]) AssimEvent.registerobserver(observer) AssimEvent(dummyclient, AssimEvent.CREATEOBJ) AssimEvent(dummyclient, AssimEvent.OBJUP, extrainfo={'origaddr': '10.10.10.254'}) os.close(fd) expectedcontent=\ '''====START==== ARG1=create ARG2=ClientClass ASSIM_fred=fred ASSIM_nodetype=ClientClass ASSIM_sevenofnine=Annika ==== JSON START ==== {"associatedobject":{"foo":{"foo":"bar"},"fred":"fred","nodetype":"ClientClass","sevenofnine":"Annika"},"eventtype":0,"extrainfo":null} ==== JSON END ==== ====END==== ====START==== ARG1=up ARG2=ClientClass ASSIM_fred=fred ASSIM_nodetype=ClientClass ASSIM_origaddr=10.10.10.254 ASSIM_sevenofnine=Annika ==== JSON START ==== {"associatedobject":{"foo":{"foo":"bar"},"fred":"fred","nodetype":"ClientClass","sevenofnine":"Annika"},"eventtype":1,"extrainfo":{"origaddr":"10.10.10.254"}} ==== JSON END ==== ====END==== ''' TestAssimEvent.waitfor(pathname, expectedcontent) f = open(pathname, 'r') content = f.read() f.close() self.assertEqual(content, expectedcontent) os.unlink(execscript) os.unlink(pathname) os.rmdir(tmpdir)
def test_fork_exec_event(self): '''This test will create a fork/exec event observer script and then test to see if its getting invoked properly... ''' AssimEvent.enable_all_observers() tmpdir = tempfile.mkdtemp('.d', 'testexec_') (fd, pathname) = tempfile.mkstemp('.out.txt') execscript = os.path.join(tmpdir, 'observer.sh') makescript(execscript, pathname) AssimEvent.observers = [] observer=ForkExecObserver(scriptdir=tmpdir) dummyclient = ClientClass() dummyclient.fred='fred' dummyclient.sevenofnine='Annika' dummyclient.foo = {'foo': 'bar'} self.assertEqual(observer.listscripts(), [execscript,]) AssimEvent.registerobserver(observer) AssimEvent(dummyclient, AssimEvent.CREATEOBJ) AssimEvent(dummyclient, AssimEvent.OBJUP, extrainfo={'origaddr': '10.10.10.254'}) os.close(fd) expectedcontent=\ '''====START==== ARG1=create ARG2=ClientClass ASSIM_fred=fred ASSIM_nodetype=ClientClass ASSIM_sevenofnine=Annika ==== JSON START ==== {"associatedobject":{"foo":{"foo":"bar"},"fred":"fred","nodetype":"ClientClass","sevenofnine":"Annika"},"eventtype":0,"extrainfo":null} ==== JSON END ==== ====END==== ====START==== ARG1=up ARG2=ClientClass ASSIM_fred=fred ASSIM_nodetype=ClientClass ASSIM_origaddr=10.10.10.254 ASSIM_sevenofnine=Annika ==== JSON START ==== {"associatedobject":{"foo":{"foo":"bar"},"fred":"fred","nodetype":"ClientClass","sevenofnine":"Annika"},"eventtype":1,"extrainfo":{"origaddr":"10.10.10.254"}} ==== JSON END ==== ====END==== ''' TestAssimEvent.waitfor(pathname, expectedcontent) f=open(pathname, 'r') content=f.read() f.close() self.assertEqual(content, expectedcontent) os.unlink(execscript) os.unlink(pathname) os.rmdir(tmpdir)
def test_fork_exec_killchild(self): '''This test will create a fork/exec event observer script and then kill the child listener and verify that it is handled correctly. ''' AssimEvent.enable_all_observers() tmpdir = tempfile.mkdtemp('.d', 'testexec_') (fd, pathname) = tempfile.mkstemp('.out.txt') execscript = os.path.join(tmpdir, 'observer.sh') makescript(execscript, pathname) AssimEvent.observers = [] observer=ForkExecObserver(scriptdir=tmpdir) dummyclient = ClientClass() dummyclient.fred='fred' dummyclient.sevenofnine='Annika' dummyclient.foo = {'foo': 'bar'} AssimEvent.registerobserver(observer) try: os.kill(observer.childpid, signal.SIGKILL) except OSError: # "docker build" doesn't let us kill processes... # so we give up on this test and call it good... os.unlink(execscript) os.unlink(pathname) os.rmdir(tmpdir) return time.sleep(0.1) AssimEvent(dummyclient, AssimEvent.CREATEOBJ) # Death of our FIFO child will cause it to get respawned, and # message sent to new child. No messages should be lost. expectedcontent=\ '''====START==== ARG1=create ARG2=ClientClass ASSIM_fred=fred ASSIM_nodetype=ClientClass ASSIM_sevenofnine=Annika ==== JSON START ==== {"associatedobject":{"foo":{"foo":"bar"},"fred":"fred","nodetype":"ClientClass","sevenofnine":"Annika"},"eventtype":0,"extrainfo":null} ==== JSON END ==== ====END==== ''' TestAssimEvent.waitfor(pathname, expectedcontent) f=open(pathname, 'r') content=f.read() f.close() self.assertEqual(content, expectedcontent) os.close(fd) os.unlink(execscript) os.unlink(pathname) os.rmdir(tmpdir)
def test_fork_exec_killchild(self): '''This test will create a fork/exec event observer script and then kill the child listener and verify that it is handled correctly. ''' AssimEvent.enable_all_observers() tmpdir = tempfile.mkdtemp('.d', 'testexec_') (fd, pathname) = tempfile.mkstemp('.out.txt') execscript = os.path.join(tmpdir, 'observer.sh') makescript(execscript, pathname) AssimEvent.observers = [] observer = ForkExecObserver(scriptdir=tmpdir) dummyclient = ClientClass() dummyclient.fred = 'fred' dummyclient.sevenofnine = 'Annika' dummyclient.foo = {'foo': 'bar'} AssimEvent.registerobserver(observer) try: os.kill(observer.childpid, signal.SIGKILL) except OSError: # "docker build" doesn't let us kill processes... # so we give up on this test and call it good... os.unlink(execscript) os.unlink(pathname) os.rmdir(tmpdir) return time.sleep(0.1) AssimEvent(dummyclient, AssimEvent.CREATEOBJ) # Death of our FIFO child will cause it to get respawned, and # message sent to new child. No messages should be lost. expectedcontent=\ '''====START==== ARG1=create ARG2=ClientClass ASSIM_fred=fred ASSIM_nodetype=ClientClass ASSIM_sevenofnine=Annika ==== JSON START ==== {"associatedobject":{"foo":{"foo":"bar"},"fred":"fred","nodetype":"ClientClass","sevenofnine":"Annika"},"eventtype":0,"extrainfo":null} ==== JSON END ==== ====END==== ''' TestAssimEvent.waitfor(pathname, expectedcontent) f = open(pathname, 'r') content = f.read() f.close() self.assertEqual(content, expectedcontent) os.close(fd) os.unlink(execscript) os.unlink(pathname) os.rmdir(tmpdir)
def test_simple_init_good(self): 'Perform a few simple AssimEvent good initializations' AssimEvent.observers = [] observer=DummyObserver() AssimEvent.registerobserver(observer) event1 = AssimEvent('first', AssimEvent.CREATEOBJ) self.assertEqual(len(observer.events), 1) self.assertTrue(observer.events[0], event1) self.assertEqual(AssimEvent.unregisterobserver(observer), True) event2 = AssimEvent('second', AssimEvent.CREATEOBJ) self.assertEqual(len(observer.events), 1) self.assertTrue(observer.events[0], event1) AssimEvent.registerobserver(observer) event3 = AssimEvent('third', AssimEvent.CREATEOBJ) self.assertEqual(len(observer.events), 2) self.assertTrue(observer.events[0], event3)
def test_simple_init_good(self): 'Perform a few simple AssimEvent good initializations' AssimEvent.enable_all_observers() AssimEvent.observers = [] observer=DummyObserver() AssimEvent.registerobserver(observer) event1 = AssimEvent('first', AssimEvent.CREATEOBJ) self.assertEqual(len(observer.events), 1) self.assertTrue(observer.events[0], event1) self.assertEqual(AssimEvent.unregisterobserver(observer), True) event2 = AssimEvent('second', AssimEvent.CREATEOBJ) self.assertEqual(len(observer.events), 1) self.assertTrue(observer.events[0], event1) AssimEvent.registerobserver(observer) event3 = AssimEvent('third', AssimEvent.CREATEOBJ) self.assertEqual(len(observer.events), 2) self.assertTrue(observer.events[0], event3)
def __init__(self, constraints): '''Initializer for AssimEventObserver class. Parameters: ----------- constraints: dict A dict describing our desired events. The constraints in the dict are effectively ANDed together. Each key is an attribute name in either the event itself or its associated object. The value associated with each attribute is either a list or a scalar value. A list implies that any one of those values is acceptable. A scalar value implies that it *must* have that value. This should be able to constrain the type of event we're looking at, the type of event-object we're looking at, and the domain of the event-object - and lots of other potentially useful things. See the "is_interesting" method below for implementation details... ''' self.constraints = constraints AssimEvent.registerobserver(self)
def __init__(self, constraints): '''Initializer for AssimEventObserver class. Parameters: ----------- constraints: dict A dict describing our desired events. The constraints in the dict are effectively ANDed together. Each key is an attribute name in either the event itself or its associated object. The value associated with each attribute is either a list or a scalar value. A list implies that any one of those values is acceptable. A scalar value implies that it *must* have that value. This should be able to constrain the type of event we're looking at, the type of event-object we're looking at, and the domain of the event-object - and lots of other potentially useful things. See the "is_interesting" method below for implementation details... ''' self.constraints = constraints AssimEvent.registerobserver(self)