]> git.proxmox.com Git - mirror_frr.git/blob - pceplib/pcep_socket_comm_mock.c
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[mirror_frr.git] / pceplib / pcep_socket_comm_mock.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 /*
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
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
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 }