def testMeasurementsBasic(self): numMes = 10 mes = Measurements(numMes) self.assertEqual(mes._numOfMeasurements, numMes) self.assertEqual(len(mes), 0) mes.append(20) self.assertEqual(len(mes), 1) self.assertEqual(mes[0], 20) mes.append(30) self.assertEqual(mes[1], 30) mes.clear() self.assertEqual(len(mes), 0) self.assertEqual(mes._numOfMeasurements, numMes)
def _setUp(self): """ Query the database to find out the main process PID, create ProcessDetail and Measurements instances. """ pid = self._getProcessPID() self._dbProcessDetail = ProcessDetail(pid, "MySQL") numOfMeasurements = round( self.config.period / self.config.pollInterval, 0) self._measurements = Measurements(numOfMeasurements)
def _setUpProcessDetailAndMeasurements(self, compPID, compName): """ Based on input, create instances of ProcessDetail and Measurements. """ myName = self.__class__.__name__ try: pd = ProcessDetail(compPID, compName) self._components.append(pd) self._compMeasurements.append(Measurements(self.numOfMeasurements)) m = ("%s: loaded process information on %s:%s" % (myName, compName, compPID)) logging.info(m) except (psutil.error.NoSuchProcess, psutil.error.AccessDenied), ex: logging.error("%s: component %s ignored, reason: %s" % (myName, compName, ex))
def testMeasurementsBasic(self): numMes = 10 mes = Measurements(numMes) self.assertEqual(mes._numOfMeasurements, numMes) self.assertEqual(len(mes), 0) mes.append(20) self.assertEqual(len(mes), 1) self.assertEqual(mes[0], 20) mes.append(30) self.assertEqual(mes[1], 30) mes.clear() self.assertEqual(len(mes), 0) self.assertEqual(mes._numOfMeasurements, numMes)
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 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)
def __init__(self, config, generator): PeriodPoller.__init__(self, config, generator) numOfMeasurements = round(self.config.period / self.config.pollInterval, 0) self._measurements = Measurements(numOfMeasurements)
handler, receiver = setUpReceiver( ti.testCase.generator.config.Alert.address, ti.testCase.generator.config.Alert.controlAddr) pid = os.getpid() numMeasurements = ti.config.period / ti.config.pollInterval # inject own input sample data provider # there is in fact input argument in this case which needs be ignored poller.sample = lambda proc_: random.randint( ti.thresholdToTest, ti.thresholdToTest + ti.thresholdDiff) # the process to run upon is fooled as well here poller._dbProcessDetail = ProcessDetail(pid, "TestProcess") poller._measurements = Measurements(numMeasurements) poller.start() ti.testCase.assertTrue(poller.is_alive()) if ti.expected != 0: # beware - if the alert is not correctly generated, the test # will hang here and will be waiting for it # #2238 AlertGenerator test can take 1 hour+ (and fail) # fail 2mins anyway if alert is not received timeLimitExceeded = False startTime = datetime.datetime.now() limitTime = 2 * 60 # seconds while len(handler.queue) == 0: time.sleep(ti.config.pollInterval / 5) if (datetime.datetime.now() - startTime).seconds > limitTime: timeLimitExceeded = True
def doGenericPeriodAndProcessPolling(ti): """ ti - Test Input instance (all variables on input to this test) The function is easier to reuse from here that from other test class. This helper function is also used for generic period polling. """ try: poller = ti.pollerClass(ti.config, ti.testCase.generator) except Exception as ex: ti.testCase.fail("%s: exception: %s" % (ti.testCase.testName, ex)) handler, receiver = setUpReceiver( ti.testCase.generator.config.Alert.address, ti.testCase.generator.config.Alert.controlAddr) pid = os.getpid() numMeasurements = ti.config.period / ti.config.pollInterval # inject own input sample data provider # there is in fact input argument in this case which needs be ignored poller.sample = lambda proc_: random.randint( ti.thresholdToTest, ti.thresholdToTest + ti.thresholdDiff) # the process to run upon is fooled as well here poller._dbProcessDetail = ProcessDetail(pid, "TestProcess") poller._measurements = Measurements(numMeasurements) poller.start() ti.testCase.assertTrue(poller.is_alive()) if ti.expected != 0: # beware - if the alert is not correctly generated, the test # will hang here and will be waiting for it # #2238 AlertGenerator test can take 1 hour+ (and fail) # fail 2mins anyway if alert is not received timeLimitExceeded = False startTime = datetime.datetime.now() limitTime = 2 * 60 # seconds while len(handler.queue) == 0: time.sleep(ti.config.pollInterval / 5) if (datetime.datetime.now() - startTime).seconds > limitTime: timeLimitExceeded = True break else: time.sleep(ti.config.period * 2) poller.terminate() receiver.shutdown() ti.testCase.assertFalse(poller.is_alive()) if ti.expected != 0: # #2238 AlertGenerator test can take 1 hour+ (and fail) # temporary measure from above loop: if timeLimitExceeded: ti.testCase.fail("No alert received in %s seconds." % limitTime) # there should be just one alert received, poller should have the # change to send a second ti.testCase.assertEqual(len(handler.queue), ti.expected) a = handler.queue[0] # soft threshold - alert should have soft level ti.testCase.assertEqual(a["Level"], ti.level) ti.testCase.assertEqual(a["Component"], ti.testCase.generator.__class__.__name__) ti.testCase.assertEqual(a["Source"], poller.__class__.__name__) else: ti.testCase.assertEqual(len(handler.queue), 0)