X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=test%2Funit_test_message_processor.cc;fp=test%2Funit_test_message_processor.cc;h=f410e5b38650781404f0c41d5a6666d731f638eb;hb=dc68642f5676cdd49f3ef92f983b319e21f16afa;hp=0000000000000000000000000000000000000000;hpb=0054ece5d9d4bcb28ecda2f0f36584f6a64fc869;p=ric-app%2Fadmin.git diff --git a/test/unit_test_message_processor.cc b/test/unit_test_message_processor.cc new file mode 100644 index 0000000..f410e5b --- /dev/null +++ b/test/unit_test_message_processor.cc @@ -0,0 +1,660 @@ +/* +================================================================================== + + Copyright (c) 2018-2019 AT&T 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. +================================================================================== +*/ + +/* Author : Ashwin Sridharan + Date : Sept 2019 +*/ + +#define CATCH_CONFIG_MAIN +#include + + +#include +#include + +#define ASN_DEBUG 1 +#define SCHEMA_FILE "../schemas/adm-ctrl-xapp-policy-schema.json" +#define SAMPLE_FILE "../schemas/samples.json" +#define VES_FILE "../schemas/ves_schema.json" + +#define BUFFER_SIZE 2<<15 + +bool report_mode_only = false; + +void policy_stub(int mtype, const char *message, int msg_len, std::string & response, bool atype){ + // do nothing; +} + +TEST_CASE("message processor functionality", "[acxapp]"){ + + mdclog_attr_t *attr; + mdclog_attr_init(&attr); + mdclog_attr_set_ident(attr, "UNIT TEST MESSAGE PROCESSOR "); + mdclog_init(attr); + mdclog_level_set(MDCLOG_DEBUG); + mdclog_attr_destroy(attr); + + bool res; + e2sm_indication e2sm_indication_obj; + FILE *pfile; + + //==== e2sm indication header : just some + // random fill for now + e2sm_header_helper indication_header; + indication_header.egNB_id="hello"; + indication_header.plmn_id="there"; + indication_header.interface_direction = 1; + indication_header.egNB_id_type = 2; + + + unsigned char buf_header[32]; + size_t buf_header_size = 32; + + // Encode the indication header + res = e2sm_indication_obj.encode_indication_header(&buf_header[0], &buf_header_size, indication_header); + REQUIRE(res == true); + + + //====== x2ap sgnb addition reuqest + unsigned char x2ap_buf[256]; + size_t x2ap_buf_size = 256; + pfile = fopen("test-data/X2AP-PDU-SgNBAdditionRequest.per", "r"); + REQUIRE(pfile != NULL); + x2ap_buf_size = fread((char *)x2ap_buf, sizeof(char), 256, pfile); + + //==== e2ap indication + ric_indication_helper dinput ; + dinput.action_id = 100; + dinput.func_id = 10; + dinput.indication_sn = 100; + dinput.req_id = 6; + dinput.req_seq_no = 11; + + //==== filler for incorrect x2ap + unsigned char * incorrect_x2ap; + size_t incorrect_x2ap_size; + + // ====== mock incorrect e2sm header ... + unsigned char incorrect_e2sm_header[32]; + size_t incorrect_e2sm_header_size = 32; + for(int i = 0; i < 32; i++){ + incorrect_e2sm_header[i] = 'q'; + } + + + ric_indication indication_pdu; + + // rmr buffer + rmr_mbuf_t rmr_message; + rmr_message.mtype = RIC_INDICATION; + + + + /* encoding pdu put here */ + size_t data_size = BUFFER_SIZE; + unsigned char * data = new unsigned char[data_size]; + assert(data != NULL); + + SECTION("Null Test cases when no handlers registered"){ + + + // message processor + message_processor my_processor; + + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == MISSING_HANDLER_ERROR); + + + rmr_message.mtype = RIC_SUB_RESP; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == MISSING_HANDLER_ERROR); + + + rmr_message.mtype = DC_ADM_INT_CONTROL; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == MISSING_HANDLER_ERROR); + + rmr_message.mtype = DC_ADM_GET_POLICY; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == MISSING_HANDLER_ERROR); + + + } + + + SECTION("Test various message types for all handlers registered in ALL mode"){ + + // message processor + message_processor my_processor(ALL, false); + + // admission control policy wrapper + admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false); + + // register the protector plugin with message processor + my_processor.register_protector(adm_plugin.get_protector_instance(0)); + + + srand(112309); + + int num_cycles = 1; + for(int i = 0; i < num_cycles;i ++){ + + data_size = BUFFER_SIZE; + dinput.indication_type = 1;// action_type; + dinput.indication_header = buf_header; + dinput.indication_header_size = buf_header_size; + + + //random injection of incorrect e2ap pdu + for(unsigned int i = 0; i < data_size; i++){ + data[i] = rand()% 256 ; + } + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == E2AP_INDICATION_ERROR); + + //random injection of erroneous x2ap pdu + for(int k = 8; k <= 14; k++){ + incorrect_x2ap_size = 2 << k; + incorrect_x2ap = new unsigned char[incorrect_x2ap_size]; + assert(incorrect_x2ap != NULL); + for(unsigned int i = 0; i < incorrect_x2ap_size; i++){ + incorrect_x2ap[i] = rand()%256; + } + + data_size = BUFFER_SIZE; + dinput.indication_type = 1; + dinput.indication_msg = incorrect_x2ap; + dinput.indication_msg_size = incorrect_x2ap_size; + res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput); + REQUIRE(res == true); + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == PLUGIN_ERROR); + + delete[] incorrect_x2ap; + } + + + //all correct e2ap and x2ap + data_size = BUFFER_SIZE; + dinput.indication_type = 1; + dinput.indication_msg = &x2ap_buf[0]; + dinput.indication_msg_size = x2ap_buf_size; + res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput); + REQUIRE(res == true); + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == NO_ERROR); + + + //incorrect e2sm header + data_size = BUFFER_SIZE; + dinput.indication_type = 1; + dinput.indication_header = incorrect_e2sm_header; + dinput.indication_header_size = incorrect_e2sm_header_size; + + res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput); + REQUIRE(res == true); + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == E2SM_INDICATION_HEADER_ERROR); + + + + // // fake buffer x2 size + std::cout <<"Trying corrupt message field size" << std::endl; + data_size = BUFFER_SIZE; + dinput.indication_type = 1; + dinput.indication_header = buf_header; + dinput.indication_header_size = buf_header_size; + + dinput.indication_msg = &x2ap_buf[0]; + dinput.indication_msg_size = rand()%128; + res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput); + REQUIRE(res == true); + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = 2<<20; // put a fake buffer size + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == RMR_ERROR); + + } + + + + } + + SECTION("Test various messages in E2AP_PROC_ONLY mode"){ + + + // message processor + message_processor my_processor(E2AP_PROC_ONLY); + + // admission control policy wrapper + admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false); + + + // register the protector plugin with message processor + my_processor.register_protector(adm_plugin.get_protector_instance(0)); + + + srand(112309); + + int num_cycles = 1; + for(int i = 0; i < num_cycles;i ++){ + + data_size = BUFFER_SIZE; + dinput.indication_type = 1;// action_type; + dinput.indication_header = buf_header; + dinput.indication_header_size = buf_header_size; + + + //random injection of incorrect e2ap pdu + //random injection of incorrect e2ap pdu + for(unsigned int i = 0; i < data_size; i++){ + data[i] = rand()% 256 ; + } + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == E2AP_INDICATION_ERROR); + + //random injection of erroneous x2ap pdu + for(int k = 8; k <= 14; k++){ + incorrect_x2ap_size = 2 << k; + incorrect_x2ap = new unsigned char[incorrect_x2ap_size]; + assert(incorrect_x2ap != NULL); + for(unsigned int i = 0; i < incorrect_x2ap_size; i++){ + incorrect_x2ap[i] = rand()%256; + } + + data_size = BUFFER_SIZE; + dinput.indication_type = 1; + dinput.indication_msg = incorrect_x2ap; + dinput.indication_msg_size = incorrect_x2ap_size; + res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput); + REQUIRE(res == true); + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == NO_ERROR); // since we don't process X2ap + + delete[] incorrect_x2ap; + } + + + //all correct e2ap and x2ap + data_size = BUFFER_SIZE; + dinput.indication_type = 1; + dinput.indication_msg = &x2ap_buf[0]; + dinput.indication_msg_size = x2ap_buf_size; + res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput); + REQUIRE(res == true); + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == NO_ERROR); + + + //incorrect e2sm header + data_size = BUFFER_SIZE; + dinput.indication_type = 1; + dinput.indication_header = incorrect_e2sm_header; + dinput.indication_header_size = incorrect_e2sm_header_size; + + res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput); + REQUIRE(res == true); + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == NO_ERROR); // since we don't process e2sm + + } + + REQUIRE(adm_plugin.get_protector_instance(0)->get_requests() == 0); + } + + + SECTION("Test various messages in E2SM_PROC_ONLY mode"){ + + + // message processor + message_processor my_processor(E2SM_PROC_ONLY); + + // admission control policy wrapper + admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false); + + // register the protector plugin with message processor + my_processor.register_protector(adm_plugin.get_protector_instance(0)); + + + srand(112309); + + int num_cycles = 1; + for(int i = 0; i < num_cycles;i ++){ + + data_size = BUFFER_SIZE; + dinput.indication_type = 1;// action_type; + dinput.indication_header = buf_header; + dinput.indication_header_size = buf_header_size; + + + //random injection of incorrect e2ap pdu + //random injection of incorrect e2ap pdu + for(unsigned int i = 0; i < data_size; i++){ + data[i] = rand()% 256 ; + } + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == E2AP_INDICATION_ERROR); + + //random injection of erroneous x2ap pdu + for(int k = 8; k <= 14; k++){ + incorrect_x2ap_size = 2 << k; + incorrect_x2ap = new unsigned char[incorrect_x2ap_size]; + assert(incorrect_x2ap != NULL); + for(unsigned int i = 0; i < incorrect_x2ap_size; i++){ + incorrect_x2ap[i] = rand()%256; + } + + data_size = BUFFER_SIZE; + dinput.indication_type = 1; + dinput.indication_msg = incorrect_x2ap; + dinput.indication_msg_size = incorrect_x2ap_size; + res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput); + REQUIRE(res == true); + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == NO_ERROR); // since we don't process X2ap + + delete[] incorrect_x2ap; + } + + + //all correct e2ap and x2ap + data_size = BUFFER_SIZE; + dinput.indication_type = 1; + dinput.indication_msg = &x2ap_buf[0]; + dinput.indication_msg_size = x2ap_buf_size; + res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput); + REQUIRE(res == true); + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == NO_ERROR); + + + //incorrect e2sm header + data_size = BUFFER_SIZE; + dinput.indication_type = 1; + dinput.indication_header = incorrect_e2sm_header; + dinput.indication_header_size = incorrect_e2sm_header_size; + + res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput); + REQUIRE(res == true); + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == E2SM_INDICATION_HEADER_ERROR); + + } + + REQUIRE(adm_plugin.get_protector_instance(0)->get_requests() == 0); + } + + + SECTION("Test various message types for all handlers registered in ALL mode with response"){ + + // message processor + message_processor my_processor(ALL, false); + + // admission control policy wrapper + admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false); + + // subscription handler + subscription_handler sub_handler; + + // register the protector plugin with message processor + my_processor.register_protector(adm_plugin.get_protector_instance(0)); + my_processor.register_policy_handler(policy_stub); + my_processor.register_subscription_handler(&sub_handler); + + srand(112309); + + int num_cycles = 1; + for(int i = 0; i < num_cycles;i ++){ + + data_size = BUFFER_SIZE; + dinput.indication_type = 1;// action_type; + dinput.indication_header = buf_header; + dinput.indication_header_size = buf_header_size; + + + //random injection of incorrect e2ap pdu + for(unsigned int i = 0; i < data_size; i++){ + data[i] = rand()% 256 ; + } + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == E2AP_INDICATION_ERROR); + + //random injection of erroneous x2ap pdu + for(int k = 8; k <= 14; k++){ + incorrect_x2ap_size = 2 << k; + incorrect_x2ap = new unsigned char[incorrect_x2ap_size]; + assert(incorrect_x2ap != NULL); + for(unsigned int i = 0; i < incorrect_x2ap_size; i++){ + incorrect_x2ap[i] = rand()%256; + } + + data_size = BUFFER_SIZE; + dinput.indication_type = 1; + dinput.indication_msg = incorrect_x2ap; + dinput.indication_msg_size = incorrect_x2ap_size; + res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput); + REQUIRE(res == true); + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == PLUGIN_ERROR); + + delete[] incorrect_x2ap; + } + + + //all correct e2ap and x2ap + data_size = BUFFER_SIZE; + dinput.indication_type = 1; + dinput.indication_msg = &x2ap_buf[0]; + dinput.indication_msg_size = x2ap_buf_size; + res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput); + REQUIRE(res == true); + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == NO_ERROR); + + + //incorrect e2sm header + data_size = BUFFER_SIZE; + dinput.indication_type = 1; + dinput.indication_header = incorrect_e2sm_header; + dinput.indication_header_size = incorrect_e2sm_header_size; + + res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput); + REQUIRE(res == true); + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == E2SM_INDICATION_HEADER_ERROR); + + + + // // rmr buffer size + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = 2 << 20; // put a fake buffer size + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == RMR_ERROR); + + + // subscription response + rmr_message.mtype = RIC_SUB_RESP; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == NO_ERROR); + + // policy get + rmr_message.mtype = DC_ADM_GET_POLICY; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == NO_ERROR); + + + // policy set + } + + + REQUIRE(adm_plugin.get_protector_instance(0)->get_requests() == num_cycles); + } + + + SECTION("Trigger control low buffer related errors"){ + + data_size = BUFFER_SIZE; + dinput.indication_type = 1;// action_type; + dinput.indication_header = buf_header; + dinput.indication_header_size = buf_header_size; + + //all correct e2ap and x2ap + data_size = BUFFER_SIZE; + dinput.indication_type = 1; + dinput.indication_msg = &x2ap_buf[0]; + dinput.indication_msg_size = x2ap_buf_size; + res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput); + REQUIRE(res == true); + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + + // message processor + message_processor my_processor(ALL, false, 128); + + // admission control policy wrapper + admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false); + + // register the protector plugin with message processor + my_processor.register_protector(adm_plugin.get_protector_instance(0)); + + + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == E2AP_CONTROL_ERROR); + } + + SECTION("Trigger buffer related errors"){ + + data_size = BUFFER_SIZE; + dinput.indication_type = 1;// action_type; + dinput.indication_header = buf_header; + dinput.indication_header_size = buf_header_size; + + //all correct e2ap and x2ap + data_size = BUFFER_SIZE; + dinput.indication_type = 1; + dinput.indication_msg = &x2ap_buf[0]; + dinput.indication_msg_size = x2ap_buf_size; + res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput); + REQUIRE(res == true); + + rmr_message.mtype = RIC_INDICATION; + rmr_message.payload = &data[0]; + rmr_message.len = data_size; + + // message processor + message_processor my_processor(ALL, false, 106); + + // admission control policy wrapper + admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false); + + // register the protector plugin with message processor + my_processor.register_protector(adm_plugin.get_protector_instance(0)); + + + res = my_processor(&rmr_message); + REQUIRE(my_processor.get_state() == BUFFER_ERROR); + + + } + + delete[] data; + +}