Updated documentation for mock a1 tool
[ric-app/admin.git] / test / unit_test_message_processor.cc
1 /*
2 ==================================================================================
3
4         Copyright (c) 2018-2019 AT&T Intellectual Property.
5
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
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
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 ==================================================================================
18 */
19
20 /* Author : Ashwin Sridharan
21    Date   : Sept 2019
22 */
23
24 #define CATCH_CONFIG_MAIN
25 #include <catch2/catch.hpp>
26
27
28 #include <message_processor_class.hpp>
29 #include <admission_policy.hpp>
30
31 #define ASN_DEBUG 1
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"
35
36 #define BUFFER_SIZE 2<<15
37
38 bool report_mode_only = false;
39
40 void policy_stub(int mtype, const char *message, int msg_len,  std::string & response, bool atype){
41   // do nothing;
42 }
43
44 TEST_CASE("message processor functionality", "[acxapp]"){
45
46   mdclog_attr_t *attr;
47   mdclog_attr_init(&attr);
48   mdclog_attr_set_ident(attr, "UNIT TEST MESSAGE PROCESSOR ");
49   mdclog_init(attr);
50   mdclog_level_set(MDCLOG_DEBUG);
51   mdclog_attr_destroy(attr);
52
53   bool res;
54   e2sm_indication e2sm_indication_obj;
55   FILE *pfile;
56   
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;
64   
65    
66    unsigned char buf_header[32];
67    size_t buf_header_size = 32;
68    
69    // Encode the indication header
70    res = e2sm_indication_obj.encode_indication_header(&buf_header[0], &buf_header_size, indication_header);
71    REQUIRE(res == true);
72
73    
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);
80    
81    //==== e2ap indication
82    ric_indication_helper dinput ;   
83    dinput.action_id = 100;
84    dinput.func_id = 10;
85    dinput.indication_sn = 100;
86    dinput.req_id = 6;
87    dinput.req_seq_no = 11;   
88
89    //==== filler for incorrect x2ap
90    unsigned char * incorrect_x2ap;
91    size_t incorrect_x2ap_size;
92
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';
98    }
99    
100    
101    ric_indication indication_pdu;
102
103    // rmr buffer
104    rmr_mbuf_t rmr_message;
105    rmr_message.mtype = RIC_INDICATION;
106
107
108
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);
113
114    SECTION("Null Test cases when no handlers registered"){
115
116      
117      // message processor
118      message_processor my_processor;
119
120
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);
126
127
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);
133
134
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);
140
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);
146
147      
148    }
149    
150    
151    SECTION("Test various message types for all handlers registered in ALL mode"){
152
153      // message processor
154      message_processor my_processor(ALL, false);
155
156      // admission control policy wrapper
157      admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false);
158      
159      // register the protector plugin with message processor 
160      my_processor.register_protector(adm_plugin.get_protector_instance(0));
161
162
163      srand(112309);
164      
165      int num_cycles = 1;     
166      for(int i = 0; i < num_cycles;i ++){
167
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;
172        
173
174        //random injection of incorrect e2ap pdu
175        for(unsigned int i = 0; i < data_size; i++){
176          data[i] = rand()% 256 ;
177        }
178        
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);
184        
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;
192          }
193          
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);
200          
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);
206
207          delete[] incorrect_x2ap;
208        }
209
210        
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);
218        
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);
224        
225        
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;
231        
232        res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
233        REQUIRE(res == true);
234        
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);
240
241
242
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;
249
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);
259                             
260      }
261
262      
263
264    }
265    
266    SECTION("Test various messages in E2AP_PROC_ONLY mode"){
267
268
269      // message processor
270      message_processor my_processor(E2AP_PROC_ONLY);
271
272      // admission control policy wrapper
273      admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false);
274
275      
276      // register the protector plugin with message processor 
277      my_processor.register_protector(adm_plugin.get_protector_instance(0));
278
279
280      srand(112309);
281      
282      int num_cycles = 1;     
283      for(int i = 0; i < num_cycles;i ++){
284
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;
289        
290
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 ;
295        }
296        
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);
302        
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;
310          }
311          
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);
318          
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
324
325          delete[] incorrect_x2ap;
326        }
327
328        
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);
336        
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);
342        
343        
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;
349        
350        res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
351        REQUIRE(res == true);
352        
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
358
359      }
360
361      REQUIRE(adm_plugin.get_protector_instance(0)->get_requests() == 0);
362    }
363
364
365    SECTION("Test various messages in E2SM_PROC_ONLY mode"){
366
367
368      // message processor
369      message_processor my_processor(E2SM_PROC_ONLY);
370
371      // admission control policy wrapper
372      admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false);
373      
374      // register the protector plugin with message processor 
375      my_processor.register_protector(adm_plugin.get_protector_instance(0));
376
377
378      srand(112309);
379      
380      int num_cycles = 1;     
381      for(int i = 0; i < num_cycles;i ++){
382
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;
387        
388
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 ;
393        }
394        
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);
400        
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;
408          }
409          
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);
416          
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
422
423          delete[] incorrect_x2ap;
424        }
425
426        
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);
434        
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);
440        
441        
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;
447        
448        res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
449        REQUIRE(res == true);
450        
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); 
456
457      }
458
459      REQUIRE(adm_plugin.get_protector_instance(0)->get_requests() == 0);
460    }
461
462
463    SECTION("Test various message types for all handlers registered in ALL mode with response"){
464
465      // message processor
466      message_processor my_processor(ALL, false);
467
468      // admission control policy wrapper
469      admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false);
470
471      // subscription handler
472      subscription_handler sub_handler;
473      
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);
478
479      srand(112309);
480      
481      int num_cycles = 1;     
482      for(int i = 0; i < num_cycles;i ++){
483
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;
488        
489
490        //random injection of incorrect e2ap pdu
491        for(unsigned int i = 0; i < data_size; i++){
492          data[i] = rand()% 256 ;
493        }
494        
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);
500        
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;
508          }
509          
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);
516          
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);
522
523          delete[] incorrect_x2ap;
524        }
525
526        
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);
534        
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);
540        
541        
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;
547        
548        res = indication_pdu.encode_e2ap_indication(&data[0], &data_size, dinput);
549        REQUIRE(res == true);
550        
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);
556
557
558
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);
565
566
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);
573
574        // policy get
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);
580
581
582        // policy set
583      }
584
585      
586      REQUIRE(adm_plugin.get_protector_instance(0)->get_requests() == num_cycles);
587    }
588
589
590    SECTION("Trigger control low buffer related errors"){
591
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;
596        
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);
604
605      rmr_message.mtype = RIC_INDICATION;
606      rmr_message.payload = &data[0];
607      rmr_message.len = data_size;
608      
609      // message processor
610      message_processor my_processor(ALL, false, 128);
611
612      // admission control policy wrapper
613      admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false);
614      
615      // register the protector plugin with message processor 
616      my_processor.register_protector(adm_plugin.get_protector_instance(0));
617
618        
619      res = my_processor(&rmr_message);
620      REQUIRE(my_processor.get_state() == E2AP_CONTROL_ERROR);
621    }
622    
623    SECTION("Trigger buffer related errors"){
624        
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;
629        
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);
637
638      rmr_message.mtype = RIC_INDICATION;
639      rmr_message.payload = &data[0];
640      rmr_message.len = data_size;
641   
642      // message processor
643      message_processor my_processor(ALL, false, 106);
644
645      // admission control policy wrapper
646      admission adm_plugin(SCHEMA_FILE, SAMPLE_FILE, VES_FILE, 1, false);
647      
648      // register the protector plugin with message processor 
649      my_processor.register_protector(adm_plugin.get_protector_instance(0));
650
651        
652      res = my_processor(&rmr_message);
653      REQUIRE(my_processor.get_state() == BUFFER_ERROR);
654
655
656    }
657    
658    delete[] data;
659
660 }