def testReceiverBuferring(self): """ Test sending alerts that are buffered into a queue. """ numAlertMsgs = 7 q = Queue() # start a process that generates 5 alerts, worker can run # as a different process, though is not necessary here self.p = Process(target = worker, args = (self.addr, self.ctrl, q, numAlertMsgs)) self.p.start() # alerts received will be added to the queue handler = lambda x: q.put(x) rec = Receiver(self.addr, handler, self.ctrl) rec.startReceiver() # non blocking call # wait here until the Receiver is not shut while rec.isReady(): time.sleep(0.2) # worker will send shutdown message and execution will resume here # check the content of the queue - 5 alert messages alertCount = 0 while not q.empty(): alert = q.get() self.failUnless(alert.has_key("Type")) self.assertEqual(alert["Type"], "Alert") alertCount += 1 self.assertEqual(alertCount, numAlertMsgs)
def testProcessorWithReceiverAndCouchSink(self): # set up couch first self.testInit = TestInitCouchApp(__file__) self.testInit.setLogging() dbName = "couch_sink" self.testInit.setupCouch(dbName) # add corresponding part of the configuration for CouchSink(s) config = self.config.AlertProcessor config.critical.sinks.section_("couch") config.critical.sinks.couch.url = self.testInit.couchUrl config.critical.sinks.couch.database = self.testInit.couchDbName # just send the Alert into couch processor = Processor(config) rec = Receiver(self.addr, processor, self.ctrl) rec.startReceiver() # non blocking call # run worker(), this time directly without Process as above, # worker will send 10 Alerts to Receiver worker(self.addr, self.ctrl, 10) # wait until the Receiver is shut by worker while rec.isReady(): time.sleep(0.3) print "%s waiting for Receiver to shut ..." % inspect.stack()[0][3]
def testReceiverBuferring(self): """ Test sending alerts that are buffered into a queue. """ # alerts received will be added to the queue alertList = [] handler = lambda x: alertList.append(x) rec = Receiver(self.addr, handler, self.ctrl) rec.startReceiver() # non blocking call numAlertMsgs = 7 thread = AlertsSender(self.addr, self.ctrl, numAlertMsgs) # thread will send numAlertMsgs and eventually shut the receiver # down by a shutdown control message thread.start() # wait here until the Receiver is not shut while rec.isReady(): time.sleep(0.2) # worker will send shutdown message and execution will resume here # check the content of the queue - 5 alert messages self.assertEqual(len(alertList), numAlertMsgs) for alert in alertList: self.failUnless(alert.has_key("Type")) self.assertEqual(alert["Type"], "Alert")
def testReceiverBuferring(self): """ Test sending alerts that are buffered into a queue. """ # alerts received will be added to the queue alertList = [] handler = lambda x: alertList.append(x) rec = Receiver(self.addr, handler, self.ctrl) rec.startReceiver() # non blocking call numAlertMsgs = 7 thread = AlertsSender(self.addr, self.ctrl, numAlertMsgs) # thread will send numAlertMsgs and eventually shut the receiver # down by a shutdown control message thread.start() # wait here until the Receiver is not shut while rec.isReady(): time.sleep(0.2) # worker will send shutdown message and execution will resume here # check the content of the queue - 5 alert messages self.assertEqual(len(alertList), numAlertMsgs) for alert in alertList: self.failUnless("Type" in alert) self.assertEqual(alert["Type"], "Alert")
def testProcessorWithReceiver(self): """ Test startup and shutdown of processor in receiver. """ processor = Processor(self.config.AlertProcessor) rec = Receiver(self.addr, processor, self.ctrl) rec.startReceiver() # since the above is non-blocking, could send the messages from here # directly, yet running via Process doesn't harm sender = Process(target=simpleWorker, args=(self.addr, self.ctrl)) sender.start() # wait until the Receiver is shut by simpleWorker while rec.isReady(): time.sleep(0.1)
def testReceiverShutdownByMessage(self): # start a Receiver rec = Receiver(self.addr, self.printer, self.ctrl) rec.startReceiver() # non blocking call workChann, contChann = self._getSenderChannels() # send some messages to the receiver and shut it eventually contChann.send_json(RegisterMsg("Receiver_t")) workChann.send_json(Alert(Type="Alert", Level=10)) contChann.send_json(UnregisterMsg("Receiver_t")) # terminate the Receiver contChann.send_json(ShutdownMsg()) # wait until the Receiver is properly shut # this will not be necessary when shutting down by a call while rec.isReady(): time.sleep(0.1)
def testReceiverShutdownByMessage(self): # start a Receiver rec = Receiver(self.addr, self.printer, self.ctrl) rec.startReceiver() # non blocking call workChann, contChann = self._getSenderChannels() # send some messages to the receiver and shut it eventually contChann.send_json(RegisterMsg("Receiver_t")) workChann.send_json(Alert(Type = "Alert", Level = 10)) contChann.send_json(UnregisterMsg("Receiver_t")) # terminate the Receiver contChann.send_json(ShutdownMsg()) # wait until the Receiver is properly shut # this will not be necessary when shutting down by a call while rec.isReady(): time.sleep(0.1)
def testProcessorWithReceiver(self): """ Test startup and shutdown of processor in receiver. """ processor = Processor(self.config.AlertProcessor) rec = Receiver(self.addr, processor, self.ctrl) rec.startReceiver() # non-blocking call # now sender tests control messages (register, unregister, shutdown) s = Sender(self.addr, self.ctrl, "Processor_t") s.register() s.unregister() s.sendShutdown() # wait until the Receiver is shut by sending the above control messages while rec.isReady(): time.sleep(0.3) print "%s waiting for Receiver to shut ..." % inspect.stack()[0][3]
def testProcessorWithReceiverAndFileSink(self): # add corresponding part of the configuration for FileSink(s) config = self.config.AlertProcessor config.critical.sinks.section_("file") config.critical.sinks.file.outputfile = self.criticalOutputFile config.soft.sinks.section_("file") config.soft.sinks.file.outputfile = self.softOutputFile processor = Processor(config) rec = Receiver(self.addr, processor, self.ctrl) rec.startReceiver() # non blocking call # run worker(), this time directly without Process as above, # worker will send 10 Alerts to Receiver worker(self.addr, self.ctrl, 10) # wait until the Receiver is shut by worker while rec.isReady(): time.sleep(0.3) print "%s waiting for Receiver to shut ..." % inspect.stack()[0][3] # now check the FileSink output files for content: # the soft Alerts has threshold level set to 0 so Alerts # with level 1 and higher, resp. for critical the level # was above set to 5 so 6 and higher out of worker's 0 .. 9 # (10 Alerts altogether) shall be present softSink = FileSink(config.soft.sinks.file) criticalSink = FileSink(config.critical.sinks.file) softList = softSink.load() criticalList = criticalSink.load() # check soft level alerts # levels 1 .. 4 went in (level 0 is, according to the config not considered) self.assertEqual(len(softList), 3) for a, level in zip(softList, range(1, 4)): self.assertEqual(a["Level"], level) # check 'critical' levels # only levels 5 .. 9 went in self.assertEqual(len(criticalList), 5) for a, level in zip(criticalList, range(5, 10)): self.assertEqual(a["Level"], level)
def testForwardSinkEntireChain(self): """ The test chain looks as follows: worker -> Receiver1(+its Processor configured to do ForwardSink) -> Receiver2 whose address as the destination the ForwardSink is configured with -> Receiver2 will do FileSink so that it's possible to verify the chain. """ # configuration for the Receiver+Processor+ForwardSink 1 (group) config1 = Configuration() config1.component_("AlertProcessor") config1.AlertProcessor.section_("critical") config1.AlertProcessor.section_("soft") config1.AlertProcessor.critical.level = 5 config1.AlertProcessor.soft.level = 0 config1.AlertProcessor.soft.bufferSize = 0 config1.AlertProcessor.critical.section_("sinks") config1.AlertProcessor.soft.section_("sinks") config1.AlertProcessor.critical.sinks.section_("forward") config1.AlertProcessor.soft.sinks.section_("forward") # address of the Receiver2 config1.AlertProcessor.critical.sinks.forward.address = self.address2 config1.AlertProcessor.critical.sinks.forward.controlAddr = self.controlAddr2 config1.AlertProcessor.critical.sinks.forward.label = "ForwardSinkTest" config1.AlertProcessor.soft.sinks.forward.address = self.address2 config1.AlertProcessor.soft.sinks.forward.controlAddr = self.controlAddr2 config1.AlertProcessor.soft.sinks.forward.label = "ForwardSinkTest" # 1) first item of the chain is source of Alerts: worker() # 2) second item is Receiver1 + its Processor + its ForwardSink processor1 = Processor(config1.AlertProcessor) # ForwardSink will be created automatically by the Processor receiver1 = Receiver(self.address1, processor1, self.controlAddr1) receiver1.startReceiver() # non blocking call # 3) third group is Receiver2 with its Processor and final FileSink config2 = Configuration() config2.component_("AlertProcessor") config2.AlertProcessor.section_("critical") config2.AlertProcessor.section_("soft") config2.AlertProcessor.critical.level = 5 config2.AlertProcessor.soft.level = 0 config2.AlertProcessor.soft.bufferSize = 0 config2.AlertProcessor.critical.section_("sinks") config2.AlertProcessor.soft.section_("sinks") config2.AlertProcessor.critical.sinks.section_("file") config2.AlertProcessor.soft.sinks.section_("file") # configuration of the final sink config2.AlertProcessor.critical.sinks.file.outputfile = self.outputfileCritical config2.AlertProcessor.soft.sinks.file.outputfile = self.outputfileSoft processor2 = Processor(config2.AlertProcessor) # final FileSink will be automatically created by the Processor receiver2 = Receiver(self.address2, processor2, self.controlAddr2) receiver2.startReceiver() # non blocking call # now send the Alert messages via worker() and eventually shut the receiver1 worker(self.address1, self.controlAddr1, 10) # wait until receiver1 shuts while receiver1.isReady(): time.sleep(0.4) print "%s waiting for Receiver1 to shut ..." % inspect.stack()[0][3] # shut down receiver2 - need to sendShutdown() to it s = Sender(self.address2, self.controlAddr2, "some_id") s.sendShutdown() # wait until receiver2 shuts while receiver2.isReady(): time.sleep(0.4) print "%s waiting for Receiver2 to shut ..." % inspect.stack()[0][3] # check the result in the files # the bufferSize for soft-level Alerts was set to 0 so all # Alerts should be present also in the soft-level type file # initial 10 Alerts (Level 0 .. 9) gets distributed though a cascade # of two Receivers. soft alerts with level 0 .. 4 are considered # so Receiver1 forwards through its ForwardSink 0 .. 4 Alerts as soft and # 5 .. 9 level Alerts through 'critical'. order is not guaranteed # critical Alerts fileConfig = ConfigSection("file") fileConfig.outputfile = self.outputfileCritical sink = FileSink(fileConfig) expectedLevels = range(5, 10) # that is 5 .. 9 loadAlerts = sink.load() self.assertEqual(len(loadAlerts), len(expectedLevels)) d = dict(very = "interesting") for a in loadAlerts: self.assertEqual(a["Details"], d) # soft Alerts fileConfig = ConfigSection("file") fileConfig.outputfile = self.outputfileSoft sink = FileSink(fileConfig) expectedLevels = range(0, 5) # that is 0 .. 4 loadAlerts = sink.load() self.assertEqual(len(loadAlerts), len(expectedLevels)) for a in loadAlerts: self.assertEqual(a["Details"], d)
class ProcessorTest(unittest.TestCase): """ TestCase for Processor. """ def setUp(self): """ Set up for tests. """ l = logging.getLogger() l.setLevel(logging.DEBUG) self.addr = "tcp://127.0.0.1:5557" self.ctrl = "tcp://127.0.0.1:5559" self.softOutputFile = "/tmp/ProcessorTestSoftAlerts.json" self.criticalOutputFile = "/tmp/ProcessorTestCriticalAlerts.json" self.config = Configuration() self.config.component_("AlertProcessor") self.config.AlertProcessor.section_("critical") self.config.AlertProcessor.section_("soft") self.config.AlertProcessor.critical.level = 5 self.config.AlertProcessor.soft.level = 1 self.config.AlertProcessor.soft.bufferSize = 3 self.config.AlertProcessor.critical.section_("sinks") self.config.AlertProcessor.soft.section_("sinks") def tearDown(self): for f in (self.criticalOutputFile, self.softOutputFile): if os.path.exists(f): os.remove(f) if hasattr(self, "testInit"): self.testInit.tearDownCouch() if hasattr(self, "receiver"): # wait until the Receiver is shut by the Shutdown control # message which the worker() function should have sent while self.receiver.isReady(): logging.info("tearDown: Waiting for Receiver shutdown ...") time.sleep(ReceiverLogic.TIMEOUT_AFTER_SHUTDOWN * 1.1) if self.receiver.isReady(): self.receiver.shutdown() logging.info("tearDown: Is the Receiver shut down: %s" % (not self.receiver.isReady())) def testProcessorBasic(self): str(self.config.AlertProcessor) p = Processor(self.config.AlertProcessor) def testProcessorWithReceiver(self): """ Test startup and shutdown of processor in receiver. """ processor = Processor(self.config.AlertProcessor) # Receiver is waited for shutdown / shutdown explicitly in tearDown() self.receiver = Receiver(self.addr, processor, self.ctrl) self.receiver.startReceiver() # non-blocking call # now sender tests control messages (register, unregister, shutdown) s = Sender(self.addr, self.ctrl, "Processor_t") s.register() s.unregister() s.sendShutdown() # give some time so that the previous call shuts down the receiver time.sleep(ReceiverLogic.TIMEOUT_AFTER_SHUTDOWN * 1.1) def testProcessorWithReceiverAndFileSink(self): # add corresponding part of the configuration for FileSink(s) config = self.config.AlertProcessor config.critical.sinks.section_("file") config.critical.sinks.file.outputfile = self.criticalOutputFile config.soft.sinks.section_("file") config.soft.sinks.file.outputfile = self.softOutputFile processor = Processor(config) # Receiver is waited for shutdown / shutdown explicitly in tearDown() self.receiver = Receiver(self.addr, processor, self.ctrl) self.receiver.startReceiver() # non blocking call # run worker(), this time directly without Process as above, # worker will send 10 Alerts to Receiver worker(self.addr, self.ctrl, 10) # wait until Receiver is shut down (by a message from worker(), then all # alerts shall be delivered and could proceed to check if successfully delivered while self.receiver.isReady(): time.sleep(ReceiverLogic.TIMEOUT_AFTER_SHUTDOWN * 1.5) logging.info("%s: Waiting for Receiver shutdown ..." % inspect.stack()[0][3]) # check the FileSink output files for content: # the soft Alerts has threshold level set to 0 so Alerts # with level 1 and higher, resp. for critical the level # was above set to 5 so 6 and higher out of worker's 0 .. 9 # (10 Alerts altogether) shall be present softSink = FileSink(config.soft.sinks.file) criticalSink = FileSink(config.critical.sinks.file) softList = softSink.load() criticalList = criticalSink.load() # check soft level alerts # levels 1 .. 4 went in (level 0 is, according to the config not considered) self.assertEqual(len(softList), 3) for a, level in zip(softList, range(1, 4)): self.assertEqual(a["Level"], level) # check 'critical' levels # only levels 5 .. 9 went in self.assertEqual(len(criticalList), 5) for a, level in zip(criticalList, range(5, 10)): self.assertEqual(a["Level"], level) def testProcessorWithReceiverAndCouchSink(self): # set up couch first self.testInit = TestInitCouchApp(__file__) self.testInit.setLogging() dbName = "couch_sink" self.testInit.setupCouch(dbName) # add corresponding part of the configuration for CouchSink(s) config = self.config.AlertProcessor config.critical.sinks.section_("couch") config.critical.sinks.couch.url = self.testInit.couchUrl config.critical.sinks.couch.database = self.testInit.couchDbName # just send the Alert into couch processor = Processor(config) # Receiver is waited for shutdown / shutdown explicitly in tearDown() self.receiver = Receiver(self.addr, processor, self.ctrl) self.receiver.startReceiver() # non blocking call # run worker(), this time directly without Process as above, # worker will send 10 Alerts to Receiver worker(self.addr, self.ctrl, 10) # wait until Receiver is shut down (by a message from worker() # also need to wait, otherwise tearDown kicks off and scrapes the # couch so half of the alerts will be undelivered while self.receiver.isReady(): time.sleep(ReceiverLogic.TIMEOUT_AFTER_SHUTDOWN * 1.5) logging.info("%s: Waiting for Receiver shutdown ..." % inspect.stack()[0][3])
def testForwardSinkEntireChain(self): """ The test chain looks as follows: worker -> Receiver1(+its Processor configured to do ForwardSink) -> Receiver2 whose address as the destination the ForwardSink is configured with -> Receiver2 will do FileSink so that it's possible to verify the chain. """ # configuration for the Receiver+Processor+ForwardSink 1 (group) config1 = Configuration() config1.component_("AlertProcessor") config1.AlertProcessor.section_("critical") config1.AlertProcessor.section_("soft") config1.AlertProcessor.critical.level = 5 config1.AlertProcessor.soft.level = 0 config1.AlertProcessor.soft.bufferSize = 0 config1.AlertProcessor.critical.section_("sinks") config1.AlertProcessor.soft.section_("sinks") config1.AlertProcessor.critical.sinks.section_("forward") config1.AlertProcessor.soft.sinks.section_("forward") # address of the Receiver2 config1.AlertProcessor.critical.sinks.forward.address = self.address2 config1.AlertProcessor.critical.sinks.forward.controlAddr = self.controlAddr2 config1.AlertProcessor.critical.sinks.forward.label = "ForwardSinkTest" config1.AlertProcessor.soft.sinks.forward.address = self.address2 config1.AlertProcessor.soft.sinks.forward.controlAddr = self.controlAddr2 config1.AlertProcessor.soft.sinks.forward.label = "ForwardSinkTest" # 1) first item of the chain is source of Alerts: worker() # 2) second item is Receiver1 + its Processor + its ForwardSink processor1 = Processor(config1.AlertProcessor) # ForwardSink will be created automatically by the Processor receiver1 = Receiver(self.address1, processor1, self.controlAddr1) receiver1.startReceiver() # non blocking call # 3) third group is Receiver2 with its Processor and final FileSink config2 = Configuration() config2.component_("AlertProcessor") config2.AlertProcessor.section_("critical") config2.AlertProcessor.section_("soft") config2.AlertProcessor.critical.level = 5 config2.AlertProcessor.soft.level = 0 config2.AlertProcessor.soft.bufferSize = 0 config2.AlertProcessor.critical.section_("sinks") config2.AlertProcessor.soft.section_("sinks") config2.AlertProcessor.critical.sinks.section_("file") config2.AlertProcessor.soft.sinks.section_("file") # configuration of the final sink config2.AlertProcessor.critical.sinks.file.outputfile = self.outputfileCritical config2.AlertProcessor.soft.sinks.file.outputfile = self.outputfileSoft processor2 = Processor(config2.AlertProcessor) # final FileSink will be automatically created by the Processor receiver2 = Receiver(self.address2, processor2, self.controlAddr2) receiver2.startReceiver() # non blocking call # now send the Alert messages via worker() and eventually shut the receiver1 worker(self.address1, self.controlAddr1, 10) # wait until receiver1 shuts while receiver1.isReady(): time.sleep(0.4) print "%s waiting for Receiver1 to shut ..." % inspect.stack( )[0][3] # shut down receiver2 - need to sendShutdown() to it s = Sender(self.address2, self.controlAddr2, "some_id") s.sendShutdown() # wait until receiver2 shuts while receiver2.isReady(): time.sleep(0.4) print "%s waiting for Receiver2 to shut ..." % inspect.stack( )[0][3] # check the result in the files # the bufferSize for soft-level Alerts was set to 0 so all # Alerts should be present also in the soft-level type file # initial 10 Alerts (Level 0 .. 9) gets distributed though a cascade # of two Receivers. soft alerts with level 0 .. 4 are considered # so Receiver1 forwards through its ForwardSink 0 .. 4 Alerts as soft and # 5 .. 9 level Alerts through 'critical'. order is not guaranteed # critical Alerts fileConfig = ConfigSection("file") fileConfig.outputfile = self.outputfileCritical sink = FileSink(fileConfig) expectedLevels = range(5, 10) # that is 5 .. 9 loadAlerts = sink.load() self.assertEqual(len(loadAlerts), len(expectedLevels)) d = dict(very="interesting") for a in loadAlerts: self.assertEqual(a["Details"], d) # soft Alerts fileConfig = ConfigSection("file") fileConfig.outputfile = self.outputfileSoft sink = FileSink(fileConfig) expectedLevels = range(0, 5) # that is 0 .. 4 loadAlerts = sink.load() self.assertEqual(len(loadAlerts), len(expectedLevels)) for a in loadAlerts: self.assertEqual(a["Details"], d)