def setUp(self, signal): self.tmpdir = tempfile.mkdtemp(prefix="test-connector-metro-") client = ClientStub("testhostname", None, None) rrd_base_dir = os.path.join(self.tmpdir, "rrds") os.mkdir(rrd_base_dir) confdb = MetroConfDB(os.path.join(os.path.dirname(__file__), "connector-metro.db")) self.rrdtool_pool = RRDToolPoolManagerStub(rrd_base_dir, "flat", "/usr/bin/rrdtool") rrdtool = RRDToolManager(self.rrdtool_pool, confdb) threshold_checker = ThresholdChecker(rrdtool, confdb) self.btr = BusToRRDtool(confdb, rrdtool, threshold_checker) self.btr.setClient(client) d = self.btr.startService() d.addCallback(lambda _x: confdb.reload()) return d
def makeService(options): """ the service that wraps everything the connector needs. """ from vigilo.connector.options import getSettings, parseSubscriptions settings = getSettings(options, __name__) from vigilo.common.logging import get_logger LOGGER = get_logger(__name__) from vigilo.common.gettext import translate _ = translate(__name__) from vigilo.connector.client import client_factory from vigilo.connector.handlers import buspublisher_factory from vigilo.connector_metro.rrdtool import RRDToolPoolManager from vigilo.connector_metro.rrdtool import RRDToolManager from vigilo.connector_metro.confdb import MetroConfDB from vigilo.connector_metro.threshold import ThresholdChecker from vigilo.connector_metro.bustorrdtool import BusToRRDtool root_service = service.MultiService() # Client du bus client = client_factory(settings) client.setServiceParent(root_service) providers = [] # Configuration try: conffile = settings["connector-metro"]["config"] except KeyError: LOGGER.error( _("Please set the path to the configuration " "database generated by VigiConf in the settings.ini.") ) sys.exit(1) confdb = MetroConfDB(conffile) confdb.setServiceParent(root_service) try: must_check_th = settings["connector-metro"].as_bool("check_thresholds") except KeyError: must_check_th = True # Gestion RRDTool rrd_base_dir = settings["connector-metro"]["rrd_base_dir"] rrd_path_mode = settings["connector-metro"]["rrd_path_mode"] rrd_bin = settings["connector-metro"].get("rrd_bin", "/usr/bin/rrdtool") rrdcached = settings["connector-metro"].get("rrdcached", None) try: pool_size = settings["connector-metro"].as_int("rrd_processes") except KeyError: pool_size = None rrdtool_pool = RRDToolPoolManager( rrd_base_dir, rrd_path_mode, rrd_bin, check_thresholds=must_check_th, rrdcached=rrdcached, pool_size=pool_size ) rrdtool = RRDToolManager(rrdtool_pool, confdb) # Gestion des seuils if must_check_th: threshold_checker = ThresholdChecker(rrdtool, confdb) bus_publisher = buspublisher_factory(settings, client) bus_publisher.registerProducer(threshold_checker, streaming=True) providers.append(bus_publisher) else: threshold_checker = None # Gestionnaire principal des messages bustorrdtool = BusToRRDtool(confdb, rrdtool, threshold_checker) bustorrdtool.setClient(client) subs = parseSubscriptions(settings) queue = settings["bus"]["queue"] queue_messages_ttl = int(settings["bus"].get("queue_messages_ttl", 0)) bustorrdtool.subscribe(queue, queue_messages_ttl, subs) providers.append(bustorrdtool) # Statistiques from vigilo.connector.status import statuspublisher_factory status_publisher = statuspublisher_factory(settings, client, providers=providers) return root_service
def setUp(self): self.btr = BusToRRDtool(Mock(), Mock(), Mock()) self.btr.rrdtool.start.return_value = defer.succeed(None) self.btr.rrdtool.stop.return_value = defer.succeed(None) return self.btr.startService()
class FunctionalTestCase(unittest.TestCase): """ Vérification que le passage d'un message produit bien un fichier RRD. (création du fichier) """ @deferred(timeout=30) @patch('signal.signal') # erreurs de threads def setUp(self, signal): self.tmpdir = tempfile.mkdtemp(prefix="test-connector-metro-") client = ClientStub("testhostname", None, None) rrd_base_dir = os.path.join(self.tmpdir, "rrds") os.mkdir(rrd_base_dir) confdb = MetroConfDB(os.path.join(os.path.dirname(__file__), "connector-metro.db")) self.rrdtool_pool = RRDToolPoolManagerStub(rrd_base_dir, "flat", "/usr/bin/rrdtool") rrdtool = RRDToolManager(self.rrdtool_pool, confdb) threshold_checker = ThresholdChecker(rrdtool, confdb) self.btr = BusToRRDtool(confdb, rrdtool, threshold_checker) self.btr.setClient(client) d = self.btr.startService() d.addCallback(lambda _x: confdb.reload()) return d @deferred(timeout=30) def tearDown(self): d = self.btr.stopService() d.addCallback(lambda _x: rmtree(self.tmpdir)) return d @deferred(timeout=30) def test_handled_host(self): """Functionnal: messages sur des hôtes déclarés.""" rrdfile = os.path.join(self.tmpdir, "rrds", "server1.example.com", "Load.rrd") # on vérifie que le fichier n'existe pas encore # (ce qui lève une exception quand on teste le fichier). self.assertRaises(OSError, os.stat, rrdfile) msg = { "type": "perf", "timestamp": "1165939739", "host": "server1.example.com", "datasource": "Load", "value": "12", } d = self.btr.processMessage(msg) # on vérifie que le fichier correspondant a bien été créé def check_created(r): self.assertTrue(os.path.exists(rrdfile), "Le fichier n'a pas été créé") self.assertTrue(stat.S_ISREG(os.stat(rrdfile).st_mode)) def check_creation_command(r): self.assertTrue(len(self.rrdtool_pool.commands) > 0) self.assertEqual(self.rrdtool_pool.commands[0], ('create', rrdfile, ['--step', '300', '--start', '1165939729', 'RRA:AVERAGE:0.5:1:600', 'RRA:AVERAGE:0.5:6:700', 'RRA:AVERAGE:0.5:24:775', 'RRA:AVERAGE:0.5:288:732', 'DS:DS:GAUGE:600:U:U'])) def check_update_command(r): self.assertEqual(self.rrdtool_pool.commands[1], ('update', rrdfile, '1165939739:12')) d.addCallback(check_created) d.addCallback(check_creation_command) d.addCallback(check_update_command) return d
class BusToRRDtoolTestCase(unittest.TestCase): """ Vérification que le passage d'un message produit bien un fichier RRD. (création du fichier) """ @deferred(timeout=30) def setUp(self): self.btr = BusToRRDtool(Mock(), Mock(), Mock()) self.btr.rrdtool.start.return_value = defer.succeed(None) self.btr.rrdtool.stop.return_value = defer.succeed(None) return self.btr.startService() @deferred(timeout=30) def tearDown(self): return self.btr.stopService() @deferred(timeout=30) def test_handled_host(self): """Prise en compte de messages sur des hôtes déclarés.""" msg = { "type": "perf", "timestamp": "1165939739", "host": "server1.example.com", "datasource": "Load", "value": "12", "has_thresholds": True, } self.btr.confdb.has_host.return_value = defer.succeed(True) self.btr.threshold_checker.hasThreshold.return_value = msg self.btr.rrdtool.createIfNeeded.return_value = msg self.btr.rrdtool.processMessage.return_value = msg d = self.btr.processMessage(msg) def check(r): self.assertTrue(self.btr.rrdtool.createIfNeeded.called) self.assertTrue(self.btr.rrdtool.processMessage.called) self.assertTrue(self.btr.threshold_checker.hasThreshold.called) self.assertTrue(self.btr.threshold_checker.checkMessage.called) d.addCallback(check) return d @deferred(timeout=30) def test_non_existing_host(self): """Reception d'un message pour un hôte absent du fichier de conf""" msg = { "type": "perf", "timestamp": "123456789", "host": "dummy_host", "datasource": "dummy_datasource", "value": "42", } self.btr.confdb.has_host.return_value = defer.succeed(False) d = self.btr._parse_message(msg) def check_failure(f): self.assertFalse(self.btr.rrdtool.createIfNeeded.called) self.assertFalse(self.btr.rrdtool.processMessage.called) if not isinstance(f.value, NotInConfiguration): self.fail("Raised exeception is not of the right type (got %s)" % type(f.value)) d.addCallbacks(lambda x: self.fail("No exception raised"), check_failure) return d @deferred(timeout=30) def test_wrong_message_type_1(self): """Réception d'un autre message que perf (_parse_message)""" msg = { "type": "event", "timestamp": "1165939739", "host": "host", "service": "service", "status": "CRITICAL", "message": "message", } d = self.btr._parse_message(msg) def cb(r): self.fail("Il y aurait dû y avoir un errback") def eb(f): self.assertEqual(f.type, WrongMessageType) d.addCallbacks(cb, eb) return d @deferred(timeout=30) def test_wrong_message_type_2(self): """Réception d'un autre message que perf (processMessage)""" msg = { "type": "event", "timestamp": "1165939739", "host": "host", "service": "service", "status": "CRITICAL", "message": "message", } self.btr.confdb.has_host.return_value = defer.succeed(True) d = self.btr.processMessage(msg) def cb(r): self.assertFalse(self.btr.rrdtool.createIfNeeded.called) self.assertFalse(self.btr.rrdtool.run.called) self.assertEqual(self.btr._messages_received, -1) d.addCallback(cb) return d @deferred(timeout=30) def test_invalid_message_1(self): """Réception d'un message invalide (_parse_message)""" msg = { "type": "perf", "timestamp": "1165939739", "host": "server1.example.com", # pas de clé datasource "value": "12", } d = self.btr._parse_message(msg) def cb(r): self.fail("Il y aurait dû y avoir un errback") def eb(f): self.assertEqual(f.type, InvalidMessage) d.addCallbacks(cb, eb) return d @deferred(timeout=30) def test_invalid_message_2(self): """Réception d'un message invalide (processMessage)""" msg = { "type": "perf", "timestamp": "1165939739", "host": "server1.example.com", # pas de clé datasource "value": "12", } d = self.btr.processMessage(msg) def cb(r): self.assertFalse(self.btr.rrdtool.createIfNeeded.called) self.assertFalse(self.btr.rrdtool.run.called) d.addCallback(cb) return d @deferred(timeout=30) def test_valid_values(self): """Réception d'un message avec une valeur valide""" self.btr.confdb.has_host.return_value = defer.succeed(True) msg_tpl = {"type": "perf", "timestamp": "1165939739", "host": "server1.example.com", "datasource": "Load"} valid_values = ["1", "1.2", "U"] dl = [] for value in valid_values: msg = msg_tpl.copy() msg["value"] = value d = self.btr._parse_message(msg) dl.append(d) return defer.DeferredList(dl, fireOnOneErrback=True) @deferred(timeout=30) def test_invalid_value_1(self): """Réception d'un message avec une valeur invalide (#802)""" msg = { "type": "perf", "timestamp": "1165939739", "host": "server1.example.com", "datasource": "Load", "value": "Invalid value", } d = self.btr._parse_message(msg) def cb(r): self.fail("Il y aurait du y avoir un errback") def eb(f): self.assertEqual(f.type, InvalidMessage) d.addCallbacks(cb, eb) return d @deferred(timeout=30) def test_stats(self): """Statistiques""" self.btr.confdb.count_datasources.return_value = defer.succeed(4) d = self.btr.getStats() def cb(r): self.assertEqual(r, {"received": 0, "pds_count": 4, "illegal_updates": 0}) d.addCallback(cb) return d @deferred(timeout=30) def test_no_check_thresholds(self): """Désactivation de la vérification des seuils""" msg = {"type": "perf", "timestamp": "1165939739", "host": "Host éçà", "datasource": "PDS éçà", "value": "42"} self.btr.threshold_checker = None d = defer.maybeDeferred(self.btr._check_has_thresholds, msg) def check(new_msg): self.assertTrue("has_thresholds" in new_msg) self.assertFalse(new_msg["has_thresholds"]) d.addCallback(check) return d