Wei-Yu Chen | ad55cb8 | 2022-02-15 20:07:01 +0800 | [diff] [blame^] | 1 | # SPDX-FileCopyrightText: 2020 The Magma Authors. |
| 2 | # SPDX-FileCopyrightText: 2022 Open Networking Foundation <support@opennetworking.org> |
| 3 | # |
| 4 | # SPDX-License-Identifier: BSD-3-Clause |
Wei-Yu Chen | 49950b9 | 2021-11-08 19:19:18 +0800 | [diff] [blame] | 5 | |
| 6 | from unittest import TestCase, mock |
| 7 | from xml.etree import ElementTree |
| 8 | |
| 9 | import pkg_resources |
| 10 | from enodebd import metrics |
| 11 | from data_models.data_model_parameters import ParameterName |
| 12 | from devices.device_utils import EnodebDeviceName |
| 13 | from state_machines.enb_acs_manager import StateMachineManager |
| 14 | from stats_manager import StatsManager |
| 15 | from tests.test_utils.config_builder import EnodebConfigBuilder |
| 16 | from tests.test_utils.enb_acs_builder import ( |
| 17 | EnodebAcsStateMachineBuilder, |
| 18 | ) |
| 19 | |
| 20 | |
| 21 | class StatsManagerTest(TestCase): |
| 22 | """ |
| 23 | Tests for eNodeB statistics manager |
| 24 | """ |
| 25 | |
| 26 | def setUp(self) -> None: |
| 27 | service = EnodebConfigBuilder.get_service_config() |
| 28 | self.enb_acs_manager = StateMachineManager(service) |
| 29 | self.mgr = StatsManager(self.enb_acs_manager) |
| 30 | self.is_clear_stats_called = False |
| 31 | |
| 32 | def tearDown(self): |
| 33 | self.mgr = None |
| 34 | |
| 35 | def test_check_rf_tx(self): |
| 36 | """ Check that stats are cleared when transmit is disabled on eNB """ |
| 37 | handler = EnodebAcsStateMachineBuilder \ |
| 38 | .build_acs_state_machine(EnodebDeviceName.BAICELLS) |
| 39 | with mock.patch( |
| 40 | 'magma.enodebd.devices.baicells.BaicellsHandler.is_enodeb_connected', |
| 41 | return_value=True, |
| 42 | ): |
| 43 | handler.device_cfg.set_parameter(ParameterName.RF_TX_STATUS, True) |
| 44 | handler.device_cfg.set_parameter( |
| 45 | ParameterName.SERIAL_NUMBER, |
| 46 | '123454', |
| 47 | ) |
| 48 | with mock.patch( |
| 49 | 'magma.enodebd.stats_manager.StatsManager' |
| 50 | '._clear_stats', |
| 51 | ) as func: |
| 52 | self.mgr._check_rf_tx_for_handler(handler) |
| 53 | func.assert_not_called() |
| 54 | handler.device_cfg.set_parameter( |
| 55 | ParameterName.RF_TX_STATUS, |
| 56 | False, |
| 57 | ) |
| 58 | self.mgr._check_rf_tx_for_handler(handler) |
| 59 | func.assert_any_call() |
| 60 | |
| 61 | def test_parse_stats(self): |
| 62 | """ Test that example statistics from eNodeB can be parsed, and metrics |
| 63 | updated """ |
| 64 | # Example performance metrics structure, sent by eNodeB |
| 65 | pm_file_example = pkg_resources.resource_string( |
| 66 | __name__, |
| 67 | 'pm_file_example.xml', |
| 68 | ) |
| 69 | |
| 70 | root = ElementTree.fromstring(pm_file_example) |
| 71 | self.mgr._parse_pm_xml('1234', root) |
| 72 | |
| 73 | # Check that metrics were correctly populated |
| 74 | # See '<V i="5">123</V>' in pm_file_example |
| 75 | rrc_estab_attempts = metrics.STAT_RRC_ESTAB_ATT.collect() |
| 76 | self.assertEqual(rrc_estab_attempts[0].samples[0][2], 123) |
| 77 | # See '<V i="7">99</V>' in pm_file_example |
| 78 | rrc_estab_successes = metrics.STAT_RRC_ESTAB_SUCC.collect() |
| 79 | self.assertEqual(rrc_estab_successes[0].samples[0][2], 99) |
| 80 | # See '<SV>654</SV>' in pm_file_example |
| 81 | rrc_reestab_att_reconf_fail = \ |
| 82 | metrics.STAT_RRC_REESTAB_ATT_RECONF_FAIL.collect() |
| 83 | self.assertEqual(rrc_reestab_att_reconf_fail[0].samples[0][2], 654) |
| 84 | # See '<SV>65537</SV>' in pm_file_example |
| 85 | erab_rel_req_radio_conn_lost = \ |
| 86 | metrics.STAT_ERAB_REL_REQ_RADIO_CONN_LOST.collect() |
| 87 | self.assertEqual(erab_rel_req_radio_conn_lost[0].samples[0][2], 65537) |
| 88 | |
| 89 | pdcp_user_plane_bytes_ul = \ |
| 90 | metrics.STAT_PDCP_USER_PLANE_BYTES_UL.collect() |
| 91 | pdcp_user_plane_bytes_dl = \ |
| 92 | metrics.STAT_PDCP_USER_PLANE_BYTES_DL.collect() |
| 93 | self.assertEqual(pdcp_user_plane_bytes_ul[0].samples[0][1], {'enodeb': '1234'}) |
| 94 | self.assertEqual(pdcp_user_plane_bytes_dl[0].samples[0][1], {'enodeb': '1234'}) |
| 95 | self.assertEqual(pdcp_user_plane_bytes_ul[0].samples[0][2], 1000) |
| 96 | self.assertEqual(pdcp_user_plane_bytes_dl[0].samples[0][2], 500) |
| 97 | |
| 98 | def test_clear_stats(self): |
| 99 | """ |
| 100 | Check that stats of PMPM_FILE_TO_METRIC_MAP is cleared successfully |
| 101 | """ |
| 102 | # Example performance metrics structure, sent by eNodeB |
| 103 | pm_file_example = pkg_resources.resource_string( |
| 104 | __name__, |
| 105 | 'pm_file_example.xml', |
| 106 | ) |
| 107 | |
| 108 | root = ElementTree.fromstring(pm_file_example) |
| 109 | self.mgr._parse_pm_xml('1234', root) |
| 110 | |
| 111 | # Check that metrics were correctly populated |
| 112 | rrc_estab_attempts = metrics.STAT_RRC_ESTAB_ATT.collect() |
| 113 | self.assertEqual(rrc_estab_attempts[0].samples[0][2], 123) |
| 114 | |
| 115 | self.mgr._clear_stats() |
| 116 | rrc_estab_attempts = metrics.STAT_RRC_ESTAB_ATT.collect() |
| 117 | # After clearing stats collection of metric should report 0 |
| 118 | self.assertEqual(rrc_estab_attempts[0].samples[0][2], 0) |