예제 #1
0
파일: test_gauge.py 프로젝트: nfz1/faucet
    def test_poller(self):
        """Test the update method to see if it pushes port stats"""

        prom_client = gauge_prom.GaugePrometheusClient()
        datapath = create_mock_datapath(2)

        conf = mock.Mock(dp=datapath,
                         type='',
                         interval=1,
                         prometheus_port=9303,
                         prometheus_addr='localhost')

        prom_poller = gauge_prom.GaugePortStatsPrometheusPoller(
            conf, '__name__', prom_client)
        msg = port_stats_msg(datapath)
        prom_poller.update(time.time(), datapath.dp_id, msg)

        prom_lines = self.get_prometheus_stats(conf.prometheus_addr,
                                               conf.prometheus_port)
        prom_lines = self.parse_prom_output(prom_lines)

        for port_num, port in datapath.ports.items():
            port_stats = msg.body[int(port_num) - 1]
            stats = prom_lines[(datapath.dp_id, port.name)]
            stats_found = set()

            for stat_name, stat_val in stats:
                self.assertAlmostEqual(stat_val,
                                       getattr(port_stats, stat_name))
                stats_found.add(stat_name)

            self.assertEqual(stats_found, set(gauge_prom.PROM_PORT_VARS))
예제 #2
0
    def test_poller(self):
        """Test the update method to see if it pushes port stats"""

        prom_client = gauge_prom.GaugePrometheusClient()
        datapath = create_mock_datapath(2)

        conf = mock.Mock(dp=datapath,
                         type='',
                         interval=1,
                         prometheus_port=9303,
                         prometheus_addr='localhost')

        prom_poller = gauge_prom.GaugePortStatsPrometheusPoller(
            conf, '__name__', prom_client)
        port1 = parser.OFPPortStats(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 100,
                                    50)
        port2 = parser.OFPPortStats(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 100,
                                    50)
        message = parser.OFPPortStatsReply(datapath, body=[port1, port2])
        dp_id = 1
        prom_poller.update(time.time(), dp_id, message)

        prom_lines = self.get_prometheus_stats(conf.prometheus_addr,
                                               conf.prometheus_port)
        prom_lines = self.parse_prom_output(prom_lines)

        for port_num, port in datapath.ports.items():
            stats = prom_lines[(dp_id, port.name)]
            stats_found = set()

            for stat_name, stat_val in stats:
                self.assertAlmostEqual(stat_val, port_num)
                stats_found.add(stat_name)

            self.assertEqual(stats_found, set(gauge_prom.PROM_PORT_VARS))
예제 #3
0
class GaugePrometheusTests(unittest.TestCase):  # pytype: disable=module-attr
    """Tests the GaugePortStatsPrometheusPoller update method"""

    prom_client = gauge_prom.GaugePrometheusClient(reg=CollectorRegistry())

    @staticmethod
    def parse_prom_output(output):
        """Parses the port stats from prometheus into a dictionary"""

        parsed_output = {}
        for line in output.split('\n'):
            # discard comments and stats not related to port stats
            if line.startswith('#') or not line.startswith(
                    gauge_prom.PROM_PORT_PREFIX):
                continue

            index = line.find('{')
            # get the stat name e.g. of_port_rx_bytes and strip 'of_port_'
            prefix = gauge_prom.PROM_PORT_PREFIX + gauge_prom.PROM_PREFIX_DELIM
            stat_name = line[0:index].replace(prefix, '')
            # get the labels within {}
            labels = line[index + 1:line.find('}')].split(',')

            for label in labels:
                lab_name, lab_val = label.split('=', 1)
                lab_val = lab_val.replace('"', '')
                if lab_name == 'dp_id':
                    dp_id = int(lab_val, 16)
                elif lab_name == 'port':
                    port_name = lab_val

            key = (dp_id, port_name)
            stat_val = line.split(' ')[-1]
            if key not in parsed_output:
                parsed_output[key] = []

            parsed_output[key].append((stat_name, float(stat_val)))

        return parsed_output

    @staticmethod
    def get_prometheus_stats(addr, port):
        """Attempts to contact the prometheus server
        at the address to grab port stats."""

        url = 'http://{}:{}'.format(addr, port)
        session = requests.Session()
        adapter = requests.adapters.HTTPAdapter(max_retries=10)
        session.mount('http://', adapter)
        return session.get(url).text

    def test_poller(self):
        """Test the update method to see if it pushes port stats"""

        datapath = create_mock_datapath(2)

        conf = mock.Mock(dp=datapath,
                         type='',
                         interval=1,
                         prometheus_port=9303,
                         prometheus_addr='localhost',
                         use_test_thread=True)

        prom_poller = gauge_prom.GaugePortStatsPrometheusPoller(
            conf, '__name__', self.prom_client)
        prom_poller._running = True
        msg = port_stats_msg(datapath)
        prom_poller.update(time.time(), msg)

        prom_lines = self.get_prometheus_stats(conf.prometheus_addr,
                                               conf.prometheus_port)
        prom_lines = self.parse_prom_output(prom_lines)

        for port_num, port in datapath.ports.items():
            port_stats = msg.body[int(port_num) - 1]
            stats = prom_lines[(datapath.dp_id, port.name)]
            stats_found = set()

            for stat_name, stat_val in stats:
                self.assertAlmostEqual(stat_val,
                                       getattr(port_stats, stat_name))
                stats_found.add(stat_name)

            self.assertEqual(stats_found, set(gauge_prom.PROM_PORT_VARS))

    def test_port_state(self):
        """Test the update method to see if it pushes port state"""

        datapath = create_mock_datapath(2)

        conf = mock.Mock(dp=datapath,
                         type='',
                         interval=1,
                         prometheus_port=9303,
                         prometheus_addr='localhost',
                         use_test_thread=True)

        prom_poller = gauge_prom.GaugePortStatePrometheusPoller(
            conf, '__name__', self.prom_client)
        prom_poller._running = True
        reasons = [
            ofproto.OFPPR_ADD, ofproto.OFPPR_DELETE, ofproto.OFPPR_MODIFY
        ]
        for i in range(1, len(conf.dp.ports) + 1):

            msg = port_state_msg(conf.dp, i, reasons[i - 1])
            port_name = conf.dp.ports[i].name
            rcv_time = int(time.time())
            prom_poller.update(rcv_time, msg)

            prom_lines = self.get_prometheus_stats(conf.prometheus_addr,
                                                   conf.prometheus_port)
            prom_lines = self.parse_prom_output(prom_lines)

            stats = prom_lines[(datapath.dp_id, port_name)]
            stats_found = set()

            for stat_name, stat_val in stats:
                msg_data = msg if stat_name == 'reason' else msg.desc
                self.assertAlmostEqual(stat_val, getattr(msg_data, stat_name))
                stats_found.add(stat_name)

            self.assertEqual(stats_found, set(gauge_prom.PROM_PORT_STATE_VARS))

    def test_flow_stats(self):
        """Check the update method of the GaugeFlowTablePrometheusPoller class"""

        datapath = create_mock_datapath(2)

        conf = mock.Mock(dp=datapath,
                         type='',
                         interval=1,
                         prometheus_port=9303,
                         prometheus_addr='localhost',
                         use_test_thread=True)

        prom_poller = gauge_prom.GaugeFlowTablePrometheusPoller(
            conf, '__name__', self.prom_client)
        rcv_time = int(time.time())
        instructions = [parser.OFPInstructionGotoTable(1)]
        msg = flow_stats_msg(conf.dp, instructions)
        prom_poller.update(rcv_time, msg)