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>
25 * This module is built into a separate library, and is used by several
26 * other modules for unit testing, so that real sockets dont have to be
34 #include <netinet/in.h>
39 #include <CUnit/CUnit.h>
41 #include "pcep_socket_comm.h"
42 #include "pcep_socket_comm_mock.h"
43 #include "pcep_utils_queue.h"
45 /* reset_mock_socket_comm_info() should be used before each test */
46 mock_socket_comm_info mock_socket_metadata
;
48 void setup_mock_socket_comm_info(void)
50 mock_socket_metadata
.socket_comm_session_initialize_times_called
= 0;
51 mock_socket_metadata
.socket_comm_session_initialize_src_times_called
=
53 mock_socket_metadata
.socket_comm_session_teardown_times_called
= 0;
54 mock_socket_metadata
.socket_comm_session_connect_tcp_times_called
= 0;
55 mock_socket_metadata
.socket_comm_session_send_message_times_called
= 0;
57 .socket_comm_session_close_tcp_after_write_times_called
= 0;
58 mock_socket_metadata
.socket_comm_session_close_tcp_times_called
= 0;
59 mock_socket_metadata
.destroy_socket_comm_loop_times_called
= 0;
60 mock_socket_metadata
.send_message_save_message
= false;
61 mock_socket_metadata
.sent_message_list
= dll_initialize();
64 void teardown_mock_socket_comm_info(void)
66 dll_destroy(mock_socket_metadata
.sent_message_list
);
69 void reset_mock_socket_comm_info(void)
71 teardown_mock_socket_comm_info();
72 setup_mock_socket_comm_info();
75 mock_socket_comm_info
*get_mock_socket_comm_info(void)
77 return &mock_socket_metadata
;
80 void verify_socket_comm_times_called(int initialized
, int teardown
, int connect
,
82 int close_tcp_after_write
, int close_tcp
,
85 CU_ASSERT_EQUAL(initialized
,
87 .socket_comm_session_initialize_times_called
);
90 mock_socket_metadata
.socket_comm_session_teardown_times_called
);
91 CU_ASSERT_EQUAL(connect
,
93 .socket_comm_session_connect_tcp_times_called
);
94 CU_ASSERT_EQUAL(send_message
,
96 .socket_comm_session_send_message_times_called
);
98 close_tcp_after_write
,
100 .socket_comm_session_close_tcp_after_write_times_called
);
101 CU_ASSERT_EQUAL(close_tcp
,
103 .socket_comm_session_close_tcp_times_called
);
106 mock_socket_metadata
.destroy_socket_comm_loop_times_called
);
111 * Mock the socket_comm functions used by session_logic for Unit Testing
114 bool initialize_socket_comm_external_infra(
115 void *external_infra_data
, ext_socket_read socket_read_cb
,
116 ext_socket_write socket_write_cb
,
117 ext_socket_pthread_create_callback thread_create_func
)
119 (void)external_infra_data
;
120 (void)socket_read_cb
;
121 (void)socket_write_cb
;
122 (void)thread_create_func
;
125 .socket_comm_initialize_external_infra_times_called
++;
130 bool destroy_socket_comm_loop()
132 mock_socket_metadata
.destroy_socket_comm_loop_times_called
++;
137 pcep_socket_comm_session
*
138 socket_comm_session_initialize(message_received_handler msg_rcv_handler
,
139 message_ready_to_read_handler msg_ready_handler
,
140 message_sent_notifier msg_sent_notifier
,
141 connection_except_notifier notifier
,
142 struct in_addr
*dst_ip
, short dst_port
,
143 uint32_t connect_timeout_millis
,
144 const char *tcp_authentication_str
,
145 bool is_tcp_auth_md5
, void *session_data
)
147 (void)msg_sent_notifier
;
148 (void)tcp_authentication_str
;
149 (void)is_tcp_auth_md5
;
151 mock_socket_metadata
.socket_comm_session_initialize_times_called
++;
153 pcep_socket_comm_session
*comm_session
=
154 malloc(sizeof(pcep_socket_comm_session
));
155 memset(comm_session
, 0, sizeof(pcep_socket_comm_session
));
157 comm_session
->message_handler
= msg_rcv_handler
;
158 comm_session
->message_ready_to_read_handler
= msg_ready_handler
;
159 comm_session
->conn_except_notifier
= notifier
;
160 comm_session
->message_queue
= queue_initialize();
161 comm_session
->session_data
= session_data
;
162 comm_session
->close_after_write
= false;
163 comm_session
->connect_timeout_millis
= connect_timeout_millis
;
164 comm_session
->is_ipv6
= false;
165 comm_session
->dest_sock_addr
.dest_sock_addr_ipv4
.sin_family
= AF_INET
;
166 comm_session
->dest_sock_addr
.dest_sock_addr_ipv4
.sin_port
=
168 comm_session
->dest_sock_addr
.dest_sock_addr_ipv4
.sin_addr
.s_addr
=
174 pcep_socket_comm_session
*socket_comm_session_initialize_ipv6(
175 message_received_handler msg_rcv_handler
,
176 message_ready_to_read_handler msg_ready_handler
,
177 message_sent_notifier msg_sent_notifier
,
178 connection_except_notifier notifier
, struct in6_addr
*dst_ip
,
179 short dst_port
, uint32_t connect_timeout_millis
,
180 const char *tcp_authentication_str
, bool is_tcp_auth_md5
,
183 (void)msg_sent_notifier
;
184 (void)tcp_authentication_str
;
185 (void)is_tcp_auth_md5
;
187 mock_socket_metadata
.socket_comm_session_initialize_times_called
++;
189 pcep_socket_comm_session
*comm_session
=
190 malloc(sizeof(pcep_socket_comm_session
));
191 memset(comm_session
, 0, sizeof(pcep_socket_comm_session
));
193 comm_session
->message_handler
= msg_rcv_handler
;
194 comm_session
->message_ready_to_read_handler
= msg_ready_handler
;
195 comm_session
->conn_except_notifier
= notifier
;
196 comm_session
->message_queue
= queue_initialize();
197 comm_session
->session_data
= session_data
;
198 comm_session
->close_after_write
= false;
199 comm_session
->connect_timeout_millis
= connect_timeout_millis
;
200 comm_session
->is_ipv6
= true;
201 comm_session
->dest_sock_addr
.dest_sock_addr_ipv6
.sin6_family
= AF_INET6
;
202 comm_session
->dest_sock_addr
.dest_sock_addr_ipv6
.sin6_port
=
204 memcpy(&comm_session
->dest_sock_addr
.dest_sock_addr_ipv6
.sin6_addr
,
205 dst_ip
, sizeof(struct in6_addr
));
210 pcep_socket_comm_session
*socket_comm_session_initialize_with_src(
211 message_received_handler msg_rcv_handler
,
212 message_ready_to_read_handler msg_ready_handler
,
213 message_sent_notifier msg_sent_notifier
,
214 connection_except_notifier notifier
, struct in_addr
*src_ip
,
215 short src_port
, struct in_addr
*dst_ip
, short dst_port
,
216 uint32_t connect_timeout_millis
, const char *tcp_authentication_str
,
217 bool is_tcp_auth_md5
, void *session_data
)
219 (void)msg_sent_notifier
;
220 (void)tcp_authentication_str
;
221 (void)is_tcp_auth_md5
;
223 mock_socket_metadata
.socket_comm_session_initialize_src_times_called
++;
225 pcep_socket_comm_session
*comm_session
=
226 malloc(sizeof(pcep_socket_comm_session
));
227 memset(comm_session
, 0, sizeof(pcep_socket_comm_session
));
229 comm_session
->message_handler
= msg_rcv_handler
;
230 comm_session
->message_ready_to_read_handler
= msg_ready_handler
;
231 comm_session
->conn_except_notifier
= notifier
;
232 comm_session
->message_queue
= queue_initialize();
233 comm_session
->session_data
= session_data
;
234 comm_session
->close_after_write
= false;
235 comm_session
->connect_timeout_millis
= connect_timeout_millis
;
236 comm_session
->is_ipv6
= false;
237 comm_session
->src_sock_addr
.src_sock_addr_ipv4
.sin_family
= AF_INET
;
238 comm_session
->src_sock_addr
.src_sock_addr_ipv4
.sin_port
=
240 comm_session
->src_sock_addr
.src_sock_addr_ipv4
.sin_addr
.s_addr
=
241 ((src_ip
== NULL
) ? INADDR_ANY
: src_ip
->s_addr
);
242 comm_session
->dest_sock_addr
.dest_sock_addr_ipv4
.sin_family
= AF_INET
;
243 comm_session
->dest_sock_addr
.dest_sock_addr_ipv4
.sin_port
=
245 comm_session
->dest_sock_addr
.dest_sock_addr_ipv4
.sin_addr
.s_addr
=
251 pcep_socket_comm_session
*socket_comm_session_initialize_with_src_ipv6(
252 message_received_handler msg_rcv_handler
,
253 message_ready_to_read_handler msg_ready_handler
,
254 message_sent_notifier msg_sent_notifier
,
255 connection_except_notifier notifier
, struct in6_addr
*src_ip
,
256 short src_port
, struct in6_addr
*dst_ip
, short dst_port
,
257 uint32_t connect_timeout_millis
, const char *tcp_authentication_str
,
258 bool is_tcp_auth_md5
, void *session_data
)
260 (void)msg_sent_notifier
;
261 (void)tcp_authentication_str
;
262 (void)is_tcp_auth_md5
;
264 mock_socket_metadata
.socket_comm_session_initialize_src_times_called
++;
266 pcep_socket_comm_session
*comm_session
=
267 malloc(sizeof(pcep_socket_comm_session
));
268 memset(comm_session
, 0, sizeof(pcep_socket_comm_session
));
270 comm_session
->message_handler
= msg_rcv_handler
;
271 comm_session
->message_ready_to_read_handler
= msg_ready_handler
;
272 comm_session
->conn_except_notifier
= notifier
;
273 comm_session
->message_queue
= queue_initialize();
274 comm_session
->session_data
= session_data
;
275 comm_session
->close_after_write
= false;
276 comm_session
->connect_timeout_millis
= connect_timeout_millis
;
277 comm_session
->is_ipv6
= true;
278 comm_session
->src_sock_addr
.src_sock_addr_ipv6
.sin6_family
= AF_INET6
;
279 comm_session
->src_sock_addr
.src_sock_addr_ipv6
.sin6_port
=
281 if (src_ip
== NULL
) {
282 comm_session
->src_sock_addr
.src_sock_addr_ipv6
.sin6_addr
=
285 memcpy(&comm_session
->src_sock_addr
.src_sock_addr_ipv6
287 src_ip
, sizeof(struct in6_addr
));
289 comm_session
->dest_sock_addr
.dest_sock_addr_ipv6
.sin6_family
= AF_INET6
;
290 comm_session
->dest_sock_addr
.dest_sock_addr_ipv6
.sin6_port
=
292 memcpy(&comm_session
->dest_sock_addr
.dest_sock_addr_ipv6
.sin6_addr
,
293 dst_ip
, sizeof(struct in6_addr
));
298 bool socket_comm_session_teardown(pcep_socket_comm_session
*socket_comm_session
)
300 mock_socket_metadata
.socket_comm_session_teardown_times_called
++;
302 if (socket_comm_session
!= NULL
) {
303 queue_destroy(socket_comm_session
->message_queue
);
304 free(socket_comm_session
);
311 bool socket_comm_session_connect_tcp(
312 pcep_socket_comm_session
*socket_comm_session
)
314 (void)socket_comm_session
;
316 mock_socket_metadata
.socket_comm_session_connect_tcp_times_called
++;
322 void socket_comm_session_send_message(
323 pcep_socket_comm_session
*socket_comm_session
,
324 const char *encoded_message
, unsigned int msg_length
,
325 bool delete_after_send
)
327 (void)socket_comm_session
;
330 mock_socket_metadata
.socket_comm_session_send_message_times_called
++;
332 if (mock_socket_metadata
.send_message_save_message
== true) {
333 /* the caller/test case is responsible for freeing the message
335 dll_append(mock_socket_metadata
.sent_message_list
,
336 (char *)encoded_message
);
338 if (delete_after_send
== true) {
339 free((void *)encoded_message
);
347 bool socket_comm_session_close_tcp_after_write(
348 pcep_socket_comm_session
*socket_comm_session
)
350 (void)socket_comm_session
;
353 .socket_comm_session_close_tcp_after_write_times_called
++;
359 bool socket_comm_session_close_tcp(
360 pcep_socket_comm_session
*socket_comm_session
)
362 (void)socket_comm_session
;
364 mock_socket_metadata
.socket_comm_session_close_tcp_times_called
++;