def mock_ad_entry(self): global val, mock_ad_xapp val = ad_to_ts mock_ad_xapp = Xapp(entrypoint=main.msg_to_ts(self, val), rmr_port=4564, use_fake_sdl=True) mock_ad_xapp.run() # this will return since mock_ad_entry isn't a loop
def test_msg_to_ts(monkeypatch, ad_to_ts): def mock_ad_entry(self): val = json.dumps(ad_to_ts).encode() self.rmr_send(val, 30003) global mock_ad_xapp mock_ad_xapp = Xapp(entrypoint=mock_ad_entry, rmr_port=4564, use_fake_sdl=True) mock_ad_xapp.run() # this will return since mock_ad_entry isn't a loop # this will return since mock_ad_entry isn't a loop
def test_rmr_init(): # test variables def_pay = None sixty_pay = None # create rmr app def default_handler(self, summary, sbuf): nonlocal def_pay def_pay = json.loads(summary["payload"]) self.rmr_free(sbuf) def sixtythou_handler(self, summary, sbuf): nonlocal sixty_pay sixty_pay = json.loads(summary["payload"]) self.rmr_free(sbuf) global rmr_xapp rmr_xapp = RMRXapp(default_handler, rmr_port=4564, use_fake_sdl=True) rmr_xapp.register_callback(sixtythou_handler, 60000) rmr_xapp.run( thread=True ) # in unit tests we need to thread here or else execution is not returned! time.sleep(1) # create a general xapp that will demonstrate some SDL functionality and launch some requests against the rmr xapp def entry(self): time.sleep(1) self.sdl_set("testns", "mykey", 6) assert self.sdl_get("testns", "mykey") == 6 assert self.sdl_find_and_get("testns", "myk") == {"mykey": 6} assert self.healthcheck() val = json.dumps({"test send 60000": 1}).encode() self.rmr_send(val, 60000) val = json.dumps({"test send 60001": 2}).encode() self.rmr_send(val, 60001) self.sdl_delete("testns", "bogus") global gen_xapp gen_xapp = Xapp(entrypoint=entry, use_fake_sdl=True) gen_xapp.run() time.sleep(1) assert def_pay == {"test send 60001": 2} assert sixty_pay == {"test send 60000": 1}
def test_rmr_flow(monkeypatch, qpd_to_qp, qp_prediction): """ this flow mocks out the xapps on both sides of QP. It first stands up a mock ts, then it starts up a mock qp-driver which will immediately send requests to the running qp. """ expected_result = {} # define a mock traffic steering xapp that listens on 4563 def mock_ts_default_handler(self, summary, sbuf): pass def mock_ts_prediction_handler(self, summary, sbuf): nonlocal expected_result # closures ftw pay = json.loads(summary["payload"]) expected_result = pay global mock_ts_xapp mock_ts_xapp = RMRXapp(mock_ts_default_handler, rmr_port=4563, use_fake_sdl=True) mock_ts_xapp.register_callback(mock_ts_prediction_handler, 30002) mock_ts_xapp.run(thread=True) time.sleep(1) # define a mock qp driver xapp that sends a message to QP under test def mock_qpd_entry(self): # good traffic steering request val = json.dumps(qpd_to_qp).encode() self.rmr_send(val, 30001) # should trigger the default handler and do nothing val = json.dumps({"test send 60001": 2}).encode() self.rmr_send(val, 60001) global mock_qpd_xapp mock_qpd_xapp = Xapp(entrypoint=mock_qpd_entry, rmr_port=4666, use_fake_sdl=True) mock_qpd_xapp.run() # this will return since entry isn't a loop time.sleep(1) assert main.get_stats() == {"PredictRequests": 1} assert expected_result == qp_prediction
def test_init_general_xapp(): def entry(self): # normally we would have some kind of loop here print("bye") gen_xapp = Xapp(entrypoint=entry, rmr_wait_for_ready=False, use_fake_sdl=True) gen_xapp.run() time.sleep(1) gen_xapp.stop() # pytest will never return without this.
def test_bad_init(): """test that an xapp whose rmr fails to init blows up""" def entry(self): pass with pytest.raises(InitFailed): bad_xapp = Xapp(entrypoint=entry, rmr_port=-1) bad_xapp.run() # we wont get here def defh(self): pass with pytest.raises(InitFailed): bad_xapp = RMRXapp(default_handler=defh, rmr_port=-1) bad_xapp.run() # we wont get here
print("ping is healthy? {}".format(xapp.healthcheck())) # rmr send to default handler self.rmr_send(json.dumps({"ping": number}).encode(), 6660666) # rmr send 60000, should trigger registered callback val = json.dumps({"test_send": number}).encode() self.rmr_send(val, 60000) number += 1 # store it in SDL and read it back; delete and read self.sdl_set(my_ns, "ping", number) self.logger.info(self.sdl_get(my_ns, "ping")) self.logger.info(self.sdl_find_and_get(my_ns, "pin")) self.sdl_delete(my_ns, "ping") self.logger.info(self.sdl_get(my_ns, "ping")) # rmr receive for (summary, sbuf) in self.rmr_get_messages(): # summary is a dict that contains bytes so we can't use json.dumps on it # so we have no good way to turn this into a string to use the logger unfortunately # print is more "verbose" than the ric logger # if you try to log this you will get: TypeError: Object of type bytes is not JSON serializable print("ping: {0}".format(summary)) self.rmr_free(sbuf) time.sleep(2) xapp = Xapp(entrypoint=entry, rmr_port=4564, use_fake_sdl=True) xapp.run()
def start(): # Initiates xapp api and runs the entry() using xapp.run() xapp = Xapp(entrypoint=entry, rmr_port=4560, use_fake_sdl=True) xapp.run()
def start(thread=False): # Initiates xapp api and runs the entry() using xapp.run() xapp = Xapp(entrypoint=entry, rmr_port=4560, use_fake_sdl=False) connectdb(thread) xapp.run()
def test_rmr_flow(monkeypatch, qpd_to_qp, qpd_to_qp_bad_cell): """ this flow mocks out the xapps on both sides of QP driver. It first stands up a mock qp, then it starts up a mock ts which will immediately send requests to the running qp driver. """ expected_result = {} # define a mock qp predictor def mock_qp_default_handler(self, summary, sbuf): pass def mock_qp_predict_handler(self, summary, sbuf): nonlocal expected_result # closures ftw pay = json.loads(summary["payload"]) expected_result[pay["PredictionUE"]] = pay global mock_qp_xapp mock_qp_xapp = RMRXapp(mock_qp_default_handler, rmr_port=4666, use_fake_sdl=True) mock_qp_xapp.register_callback(mock_qp_predict_handler, 30001) mock_qp_xapp.run(thread=True) time.sleep(1) # define a mock traffic steering xapp def mock_ts_entry(self): # make sure a bad steering request doesn't blow up in qpd val = "notevenjson".encode() self.rmr_send(val, 30000) val = json.dumps({ "bad": "tothebone" }).encode() # json but missing UEPredictionSet self.rmr_send(val, 30000) # valid request body but missing cell id val = json.dumps({"UEPredictionSet": ["VOIDOFLIGHT"]}).encode() self.rmr_send(val, 30000) # good traffic steering request val = json.dumps({"UEPredictionSet": ["12345", "8675309"]}).encode() self.rmr_send(val, 30000) # should trigger the default handler and do nothing val = json.dumps({"test send 60001": 2}).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 time.sleep(1) assert expected_result == { "12345": qpd_to_qp, "8675309": qpd_to_qp_bad_cell } assert main.get_stats() == {"DefCalled": 1, "SteeringRequests": 4} # break SDL and send traffic again def sdl_healthcheck_fails(self): return False monkeypatch.setattr("ricxappframe.xapp_sdl.SDLWrapper.healthcheck", sdl_healthcheck_fails) mock_ts_xapp.run() # restore SDL and send traffic once more def sdl_healthcheck_passes(self): return True monkeypatch.setattr("ricxappframe.xapp_sdl.SDLWrapper.healthcheck", sdl_healthcheck_passes) mock_ts_xapp.run()