1. Transitioned to using latest asn1c compiler
[ric-app/admin.git] / test / unit_test_message_processor.cc
diff --git a/test/unit_test_message_processor.cc b/test/unit_test_message_processor.cc
new file mode 100644 (file)
index 0000000..f410e5b
--- /dev/null
@@ -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 <catch2/catch.hpp>
+
+
+#include <message_processor_class.hpp>
+#include <admission_policy.hpp>
+
+#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;
+
+}