]>
Commit | Line | Data |
---|---|---|
74971473 JG |
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 | /* | |
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 | |
27 | * created. | |
28 | */ | |
29 | ||
1f8031f7 DL |
30 | #ifdef HAVE_CONFIG_H |
31 | #include "config.h" | |
32 | #endif | |
33 | ||
74971473 JG |
34 | #include <netinet/in.h> |
35 | #include <stdbool.h> | |
36 | #include <stdlib.h> | |
37 | #include <string.h> | |
38 | ||
39 | #include <CUnit/CUnit.h> | |
40 | ||
41 | #include "pcep_socket_comm.h" | |
42 | #include "pcep_socket_comm_mock.h" | |
43 | #include "pcep_utils_queue.h" | |
44 | ||
45 | /* reset_mock_socket_comm_info() should be used before each test */ | |
46 | mock_socket_comm_info mock_socket_metadata; | |
47 | ||
48 | void setup_mock_socket_comm_info(void) | |
49 | { | |
50 | mock_socket_metadata.socket_comm_session_initialize_times_called = 0; | |
51 | mock_socket_metadata.socket_comm_session_initialize_src_times_called = | |
52 | 0; | |
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; | |
56 | mock_socket_metadata | |
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(); | |
62 | } | |
63 | ||
64 | void teardown_mock_socket_comm_info(void) | |
65 | { | |
66 | dll_destroy(mock_socket_metadata.sent_message_list); | |
67 | } | |
68 | ||
69 | void reset_mock_socket_comm_info(void) | |
70 | { | |
71 | teardown_mock_socket_comm_info(); | |
72 | setup_mock_socket_comm_info(); | |
73 | } | |
74 | ||
75 | mock_socket_comm_info *get_mock_socket_comm_info(void) | |
76 | { | |
77 | return &mock_socket_metadata; | |
78 | } | |
79 | ||
80 | void verify_socket_comm_times_called(int initialized, int teardown, int connect, | |
81 | int send_message, | |
82 | int close_tcp_after_write, int close_tcp, | |
83 | int destroy) | |
84 | { | |
85 | CU_ASSERT_EQUAL(initialized, | |
86 | mock_socket_metadata | |
87 | .socket_comm_session_initialize_times_called); | |
88 | CU_ASSERT_EQUAL( | |
89 | teardown, | |
90 | mock_socket_metadata.socket_comm_session_teardown_times_called); | |
91 | CU_ASSERT_EQUAL(connect, | |
92 | mock_socket_metadata | |
93 | .socket_comm_session_connect_tcp_times_called); | |
94 | CU_ASSERT_EQUAL(send_message, | |
95 | mock_socket_metadata | |
96 | .socket_comm_session_send_message_times_called); | |
97 | CU_ASSERT_EQUAL( | |
98 | close_tcp_after_write, | |
99 | mock_socket_metadata | |
100 | .socket_comm_session_close_tcp_after_write_times_called); | |
101 | CU_ASSERT_EQUAL(close_tcp, | |
102 | mock_socket_metadata | |
103 | .socket_comm_session_close_tcp_times_called); | |
104 | CU_ASSERT_EQUAL( | |
105 | destroy, | |
106 | mock_socket_metadata.destroy_socket_comm_loop_times_called); | |
107 | } | |
108 | ||
109 | ||
110 | /* | |
111 | * Mock the socket_comm functions used by session_logic for Unit Testing | |
112 | */ | |
113 | ||
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) | |
118 | { | |
119 | (void)external_infra_data; | |
120 | (void)socket_read_cb; | |
121 | (void)socket_write_cb; | |
122 | (void)thread_create_func; | |
123 | ||
124 | mock_socket_metadata | |
125 | .socket_comm_initialize_external_infra_times_called++; | |
126 | ||
127 | return true; | |
128 | } | |
129 | ||
130 | bool destroy_socket_comm_loop() | |
131 | { | |
132 | mock_socket_metadata.destroy_socket_comm_loop_times_called++; | |
133 | ||
134 | return false; | |
135 | } | |
136 | ||
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) | |
146 | { | |
147 | (void)msg_sent_notifier; | |
148 | (void)tcp_authentication_str; | |
149 | (void)is_tcp_auth_md5; | |
150 | ||
151 | mock_socket_metadata.socket_comm_session_initialize_times_called++; | |
152 | ||
153 | pcep_socket_comm_session *comm_session = | |
154 | malloc(sizeof(pcep_socket_comm_session)); | |
155 | memset(comm_session, 0, sizeof(pcep_socket_comm_session)); | |
156 | ||
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 = | |
167 | htons(dst_port); | |
168 | comm_session->dest_sock_addr.dest_sock_addr_ipv4.sin_addr.s_addr = | |
169 | dst_ip->s_addr; | |
170 | ||
171 | return comm_session; | |
172 | } | |
173 | ||
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, | |
181 | void *session_data) | |
182 | { | |
183 | (void)msg_sent_notifier; | |
184 | (void)tcp_authentication_str; | |
185 | (void)is_tcp_auth_md5; | |
186 | ||
187 | mock_socket_metadata.socket_comm_session_initialize_times_called++; | |
188 | ||
189 | pcep_socket_comm_session *comm_session = | |
190 | malloc(sizeof(pcep_socket_comm_session)); | |
191 | memset(comm_session, 0, sizeof(pcep_socket_comm_session)); | |
192 | ||
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 = | |
203 | htons(dst_port); | |
204 | memcpy(&comm_session->dest_sock_addr.dest_sock_addr_ipv6.sin6_addr, | |
205 | dst_ip, sizeof(struct in6_addr)); | |
206 | ||
207 | return comm_session; | |
208 | } | |
209 | ||
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) | |
218 | { | |
219 | (void)msg_sent_notifier; | |
220 | (void)tcp_authentication_str; | |
221 | (void)is_tcp_auth_md5; | |
222 | ||
223 | mock_socket_metadata.socket_comm_session_initialize_src_times_called++; | |
224 | ||
225 | pcep_socket_comm_session *comm_session = | |
226 | malloc(sizeof(pcep_socket_comm_session)); | |
227 | memset(comm_session, 0, sizeof(pcep_socket_comm_session)); | |
228 | ||
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 = | |
239 | htons(src_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 = | |
244 | htons(dst_port); | |
245 | comm_session->dest_sock_addr.dest_sock_addr_ipv4.sin_addr.s_addr = | |
246 | dst_ip->s_addr; | |
247 | ||
248 | return comm_session; | |
249 | } | |
250 | ||
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) | |
259 | { | |
260 | (void)msg_sent_notifier; | |
261 | (void)tcp_authentication_str; | |
262 | (void)is_tcp_auth_md5; | |
263 | ||
264 | mock_socket_metadata.socket_comm_session_initialize_src_times_called++; | |
265 | ||
266 | pcep_socket_comm_session *comm_session = | |
267 | malloc(sizeof(pcep_socket_comm_session)); | |
268 | memset(comm_session, 0, sizeof(pcep_socket_comm_session)); | |
269 | ||
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 = | |
280 | htons(src_port); | |
281 | if (src_ip == NULL) { | |
282 | comm_session->src_sock_addr.src_sock_addr_ipv6.sin6_addr = | |
283 | in6addr_any; | |
284 | } else { | |
285 | memcpy(&comm_session->src_sock_addr.src_sock_addr_ipv6 | |
286 | .sin6_addr, | |
287 | src_ip, sizeof(struct in6_addr)); | |
288 | } | |
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 = | |
291 | htons(dst_port); | |
292 | memcpy(&comm_session->dest_sock_addr.dest_sock_addr_ipv6.sin6_addr, | |
293 | dst_ip, sizeof(struct in6_addr)); | |
294 | ||
295 | return comm_session; | |
296 | } | |
297 | ||
298 | bool socket_comm_session_teardown(pcep_socket_comm_session *socket_comm_session) | |
299 | { | |
300 | mock_socket_metadata.socket_comm_session_teardown_times_called++; | |
301 | ||
302 | if (socket_comm_session != NULL) { | |
303 | queue_destroy(socket_comm_session->message_queue); | |
304 | free(socket_comm_session); | |
305 | } | |
306 | ||
307 | return true; | |
308 | } | |
309 | ||
310 | ||
311 | bool socket_comm_session_connect_tcp( | |
312 | pcep_socket_comm_session *socket_comm_session) | |
313 | { | |
314 | (void)socket_comm_session; | |
315 | ||
316 | mock_socket_metadata.socket_comm_session_connect_tcp_times_called++; | |
317 | ||
318 | return true; | |
319 | } | |
320 | ||
321 | ||
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) | |
326 | { | |
327 | (void)socket_comm_session; | |
328 | (void)msg_length; | |
329 | ||
330 | mock_socket_metadata.socket_comm_session_send_message_times_called++; | |
331 | ||
332 | if (mock_socket_metadata.send_message_save_message == true) { | |
333 | /* the caller/test case is responsible for freeing the message | |
334 | */ | |
335 | dll_append(mock_socket_metadata.sent_message_list, | |
336 | (char *)encoded_message); | |
337 | } else { | |
338 | if (delete_after_send == true) { | |
339 | free((void *)encoded_message); | |
340 | } | |
341 | } | |
342 | ||
343 | return; | |
344 | } | |
345 | ||
346 | ||
347 | bool socket_comm_session_close_tcp_after_write( | |
348 | pcep_socket_comm_session *socket_comm_session) | |
349 | { | |
350 | (void)socket_comm_session; | |
351 | ||
352 | mock_socket_metadata | |
353 | .socket_comm_session_close_tcp_after_write_times_called++; | |
354 | ||
355 | return true; | |
356 | } | |
357 | ||
358 | ||
359 | bool socket_comm_session_close_tcp( | |
360 | pcep_socket_comm_session *socket_comm_session) | |
361 | { | |
362 | (void)socket_comm_session; | |
363 | ||
364 | mock_socket_metadata.socket_comm_session_close_tcp_times_called++; | |
365 | ||
366 | return true; | |
367 | } |