]> git.proxmox.com Git - mirror_frr.git/blob - pceplib/test/pcep_session_logic_states_test.c
*: Fix doesnt spelling mistakes
[mirror_frr.git] / pceplib / test / pcep_session_logic_states_test.c
1 /*
2 * This file is part of the PCEPlib, a PCEP protocol library.
3 *
4 * Copyright (C) 2020 Volta Networks https://voltanet.io/
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 *
19 * Author : Brady Johnson <brady@voltanet.io>
20 *
21 */
22
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <assert.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include <CUnit/CUnit.h>
33
34 #include "pcep_socket_comm_mock.h"
35 #include "pcep_session_logic.h"
36 #include "pcep_session_logic_internals.h"
37 #include "pcep_timers.h"
38 #include "pcep_utils_ordered_list.h"
39 #include "pcep_utils_double_linked_list.h"
40 #include "pcep_utils_memory.h"
41 #include "pcep_msg_objects.h"
42 #include "pcep_msg_tools.h"
43 #include "pcep_session_logic_states_test.h"
44
45 /* Functions being tested */
46 extern pcep_session_logic_handle *session_logic_handle_;
47 extern pcep_event_queue *session_logic_event_queue_;
48
49 static pcep_session_event event;
50 static pcep_session session;
51 /* A message list is a dll of struct pcep_messages_list_node items */
52 static double_linked_list *msg_list;
53 struct pcep_message *message;
54 static bool free_msg_list;
55 static bool msg_enqueued;
56 /* Forward declaration */
57 void destroy_message_for_test(void);
58 void create_message_for_test(uint8_t msg_type, bool free_msg_list_at_teardown,
59 bool was_msg_enqueued);
60 void test_handle_timer_event_open_keep_alive(void);
61
62 /*
63 * Test suite setup and teardown called before AND after the test suite.
64 */
65
66 int pcep_session_logic_states_test_suite_setup(void)
67 {
68 pceplib_memory_reset();
69 return 0;
70 }
71
72 int pcep_session_logic_states_test_suite_teardown(void)
73 {
74 printf("\n");
75 pceplib_memory_dump();
76 return 0;
77 }
78
79 /*
80 * Test case setup and teardown called before AND after each test.
81 */
82
83 void pcep_session_logic_states_test_setup()
84 {
85 session_logic_handle_ = pceplib_malloc(
86 PCEPLIB_INFRA, sizeof(pcep_session_logic_handle));
87 memset(session_logic_handle_, 0, sizeof(pcep_session_logic_handle));
88
89 session_logic_event_queue_ =
90 pceplib_malloc(PCEPLIB_INFRA, sizeof(pcep_event_queue));
91 memset(session_logic_event_queue_, 0, sizeof(pcep_event_queue));
92 session_logic_event_queue_->event_queue = queue_initialize();
93
94 memset(&session, 0, sizeof(pcep_session));
95 session.pcc_config.keep_alive_seconds = 5;
96 session.pcc_config.keep_alive_pce_negotiated_timer_seconds = 5;
97 session.pcc_config.min_keep_alive_seconds = 1;
98 session.pcc_config.max_keep_alive_seconds = 10;
99 session.pcc_config.dead_timer_seconds = 5;
100 session.pcc_config.dead_timer_pce_negotiated_seconds = 5;
101 session.pcc_config.min_dead_timer_seconds = 1;
102 session.pcc_config.max_dead_timer_seconds = 10;
103 session.pcc_config.max_unknown_messages = 2;
104 memcpy(&session.pce_config, &session.pcc_config,
105 sizeof(pcep_configuration));
106 session.num_unknown_messages_time_queue = queue_initialize();
107
108 memset(&event, 0, sizeof(pcep_session_event));
109 event.socket_closed = false;
110 event.session = &session;
111
112 setup_mock_socket_comm_info();
113 free_msg_list = false;
114 msg_enqueued = false;
115 }
116
117
118 void pcep_session_logic_states_test_teardown()
119 {
120 destroy_message_for_test();
121 pceplib_free(PCEPLIB_INFRA, session_logic_handle_);
122 queue_destroy(session_logic_event_queue_->event_queue);
123 pceplib_free(PCEPLIB_INFRA, session_logic_event_queue_);
124 session_logic_handle_ = NULL;
125 session_logic_event_queue_ = NULL;
126 queue_destroy_with_data(session.num_unknown_messages_time_queue);
127 teardown_mock_socket_comm_info();
128 }
129
130 void create_message_for_test(uint8_t msg_type, bool free_msg_list_at_teardown,
131 bool was_msg_enqueued)
132 {
133 /* See the comments in destroy_message_for_test() about these 2
134 * variables */
135 free_msg_list = free_msg_list_at_teardown;
136 msg_enqueued = was_msg_enqueued;
137
138 message = pceplib_malloc(PCEPLIB_MESSAGES, sizeof(struct pcep_message));
139 memset(message, 0, sizeof(struct pcep_message));
140
141 message->msg_header = pceplib_malloc(
142 PCEPLIB_MESSAGES, sizeof(struct pcep_message_header));
143 memset(message->msg_header, 0, sizeof(struct pcep_message_header));
144 message->obj_list = dll_initialize();
145 message->msg_header->type = msg_type;
146
147 msg_list = dll_initialize();
148 dll_append(msg_list, message);
149 event.received_msg_list = msg_list;
150 }
151
152 void destroy_message_for_test()
153 {
154 /* Some test cases internally free the message list, so we dont
155 * want to double free it */
156 if (free_msg_list == true) {
157 /* This will destroy both the msg_list and the obj_list */
158 pcep_msg_free_message_list(msg_list);
159 }
160
161 /* Some tests cause the message to be enqueued and dont delete it,
162 * so we have to delete it here */
163 if (msg_enqueued == true) {
164 pcep_msg_free_message(message);
165 }
166 }
167
168 /*
169 * Test cases
170 */
171
172 void test_handle_timer_event_dead_timer()
173 {
174 /* Dead Timer expired */
175 event.expired_timer_id = session.timer_id_dead_timer = 100;
176
177 handle_timer_event(&event);
178
179 CU_ASSERT_EQUAL(session.timer_id_dead_timer, TIMER_ID_NOT_SET);
180 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_INITIALIZED);
181 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
182 1);
183
184 pcep_event *e = queue_dequeue(session_logic_event_queue_->event_queue);
185 CU_ASSERT_EQUAL(PCE_DEAD_TIMER_EXPIRED, e->event_type);
186 pceplib_free(PCEPLIB_INFRA, e);
187
188 /* verify_socket_comm_times_called(
189 * initialized, teardown, connect, send_message, close_after_write,
190 * close, destroy); */
191 verify_socket_comm_times_called(0, 0, 0, 1, 1, 0, 0);
192 }
193
194
195 void test_handle_timer_event_keep_alive()
196 {
197 /* Keep Alive timer expired */
198 event.expired_timer_id = session.timer_id_keep_alive = 200;
199
200 handle_timer_event(&event);
201
202 CU_ASSERT_EQUAL(session.timer_id_keep_alive, TIMER_ID_NOT_SET);
203 verify_socket_comm_times_called(0, 0, 0, 1, 0, 0, 0);
204 }
205
206
207 void test_handle_timer_event_open_keep_wait()
208 {
209 /* Open Keep Wait timer expired */
210 event.expired_timer_id = session.timer_id_open_keep_wait = 300;
211 session.session_state = SESSION_STATE_PCEP_CONNECTING;
212 handle_timer_event(&event);
213
214 CU_ASSERT_EQUAL(session.timer_id_open_keep_wait, TIMER_ID_NOT_SET);
215 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_INITIALIZED);
216 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
217 1);
218 verify_socket_comm_times_called(0, 0, 0, 0, 1, 0, 0);
219
220 pcep_event *e = queue_dequeue(session_logic_event_queue_->event_queue);
221 CU_ASSERT_EQUAL(PCE_OPEN_KEEP_WAIT_TIMER_EXPIRED, e->event_type);
222 pceplib_free(PCEPLIB_INFRA, e);
223
224 /* If the state is not SESSION_STATE_PCEP_CONNECTED, then nothing should
225 * happen */
226 reset_mock_socket_comm_info();
227 session.session_state = SESSION_STATE_UNKNOWN;
228 event.expired_timer_id = session.timer_id_open_keep_wait = 300;
229 handle_timer_event(&event);
230
231 CU_ASSERT_EQUAL(session.timer_id_open_keep_wait, 300);
232 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_UNKNOWN);
233 verify_socket_comm_times_called(0, 0, 0, 0, 0, 0, 0);
234 }
235
236
237 void test_handle_timer_event_open_keep_alive()
238 {
239 /* Open Keep Alive timer expired, but the Keep Alive should not be sent
240 * since the PCE Open has not been received yet */
241 event.expired_timer_id = session.timer_id_open_keep_alive = 300;
242 session.session_state = SESSION_STATE_PCEP_CONNECTING;
243 session.pce_open_keep_alive_sent = false;
244 session.pce_open_received = false;
245 handle_timer_event(&event);
246
247 CU_ASSERT_EQUAL(session.timer_id_open_keep_alive, TIMER_ID_NOT_SET);
248 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_PCEP_CONNECTING);
249 CU_ASSERT_FALSE(session.pce_open_keep_alive_sent);
250
251 /* Open Keep Alive timer expired, the Keep Alive should be sent,
252 * but the session should not be connected, since the PCC Open
253 * has not been accepted yet */
254 event.expired_timer_id = session.timer_id_open_keep_alive = 300;
255 session.session_state = SESSION_STATE_PCEP_CONNECTING;
256 session.pce_open_keep_alive_sent = false;
257 session.pce_open_received = true;
258 session.pce_open_rejected = false;
259 session.pcc_open_accepted = false;
260 handle_timer_event(&event);
261
262 CU_ASSERT_EQUAL(session.timer_id_open_keep_alive, TIMER_ID_NOT_SET);
263 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_PCEP_CONNECTING);
264 CU_ASSERT_TRUE(session.pce_open_keep_alive_sent);
265
266 /* Open Keep Alive timer expired, the Keep Alive should be sent,
267 * and the session is connected */
268 event.expired_timer_id = session.timer_id_open_keep_alive = 300;
269 session.session_state = SESSION_STATE_PCEP_CONNECTING;
270 session.pce_open_keep_alive_sent = false;
271 session.pce_open_received = true;
272 session.pce_open_rejected = false;
273 session.pcc_open_accepted = true;
274 handle_timer_event(&event);
275
276 CU_ASSERT_EQUAL(session.timer_id_open_keep_alive, TIMER_ID_NOT_SET);
277 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_PCEP_CONNECTED);
278 CU_ASSERT_FALSE(session.pce_open_keep_alive_sent);
279 }
280
281
282 void test_handle_socket_comm_event_null_params()
283 {
284 /* Verify it doesn't core dump */
285 handle_socket_comm_event(NULL);
286 verify_socket_comm_times_called(0, 0, 0, 0, 0, 0, 0);
287 reset_mock_socket_comm_info();
288
289 event.received_msg_list = NULL;
290 handle_socket_comm_event(&event);
291 verify_socket_comm_times_called(0, 0, 0, 0, 0, 0, 0);
292 }
293
294
295 void test_handle_socket_comm_event_close()
296 {
297 event.socket_closed = true;
298 handle_socket_comm_event(&event);
299
300 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_INITIALIZED);
301 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
302 1);
303 verify_socket_comm_times_called(0, 0, 0, 0, 0, 1, 0);
304
305 pcep_event *e = queue_dequeue(session_logic_event_queue_->event_queue);
306 CU_ASSERT_EQUAL(PCE_CLOSED_SOCKET, e->event_type);
307 pceplib_free(PCEPLIB_INFRA, e);
308 }
309
310
311 void test_handle_socket_comm_event_open()
312 {
313 /*
314 * Test when a PCE Open is received, but the PCC Open has not been
315 * accepted yet
316 */
317 create_message_for_test(PCEP_TYPE_OPEN, false, true);
318 struct pcep_object_open *open_object =
319 pcep_obj_create_open(1, 1, 1, NULL);
320 dll_append(message->obj_list, open_object);
321 session.pcc_open_accepted = false;
322 session.pce_open_received = false;
323 session.pce_open_accepted = false;
324 session.timer_id_open_keep_alive = 100;
325 session.session_state = SESSION_STATE_PCEP_CONNECTING;
326
327 handle_socket_comm_event(&event);
328
329 CU_ASSERT_TRUE(session.pce_open_received);
330 CU_ASSERT_TRUE(session.pce_open_accepted);
331 CU_ASSERT_FALSE(session.pce_open_rejected);
332 CU_ASSERT_FALSE(session.pce_open_keep_alive_sent);
333 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_PCEP_CONNECTING);
334 CU_ASSERT_NOT_EQUAL(session.timer_id_open_keep_alive, 100);
335 /* A keep alive response should NOT be sent yet */
336 verify_socket_comm_times_called(0, 0, 0, 0, 0, 0, 0);
337 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
338 1);
339 pcep_event *e = queue_dequeue(session_logic_event_queue_->event_queue);
340 CU_ASSERT_EQUAL(MESSAGE_RECEIVED, e->event_type);
341 CU_ASSERT_EQUAL(PCEP_TYPE_OPEN, e->message->msg_header->type);
342 pceplib_free(PCEPLIB_INFRA, e);
343 destroy_message_for_test();
344
345 /*
346 * Test when a PCE Open is received, and the PCC Open has been accepted
347 */
348 create_message_for_test(PCEP_TYPE_OPEN, false, true);
349 reset_mock_socket_comm_info();
350 open_object = pcep_obj_create_open(1, 1, 1, NULL);
351 dll_append(message->obj_list, open_object);
352 session.pcc_open_accepted = true;
353 session.pce_open_received = false;
354 session.pce_open_accepted = false;
355 session.session_state = SESSION_STATE_PCEP_CONNECTING;
356
357 handle_socket_comm_event(&event);
358
359 CU_ASSERT_TRUE(session.pce_open_received);
360 CU_ASSERT_TRUE(session.pce_open_accepted);
361 CU_ASSERT_FALSE(session.pce_open_rejected);
362 CU_ASSERT_TRUE(session.pce_open_keep_alive_sent);
363 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_PCEP_CONNECTED);
364 /* A keep alive response should be sent, accepting the Open */
365 verify_socket_comm_times_called(0, 0, 0, 1, 0, 0, 0);
366 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
367 2);
368 e = queue_dequeue(session_logic_event_queue_->event_queue);
369 CU_ASSERT_EQUAL(MESSAGE_RECEIVED, e->event_type);
370 CU_ASSERT_EQUAL(PCEP_TYPE_OPEN, e->message->msg_header->type);
371 pceplib_free(PCEPLIB_INFRA, e);
372 e = queue_dequeue(session_logic_event_queue_->event_queue);
373 CU_ASSERT_EQUAL(PCC_CONNECTED_TO_PCE, e->event_type);
374 pceplib_free(PCEPLIB_INFRA, e);
375 destroy_message_for_test();
376
377 /*
378 * Send a 2nd Open, an error should be sent
379 */
380 create_message_for_test(PCEP_TYPE_OPEN, false, false);
381 reset_mock_socket_comm_info();
382 mock_socket_comm_info *mock_info = get_mock_socket_comm_info();
383 mock_info->send_message_save_message = true;
384
385 handle_socket_comm_event(&event);
386
387 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
388 0);
389 verify_socket_comm_times_called(0, 0, 0, 1, 0, 0, 0);
390 /* What gets saved in the mock is the msg byte buffer. The msg struct
391 * was deleted when it was sent. Instead of inspecting the msg byte
392 * buffer, lets just decode it. */
393 uint8_t *encoded_msg =
394 dll_delete_first_node(mock_info->sent_message_list);
395 CU_ASSERT_PTR_NOT_NULL(encoded_msg);
396 struct pcep_message *msg = pcep_decode_message(encoded_msg);
397 CU_ASSERT_PTR_NOT_NULL(msg);
398 assert(msg != NULL);
399 CU_ASSERT_EQUAL(PCEP_TYPE_ERROR, msg->msg_header->type);
400 /* Verify the error object */
401 CU_ASSERT_EQUAL(1, msg->obj_list->num_entries);
402 struct pcep_object_error *error_obj = msg->obj_list->head->data;
403 CU_ASSERT_EQUAL(PCEP_OBJ_CLASS_ERROR, error_obj->header.object_class);
404 CU_ASSERT_EQUAL(PCEP_OBJ_TYPE_ERROR, error_obj->header.object_type);
405 CU_ASSERT_EQUAL(PCEP_ERRT_ATTEMPT_TO_ESTABLISH_2ND_PCEP_SESSION,
406 error_obj->error_type);
407 CU_ASSERT_EQUAL(PCEP_ERRV_RECVD_INVALID_OPEN_MSG,
408 error_obj->error_value);
409 pcep_msg_free_message(msg);
410 pceplib_free(PCEPLIB_MESSAGES, encoded_msg);
411 }
412
413
414 void test_handle_socket_comm_event_open_error()
415 {
416 /* Test when the PCE rejects the PCC Open with an Error
417 * that a "corrected" Open message is sent. */
418
419 create_message_for_test(PCEP_TYPE_ERROR, false, true);
420 struct pcep_object_error *error_object = pcep_obj_create_error(
421 PCEP_ERRT_SESSION_FAILURE, PCEP_ERRV_UNACCEPTABLE_OPEN_MSG_NEG);
422 struct pcep_object_open *error_open_object =
423 pcep_obj_create_open(1, 1, 1, NULL);
424 /* The configured [Keep-alive, Dead-timer] values are [5, 5],
425 * this error open object will request they be changed to [10, 10] */
426 error_open_object->open_keepalive = 10;
427 error_open_object->open_deadtimer = 10;
428 dll_append(message->obj_list, error_object);
429 dll_append(message->obj_list, error_open_object);
430 session.session_state = SESSION_STATE_PCEP_CONNECTING;
431 mock_socket_comm_info *mock_info = get_mock_socket_comm_info();
432 mock_info->send_message_save_message = true;
433
434 handle_socket_comm_event(&event);
435
436 CU_ASSERT_TRUE(session.pcc_open_rejected);
437 CU_ASSERT_FALSE(session.pce_open_keep_alive_sent);
438 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_PCEP_CONNECTING);
439 /* Another Open should be sent */
440 verify_socket_comm_times_called(0, 0, 0, 1, 0, 0, 0);
441 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
442 2);
443
444 pcep_event *e = queue_dequeue(session_logic_event_queue_->event_queue);
445 CU_ASSERT_EQUAL(PCC_SENT_INVALID_OPEN, e->event_type);
446 pceplib_free(PCEPLIB_INFRA, e);
447
448 e = queue_dequeue(session_logic_event_queue_->event_queue);
449 CU_ASSERT_EQUAL(MESSAGE_RECEIVED, e->event_type);
450 CU_ASSERT_EQUAL(PCEP_TYPE_ERROR, e->message->msg_header->type);
451 pceplib_free(PCEPLIB_INFRA, e);
452
453 /* Check the Corrected Open Message */
454
455 /* What gets saved in the mock is the msg byte buffer. The msg struct
456 * was deleted when it was sent. Instead of inspecting the msg byte
457 * buffer, lets just decode it. */
458 uint8_t *encoded_msg =
459 dll_delete_first_node(mock_info->sent_message_list);
460 CU_ASSERT_PTR_NOT_NULL(encoded_msg);
461 assert(encoded_msg != NULL);
462 struct pcep_message *open_msg_corrected =
463 pcep_decode_message(encoded_msg);
464 CU_ASSERT_PTR_NOT_NULL(open_msg_corrected);
465 struct pcep_object_open *open_object_corrected =
466 (struct pcep_object_open *)pcep_obj_get(
467 open_msg_corrected->obj_list, PCEP_OBJ_CLASS_OPEN);
468 CU_ASSERT_PTR_NOT_NULL(open_object_corrected);
469 assert(open_object_corrected != NULL);
470 /* Verify the Keep-alive and Dead timers have been negotiated */
471 CU_ASSERT_EQUAL(error_open_object->open_keepalive,
472 open_object_corrected->open_keepalive);
473 CU_ASSERT_EQUAL(error_open_object->open_deadtimer,
474 open_object_corrected->open_deadtimer);
475 CU_ASSERT_EQUAL(session.pcc_config.dead_timer_pce_negotiated_seconds,
476 open_object_corrected->open_deadtimer);
477 CU_ASSERT_EQUAL(
478 session.pcc_config.keep_alive_pce_negotiated_timer_seconds,
479 open_object_corrected->open_keepalive);
480 CU_ASSERT_NOT_EQUAL(
481 session.pcc_config.dead_timer_pce_negotiated_seconds,
482 session.pcc_config.dead_timer_seconds);
483 CU_ASSERT_NOT_EQUAL(
484 session.pcc_config.keep_alive_pce_negotiated_timer_seconds,
485 session.pcc_config.keep_alive_seconds);
486
487 pcep_msg_free_message(open_msg_corrected);
488 pceplib_free(PCEPLIB_MESSAGES, encoded_msg);
489 }
490
491
492 void test_handle_socket_comm_event_keep_alive()
493 {
494 /* Test when a Keep Alive is received, but the PCE Open has not been
495 * received yet */
496 create_message_for_test(PCEP_TYPE_KEEPALIVE, false, false);
497 session.session_state = SESSION_STATE_PCEP_CONNECTING;
498 session.timer_id_dead_timer = 100;
499 session.timer_id_open_keep_wait = 200;
500 session.pce_open_accepted = false;
501 session.pce_open_received = false;
502 session.pcc_open_accepted = false;
503
504 handle_socket_comm_event(&event);
505
506 CU_ASSERT_TRUE(session.pcc_open_accepted);
507 CU_ASSERT_FALSE(session.pce_open_keep_alive_sent);
508 CU_ASSERT_FALSE(session.pcc_open_rejected);
509 CU_ASSERT_FALSE(session.pce_open_accepted);
510 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_PCEP_CONNECTING);
511 CU_ASSERT_EQUAL(session.timer_id_open_keep_wait, TIMER_ID_NOT_SET);
512 CU_ASSERT_EQUAL(session.timer_id_dead_timer, 100);
513 verify_socket_comm_times_called(0, 0, 0, 0, 0, 0, 0);
514 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
515 0);
516
517 /* Test when a Keep Alive is received, and the PCE Open has been
518 * received and accepted */
519 create_message_for_test(PCEP_TYPE_KEEPALIVE, false, false);
520 session.session_state = SESSION_STATE_PCEP_CONNECTING;
521 session.timer_id_dead_timer = 100;
522 session.timer_id_open_keep_wait = 200;
523 session.pce_open_received = true;
524 session.pce_open_accepted = true;
525 session.pcc_open_accepted = false;
526
527 handle_socket_comm_event(&event);
528
529 CU_ASSERT_TRUE(session.pcc_open_accepted);
530 CU_ASSERT_TRUE(session.pce_open_keep_alive_sent);
531 CU_ASSERT_FALSE(session.pcc_open_rejected);
532 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_PCEP_CONNECTED);
533 CU_ASSERT_EQUAL(session.timer_id_open_keep_wait, TIMER_ID_NOT_SET);
534 CU_ASSERT_EQUAL(session.timer_id_dead_timer, 100);
535 verify_socket_comm_times_called(0, 0, 0, 1, 0, 0, 0);
536
537 /* Test when a Keep Alive is received, and the PCE Open has been
538 * received and rejected */
539 create_message_for_test(PCEP_TYPE_KEEPALIVE, false, false);
540 session.session_state = SESSION_STATE_PCEP_CONNECTING;
541 session.timer_id_dead_timer = 100;
542 session.timer_id_open_keep_wait = 200;
543 session.pce_open_received = true;
544 session.pce_open_accepted = false;
545 session.pce_open_rejected = true;
546 session.pce_open_keep_alive_sent = false;
547 session.pcc_open_accepted = true;
548
549 handle_socket_comm_event(&event);
550
551 CU_ASSERT_TRUE(session.pcc_open_accepted);
552 CU_ASSERT_FALSE(session.pce_open_keep_alive_sent);
553 CU_ASSERT_FALSE(session.pcc_open_rejected);
554 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_PCEP_CONNECTING);
555 CU_ASSERT_EQUAL(session.timer_id_open_keep_wait, TIMER_ID_NOT_SET);
556 CU_ASSERT_EQUAL(session.timer_id_dead_timer, 100);
557 verify_socket_comm_times_called(0, 0, 0, 1, 0, 0, 0);
558
559 /* The session is considered connected, when both the
560 * PCE and PCC Open messages have been accepted */
561 pcep_event *e = queue_dequeue(session_logic_event_queue_->event_queue);
562 CU_ASSERT_EQUAL(PCC_CONNECTED_TO_PCE, e->event_type);
563 pceplib_free(PCEPLIB_INFRA, e);
564 }
565
566
567 void test_handle_socket_comm_event_pcrep()
568 {
569 create_message_for_test(PCEP_TYPE_PCREP, false, true);
570 struct pcep_object_rp *rp =
571 pcep_obj_create_rp(1, true, true, true, true, 1, NULL);
572 dll_append(message->obj_list, rp);
573
574 handle_socket_comm_event(&event);
575
576 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
577 1);
578 verify_socket_comm_times_called(0, 0, 0, 0, 0, 0, 0);
579 pcep_event *e = queue_dequeue(session_logic_event_queue_->event_queue);
580 CU_ASSERT_EQUAL(MESSAGE_RECEIVED, e->event_type);
581 pceplib_free(PCEPLIB_INFRA, e);
582 }
583
584
585 void test_handle_socket_comm_event_pcreq()
586 {
587 create_message_for_test(PCEP_TYPE_PCREQ, false, false);
588 mock_socket_comm_info *mock_info = get_mock_socket_comm_info();
589 mock_info->send_message_save_message = true;
590
591 handle_socket_comm_event(&event);
592
593 /* The PCC does not support receiving PcReq messages, so an error should
594 * be sent */
595 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
596 0);
597 verify_socket_comm_times_called(0, 0, 0, 1, 0, 0, 0);
598 uint8_t *encoded_msg =
599 dll_delete_first_node(mock_info->sent_message_list);
600 CU_ASSERT_PTR_NOT_NULL(encoded_msg);
601 struct pcep_message *error_msg = pcep_decode_message(encoded_msg);
602 CU_ASSERT_PTR_NOT_NULL(error_msg);
603 assert(error_msg != NULL);
604 CU_ASSERT_EQUAL(PCEP_TYPE_ERROR, error_msg->msg_header->type);
605 /* Verify the error object */
606 CU_ASSERT_EQUAL(1, error_msg->obj_list->num_entries);
607 struct pcep_object_error *obj = error_msg->obj_list->head->data;
608 CU_ASSERT_EQUAL(PCEP_OBJ_CLASS_ERROR, obj->header.object_class);
609 CU_ASSERT_EQUAL(PCEP_OBJ_TYPE_ERROR, obj->header.object_type);
610 CU_ASSERT_EQUAL(PCEP_ERRT_CAPABILITY_NOT_SUPPORTED, obj->error_type);
611 CU_ASSERT_EQUAL(PCEP_ERRV_UNASSIGNED, obj->error_value);
612 pcep_msg_free_message(error_msg);
613 pceplib_free(PCEPLIB_MESSAGES, encoded_msg);
614 }
615
616
617 void test_handle_socket_comm_event_report()
618 {
619 create_message_for_test(PCEP_TYPE_REPORT, false, false);
620 mock_socket_comm_info *mock_info = get_mock_socket_comm_info();
621 mock_info->send_message_save_message = true;
622
623 handle_socket_comm_event(&event);
624
625 /* The PCC does not support receiving Report messages, so an error
626 * should be sent */
627 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
628 0);
629 verify_socket_comm_times_called(0, 0, 0, 1, 0, 0, 0);
630 uint8_t *encoded_msg =
631 dll_delete_first_node(mock_info->sent_message_list);
632 CU_ASSERT_PTR_NOT_NULL(encoded_msg);
633 struct pcep_message *error_msg = pcep_decode_message(encoded_msg);
634 CU_ASSERT_PTR_NOT_NULL(error_msg);
635 assert(error_msg != NULL);
636 CU_ASSERT_EQUAL(PCEP_TYPE_ERROR, error_msg->msg_header->type);
637 /* Verify the error object */
638 CU_ASSERT_EQUAL(1, error_msg->obj_list->num_entries);
639 struct pcep_object_error *obj = error_msg->obj_list->head->data;
640 CU_ASSERT_EQUAL(PCEP_OBJ_CLASS_ERROR, obj->header.object_class);
641 CU_ASSERT_EQUAL(PCEP_OBJ_TYPE_ERROR, obj->header.object_type);
642 CU_ASSERT_EQUAL(PCEP_ERRT_CAPABILITY_NOT_SUPPORTED, obj->error_type);
643 CU_ASSERT_EQUAL(PCEP_ERRV_UNASSIGNED, obj->error_value);
644 pcep_msg_free_message(error_msg);
645 pceplib_free(PCEPLIB_MESSAGES, encoded_msg);
646 }
647
648
649 void test_handle_socket_comm_event_update()
650 {
651 create_message_for_test(PCEP_TYPE_UPDATE, false, true);
652 struct pcep_object_srp *srp = pcep_obj_create_srp(false, 100, NULL);
653 struct pcep_object_lsp *lsp =
654 pcep_obj_create_lsp(100, PCEP_LSP_OPERATIONAL_UP, true, true,
655 true, true, true, NULL);
656 double_linked_list *ero_subobj_list = dll_initialize();
657 dll_append(ero_subobj_list, pcep_obj_create_ro_subobj_asn(0x0102));
658 struct pcep_object_ro *ero = pcep_obj_create_ero(ero_subobj_list);
659 struct pcep_object_metric *metric =
660 pcep_obj_create_metric(PCEP_METRIC_TE, false, true, 16.0);
661 dll_append(message->obj_list, srp);
662 dll_append(message->obj_list, lsp);
663 dll_append(message->obj_list, ero);
664 dll_append(message->obj_list, metric);
665 mock_socket_comm_info *mock_info = get_mock_socket_comm_info();
666 mock_info->send_message_save_message = true;
667
668 handle_socket_comm_event(&event);
669
670 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
671 1);
672 verify_socket_comm_times_called(0, 0, 0, 0, 0, 0, 0);
673 pcep_event *e = queue_dequeue(session_logic_event_queue_->event_queue);
674 CU_ASSERT_EQUAL(MESSAGE_RECEIVED, e->event_type);
675 CU_ASSERT_EQUAL(PCEP_TYPE_UPDATE, e->message->msg_header->type);
676 pceplib_free(PCEPLIB_INFRA, e);
677 }
678
679
680 void test_handle_socket_comm_event_initiate()
681 {
682 create_message_for_test(PCEP_TYPE_INITIATE, false, true);
683 struct pcep_object_srp *srp = pcep_obj_create_srp(false, 100, NULL);
684 struct pcep_object_lsp *lsp =
685 pcep_obj_create_lsp(100, PCEP_LSP_OPERATIONAL_UP, true, true,
686 true, true, true, NULL);
687 dll_append(message->obj_list, srp);
688 dll_append(message->obj_list, lsp);
689 mock_socket_comm_info *mock_info = get_mock_socket_comm_info();
690 mock_info->send_message_save_message = true;
691
692 handle_socket_comm_event(&event);
693
694 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
695 1);
696 verify_socket_comm_times_called(0, 0, 0, 0, 0, 0, 0);
697 pcep_event *e = queue_dequeue(session_logic_event_queue_->event_queue);
698 CU_ASSERT_EQUAL(MESSAGE_RECEIVED, e->event_type);
699 CU_ASSERT_EQUAL(PCEP_TYPE_INITIATE, e->message->msg_header->type);
700 pceplib_free(PCEPLIB_INFRA, e);
701 }
702
703
704 void test_handle_socket_comm_event_notify()
705 {
706 create_message_for_test(PCEP_TYPE_PCNOTF, false, true);
707 handle_socket_comm_event(&event);
708
709 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
710 1);
711 verify_socket_comm_times_called(0, 0, 0, 0, 0, 0, 0);
712 pcep_event *e = queue_dequeue(session_logic_event_queue_->event_queue);
713 CU_ASSERT_EQUAL(MESSAGE_RECEIVED, e->event_type);
714 CU_ASSERT_EQUAL(PCEP_TYPE_PCNOTF, e->message->msg_header->type);
715 pceplib_free(PCEPLIB_INFRA, e);
716 }
717
718
719 void test_handle_socket_comm_event_error()
720 {
721 create_message_for_test(PCEP_TYPE_ERROR, false, true);
722 handle_socket_comm_event(&event);
723
724 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
725 1);
726 verify_socket_comm_times_called(0, 0, 0, 0, 0, 0, 0);
727 pcep_event *e = queue_dequeue(session_logic_event_queue_->event_queue);
728 CU_ASSERT_EQUAL(MESSAGE_RECEIVED, e->event_type);
729 CU_ASSERT_EQUAL(PCEP_TYPE_ERROR, e->message->msg_header->type);
730 pceplib_free(PCEPLIB_INFRA, e);
731 }
732
733
734 void test_handle_socket_comm_event_unknown_msg()
735 {
736 create_message_for_test(13, false, false);
737 mock_socket_comm_info *mock_info = get_mock_socket_comm_info();
738 mock_info->send_message_save_message = true;
739
740 handle_socket_comm_event(&event);
741
742 /* Sending an unsupported message type, so an error should be sent,
743 * but the connection should remain open, since max_unknown_messages = 2
744 */
745 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
746 0);
747 verify_socket_comm_times_called(0, 0, 0, 1, 0, 0, 0);
748 uint8_t *encoded_msg =
749 dll_delete_first_node(mock_info->sent_message_list);
750 CU_ASSERT_PTR_NOT_NULL(encoded_msg);
751 struct pcep_message *msg = pcep_decode_message(encoded_msg);
752 CU_ASSERT_PTR_NOT_NULL(msg);
753 assert(msg != NULL);
754 CU_ASSERT_EQUAL(PCEP_TYPE_ERROR, msg->msg_header->type);
755 /* Verify the error object */
756 CU_ASSERT_EQUAL(1, msg->obj_list->num_entries);
757 struct pcep_object_error *error_obj = msg->obj_list->head->data;
758 CU_ASSERT_EQUAL(PCEP_OBJ_CLASS_ERROR, error_obj->header.object_class);
759 CU_ASSERT_EQUAL(PCEP_OBJ_TYPE_ERROR, error_obj->header.object_type);
760 CU_ASSERT_EQUAL(PCEP_ERRT_CAPABILITY_NOT_SUPPORTED,
761 error_obj->error_type);
762 CU_ASSERT_EQUAL(PCEP_ERRV_UNASSIGNED, error_obj->error_value);
763 pcep_msg_free_message(msg);
764 pceplib_free(PCEPLIB_MESSAGES, encoded_msg);
765 destroy_message_for_test();
766
767 /* Send another unsupported message type, an error should be sent and
768 * the connection should be closed, since max_unknown_messages = 2 */
769 create_message_for_test(13, false, false);
770 reset_mock_socket_comm_info();
771 mock_info = get_mock_socket_comm_info();
772 mock_info->send_message_save_message = true;
773
774 handle_socket_comm_event(&event);
775
776 verify_socket_comm_times_called(0, 0, 0, 2, 1, 0, 0);
777 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
778 1);
779 pcep_event *e = queue_dequeue(session_logic_event_queue_->event_queue);
780 CU_ASSERT_EQUAL(PCC_RCVD_MAX_UNKOWN_MSGS, e->event_type);
781 pceplib_free(PCEPLIB_INFRA, e);
782
783 /* Verify the error message */
784 encoded_msg = dll_delete_first_node(mock_info->sent_message_list);
785 CU_ASSERT_PTR_NOT_NULL(encoded_msg);
786 assert(encoded_msg != NULL);
787 msg = pcep_decode_message(encoded_msg);
788 CU_ASSERT_PTR_NOT_NULL(msg);
789 CU_ASSERT_EQUAL(PCEP_TYPE_ERROR, msg->msg_header->type);
790 /* Verify the error object */
791 CU_ASSERT_EQUAL(1, msg->obj_list->num_entries);
792 error_obj = msg->obj_list->head->data;
793 CU_ASSERT_EQUAL(PCEP_OBJ_CLASS_ERROR, error_obj->header.object_class);
794 CU_ASSERT_EQUAL(PCEP_OBJ_TYPE_ERROR, error_obj->header.object_type);
795 CU_ASSERT_EQUAL(PCEP_ERRT_CAPABILITY_NOT_SUPPORTED,
796 error_obj->error_type);
797 CU_ASSERT_EQUAL(PCEP_ERRV_UNASSIGNED, error_obj->error_value);
798 pcep_msg_free_message(msg);
799 pceplib_free(PCEPLIB_MESSAGES, encoded_msg);
800
801 /* Verify the Close message */
802 encoded_msg = dll_delete_first_node(mock_info->sent_message_list);
803 CU_ASSERT_PTR_NOT_NULL(encoded_msg);
804 assert(encoded_msg != NULL);
805 msg = pcep_decode_message(encoded_msg);
806 CU_ASSERT_PTR_NOT_NULL(msg);
807 assert(msg != NULL);
808 CU_ASSERT_EQUAL(PCEP_TYPE_CLOSE, msg->msg_header->type);
809 /* Verify the error object */
810 CU_ASSERT_EQUAL(1, msg->obj_list->num_entries);
811 struct pcep_object_close *close_obj = msg->obj_list->head->data;
812 CU_ASSERT_EQUAL(PCEP_OBJ_CLASS_CLOSE, close_obj->header.object_class);
813 CU_ASSERT_EQUAL(PCEP_OBJ_TYPE_CLOSE, close_obj->header.object_type);
814 CU_ASSERT_EQUAL(PCEP_CLOSE_REASON_UNREC_MSG, close_obj->reason);
815 pcep_msg_free_message(msg);
816 pceplib_free(PCEPLIB_MESSAGES, encoded_msg);
817 }
818
819
820 void test_connection_failure(void)
821 {
822 /*
823 * Test when 2 invalid Open messages are received that a
824 * PCC_CONNECTION_FAILURE event is generated.
825 */
826 create_message_for_test(PCEP_TYPE_OPEN, false, false);
827 reset_mock_socket_comm_info();
828 struct pcep_object_open *open_object =
829 pcep_obj_create_open(1, 1, 1, NULL);
830 /* Make the Open message invalid */
831 open_object->open_deadtimer =
832 session.pcc_config.max_dead_timer_seconds + 1;
833 dll_append(message->obj_list, open_object);
834 session.pce_open_received = false;
835 session.pce_open_accepted = false;
836 session.pce_open_rejected = false;
837 session.session_state = SESSION_STATE_PCEP_CONNECTING;
838
839 handle_socket_comm_event(&event);
840
841 CU_ASSERT_TRUE(session.pce_open_received);
842 CU_ASSERT_TRUE(session.pce_open_rejected);
843 CU_ASSERT_FALSE(session.pce_open_accepted);
844 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_PCEP_CONNECTING);
845 /* An error response should be sent, rejecting the Open */
846 verify_socket_comm_times_called(0, 0, 0, 1, 0, 0, 0);
847 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
848 1);
849 pcep_event *e = queue_dequeue(session_logic_event_queue_->event_queue);
850 CU_ASSERT_EQUAL(PCC_RCVD_INVALID_OPEN, e->event_type);
851 pceplib_free(PCEPLIB_INFRA, e);
852 destroy_message_for_test();
853
854 /* Send the same erroneous Open again */
855 create_message_for_test(PCEP_TYPE_OPEN, false, false);
856 reset_mock_socket_comm_info();
857 open_object = pcep_obj_create_open(1, 1, 1, NULL);
858 /* Make the Open message invalid */
859 open_object->open_deadtimer =
860 session.pcc_config.max_dead_timer_seconds + 1;
861 dll_append(message->obj_list, open_object);
862
863 handle_socket_comm_event(&event);
864
865 CU_ASSERT_TRUE(session.pce_open_received);
866 CU_ASSERT_TRUE(session.pce_open_rejected);
867 CU_ASSERT_FALSE(session.pce_open_accepted);
868 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_INITIALIZED);
869 /* An error response should be sent, rejecting the Open */
870 verify_socket_comm_times_called(0, 0, 0, 1, 1, 0, 0);
871 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
872 2);
873 e = queue_dequeue(session_logic_event_queue_->event_queue);
874 CU_ASSERT_EQUAL(PCC_RCVD_INVALID_OPEN, e->event_type);
875 pceplib_free(PCEPLIB_INFRA, e);
876 e = queue_dequeue(session_logic_event_queue_->event_queue);
877 CU_ASSERT_EQUAL(PCC_CONNECTION_FAILURE, e->event_type);
878 pceplib_free(PCEPLIB_INFRA, e);
879
880 destroy_message_for_test();
881
882 /*
883 * Test when 2 invalid Open messages are sent that a
884 * PCC_CONNECTION_FAILURE event is generated.
885 */
886 create_message_for_test(PCEP_TYPE_ERROR, false, false);
887 reset_mock_socket_comm_info();
888 struct pcep_object_error *error_object = pcep_obj_create_error(
889 PCEP_ERRT_SESSION_FAILURE, PCEP_ERRV_UNACCEPTABLE_OPEN_MSG_NEG);
890 dll_append(message->obj_list, error_object);
891 session.pcc_open_accepted = false;
892 session.pcc_open_rejected = false;
893 session.session_state = SESSION_STATE_PCEP_CONNECTING;
894
895 handle_socket_comm_event(&event);
896
897 CU_ASSERT_TRUE(session.pcc_open_rejected);
898 CU_ASSERT_FALSE(session.pcc_open_accepted);
899 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_PCEP_CONNECTING);
900 /* Another Open should be sent */
901 verify_socket_comm_times_called(0, 0, 0, 1, 0, 0, 0);
902 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
903 2);
904 e = queue_dequeue(session_logic_event_queue_->event_queue);
905 CU_ASSERT_EQUAL(PCC_SENT_INVALID_OPEN, e->event_type);
906 pceplib_free(PCEPLIB_INFRA, e);
907 e = queue_dequeue(session_logic_event_queue_->event_queue);
908 CU_ASSERT_EQUAL(MESSAGE_RECEIVED, e->event_type);
909 CU_ASSERT_EQUAL(PCEP_TYPE_ERROR, e->message->msg_header->type);
910 pceplib_free(PCEPLIB_INFRA, e);
911 destroy_message_for_test();
912
913 /* Send a socket close while connecting, which should
914 * generate a PCC_CONNECTION_FAILURE event */
915 reset_mock_socket_comm_info();
916 event.socket_closed = true;
917 event.received_msg_list = NULL;
918
919 handle_socket_comm_event(&event);
920
921 CU_ASSERT_TRUE(session.pcc_open_rejected);
922 CU_ASSERT_FALSE(session.pcc_open_accepted);
923 CU_ASSERT_EQUAL(session.session_state, SESSION_STATE_INITIALIZED);
924 verify_socket_comm_times_called(0, 0, 0, 0, 0, 1, 0);
925 CU_ASSERT_EQUAL(session_logic_event_queue_->event_queue->num_entries,
926 2);
927 e = queue_dequeue(session_logic_event_queue_->event_queue);
928 CU_ASSERT_EQUAL(PCE_CLOSED_SOCKET, e->event_type);
929 pceplib_free(PCEPLIB_INFRA, e);
930 e = queue_dequeue(session_logic_event_queue_->event_queue);
931 CU_ASSERT_EQUAL(PCC_CONNECTION_FAILURE, e->event_type);
932 pceplib_free(PCEPLIB_INFRA, e);
933 }