def testPeriodPollerOnRealProcess(self): config = getConfig("/tmp") config.component_("AlertProcessor") config.AlertProcessor.section_("critical") config.AlertProcessor.section_("soft") config.AlertProcessor.critical.level = 5 config.AlertProcessor.soft.level = 0 config.component_("AlertGenerator") config.AlertGenerator.section_("bogusPoller") config.AlertGenerator.bogusPoller.soft = 5 # [percent] # the way the worker is implemented should take 100% CPU, but it sometimes # take a while, test safer threshold here, testing thresholds # more rigorously happens in Pollers_t config.AlertGenerator.bogusPoller.critical = 50 # [percent] config.AlertGenerator.bogusPoller.pollInterval = 0.2 # [second] # period during which measurements are collected before evaluating for possible alert triggering config.AlertGenerator.bogusPoller.period = 1 generator = utils.AlertGeneratorMock(config) poller = PeriodPoller(config.AlertGenerator.bogusPoller, generator) poller.sender = utils.SenderMock() # get CPU usage percentage, it's like measuring CPU usage of a real # component, so use the appropriate poller's method for that # (PeriodPoller itself is higher-level class so it doesn't define # a method to provide sampling data) poller.sample = lambda processDetail: ComponentsCPUPoller.sample(processDetail) p = utils.getProcess() self.testProcesses.append(p) while not p.is_alive(): time.sleep(0.2) name = "mytestprocess-testPeriodPollerBasic" pd = ProcessDetail(p.pid, name) # need to repeat sampling required number of measurements numOfMeasurements = int(config.AlertGenerator.bogusPoller.period / config.AlertGenerator.bogusPoller.pollInterval) mes = Measurements(numOfMeasurements) self.assertEqual(len(mes), 0) for i in range(mes._numOfMeasurements): poller.check(pd, mes) # 1 alert should have arrived, test it # though there may be a second alert as well if the test managed to # run second round - don't test number of received alerts # also the Level and threshold is not deterministic: given it's # measured on a live process it can't be determined up-front how # much CPU this simple process will be given: don't test Level # and threshold a = poller.sender.queue[0] self.assertEqual(a["Component"], generator.__class__.__name__) self.assertEqual(a["Source"], poller.__class__.__name__) d = a["Details"] self.assertEqual(d["numMeasurements"], mes._numOfMeasurements) self.assertEqual(d["component"], name) self.assertEqual(d["period"], config.AlertGenerator.bogusPoller.period) # since the whole measurement cycle was done, values should have been nulled self.assertEqual(len(mes), 0)
def testProcessMemoryPollerBasic(self): p = utils.getProcess() self.testProcesses.append(p) name = "mytestprocess" pd = ProcessDetail(p.pid, name) poller = ProcessMemoryPoller() v = poller.sample(pd) self.assertTrue(isinstance(v, types.FloatType)) # psutil.error.AccessDenied will result into -1 returned self.assertTrue(v > 0)
def testComponentsPollerBasic(self): """ Test ComponentsPoller class. Beware of different process context in real running. """ config = getConfig("/tmp") config.component_("AlertProcessor") config.AlertProcessor.section_("critical") config.AlertProcessor.section_("soft") config.AlertProcessor.critical.level = 5 config.AlertProcessor.soft.level = 0 config.component_("AlertGenerator") config.AlertGenerator.section_("bogusPoller") config.AlertGenerator.bogusPoller.soft = 5 # [percent] config.AlertGenerator.bogusPoller.critical = 90 # [percent] config.AlertGenerator.bogusPoller.pollInterval = 2 # [second] # period during which measurements are collected before evaluating for possible alert triggering config.AlertGenerator.bogusPoller.period = 10 # need to create some temp directory, real process and it's # Daemon.xml so that is looks like agents component process # and check back the information p = utils.getProcess() self.testProcesses.append(p) while not p.is_alive(): time.sleep(0.2) config.component_("TestComponent") d = os.path.dirname(self.testComponentDaemonXml) config.TestComponent.componentDir = d if not os.path.exists(d): os.mkdir(d) f = open(self.testComponentDaemonXml, 'w') f.write(utils.daemonXmlContent % dict(PID_TO_PUT = p.pid)) f.close() generator = utils.AlertGeneratorMock(config) poller = ComponentsPoller(config.AlertGenerator.bogusPoller, generator) # only 1 component should have valid workDir with proper Daemon.xml content # other components present in the configuration (AlertProcessor, AlertGenerator) # should have been ignored self.assertEqual(len(poller._components), 1) pd = poller._components[0] self.assertEqual(pd.pid, p.pid) self.assertEqual(pd.name, "TestComponent") self.assertEqual(len(pd.children), 0) self.assertEqual(len(poller._compMeasurements), 1) mes = poller._compMeasurements[0] numMeasurements = round(config.AlertGenerator.bogusPoller.period / config.AlertGenerator.bogusPoller.pollInterval, 0) self.assertEqual(mes._numOfMeasurements, numMeasurements) shutil.rmtree(d)
def testAllFinalClassPollerImplementations(self): """ Any new end (final) implementation of new poller(s) should be add here to test its basic flow chain. """ config = getConfig("/tmp") # create some non-sence config section. just need a bunch of values defined config.AlertGenerator.section_("bogusPoller") config.AlertGenerator.bogusPoller.soft = 5 # [percent] config.AlertGenerator.bogusPoller.critical = 50 # [percent] config.AlertGenerator.bogusPoller.pollInterval = 0.2 # [second] config.AlertGenerator.bogusPoller.period = 0.5 # currently only CouchErrorsPoller uses this config value config.AlertGenerator.bogusPoller.observables = 4000 # need to create some temp directory, real process and it's # Daemon.xml so that is looks like agents component process # and check back the information p = utils.getProcess() self.testProcesses.append(p) while not p.is_alive(): time.sleep(0.2) config.component_("TestComponent") d = os.path.dirname(self.testComponentDaemonXml) config.TestComponent.componentDir = d if not os.path.exists(d): os.mkdir(d) f = open(self.testComponentDaemonXml, 'w') f.write(utils.daemonXmlContent % dict(PID_TO_PUT = p.pid)) f.close() generator = utils.AlertGeneratorMock(config) pollers = [] for pollerClass in finalPollerClasses: p = pollerClass(config.AlertGenerator.bogusPoller, generator) # poller may send something during below check(), satisfy sender method p.sender = lambda alert: 1 + 1 pollers.append(p) for poller in pollers: poller.check() if hasattr(poller, "_measurements"): mes = poller._measurements self.assertEqual(len(mes), 1) self.assertTrue(isinstance(mes[0], types.FloatType)) if hasattr(poller, "_compMeasurements"): for measurements in poller._compMeasurements: self.assertEqual(len(measurements), 1) self.assertTrue(isinstance(measurements[0], types.FloatType)) shutil.rmtree(d)
def testProcessDetailBasic(self): p = utils.getProcess() self.testProcesses.append(p) name = "mytestprocess" pd = ProcessDetail(p.pid, name) self.assertEqual(pd.pid, p.pid) self.assertEqual(pd.name, name) self.assertEqual(pd.proc.pid, p.pid) self.assertEqual(len(pd.children), 0) self.assertEqual(len(pd.allProcs), 1) utils.terminateProcesses(self.testProcesses) d = pd.getDetails() self.assertEqual(d["pid"], p.pid) self.assertEqual(d["component"], name) self.assertEqual(d["numChildrenProcesses"], 0)
def testProcessDetailChildren(self): numSubProcesses = 3 p = utils.getProcess(numChildren = numSubProcesses) self.testProcesses.append(p) # wait until all desired processes are running while len(psutil.Process(p.pid).get_children()) < numSubProcesses: print "waiting for children processes to start" time.sleep(0.5) name = "mytestprocess2" pd = ProcessDetail(p.pid, name) self.assertEqual(pd.proc.pid, p.pid) self.assertEqual(len(pd.children), numSubProcesses) self.assertEqual(len(pd.allProcs), numSubProcesses + 1) utils.terminateProcesses(self.testProcesses) d = pd.getDetails() self.assertEqual(d["pid"], p.pid) self.assertEqual(d["numChildrenProcesses"], numSubProcesses)