2 ==================================================================================
4 Copyright (c) 2018-2019 AT&T Intellectual Property.
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 ==================================================================================
20 /* Author : Ashwin Sridharan
24 #define CATCH_CONFIG_MAIN
25 #include <catch2/catch.hpp>
28 #include <message_processor_class.hpp>
29 #include <admission_policy.hpp>
32 #define SCHEMA_FILE "../schemas/adm-ctrl-xapp-policy-schema.json"
33 #define SAMPLE_FILE "../schemas/samples.json"
34 #define VES_FILE "../schemas/ves_schema.json"
36 #define BUFFER_SIZE 2<<15
38 bool report_mode_only = false;
40 void policy_stub(int mtype, const char *message, int msg_len, std::string & response, bool atype){
44 TEST_CASE("message processor functionality", "[acxapp]"){
47 mdclog_attr_init(&attr);
48 mdclog_attr_set_ident(attr, "UNIT TEST MESSAGE PROCESSOR ");
50 mdclog_level_set(MDCLOG_DEBUG);
51 mdclog_attr_destroy(attr);
54 e2sm_indication e2sm_indication_obj;
57 //==== e2sm indication header : just some
58 // random fill for now
59 e2sm_header_helper indication_header;
60 indication_header.egNB_id="hello";
61 indication_header.plmn_id="there";
62 indication_header.interface_direction = 1;
63 indication_header.egNB_id_type = 2;
66 unsigned char buf_header[32];
67 size_t buf_header_size = 32;
69 // Encode the indication header
70 res = e2sm_indication_obj.encode_indication_header(&buf_header[0], &buf_header_size, indication_header);
74 //====== x2ap sgnb addition reuqest
75 unsigned char x2ap_buf[256];
76 size_t x2ap_buf_size = 256;
77 pfile = fopen("test-data/X2AP-PDU-SgNBAdditionRequest.per", "r");
78 REQUIRE(pfile != NULL);
79 x2ap_buf_size = fread((char *)x2ap_buf, sizeof(char), 256, pfile);
81 //==== e2ap indication
82 ric_indication_helper dinput ;
83 dinput.action_id = 100;
85 dinput.indication_sn = 100;
87 dinput.req_seq_no = 11;
89 //==== filler for incorrect x2ap
90 unsigned char * incorrect_x2ap;
91 size_t incorrect_x2ap_size;
93 // ====== mock incorrect e2sm header ...
94 unsigned char incorrect_e2sm_header[32];
95 size_t incorrect_e2sm_header_size = 32;
96 for(int i = 0; i < 32; i++){
97 incorrect_e2sm_header[i] = 'q';
101 ric_indication indication_pdu;
104 rmr_mbuf_t rmr_message;
105 rmr_message.mtype = RIC_INDICATION;
109 /* encoding pdu put here */
110 size_t data_size = BUFFER_SIZE;
111 unsigned char * data = new unsigned char[data_size];
112 assert(data != NULL);
114 SECTION("Null Test cases when no handlers registered"){
118 message_processor my_processor;
121 rmr_message.mtype = RIC_INDICATION;
122 rmr_message.payload = &data[0];
123 rmr_message.len = data_size;
124 my_processor(&rmr_message);
125 REQUIRE(my_processor.get_state() == MISSING_HANDLER_ERROR);
128 rmr_message.mtype = RIC_SUB_RESP;
129 rmr_message.payload = &data[0];
130 rmr_message.len = data_size;
131 res = my_processor(&rmr_message);
132 REQUIRE(my_processor.get_state() == MISSING_HANDLER_ERROR);
135 rmr_message.mtype = DC_ADM_INT_CONTROL;
136 rmr_message.payload = &data[0];
137 rmr_message.len = data_size;
138 res = my_processor(&rmr_message);
139 REQUIRE(my_processor.get_state() == MISSING_HANDLER_ERROR);
141 rmr_message.mtype = DC_ADM_GET_POLICY;
142 rmr_message.payload = &data[0];
143 rmr_message.len = data_size;
144 res = my_processor(&rmr_message);
145 REQUIRE(my_processor.get_state() == MISSING_HANDLER_ERROR);
151 SECTION("Test various message types for all handlers registered in ALL mode"){
154 message_processor my_processor(ALL, false);
156 // admission control policy wrapper
157 admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false);
159 // register the protector plugin with message processor
160 my_processor.register_protector(adm_plugin.get_protector_instance(0));
166 for(int i = 0; i < num_cycles;i ++){
168 data_size = BUFFER_SIZE;
169 dinput.indication_type = 1;// action_type;
170 dinput.indication_header = buf_header;
171 dinput.indication_header_size = buf_header_size;
174 //random injection of incorrect e2ap pdu
175 for(unsigned int i = 0; i < data_size; i++){
176 data[i] = rand()% 256 ;
179 rmr_message.mtype = RIC_INDICATION;
180 rmr_message.payload = &data[0];
181 rmr_message.len = data_size;
182 res = my_processor(&rmr_message);
183 REQUIRE(my_processor.get_state() == E2AP_INDICATION_ERROR);
185 //random injection of erroneous x2ap pdu
186 for(int k = 8; k <= 14; k++){
187 incorrect_x2ap_size = 2 << k;
188 incorrect_x2ap = new unsigned char[incorrect_x2ap_size];
189 assert(incorrect_x2ap != NULL);
190 for(unsigned int i = 0; i < incorrect_x2ap_size; i++){
191 incorrect_x2ap[i] = rand()%256;
194 data_size = BUFFER_SIZE;
195 dinput.indication_type = 1;
196 dinput.indication_msg = incorrect_x2ap;
197 dinput.indication_msg_size = incorrect_x2ap_size;
198 res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
199 REQUIRE(res == true);
201 rmr_message.mtype = RIC_INDICATION;
202 rmr_message.payload = &data[0];
203 rmr_message.len = data_size;
204 res = my_processor(&rmr_message);
205 REQUIRE(my_processor.get_state() == PLUGIN_ERROR);
207 delete[] incorrect_x2ap;
211 //all correct e2ap and x2ap
212 data_size = BUFFER_SIZE;
213 dinput.indication_type = 1;
214 dinput.indication_msg = &x2ap_buf[0];
215 dinput.indication_msg_size = x2ap_buf_size;
216 res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
217 REQUIRE(res == true);
219 rmr_message.mtype = RIC_INDICATION;
220 rmr_message.payload = &data[0];
221 rmr_message.len = data_size;
222 res = my_processor(&rmr_message);
223 REQUIRE(my_processor.get_state() == NO_ERROR);
226 //incorrect e2sm header
227 data_size = BUFFER_SIZE;
228 dinput.indication_type = 1;
229 dinput.indication_header = incorrect_e2sm_header;
230 dinput.indication_header_size = incorrect_e2sm_header_size;
232 res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
233 REQUIRE(res == true);
235 rmr_message.mtype = RIC_INDICATION;
236 rmr_message.payload = &data[0];
237 rmr_message.len = data_size;
238 res = my_processor(&rmr_message);
239 REQUIRE(my_processor.get_state() == E2SM_INDICATION_HEADER_ERROR);
243 // // fake buffer x2 size
244 std::cout <<"Trying corrupt message field size" << std::endl;
245 data_size = BUFFER_SIZE;
246 dinput.indication_type = 1;
247 dinput.indication_header = buf_header;
248 dinput.indication_header_size = buf_header_size;
250 dinput.indication_msg = &x2ap_buf[0];
251 dinput.indication_msg_size = rand()%128;
252 res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
253 REQUIRE(res == true);
254 rmr_message.mtype = RIC_INDICATION;
255 rmr_message.payload = &data[0];
256 rmr_message.len = 2<<20; // put a fake buffer size
257 res = my_processor(&rmr_message);
258 REQUIRE(my_processor.get_state() == RMR_ERROR);
266 SECTION("Test various messages in E2AP_PROC_ONLY mode"){
270 message_processor my_processor(E2AP_PROC_ONLY);
272 // admission control policy wrapper
273 admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false);
276 // register the protector plugin with message processor
277 my_processor.register_protector(adm_plugin.get_protector_instance(0));
283 for(int i = 0; i < num_cycles;i ++){
285 data_size = BUFFER_SIZE;
286 dinput.indication_type = 1;// action_type;
287 dinput.indication_header = buf_header;
288 dinput.indication_header_size = buf_header_size;
291 //random injection of incorrect e2ap pdu
292 //random injection of incorrect e2ap pdu
293 for(unsigned int i = 0; i < data_size; i++){
294 data[i] = rand()% 256 ;
297 rmr_message.mtype = RIC_INDICATION;
298 rmr_message.payload = &data[0];
299 rmr_message.len = data_size;
300 res = my_processor(&rmr_message);
301 REQUIRE(my_processor.get_state() == E2AP_INDICATION_ERROR);
303 //random injection of erroneous x2ap pdu
304 for(int k = 8; k <= 14; k++){
305 incorrect_x2ap_size = 2 << k;
306 incorrect_x2ap = new unsigned char[incorrect_x2ap_size];
307 assert(incorrect_x2ap != NULL);
308 for(unsigned int i = 0; i < incorrect_x2ap_size; i++){
309 incorrect_x2ap[i] = rand()%256;
312 data_size = BUFFER_SIZE;
313 dinput.indication_type = 1;
314 dinput.indication_msg = incorrect_x2ap;
315 dinput.indication_msg_size = incorrect_x2ap_size;
316 res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
317 REQUIRE(res == true);
319 rmr_message.mtype = RIC_INDICATION;
320 rmr_message.payload = &data[0];
321 rmr_message.len = data_size;
322 res = my_processor(&rmr_message);
323 REQUIRE(my_processor.get_state() == NO_ERROR); // since we don't process X2ap
325 delete[] incorrect_x2ap;
329 //all correct e2ap and x2ap
330 data_size = BUFFER_SIZE;
331 dinput.indication_type = 1;
332 dinput.indication_msg = &x2ap_buf[0];
333 dinput.indication_msg_size = x2ap_buf_size;
334 res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
335 REQUIRE(res == true);
337 rmr_message.mtype = RIC_INDICATION;
338 rmr_message.payload = &data[0];
339 rmr_message.len = data_size;
340 res = my_processor(&rmr_message);
341 REQUIRE(my_processor.get_state() == NO_ERROR);
344 //incorrect e2sm header
345 data_size = BUFFER_SIZE;
346 dinput.indication_type = 1;
347 dinput.indication_header = incorrect_e2sm_header;
348 dinput.indication_header_size = incorrect_e2sm_header_size;
350 res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
351 REQUIRE(res == true);
353 rmr_message.mtype = RIC_INDICATION;
354 rmr_message.payload = &data[0];
355 rmr_message.len = data_size;
356 res = my_processor(&rmr_message);
357 REQUIRE(my_processor.get_state() == NO_ERROR); // since we don't process e2sm
361 REQUIRE(adm_plugin.get_protector_instance(0)->get_requests() == 0);
365 SECTION("Test various messages in E2SM_PROC_ONLY mode"){
369 message_processor my_processor(E2SM_PROC_ONLY);
371 // admission control policy wrapper
372 admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false);
374 // register the protector plugin with message processor
375 my_processor.register_protector(adm_plugin.get_protector_instance(0));
381 for(int i = 0; i < num_cycles;i ++){
383 data_size = BUFFER_SIZE;
384 dinput.indication_type = 1;// action_type;
385 dinput.indication_header = buf_header;
386 dinput.indication_header_size = buf_header_size;
389 //random injection of incorrect e2ap pdu
390 //random injection of incorrect e2ap pdu
391 for(unsigned int i = 0; i < data_size; i++){
392 data[i] = rand()% 256 ;
395 rmr_message.mtype = RIC_INDICATION;
396 rmr_message.payload = &data[0];
397 rmr_message.len = data_size;
398 res = my_processor(&rmr_message);
399 REQUIRE(my_processor.get_state() == E2AP_INDICATION_ERROR);
401 //random injection of erroneous x2ap pdu
402 for(int k = 8; k <= 14; k++){
403 incorrect_x2ap_size = 2 << k;
404 incorrect_x2ap = new unsigned char[incorrect_x2ap_size];
405 assert(incorrect_x2ap != NULL);
406 for(unsigned int i = 0; i < incorrect_x2ap_size; i++){
407 incorrect_x2ap[i] = rand()%256;
410 data_size = BUFFER_SIZE;
411 dinput.indication_type = 1;
412 dinput.indication_msg = incorrect_x2ap;
413 dinput.indication_msg_size = incorrect_x2ap_size;
414 res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
415 REQUIRE(res == true);
417 rmr_message.mtype = RIC_INDICATION;
418 rmr_message.payload = &data[0];
419 rmr_message.len = data_size;
420 res = my_processor(&rmr_message);
421 REQUIRE(my_processor.get_state() == NO_ERROR); // since we don't process X2ap
423 delete[] incorrect_x2ap;
427 //all correct e2ap and x2ap
428 data_size = BUFFER_SIZE;
429 dinput.indication_type = 1;
430 dinput.indication_msg = &x2ap_buf[0];
431 dinput.indication_msg_size = x2ap_buf_size;
432 res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
433 REQUIRE(res == true);
435 rmr_message.mtype = RIC_INDICATION;
436 rmr_message.payload = &data[0];
437 rmr_message.len = data_size;
438 res = my_processor(&rmr_message);
439 REQUIRE(my_processor.get_state() == NO_ERROR);
442 //incorrect e2sm header
443 data_size = BUFFER_SIZE;
444 dinput.indication_type = 1;
445 dinput.indication_header = incorrect_e2sm_header;
446 dinput.indication_header_size = incorrect_e2sm_header_size;
448 res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
449 REQUIRE(res == true);
451 rmr_message.mtype = RIC_INDICATION;
452 rmr_message.payload = &data[0];
453 rmr_message.len = data_size;
454 res = my_processor(&rmr_message);
455 REQUIRE(my_processor.get_state() == E2SM_INDICATION_HEADER_ERROR);
459 REQUIRE(adm_plugin.get_protector_instance(0)->get_requests() == 0);
463 SECTION("Test various message types for all handlers registered in ALL mode with response"){
466 message_processor my_processor(ALL, false);
468 // admission control policy wrapper
469 admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false);
471 // subscription handler
472 subscription_handler sub_handler;
474 // register the protector plugin with message processor
475 my_processor.register_protector(adm_plugin.get_protector_instance(0));
476 my_processor.register_policy_handler(policy_stub);
477 my_processor.register_subscription_handler(&sub_handler);
482 for(int i = 0; i < num_cycles;i ++){
484 data_size = BUFFER_SIZE;
485 dinput.indication_type = 1;// action_type;
486 dinput.indication_header = buf_header;
487 dinput.indication_header_size = buf_header_size;
490 //random injection of incorrect e2ap pdu
491 for(unsigned int i = 0; i < data_size; i++){
492 data[i] = rand()% 256 ;
495 rmr_message.mtype = RIC_INDICATION;
496 rmr_message.payload = &data[0];
497 rmr_message.len = data_size;
498 res = my_processor(&rmr_message);
499 REQUIRE(my_processor.get_state() == E2AP_INDICATION_ERROR);
501 //random injection of erroneous x2ap pdu
502 for(int k = 8; k <= 14; k++){
503 incorrect_x2ap_size = 2 << k;
504 incorrect_x2ap = new unsigned char[incorrect_x2ap_size];
505 assert(incorrect_x2ap != NULL);
506 for(unsigned int i = 0; i < incorrect_x2ap_size; i++){
507 incorrect_x2ap[i] = rand()%256;
510 data_size = BUFFER_SIZE;
511 dinput.indication_type = 1;
512 dinput.indication_msg = incorrect_x2ap;
513 dinput.indication_msg_size = incorrect_x2ap_size;
514 res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
515 REQUIRE(res == true);
517 rmr_message.mtype = RIC_INDICATION;
518 rmr_message.payload = &data[0];
519 rmr_message.len = data_size;
520 res = my_processor(&rmr_message);
521 REQUIRE(my_processor.get_state() == PLUGIN_ERROR);
523 delete[] incorrect_x2ap;
527 //all correct e2ap and x2ap
528 data_size = BUFFER_SIZE;
529 dinput.indication_type = 1;
530 dinput.indication_msg = &x2ap_buf[0];
531 dinput.indication_msg_size = x2ap_buf_size;
532 res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
533 REQUIRE(res == true);
535 rmr_message.mtype = RIC_INDICATION;
536 rmr_message.payload = &data[0];
537 rmr_message.len = data_size;
538 res = my_processor(&rmr_message);
539 REQUIRE(my_processor.get_state() == NO_ERROR);
542 //incorrect e2sm header
543 data_size = BUFFER_SIZE;
544 dinput.indication_type = 1;
545 dinput.indication_header = incorrect_e2sm_header;
546 dinput.indication_header_size = incorrect_e2sm_header_size;
548 res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
549 REQUIRE(res == true);
551 rmr_message.mtype = RIC_INDICATION;
552 rmr_message.payload = &data[0];
553 rmr_message.len = data_size;
554 res = my_processor(&rmr_message);
555 REQUIRE(my_processor.get_state() == E2SM_INDICATION_HEADER_ERROR);
559 // // rmr buffer size
560 rmr_message.mtype = RIC_INDICATION;
561 rmr_message.payload = &data[0];
562 rmr_message.len = 2 << 20; // put a fake buffer size
563 res = my_processor(&rmr_message);
564 REQUIRE(my_processor.get_state() == RMR_ERROR);
567 // subscription response
568 rmr_message.mtype = RIC_SUB_RESP;
569 rmr_message.payload = &data[0];
570 rmr_message.len = data_size;
571 res = my_processor(&rmr_message);
572 REQUIRE(my_processor.get_state() == NO_ERROR);
575 rmr_message.mtype = DC_ADM_GET_POLICY;
576 rmr_message.payload = &data[0];
577 rmr_message.len = data_size;
578 res = my_processor(&rmr_message);
579 REQUIRE(my_processor.get_state() == NO_ERROR);
586 REQUIRE(adm_plugin.get_protector_instance(0)->get_requests() == num_cycles);
590 SECTION("Trigger control low buffer related errors"){
592 data_size = BUFFER_SIZE;
593 dinput.indication_type = 1;// action_type;
594 dinput.indication_header = buf_header;
595 dinput.indication_header_size = buf_header_size;
597 //all correct e2ap and x2ap
598 data_size = BUFFER_SIZE;
599 dinput.indication_type = 1;
600 dinput.indication_msg = &x2ap_buf[0];
601 dinput.indication_msg_size = x2ap_buf_size;
602 res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
603 REQUIRE(res == true);
605 rmr_message.mtype = RIC_INDICATION;
606 rmr_message.payload = &data[0];
607 rmr_message.len = data_size;
610 message_processor my_processor(ALL, false, 128);
612 // admission control policy wrapper
613 admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false);
615 // register the protector plugin with message processor
616 my_processor.register_protector(adm_plugin.get_protector_instance(0));
619 res = my_processor(&rmr_message);
620 REQUIRE(my_processor.get_state() == E2AP_CONTROL_ERROR);
623 SECTION("Trigger buffer related errors"){
625 data_size = BUFFER_SIZE;
626 dinput.indication_type = 1;// action_type;
627 dinput.indication_header = buf_header;
628 dinput.indication_header_size = buf_header_size;
630 //all correct e2ap and x2ap
631 data_size = BUFFER_SIZE;
632 dinput.indication_type = 1;
633 dinput.indication_msg = &x2ap_buf[0];
634 dinput.indication_msg_size = x2ap_buf_size;
635 res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
636 REQUIRE(res == true);
638 rmr_message.mtype = RIC_INDICATION;
639 rmr_message.payload = &data[0];
640 rmr_message.len = data_size;
643 message_processor my_processor(ALL, false, 106);
645 // admission control policy wrapper
646 admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false);
648 // register the protector plugin with message processor
649 my_processor.register_protector(adm_plugin.get_protector_instance(0));
652 res = my_processor(&rmr_message);
653 REQUIRE(my_processor.get_state() == BUFFER_ERROR);