blob: 6e74c395a35598499c8efada583e2619b8a75b79 [file] [log] [blame]
# ==================================================================================
# Copyright (c) 2020 China Mobile Technology (USA) Inc. Intellectual Property.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==================================================================================
import json
import time
from contextlib import suppress
from lp import main, sdl
from lp.exceptions import UENotFound, CellNotFound
from ricxappframe.xapp_frame import Xapp, RMRXapp
import pytest
import pdb
@pytest.fixture
def ue_metrics():
return {
"UEID": "9876543",
"ServingCellID": "460-7-797-57315",
"MeasTimestampUEPDCPBytes": "2021-06-20 13:58:29.220",
"MeasPeriodUEPDCPBytes": 20,
"UEPDCPBytesDL": 250000,
"UEPDCPBytesUL": 100000,
"MeasTimestampUEPRBUsage": "2021-06-20 13:58:29.220",
"MeasPeriodUEPRBUsage": 20,
"UEPRBUsageDL": 10,
"UEPRBUsageUL": 30,
"MeasTimestampRF": "2021-06-20 13:58:29.210",
"MeasPeriodRF": 40,
"ServingCellRF": {"RSRP": -115, "RSRQ": -16, "RSSINR": -5},
"NeighborCellRF": [
{"CID": "460-7-797-57314", "CellRF": {"RSRP": -90, "RSRQ": -13, "RSSINR": -2.5}},
{"CID": "460-7-797-57316", "CellRF": {"RSRP": -140, "RSRQ": -17, "RSSINR": -6}},
],
"FAKE_BAD_DATA_TEST": "THIS SHOULD GET DELETED",
}
@pytest.fixture
def ue_metrics_with_bad_cell():
return {
"UEID": "3456789",
"ServingCellID": "460-7-797-57315",
"MeasTimestampUEPDCPBytes": "2021-06-20 13:58:29.220",
"MeasPeriodUEPDCPBytes": 20,
"UEPDCPBytesDL": 250000,
"UEPDCPBytesUL": 100000,
"MeasTimestampUEPRBUsage": "2021-06-20 13:58:29.220",
"MeasPeriodUEPRBUsage": 20,
"UEPRBUsageDL": 10,
"UEPRBUsageUL": 30,
"MeasTimestampRF": "2021-06-20 13:58:29.210",
"MeasPeriodRF": 40,
"ServingCellRF": {"RSRP": -115, "RSRQ": -16, "RSSINR": -5},
"NeighborCellRF": [
{"CID": "460-7-797-57314", "CellRF": {"RSRP": -90, "RSRQ": -13, "RSSINR": -2.5}},
{"CID": "CANTTOUCHTHIS", "CellRF": {"RSRP": -140, "RSRQ": -17, "RSSINR": -6}},
],
}
@pytest.fixture
def cell_metrics_1():
return {
"CellID": "460-7-797-57314",
"MeasTimestampPDCPBytes": "2021-06-20 13:58:29.220",
"MeasPeriodPDCPBytes": 20,
"PDCPBytesDL": 2000000,
"PDCPBytesUL": 1200000,
"MeasTimestampAvailPRB": "2021-06-20 13:58:29.220",
"MeasPeriodAvailPRB": 20,
"AvailPRBDL": 30,
"AvailPRBUL": 50,
}
@pytest.fixture
def cell_metrics_2():
return {
"CellID": "460-7-797-57315",
"MeasTimestampPDCPBytes": "2021-06-20 13:58:29.220",
"MeasPeriodPDCPBytes": 20,
"PDCPBytesDL": 800000,
"PDCPBytesUL": 400000,
"MeasTimestampAvailPRB": "2021-06-20 13:58:29.220",
"MeasPeriodAvailPRB": 20,
"AvailPRBDL": 30,
"AvailPRBUL": 45,
"FAKE_BAD_DATA_TEST": "THIS SHOULD GET DELETED",
}
@pytest.fixture
def cell_metrics_3():
return {
"CellID": "460-7-797-57316",
"MeasTimestampPDCPBytes": "2021-06-20 13:58:29.220",
"MeasPeriodPDCPBytes": 20,
"PDCPBytesDL": 1900000,
"PDCPBytesUL": 1000000,
"MeasTimestampAvailPRB": "2021-06-20 13:58:29.220",
"MeasPeriodAvailPRB": 20,
"AvailPRBDL": 60,
"AvailPRBUL": 80,
}
@pytest.fixture
def good_cell():
return {
"PredictionUE": "9876543",
"UEMeasurements": {
"ServingCellID": "460-7-797-57315",
"MeasTimestampUEPDCPBytes": "2021-06-20 13:58:29.220",
"MeasPeriodUEPDCPBytes": 20,
"UEPDCPBytesDL": 250000,
"UEPDCPBytesUL": 100000,
"MeasTimestampUEPRBUsage": "2021-06-20 13:58:29.220",
"MeasPeriodUEPRBUsage": 20,
"UEPRBUsageDL": 10,
"UEPRBUsageUL": 30,
},
"CellMeasurements": [
{
"CellID": "460-7-797-57314",
"MeasTimestampPDCPBytes": "2021-06-20 13:58:29.220",
"MeasPeriodPDCPBytes": 20,
"PDCPBytesDL": 2000000,
"PDCPBytesUL": 1200000,
"MeasTimestampAvailPRB": "2021-06-20 13:58:29.220",
"MeasPeriodAvailPRB": 20,
"AvailPRBDL": 30,
"AvailPRBUL": 50,
"MeasTimestampRF": "2021-06-20 13:58:29.210",
"MeasPeriodRF": 40,
"RFMeasurements": {"RSRP": -90, "RSRQ": -13, "RSSINR": -2.5},
},
{
"CellID": "460-7-797-57316",
"MeasTimestampPDCPBytes": "2021-06-20 13:58:29.220",
"MeasPeriodPDCPBytes": 20,
"PDCPBytesDL": 1900000,
"PDCPBytesUL": 1000000,
"MeasTimestampAvailPRB": "2021-06-20 13:58:29.220",
"MeasPeriodAvailPRB": 20,
"AvailPRBDL": 60,
"AvailPRBUL": 80,
"MeasTimestampRF": "2021-06-20 13:58:29.210",
"MeasPeriodRF": 40,
"RFMeasurements": {"RSRP": -140, "RSRQ": -17, "RSSINR": -6},
},
{
"CellID": "460-7-797-57315",
"MeasTimestampPDCPBytes": "2021-06-20 13:58:29.220",
"MeasPeriodPDCPBytes": 20,
"PDCPBytesDL": 800000,
"PDCPBytesUL": 400000,
"MeasTimestampAvailPRB": "2021-06-20 13:58:29.220",
"MeasPeriodAvailPRB": 20,
"AvailPRBDL": 30,
"AvailPRBUL": 45,
"MeasTimestampRF": "2021-06-20 13:58:29.210",
"MeasPeriodRF": 40,
"RFMeasurements": {"RSRP": -115, "RSRQ": -16, "RSSINR": -5},
},
],
}
@pytest.fixture
def bad_cell():
return {
"PredictionUE": "3456789",
"UEMeasurements": {
"ServingCellID": "460-7-797-57315",
"MeasTimestampUEPDCPBytes": "2021-06-20 13:58:29.220",
"MeasPeriodUEPDCPBytes": 20,
"UEPDCPBytesDL": 250000,
"UEPDCPBytesUL": 100000,
"MeasTimestampUEPRBUsage": "2021-06-20 13:58:29.220",
"MeasPeriodUEPRBUsage": 20,
"UEPRBUsageDL": 10,
"UEPRBUsageUL": 30,
},
"CellMeasurements": [
{
"CellID": "460-7-797-57314",
"MeasTimestampPDCPBytes": "2021-06-20 13:58:29.220",
"MeasPeriodPDCPBytes": 20,
"PDCPBytesDL": 2000000,
"PDCPBytesUL": 1200000,
"MeasTimestampAvailPRB": "2021-06-20 13:58:29.220",
"MeasPeriodAvailPRB": 20,
"AvailPRBDL": 30,
"AvailPRBUL": 50,
"MeasTimestampRF": "2021-06-20 13:58:29.210",
"MeasPeriodRF": 40,
"RFMeasurements": {"RSRP": -90, "RSRQ": -13, "RSSINR": -2.5},
},
{
"CellID": "460-7-797-57315",
"MeasTimestampPDCPBytes": "2021-06-20 13:58:29.220",
"MeasPeriodPDCPBytes": 20,
"PDCPBytesDL": 800000,
"PDCPBytesUL": 400000,
"MeasTimestampAvailPRB": "2021-06-20 13:58:29.220",
"MeasPeriodAvailPRB": 20,
"AvailPRBDL": 30,
"AvailPRBUL": 45,
"MeasTimestampRF": "2021-06-20 13:58:29.210",
"MeasPeriodRF": 40,
"RFMeasurements": {"RSRP": -115, "RSRQ": -16, "RSSINR": -5},
},
],
}
mock_lp_xapp = None
# tox.ini sets env var to this value
config_file_path = "/tmp/config.json"
def init_config_file():
with open(config_file_path, "w") as file:
file.write('{ "version_int" : 1 }')
def write_config_file():
# generate an inotify/config event
with open(config_file_path, "w") as file:
file.write('{ "version_int" : 2 }')
def test_init_xapp(monkeypatch, ue_metrics, cell_metrics_1, cell_metrics_2, cell_metrics_3, ue_metrics_with_bad_cell, good_cell):
_original_post_init = main.post_init
def fake_post_init(self):
_original_post_init(self)
self.sdl_set(sdl.UE_NS, "9876543", json.dumps(ue_metrics).encode(), usemsgpack=False)
self.sdl_set(sdl.UE_NS, "3456789", json.dumps(ue_metrics_with_bad_cell).encode(), usemsgpack=False)
self.sdl_set(sdl.CELL_NS, "460-7-797-57314", json.dumps(cell_metrics_1).encode(), usemsgpack=False)
self.sdl_set(sdl.CELL_NS, "460-7-797-57315", json.dumps(cell_metrics_2).encode(), usemsgpack=False)
self.sdl_set(sdl.CELL_NS, "460-7-797-57316", json.dumps(cell_metrics_3).encode(), usemsgpack=False)
expected=sdl.get_uedata(self, "9876543")
assert expected==good_cell
expected=main.run_prediction(self)
assert expected=="Normal"
expected=main.predict(self, expected)
assert expected=="Normal"
expected=sdl.get_uedata(self, "3456789")
try:
sdl.get_uedata(self, "1234567")
except UENotFound:
self.logger.warning("UE doesn't exist!")
# patch
monkeypatch.setattr("lp.main.post_init", fake_post_init)
# establish config
init_config_file()
# test db connection
main.connectdb(thread=True)
# start lp
#main.start(thread=False)
# wait a bit then update config
time.sleep(1)
write_config_file()
def test_mock_xapp():
# define a mock traffic steering xapp
def mock_ts_entry(self):
# make sure a bad steering request doesn't blow up in lp
val = "".encode() # send empty string encoded message
self.rmr_send(val, 30000)
val = "just a string".encode() # not json
self.rmr_send(val, 30000)
val = json.dumps({"key": "value"}).encode() # json but missing UEPredictionSet
self.rmr_send(val, 30000)
# valid request body but missing cell id
val = json.dumps({"UEPredictionSet": ["NOTVALIDUEs"]}).encode()
self.rmr_send(val, 30000)
# good traffic steering request
val = json.dumps({"UEPredictionSet": ["9876543", "3456789"]}).encode()
self.rmr_send(val, 30000)
# should trigger the default handler and do nothing
val = json.dumps({"send other message types": 1}).encode()
self.rmr_send(val, 60001)
global mock_ts_xapp
mock_ts_xapp = Xapp(entrypoint=mock_ts_entry, rmr_port=4564, use_fake_sdl=True)
mock_ts_xapp.run() # this will return since entry isn't a loop
def teardown_module():
"""
this is like a "finally"; the name of this function is pytest magic
safer to put down here since certain failures above can lead to pytest never returning
for example if an exception gets raised before stop is called in any test function above,
pytest will hang forever
"""
with suppress(Exception):
mock_ts_xapp.stop()
with suppress(Exception):
mock_lp_xapp.stop()
with suppress(Exception):
main.stop()