def testMySQLCPUPollerBasic(self): config = getConfig("/tmp") generator = utils.AlertGeneratorMock(config) try: poller = MySQLCPUPoller(config.AlertGenerator.mysqlCPUPoller, generator) except Exception, ex: self.fail("%s: exception: %s" % (self.testName, ex))
def setUp(self): self.testInit = TestInit(__file__) self.testInit.setLogging(logLevel=logging.DEBUG) self.testDir = self.testInit.generateWorkDir() self.config = getConfig(self.testDir) # mock generator instance to communicate some configuration values self.generator = utils.AlertGeneratorMock(self.config)
def testComponentsCPUPollerPossiblyOnLiveAgent(self): """ If there is currently running agent upon WMAGENT_CONFIG configuration, then the test will pick up live processes and poll them. """ # check if the live agent configuration was loaded (above this class) if globals().has_key("config"): self.config = config # AlertProcessor values - values for Level soft, resp. critical # are also needed by this AlertGenerator test self.config.component_("AlertProcessor") self.config.AlertProcessor.componentDir = "/tmp" self.config.AlertProcessor.section_("critical") self.config.AlertProcessor.section_("soft") self.config.AlertProcessor.critical.level = 5 self.config.AlertProcessor.soft.level = 0 self.config.component_("AlertGenerator") self.config.AlertGenerator.componentDir = "/tmp" self.config.section_("Alert") self.config.Alert.address = "tcp://127.0.0.1:6557" self.config.Alert.controlAddr = "tcp://127.0.0.1:6559" self.config.AlertGenerator.section_("componentsCPUPoller") else: self.config = getConfig("/tmp") self.config.AlertGenerator.componentsCPUPoller.soft = 70 self.config.AlertGenerator.componentsCPUPoller.critical = 80 self.config.AlertGenerator.componentsCPUPoller.pollInterval = 0.2 self.config.AlertGenerator.componentsCPUPoller.period = 0.3 # generator has already been instantiated, but need another one # with just defined configuration # mock generator instance to communicate some configuration values self.generator = utils.AlertGeneratorMock(self.config) handler, receiver = utils.setUpReceiver(self.generator.config.Alert.address, self.generator.config.Alert.controlAddr) numMeasurements = self.config.AlertGenerator.componentsCPUPoller.period / self.config.AlertGenerator.componentsCPUPoller.pollInterval poller = ComponentsCPUPoller(self.config.AlertGenerator.componentsCPUPoller, self.generator) # inject own input sample data provider thresholdToTest = self.config.AlertGenerator.componentsCPUPoller.soft # there is in fact input argument in this case which needs be ignored poller.sample = lambda proc_: random.randint(thresholdToTest - 10, thresholdToTest) poller.start() self.assertTrue(poller.is_alive()) # no alert shall arrive time.sleep(5 * self.config.AlertGenerator.componentsCPUPoller.period) poller.terminate() receiver.shutdown() self.assertFalse(poller.is_alive())
def testMySQLPollerBasic(self): config = getConfig("/tmp") generator = utils.AlertGeneratorMock(config) # take for instance mysqlCPUPoller configuration here, just need # appropriate attributes set try: poller = MySQLPoller(config.AlertGenerator.mysqlCPUPoller, generator) except Exception, ex: self.fail("%s: exception: %s" % (self.testName, ex))
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") # only couch-related pollers require couchURL, this way it'll be used at the # other ones as well, should do no harm ; it's just because all pollers are # probed here in a single test ... config.AlertGenerator.bogusPoller.couchURL = os.getenv("COUCHURL", None) 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, give its own PID pid = os.getpid() 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 = 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 testDirectorySizePollerUnitTest(self): config = getConfig("/tmp") generator = utils.AlertGeneratorMock(config) poller = DirectorySizePoller(config.AlertGenerator.mysqlDbSizePoller, generator, unitSelection=1) # kilobytes poller.sender = lambda alert: 1 + 1 self.assertEqual(poller._currSizeUnit, "kB") self.assertEqual(poller._prefixBytesFactor, 1024) # this actually tests the real sample method poller._dbDirectory = "/dev" poller.check() # calls sample() automatically
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 pid = os.getpid() 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=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, 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 testMySQLCPUPollerBasic(self): config = getConfig("/tmp") generator = utils.AlertGeneratorMock(config) try: poller = MySQLCPUPoller(config.AlertGenerator.mysqlCPUPoller, generator) except Exception as ex: self.fail("%s: exception: %s" % (self.testName, ex)) self.assertEqual(len(poller._measurements), 0) poller.check() # assuming MySQL server is running, check that 1 sensible measurement value was collected self.assertEqual(len(poller._measurements), 1) self.assertTrue(isinstance(poller._measurements[0], types.FloatType))
def testPeriodPollerCalculationPredefinedInput(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") # put some threshold numbers, just need to check output calculation # from check() method config.AlertGenerator.bogusPoller.soft = 5 # [percent] config.AlertGenerator.bogusPoller.critical = 50 # [percent] config.AlertGenerator.bogusPoller.pollInterval = 0.2 # [second] config.AlertGenerator.bogusPoller.period = 1 generator = utils.AlertGeneratorMock(config) poller = PeriodPoller(config.AlertGenerator.bogusPoller, generator) # since poller may trigger an alert, give it mock sender poller.sender = utils.SenderMock() # provide sample method with predefined input, float predefInput = 10.12 poller.sample = lambda processDetail: predefInput processDetail = None numOfMeasurements = int(config.AlertGenerator.bogusPoller.period / config.AlertGenerator.bogusPoller.pollInterval) mes = Measurements(numOfMeasurements) for i in range(mes._numOfMeasurements): poller.check(processDetail, mes) # the above loop should went 5 times, should reach evaluation of 5 x predefInput # values, the average should end up 10, which should trigger soft threshold self.assertEqual(len(poller.sender.queue), 1) 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["threshold"], "%s%%" % config.AlertGenerator.bogusPoller.soft) self.assertEqual(d["numMeasurements"], mes._numOfMeasurements) self.assertEqual(d["period"], config.AlertGenerator.bogusPoller.period) self.assertEqual(d["average"], "%s%%" % predefInput) # since the whole measurement cycle was done, values should have been nulled self.assertEqual(len(mes), 0)
def testMySQLDbSizePollerBasic(self): config = getConfig("/tmp") generator = utils.AlertGeneratorMock(config) try: poller = MySQLDbSizePoller(config.AlertGenerator.mysqlCPUPoller, generator) except Exception as ex: self.fail("%s: exception: %s" % (self.testName, ex)) poller.check() # test failing during set up poller = MySQLDbSizePoller(config.AlertGenerator.mysqlCPUPoller, generator) poller._query = "nonsense query" # this will fail on the above query self.assertRaises(Exception, poller._getDbDir) poller.check()
def testBasePollerHandleFailedPolling(self): 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 = 2 # [second] config.AlertGenerator.bogusPoller.period = 10 generator = utils.AlertGeneratorMock(config) poller = BasePoller(config.AlertGenerator.bogusPoller, generator) ex = Exception("test exception") class Sender(object): def __call__(self, alert): self.alert = alert poller.sender = Sender() poller._handleFailedPolling(ex) self.assertEqual(poller.sender.alert["Source"], "BasePoller")
def testBasePollerBasic(self): 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 = 2 # [second] config.AlertGenerator.bogusPoller.period = 10 generator = utils.AlertGeneratorMock(config) poller = BasePoller(config.AlertGenerator.bogusPoller, generator) # define dummy check method poller.check = lambda: 1 + 1 poller.start() # poller now runs time.sleep(config.AlertGenerator.bogusPoller.pollInterval * 2) poller.terminate() while poller.is_alive(): time.sleep(0.2) print "%s waiting for test poller to terminate" % inspect.stack( )[0][3]
def testMySQLPollerBasic(self): config = getConfig("/tmp") generator = utils.AlertGeneratorMock(config) # take for instance mysqlCPUPoller configuration here, just need # appropriate attributes set try: poller = MySQLPoller(config.AlertGenerator.mysqlCPUPoller, generator) except Exception as ex: self.fail("%s: exception: %s" % (self.testName, ex)) # this class would not have defined polling sample function, give it one poller.sample = lambda proc: float(12) self.assertEqual(len(poller._measurements), 0) poller.check() self.assertEqual(len(poller._measurements), 1) self.assertEqual(poller._measurements[0], 12) # test handling of a non-existing process MySQLPoller._getProcessPID = lambda inst: 1212121212 self.assertRaises(Exception, MySQLPoller, config.AlertGenerator.mysqlCPUPoller, generator)
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] 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) # get own pid pid = os.getpid() name = inspect.stack()[0][3] # test name pd = ProcessDetail(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) # since the whole measurement cycle was done, values should have been nulled self.assertEqual(len(mes), 0)