2 * This file is part of the PCEPlib, a PCEP protocol library.
4 * Copyright (C) 2020 Volta Networks https://voltanet.io/
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.
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.
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/>.
19 * Author : Brady Johnson <brady@voltanet.io>
32 #include <CUnit/CUnit.h>
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"
45 /* Functions being tested */
46 extern pcep_session_logic_handle
*session_logic_handle_
;
47 extern pcep_event_queue
*session_logic_event_queue_
;
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);
63 * Test suite setup and teardown called before AND after the test suite.
66 int pcep_session_logic_states_test_suite_setup(void)
68 pceplib_memory_reset();
72 int pcep_session_logic_states_test_suite_teardown(void)
75 pceplib_memory_dump();
80 * Test case setup and teardown called before AND after each test.
83 void pcep_session_logic_states_test_setup()
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
));
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();
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();
108 memset(&event
, 0, sizeof(pcep_session_event
));
109 event
.socket_closed
= false;
110 event
.session
= &session
;
112 setup_mock_socket_comm_info();
113 free_msg_list
= false;
114 msg_enqueued
= false;
118 void pcep_session_logic_states_test_teardown()
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();
130 void create_message_for_test(uint8_t msg_type
, bool free_msg_list_at_teardown
,
131 bool was_msg_enqueued
)
133 /* See the comments in destroy_message_for_test() about these 2
135 free_msg_list
= free_msg_list_at_teardown
;
136 msg_enqueued
= was_msg_enqueued
;
138 message
= pceplib_malloc(PCEPLIB_MESSAGES
, sizeof(struct pcep_message
));
139 memset(message
, 0, sizeof(struct pcep_message
));
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
;
147 msg_list
= dll_initialize();
148 dll_append(msg_list
, message
);
149 event
.received_msg_list
= msg_list
;
152 void destroy_message_for_test()
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
);
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
);
172 void test_handle_timer_event_dead_timer()
174 /* Dead Timer expired */
175 event
.expired_timer_id
= session
.timer_id_dead_timer
= 100;
177 handle_timer_event(&event
);
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
,
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
);
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);
195 void test_handle_timer_event_keep_alive()
197 /* Keep Alive timer expired */
198 event
.expired_timer_id
= session
.timer_id_keep_alive
= 200;
200 handle_timer_event(&event
);
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);
207 void test_handle_timer_event_open_keep_wait()
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
);
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
,
218 verify_socket_comm_times_called(0, 0, 0, 0, 1, 0, 0);
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
);
224 /* If the state is not SESSION_STATE_PCEP_CONNECTED, then nothing should
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
);
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);
237 void test_handle_timer_event_open_keep_alive()
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
);
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
);
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
);
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
);
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
);
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
);
282 void test_handle_socket_comm_event_null_params()
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();
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);
295 void test_handle_socket_comm_event_close()
297 event
.socket_closed
= true;
298 handle_socket_comm_event(&event
);
300 CU_ASSERT_EQUAL(session
.session_state
, SESSION_STATE_INITIALIZED
);
301 CU_ASSERT_EQUAL(session_logic_event_queue_
->event_queue
->num_entries
,
303 verify_socket_comm_times_called(0, 0, 0, 0, 0, 1, 0);
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
);
311 void test_handle_socket_comm_event_open()
314 * Test when a PCE Open is received, but the PCC Open has not been
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
;
327 handle_socket_comm_event(&event
);
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
,
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();
346 * Test when a PCE Open is received, and the PCC Open has been accepted
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
;
357 handle_socket_comm_event(&event
);
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
,
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();
378 * Send a 2nd Open, an error should be sent
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;
385 handle_socket_comm_event(&event
);
387 CU_ASSERT_EQUAL(session_logic_event_queue_
->event_queue
->num_entries
,
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
);
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
);
414 void test_handle_socket_comm_event_open_error()
416 /* Test when the PCE rejects the PCC Open with an Error
417 * that a "corrected" Open message is sent. */
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;
434 handle_socket_comm_event(&event
);
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
,
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
);
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
);
453 /* Check the Corrected Open Message */
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
);
478 session
.pcc_config
.keep_alive_pce_negotiated_timer_seconds
,
479 open_object_corrected
->open_keepalive
);
481 session
.pcc_config
.dead_timer_pce_negotiated_seconds
,
482 session
.pcc_config
.dead_timer_seconds
);
484 session
.pcc_config
.keep_alive_pce_negotiated_timer_seconds
,
485 session
.pcc_config
.keep_alive_seconds
);
487 pcep_msg_free_message(open_msg_corrected
);
488 pceplib_free(PCEPLIB_MESSAGES
, encoded_msg
);
492 void test_handle_socket_comm_event_keep_alive()
494 /* Test when a Keep Alive is received, but the PCE Open has not been
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;
504 handle_socket_comm_event(&event
);
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
,
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;
527 handle_socket_comm_event(&event
);
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);
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;
549 handle_socket_comm_event(&event
);
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);
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
);
567 void test_handle_socket_comm_event_pcrep()
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
);
574 handle_socket_comm_event(&event
);
576 CU_ASSERT_EQUAL(session_logic_event_queue_
->event_queue
->num_entries
,
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
);
585 void test_handle_socket_comm_event_pcreq()
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;
591 handle_socket_comm_event(&event
);
593 /* The PCC does not support receiving PcReq messages, so an error should
595 CU_ASSERT_EQUAL(session_logic_event_queue_
->event_queue
->num_entries
,
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
);
617 void test_handle_socket_comm_event_report()
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;
623 handle_socket_comm_event(&event
);
625 /* The PCC does not support receiving Report messages, so an error
627 CU_ASSERT_EQUAL(session_logic_event_queue_
->event_queue
->num_entries
,
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
);
649 void test_handle_socket_comm_event_update()
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;
668 handle_socket_comm_event(&event
);
670 CU_ASSERT_EQUAL(session_logic_event_queue_
->event_queue
->num_entries
,
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
);
680 void test_handle_socket_comm_event_initiate()
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;
692 handle_socket_comm_event(&event
);
694 CU_ASSERT_EQUAL(session_logic_event_queue_
->event_queue
->num_entries
,
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
);
704 void test_handle_socket_comm_event_notify()
706 create_message_for_test(PCEP_TYPE_PCNOTF
, false, true);
707 handle_socket_comm_event(&event
);
709 CU_ASSERT_EQUAL(session_logic_event_queue_
->event_queue
->num_entries
,
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
);
719 void test_handle_socket_comm_event_error()
721 create_message_for_test(PCEP_TYPE_ERROR
, false, true);
722 handle_socket_comm_event(&event
);
724 CU_ASSERT_EQUAL(session_logic_event_queue_
->event_queue
->num_entries
,
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
);
734 void test_handle_socket_comm_event_unknown_msg()
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;
740 handle_socket_comm_event(&event
);
742 /* Sending an unsupported message type, so an error should be sent,
743 * but the connection should remain open, since max_unknown_messages = 2
745 CU_ASSERT_EQUAL(session_logic_event_queue_
->event_queue
->num_entries
,
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
);
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();
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;
774 handle_socket_comm_event(&event
);
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
,
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
);
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
);
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
);
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
);
820 void test_connection_failure(void)
823 * Test when 2 invalid Open messages are received that a
824 * PCC_CONNECTION_FAILURE event is generated.
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
;
839 handle_socket_comm_event(&event
);
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
,
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();
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
);
863 handle_socket_comm_event(&event
);
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
,
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
);
880 destroy_message_for_test();
883 * Test when 2 invalid Open messages are sent that a
884 * PCC_CONNECTION_FAILURE event is generated.
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
;
895 handle_socket_comm_event(&event
);
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
,
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();
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
;
919 handle_socket_comm_event(&event
);
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
,
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
);