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>
27 #include <NetworkProtector.h>
30 TEST_CASE("Protector Plugin", "Test Input types"){
34 mdclog_attr_init(&attr);
35 mdclog_attr_set_ident(attr, "UNIT TEST PROTECTOR PLUGIN ");
37 mdclog_level_set(MDCLOG_ERR);
38 mdclog_attr_destroy(attr);
41 unsigned char scratch_buf[512];
42 size_t scratch_buf_size = 512;
44 // Load buffers with different types of X2AP PDUs to test
45 // behaviour if valid/invalid
46 //========================================================
47 // valid x2 sgnb addition request
48 unsigned char x2ap_buf[256];
49 size_t x2ap_buf_size ;
50 pfile = fopen("test-data/X2AP-PDU-SgNBAdditionRequest.per", "r");
51 REQUIRE(pfile != NULL);
52 x2ap_buf_size = fread((char *)x2ap_buf, sizeof(char), 256, pfile);
58 unsigned char incorrect_x2ap_buf[8192];
59 size_t incorrect_x2ap_buf_size = 8192;
60 for(int i = 0; i < 8192; i++){
61 incorrect_x2ap_buf[i] = rand()%256;
64 // valid x2 but not an initiating message
65 unsigned char x2ap_sgnb_ack[512];
66 size_t x2ap_sgnb_ack_size;
67 pfile = fopen("test-data/X2AP-PDU-SgNBAdditionAck.per", "r");
68 REQUIRE(pfile != NULL);
69 x2ap_sgnb_ack_size = fread((char *)x2ap_sgnb_ack, sizeof(char), 512, pfile);
72 //valid x2 initiating message, but not sgnb addition request
73 unsigned char x2ap_resource_req_buf[512];
74 size_t x2ap_resource_req_buf_size;
75 pfile = fopen("test-data/X2AP-PDU-ResourceStatusRequest.per", "r");
76 REQUIRE(pfile != NULL);
77 x2ap_resource_req_buf_size = fread((char *)x2ap_resource_req_buf, sizeof(char), 512, pfile);
81 SECTION("Valid X2 SgnB Addition Request"){
82 protector n_plugin(false);
83 bool res = n_plugin(x2ap_buf, x2ap_buf_size, scratch_buf, &scratch_buf_size);
85 REQUIRE(n_plugin.get_requests(0) == 1);
87 // todo: need to validate response ...
88 // decode x2ap response
89 // verify it is a successful message and compare against input x2ap ..
93 SECTION("Invalid X2 message"){
94 protector n_plugin(1, 20, 5, 0, false);
95 bool res = n_plugin(incorrect_x2ap_buf, incorrect_x2ap_buf_size, scratch_buf, &scratch_buf_size);
96 REQUIRE(res == false);
97 REQUIRE(n_plugin.get_requests(0) == 0);
100 SECTION("Valid X2 but not Initating message"){
102 protector n_plugin(1, 20, 5, 0, false);
103 bool res = n_plugin(x2ap_sgnb_ack, x2ap_sgnb_ack_size, scratch_buf, &scratch_buf_size);
104 REQUIRE(res == false);
105 REQUIRE(n_plugin.get_requests(0) == 0);
109 SECTION("Valid X2 Initiating but not SgNB Addition Request"){
111 protector n_plugin(1, 20, 5, 0, false);
112 bool res = n_plugin(x2ap_resource_req_buf, x2ap_resource_req_buf_size, scratch_buf, &scratch_buf_size);
113 REQUIRE(res == false);
114 REQUIRE(n_plugin.get_requests(0) == 0);
118 SECTION("Cycle through various messages"){
119 int num_cycles = 1000;
121 protector n_plugin(1, 20, 5, 0, false);
124 for(int i = 0; i < num_cycles;i++){
125 scratch_buf_size = 512;
126 res = n_plugin(x2ap_buf, x2ap_buf_size, scratch_buf, &scratch_buf_size);
127 REQUIRE(res == true);
130 res = n_plugin(x2ap_sgnb_ack, x2ap_sgnb_ack_size, scratch_buf, &scratch_buf_size);
131 REQUIRE(res == false);
133 res = n_plugin(x2ap_resource_req_buf, x2ap_resource_req_buf_size, scratch_buf, &scratch_buf_size);
134 REQUIRE(res == false);
136 res = n_plugin(incorrect_x2ap_buf, incorrect_x2ap_buf_size, scratch_buf, &scratch_buf_size);
137 REQUIRE(res == false);
141 REQUIRE(num_valid == n_plugin.get_requests(0));
142 REQUIRE(num_valid == n_plugin.get_requests(-1));
143 REQUIRE(n_plugin.get_rejects(0) == 0);
150 SECTION("No blocking"){
152 int num_packets = 1000;
153 protector n_plugin(1, 20, 5, 0, false);
154 for(int i = 0; i < num_packets; i++){
155 res = n_plugin(x2ap_buf, x2ap_buf_size, scratch_buf, &scratch_buf_size);
156 REQUIRE(res == true);
159 REQUIRE(n_plugin.get_requests(0) == num_packets);
160 REQUIRE(n_plugin.get_rejects(0) == 0);
164 SECTION("All blocking"){
166 int num_packets = 1000;
167 protector n_plugin(1, 20, 0, 100, false);
168 for(int i = 0; i < num_packets; i++){
169 scratch_buf_size = 512;
170 res = n_plugin(x2ap_buf, x2ap_buf_size, scratch_buf, &scratch_buf_size);
171 REQUIRE(res == true);
174 REQUIRE(n_plugin.get_requests(0) == num_packets);
175 REQUIRE(n_plugin.get_rejects(0) == num_packets);
177 REQUIRE(n_plugin.get_requests(-1) == num_packets);
178 REQUIRE(n_plugin.get_rejects(-1) == num_packets);
181 SECTION("Add/delete/configure/query policies"){
184 std::vector<double> info;
185 std::vector<int> active_list;
187 protector n_plugin(1, 20, 0, 100, false);
189 // metrics query default policy always returns
190 REQUIRE(n_plugin.get_requests(0) == 0);
191 REQUIRE(n_plugin.get_rejects(0) == 0);
193 //metrics invalid policy returns -1;
194 REQUIRE(n_plugin.get_requests(100) == -1);
195 REQUIRE(n_plugin.get_rejects(100) == -1);
198 n_plugin.get_active_policies(active_list);
199 REQUIRE(active_list.size() == 1);
201 // verify returned policy
202 REQUIRE(n_plugin.is_active(active_list[0]) == true);
205 res = n_plugin.add_policy(1, 35, 10, 10, policy_id);
206 REQUIRE(res == true);
209 n_plugin.get_active_policies(active_list);
210 REQUIRE(active_list.size() == 2);
212 // query default policy
213 res = n_plugin.query_policy(0, info);
214 REQUIRE(res == true);
215 REQUIRE(info.size() == 4);
216 REQUIRE(info[0] == 1);
217 REQUIRE(info[1] == 20);
218 REQUIRE(info[2] == 0);
219 REQUIRE(info[3] == 100);
223 res = n_plugin.query_policy(policy_id, info);
224 REQUIRE(res == true);
225 REQUIRE(info.size() == 4);
226 REQUIRE(info[0] == 1);
227 REQUIRE(info[1] == 35);
228 REQUIRE(info[2] == 10);
229 REQUIRE(info[3] == 10);
231 // try adding same policy
232 res = n_plugin.add_policy(1, 200, 10, 10, policy_id);
233 REQUIRE(res == false);
234 REQUIRE_THAT(n_plugin.get_error(), Catch::Matchers::Contains("already exists"));
237 res = n_plugin.delete_policy(policy_id);
238 REQUIRE(res == true);
240 // delete non-existent policy
241 res = n_plugin.delete_policy(policy_id);
242 REQUIRE(res == false);
243 REQUIRE_THAT(n_plugin.get_error(), Catch::Matchers::Contains("No policy with id"));
245 // configure non-existent policy
246 res = n_plugin.configure(1, 20, 0, 100, policy_id);
247 REQUIRE(res == false);
249 // invalid window size to configure policy
250 res = n_plugin.configure(0, -1, 0, 100, 0);
251 REQUIRE(res == false);
252 REQUIRE_THAT(n_plugin.get_error(), Catch::Matchers::Contains("Illegal value for window"));
254 // invalid trigger in configure policy
255 res = n_plugin.configure(0, 12, -1, 100, 0);
256 REQUIRE(res == false);
257 REQUIRE_THAT(n_plugin.get_error(), Catch::Matchers::Contains("Illegal"));
259 // invalid class in configure policy
260 res = n_plugin.configure(0, 20, 1, 100, -25);
261 REQUIRE(res == false);
262 REQUIRE_THAT(n_plugin.get_error(), Catch::Matchers::Contains("Illegal"));
264 // invalid blocking rate in configure policy
265 res = n_plugin.configure(0, 21, 0, 105, 0);
266 REQUIRE(res == false);
267 REQUIRE_THAT(n_plugin.get_error(), Catch::Matchers::Contains("Illegal"));
270 // invalid window size in add policy
271 res = n_plugin.add_policy(0, -1, 0, 100, 25);
272 REQUIRE(res == false);
273 REQUIRE_THAT(n_plugin.get_error(), Catch::Matchers::Contains("Illegal"));
275 // invalid trigger in add policy
276 res = n_plugin.add_policy(0, 12, -1, 100, 25);
277 REQUIRE(res == false);
278 REQUIRE_THAT(n_plugin.get_error(), Catch::Matchers::Contains("Illegal"));
280 // invalid class in add policy
281 res = n_plugin.add_policy(0, 20, 1, 100, -25);
282 REQUIRE(res == false);
283 REQUIRE_THAT(n_plugin.get_error(), Catch::Matchers::Contains("Illegal"));
285 // invalid blocking rate in add policy
286 res = n_plugin.add_policy(0, 21, 0, 105, 25);
287 REQUIRE(res == false);
288 REQUIRE_THAT(n_plugin.get_error(), Catch::Matchers::Contains("Illegal"));
290 // query a non-existant policy
291 res = n_plugin.query_policy(200, info);
292 REQUIRE(res == false);
297 SECTION("Test turning enforcement on off "){
299 protector n_plugin(1, 20, 0, 100, false);
300 int num_packets = 10;
302 for(int i = 0; i < num_packets; i++){
303 scratch_buf_size = 512;
304 res = n_plugin(x2ap_buf, x2ap_buf_size, scratch_buf, &scratch_buf_size);
305 REQUIRE(res == true);
308 // enforcement with 100% blocking. all should be rejected
309 REQUIRE(n_plugin.get_requests(0) == num_packets);
310 REQUIRE(n_plugin.get_rejects(0) == num_packets);
313 REQUIRE(n_plugin.get_requests(0) == 0);
314 REQUIRE(n_plugin.get_rejects(0) == 0);
316 // no enforcement even if blocking set to 100%
317 // all should be accepted
318 n_plugin.configure(0, 20, 0, 100, 0);
319 for(int i = 0; i < num_packets; i++){
320 scratch_buf_size = 512;
321 res = n_plugin(x2ap_buf, x2ap_buf_size, scratch_buf, &scratch_buf_size);
322 REQUIRE(res == true);
325 REQUIRE(n_plugin.get_requests(0) == num_packets);
326 REQUIRE(n_plugin.get_rejects(0) == 0);
330 SECTION("Test using various policies against pdus with different subscriber profile ids"){
332 // use pre-generated X2AP PDUs with two different subscriber profile ids
333 unsigned char x2ap1_buf[512];
335 unsigned char x2ap2_buf[512];
338 pfile = fopen("test-data/X2AP-PDU-SgNBAdditionRequest_SubId_29.per", "r");
339 REQUIRE(pfile != NULL);
340 x2ap1_size = fread((char *)x2ap1_buf, sizeof(char), 512, pfile);
343 pfile = fopen("test-data/X2AP-PDU-SgNBAdditionRequest_SubId_34.per", "r");
344 REQUIRE(pfile != NULL);
345 x2ap2_size = fread((char *)x2ap2_buf, sizeof(char), 512, pfile);
350 protector n_plugin(1, 20, 0, 100, false);
351 // test with just default policy
352 scratch_buf_size = 512;
353 res = n_plugin(x2ap1_buf, x2ap1_size, scratch_buf, &scratch_buf_size);
354 REQUIRE(res == true);
355 scratch_buf_size = 512;
356 res = n_plugin(x2ap2_buf, x2ap2_size, scratch_buf, &scratch_buf_size);
357 REQUIRE(res == true);
358 REQUIRE(n_plugin.get_requests(0) == 2);
362 // add a policy and test
363 n_plugin.add_policy(1, 20, 0, 100, 29);
364 scratch_buf_size = 512;
365 res = n_plugin(x2ap1_buf, x2ap1_size, scratch_buf, &scratch_buf_size);
366 REQUIRE(res == true);
367 scratch_buf_size = 512;
368 res = n_plugin(x2ap2_buf, x2ap2_size, scratch_buf, &scratch_buf_size);
369 REQUIRE(res == true);
370 REQUIRE(n_plugin.get_requests(0) == 1);
371 REQUIRE(n_plugin.get_requests(29) == 1);
373 // add another policy and test
374 n_plugin.add_policy(1, 20, 0, 100, 34);
375 scratch_buf_size = 512;
376 res = n_plugin(x2ap2_buf, x2ap2_size, scratch_buf, &scratch_buf_size);
377 REQUIRE(res == true);
378 scratch_buf_size = 512;
379 res = n_plugin(x2ap1_buf, x2ap1_size, scratch_buf, &scratch_buf_size);
380 REQUIRE(res == true);
382 REQUIRE(n_plugin.get_requests(34) == 1);
383 REQUIRE(n_plugin.get_requests(29) == 2);
384 REQUIRE(n_plugin.get_requests(-1) == 4); // 1 for 0, 2 for 29 and 1 for 34