예제 #1
0
    def test_ListenerStatistics_iadd(self):
        # test incrementing add function

        bytes_in1 = random.randrange(1000000000)
        bytes_out1 = random.randrange(1000000000)
        active_conns1 = random.randrange(1000000000)
        total_conns1 = random.randrange(1000000000)
        request_errors1 = random.randrange(1000000000)
        stats_1 = data_models.ListenerStatistics(
            listener_id=self.LISTENER_ID,
            amphora_id=self.AMP_ID,
            bytes_in=bytes_in1,
            bytes_out=bytes_out1,
            active_connections=active_conns1,
            total_connections=total_conns1,
            request_errors=request_errors1)

        bytes_in2 = random.randrange(1000000000)
        bytes_out2 = random.randrange(1000000000)
        active_conns2 = random.randrange(1000000000)
        total_conns2 = random.randrange(1000000000)
        request_errors2 = random.randrange(1000000000)
        stats_2 = data_models.ListenerStatistics(
            listener_id="listener 2",
            amphora_id="amphora 2",
            bytes_in=bytes_in2,
            bytes_out=bytes_out2,
            active_connections=active_conns2,
            total_connections=total_conns2,
            request_errors=request_errors2)

        # test successful +=
        stats_1 += stats_2

        # not a delta, so it won't be incremented
        self.assertEqual(stats_1.active_connections, active_conns1)
        self.assertEqual(stats_1.listener_id, self.LISTENER_ID)
        self.assertEqual(stats_1.amphora_id, self.AMP_ID)

        # deltas will be incremented
        self.assertEqual(stats_1.bytes_in, bytes_in1 + bytes_in2)
        self.assertEqual(stats_1.bytes_out, bytes_out1 + bytes_out2)
        self.assertEqual(stats_1.total_connections,
                         total_conns1 + total_conns2)
        self.assertEqual(stats_1.request_errors,
                         request_errors1 + request_errors2)

        # test incrementing an incompatible object
        self.assertRaises(TypeError, stats_1.__iadd__, "boom")
예제 #2
0
    def setUp(self):
        super(TestStatsMixin, self).setUp()
        self.sm = stats.StatsMixin()

        self.session = mock.MagicMock()
        self.listener_id = uuidutils.generate_uuid()
        self.amphora_id = uuidutils.generate_uuid()

        self.repo_listener_stats = mock.MagicMock()
        self.sm.listener_stats_repo = self.repo_listener_stats

        self.fake_stats = data_models.ListenerStatistics(
            listener_id=self.listener_id,
            amphora_id=self.amphora_id,
            bytes_in=random.randrange(1000000000),
            bytes_out=random.randrange(1000000000),
            active_connections=random.randrange(1000000000),
            total_connections=random.randrange(1000000000),
            request_errors=random.randrange(1000000000))

        self.sm.listener_stats_repo.get_all.return_value = ([self.fake_stats],
                                                            None)

        self.repo_amphora = mock.MagicMock()
        self.sm.repo_amphora = self.repo_amphora
예제 #3
0
    def setUp(self):
        super(TestStatsBase, self).setUp()

        self.conf = oslo_fixture.Config(cfg.CONF)
        self.conf.config(group="controller_worker",
                         statistics_drivers=STATS_DRIVERS)
        self.amphora_id = uuidutils.generate_uuid()
        self.listener_id = uuidutils.generate_uuid()
        self.listener_stats = data_models.ListenerStatistics(
            amphora_id=self.amphora_id,
            listener_id=self.listener_id,
            bytes_in=random.randrange(1000000000),
            bytes_out=random.randrange(1000000000),
            active_connections=random.randrange(1000000000),
            total_connections=random.randrange(1000000000),
            request_errors=random.randrange(1000000000))
        self.listener_stats_dict = {
            self.listener_id: {
                "request_errors": self.listener_stats.request_errors,
                "active_connections": self.listener_stats.active_connections,
                "total_connections": self.listener_stats.total_connections,
                "bytes_in": self.listener_stats.bytes_in,
                "bytes_out": self.listener_stats.bytes_out,
            }
        }
예제 #4
0
    def test_update_stats(self, mock_get_session, mock_listener_stats_repo):
        bytes_in1 = random.randrange(1000000000)
        bytes_out1 = random.randrange(1000000000)
        active_conns1 = random.randrange(1000000000)
        total_conns1 = random.randrange(1000000000)
        request_errors1 = random.randrange(1000000000)
        stats_1 = data_models.ListenerStatistics(
            listener_id=self.listener_id,
            amphora_id=self.amphora_id,
            bytes_in=bytes_in1,
            bytes_out=bytes_out1,
            active_connections=active_conns1,
            total_connections=total_conns1,
            request_errors=request_errors1
        )
        bytes_in2 = random.randrange(1000000000)
        bytes_out2 = random.randrange(1000000000)
        active_conns2 = random.randrange(1000000000)
        total_conns2 = random.randrange(1000000000)
        request_errors2 = random.randrange(1000000000)
        stats_2 = data_models.ListenerStatistics(
            listener_id=self.listener_id,
            amphora_id=self.amphora_id,
            bytes_in=bytes_in2,
            bytes_out=bytes_out2,
            active_connections=active_conns2,
            total_connections=total_conns2,
            request_errors=request_errors2
        )

        update_db.StatsUpdateDb().update_stats(
            [stats_1, stats_2], deltas=False)

        mock_listener_stats_repo().replace.assert_has_calls([
            mock.call(mock_get_session(), stats_1),
            mock.call(mock_get_session(), stats_2)
        ])

        update_db.StatsUpdateDb().update_stats(
            [stats_1, stats_2], deltas=True)

        mock_listener_stats_repo().increment.assert_has_calls([
            mock.call(mock_get_session(), stats_1),
            mock.call(mock_get_session(), stats_2)
        ])
예제 #5
0
 def test_update_listeners_stats_with_statistics(self, mock_stats_base):
     LISTENER_STATS = o_data_models.ListenerStatistics(
         listener_id=uuidutils.generate_uuid())
     mock_get_listener = task.UpdateListenersStats()
     mock_get_listener.listener_repo = mock.MagicMock()
     mock_get_listener.listener_repo.get_all.return_value = [LISTENER], None
     mock_get_listener.listener_stats_repo = mock.MagicMock()
     mock_get_listener.listener_stats_repo.get_all.return_value = [
         LISTENER_STATS
     ], None
     mock_get_listener.execute([LISTENER_STATS])
     mock_stats_base.assert_called_once_with([LISTENER_STATS])
예제 #6
0
    def update_listener_statistics(self, statistics):
        """Update listener statistics.

        :param statistics: Statistics for listeners:
              id (string): ID for listener.
              active_connections (int): Number of currently active connections.
              bytes_in (int): Total bytes received.
              bytes_out (int): Total bytes sent.
              request_errors (int): Total requests not fulfilled.
              total_connections (int): The total connections handled.
        :type statistics: dict
        :raises: UpdateStatisticsError
        :returns: None
        """
        listener_stats = statistics.get(lib_consts.LISTENERS, [])
        stats_objects = []
        for stat in listener_stats:
            try:
                stats_obj = data_models.ListenerStatistics(
                    listener_id=stat['id'],
                    bytes_in=stat['bytes_in'],
                    bytes_out=stat['bytes_out'],
                    active_connections=stat['active_connections'],
                    total_connections=stat['total_connections'],
                    request_errors=stat['request_errors'],
                    received_time=time.time())
                stats_objects.append(stats_obj)
            except Exception as e:
                return {
                    lib_consts.STATUS_CODE: lib_consts.DRVR_STATUS_CODE_FAILED,
                    lib_consts.FAULT_STRING: str(e),
                    lib_consts.STATS_OBJECT: lib_consts.LISTENERS
                }

        # Provider drivers other than the amphora driver do not have
        # an amphora ID, use the listener ID again here to meet the
        # constraint requirement.
        try:
            if stats_objects:
                stats_base.update_stats_via_driver(stats_objects)
        except Exception as e:
            return {
                lib_consts.STATUS_CODE: lib_consts.DRVR_STATUS_CODE_FAILED,
                lib_consts.FAULT_STRING: str(e),
                lib_consts.STATS_OBJECT: lib_consts.LISTENERS
            }
        return {lib_consts.STATUS_CODE: lib_consts.DRVR_STATUS_CODE_OK}
예제 #7
0
    def setUp(self):
        super(TestUpdateStatsDb, self).setUp()

        conf = self.useFixture(oslo_fixture.Config(cfg.CONF))
        conf.config(group="health_manager",
                    event_streamer_driver='queue_event_streamer')

        self.sm = update_db.UpdateStatsDb()
        self.event_client = mock.MagicMock()
        self.sm.event_streamer.client = self.event_client

        self.listener_stats_repo = mock.MagicMock()
        self.sm.listener_stats_repo = self.listener_stats_repo

        self.loadbalancer_id = uuidutils.generate_uuid()
        self.listener_id = uuidutils.generate_uuid()

        self.listener_stats = data_models.ListenerStatistics(
            listener_id=self.listener_id,
            bytes_in=random.randrange(1000000000),
            bytes_out=random.randrange(1000000000),
            active_connections=random.randrange(1000000000),
            total_connections=random.randrange(1000000000),
            request_errors=random.randrange(1000000000))

        self.sm.get_listener_stats = mock.MagicMock()
        self.sm.get_listener_stats.return_value = self.listener_stats

        self.loadbalancer_id = uuidutils.generate_uuid()
        self.amphora_id = uuidutils.generate_uuid()
        self.listener_id = uuidutils.generate_uuid()

        self.listener = db_models.Listener(
            load_balancer_id=self.loadbalancer_id)

        self.listener_repo = mock.MagicMock()
        self.sm.repo_listener = self.listener_repo
        self.sm.repo_listener.get.return_value = self.listener

        self.loadbalancer_repo = mock.MagicMock()
        self.sm.repo_loadbalancer = self.loadbalancer_repo

        self.loadbalancer = db_models.LoadBalancer(
            id=self.loadbalancer_id,
            listeners=[self.listener])
        self.loadbalancer_repo.get.return_value = self.loadbalancer
예제 #8
0
파일: stats.py 프로젝트: xinhuoxing/octavia
    def get_listener_stats(self, session, listener_id):
        """Gets the listener statistics data_models object."""
        db_ls, _ = self.listener_stats_repo.get_all(session,
                                                    listener_id=listener_id)
        if not db_ls:
            LOG.warning("Listener Statistics for Listener %s was not found",
                        listener_id)

        statistics = data_models.ListenerStatistics(listener_id=listener_id)

        for db_l in db_ls:
            statistics += db_l

            amp = self.repo_amphora.get(session, id=db_l.amphora_id)
            if amp and amp.status == constants.AMPHORA_ALLOCATED:
                statistics.active_connections += db_l.active_connections
        return statistics
예제 #9
0
    def setUp(self):
        super(TestUpdateStatsDb, self).setUp()
        self.sm = update_db.UpdateStatsDb()
        self.event_client = mock.MagicMock()
        self.sm.event_streamer.client = self.event_client

        self.listener_stats_repo = mock.MagicMock()
        self.sm.listener_stats_repo = self.listener_stats_repo

        self.loadbalancer_id = uuidutils.generate_uuid()
        self.listener_id = uuidutils.generate_uuid()

        self.listener_stats = data_models.ListenerStatistics(
            listener_id=self.listener_id,
            bytes_in=random.randrange(1000000000),
            bytes_out=random.randrange(1000000000),
            active_connections=random.randrange(1000000000),
            total_connections=random.randrange(1000000000),
            request_errors=random.randrange(1000000000))

        self.sm.get_listener_stats = mock.MagicMock()
        self.sm.get_listener_stats.return_value = self.listener_stats

        self.loadbalancer_id = uuidutils.generate_uuid()
        self.amphora_id = uuidutils.generate_uuid()
        self.listener_id = uuidutils.generate_uuid()

        self.listener = db_models.Listener(
            load_balancer_id=self.loadbalancer_id)

        self.listener_repo = mock.MagicMock()
        self.sm.repo_listener = self.listener_repo
        self.sm.repo_listener.get.return_value = self.listener

        self.loadbalancer_repo = mock.MagicMock()
        self.sm.repo_loadbalancer = self.loadbalancer_repo

        self.loadbalancer = db_models.LoadBalancer(id=self.loadbalancer_id,
                                                   listeners=[self.listener])
        self.loadbalancer_repo.get.return_value = self.loadbalancer
예제 #10
0
    def get_listener_stats(self, session, listener_id):
        """Gets the listener statistics data_models object."""
        db_ls, _ = self.listener_stats_repo.get_all(session,
                                                    listener_id=listener_id)
        if not db_ls:
            LOG.warning("Listener Statistics for Listener %s was not found",
                        listener_id)

        statistics = data_models.ListenerStatistics(listener_id=listener_id)

        for db_l in db_ls:
            statistics += db_l

            amp = self.repo_amphora.get(session, id=db_l.amphora_id)
            # Amphora ID and Listener ID will be the same in the case that the
            # stats are coming from a provider driver other than the `amphora`
            # driver. In that case and when the current amphora is ALLOCATED
            # are the only times we should include the *active* connections,
            # because non-active amphora will have incorrect counts.
            if (amp and amp.status == constants.AMPHORA_ALLOCATED) or (
                    db_l.amphora_id == db_l.listener_id):
                statistics.active_connections += db_l.active_connections
        return statistics
예제 #11
0
def update_stats(health_message):
    """Parses the health message then passes it to the stats driver(s)

    :param health_message: The health message containing the listener stats
    :type health_message: dict

    Example V1 message::

        health = {
            "id": "<amphora_id>",
            "listeners": {
                "<listener_id>": {
                    "status": "OPEN",
                    "stats": {
                        "ereq": 0,
                        "conns": 0,
                        "totconns": 0,
                        "rx": 0,
                        "tx": 0,
                    },
                    "pools": {
                        "<pool_id>": {
                            "status": "UP",
                            "members": {"<member_id>": "ONLINE"}
                        }
                    }
                }
            }
        }

    Example V2 message::

        {"id": "<amphora_id>",
         "seq": 67,
         "listeners": {
           "<listener_id>": {
             "status": "OPEN",
             "stats": {
               "tx": 0,
               "rx": 0,
               "conns": 0,
               "totconns": 0,
               "ereq": 0
             }
           }
         },
         "pools": {
             "<pool_id>:<listener_id>": {
               "status": "UP",
               "members": {
                 "<member_id>": "no check"
               }
             }
         },
         "ver": 2
         "recv_time": time.time()
        }

    Example V3 message::

        Same as V2 message, except values are deltas rather than absolutes.
    """
    version = health_message.get("ver", 2)

    deltas = False
    if version >= 3:
        deltas = True

    amphora_id = health_message.get('id')
    listeners = health_message.get('listeners', {})
    listener_stats = []
    for listener_id, listener in listeners.items():
        listener_dict = listener.get('stats')
        stats_model = data_models.ListenerStatistics(
            listener_id=listener_id,
            amphora_id=amphora_id,
            bytes_in=listener_dict.get('rx'),
            bytes_out=listener_dict.get('tx'),
            active_connections=listener_dict.get('conns'),
            total_connections=listener_dict.get('totconns'),
            request_errors=listener_dict.get('ereq'),
            received_time=health_message.get('recv_time'))
        LOG.debug("Listener %s / Amphora %s stats: %s", listener_id,
                  amphora_id, stats_model.get_stats())
        listener_stats.append(stats_model)
    stats_base.update_stats_via_driver(listener_stats, deltas=deltas)
예제 #12
0
    def test_update_listener_statistics(self, mock_stats_base, mock_time):
        mock_time.return_value = 12345.6
        listener_stats_li = [
            {"id": 1,
             "active_connections": 10,
             "bytes_in": 20,
             "bytes_out": 30,
             "request_errors": 40,
             "total_connections": 50},
            {"id": 2,
             "active_connections": 60,
             "bytes_in": 70,
             "bytes_out": 80,
             "request_errors": 90,
             "total_connections": 100}]
        listener_stats_dict = {"listeners": listener_stats_li}

        mock_stats_base.side_effect = [mock.DEFAULT, Exception('boom')]
        result = self.driver_updater.update_listener_statistics(
            listener_stats_dict)
        listener_stats_objects = [
            data_models.ListenerStatistics(
                listener_id=listener_stats_li[0]['id'],
                active_connections=listener_stats_li[0]['active_connections'],
                bytes_in=listener_stats_li[0]['bytes_in'],
                bytes_out=listener_stats_li[0]['bytes_out'],
                request_errors=listener_stats_li[0]['request_errors'],
                total_connections=listener_stats_li[0]['total_connections'],
                received_time=mock_time.return_value),
            data_models.ListenerStatistics(
                listener_id=listener_stats_li[1]['id'],
                active_connections=listener_stats_li[1]['active_connections'],
                bytes_in=listener_stats_li[1]['bytes_in'],
                bytes_out=listener_stats_li[1]['bytes_out'],
                request_errors=listener_stats_li[1]['request_errors'],
                total_connections=listener_stats_li[1]['total_connections'],
                received_time=mock_time.return_value)]
        mock_stats_base.assert_called_once_with(listener_stats_objects)
        self.assertEqual(self.ref_ok_response, result)

        # Test empty stats updates
        mock_stats_base.reset_mock()
        result = self.driver_updater.update_listener_statistics({})
        mock_stats_base.assert_not_called()
        self.assertEqual(self.ref_ok_response, result)

        # Test missing ID
        bad_id_dict = {"listeners": [{"notID": "one"}]}
        result = self.driver_updater.update_listener_statistics(bad_id_dict)
        ref_update_listener_stats_error = {
            lib_consts.STATUS_CODE: lib_consts.DRVR_STATUS_CODE_FAILED,
            lib_consts.STATS_OBJECT: lib_consts.LISTENERS,
            lib_consts.FAULT_STRING: "'id'"}
        self.assertEqual(ref_update_listener_stats_error, result)

        # Test for replace exception
        result = self.driver_updater.update_listener_statistics(
            listener_stats_dict)
        ref_update_listener_stats_error = {
            lib_consts.STATUS_CODE: lib_consts.DRVR_STATUS_CODE_FAILED,
            lib_consts.STATS_OBJECT: lib_consts.LISTENERS,
            lib_consts.FAULT_STRING: 'boom'}
        self.assertEqual(ref_update_listener_stats_error, result)
예제 #13
0
 def test_update_stats(self, mock_log):
     self.logger.update_stats([data_models.ListenerStatistics()])
     self.assertEqual(1, mock_log.info.call_count)