aboutsummaryrefslogtreecommitdiff
path: root/src/testing/testing_api_cmd_netjail_start_testsystem_v2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testing/testing_api_cmd_netjail_start_testsystem_v2.c')
-rw-r--r--src/testing/testing_api_cmd_netjail_start_testsystem_v2.c723
1 files changed, 0 insertions, 723 deletions
diff --git a/src/testing/testing_api_cmd_netjail_start_testsystem_v2.c b/src/testing/testing_api_cmd_netjail_start_testsystem_v2.c
deleted file mode 100644
index d319b73b4..000000000
--- a/src/testing/testing_api_cmd_netjail_start_testsystem_v2.c
+++ /dev/null
@@ -1,723 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing/testing_api_cmd_hello_world.c
23 * @brief Command to start the netjail peers.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28#include "testing_cmds.h"
29
30#define NETJAIL_EXEC_SCRIPT "./../testing/netjail_exec_v2.sh"
31
32/**
33 * Struct to store messages send/received by the helper into a DLL
34 *
35 */
36struct HelperMessage
37{
38
39 /**
40 * Kept in a DLL.
41 */
42 struct HelperMessage *next;
43
44 /**
45 * Kept in a DLL.
46 */
47 struct HelperMessage *prev;
48
49 /**
50 * Size of the original message.
51 */
52 uint16_t bytes_msg;
53
54 /* Followed by @e bytes_msg of msg.*/
55};
56
57
58/**
59 * Struct to store information handed over to callbacks.
60 *
61 */
62struct NetJailState
63{
64 /**
65 * Context for our asynchronous completion.
66 */
67 struct GNUNET_TESTING_AsyncContext ac;
68
69 /**
70 * The complete topology information.
71 */
72 struct GNUNET_TESTING_NetjailTopology *topology;
73
74 /**
75 * Pointer to the return value of the test.
76 *
77 */
78 unsigned int *rv;
79
80 /**
81 * Head of the DLL which stores messages received by the helper.
82 *
83 */
84 struct HelperMessage *hp_messages_head;
85
86 /**
87 * Tail of the DLL which stores messages received by the helper.
88 *
89 */
90 struct HelperMessage *hp_messages_tail;
91
92 /**
93 * Array with handles of helper processes.
94 */
95 struct GNUNET_HELPER_Handle **helper;
96
97 /**
98 * Size of the array NetJailState#helper.
99 *
100 */
101 unsigned int n_helper;
102
103 /**
104 * Number of nodes in a natted subnet.
105 *
106 */
107 unsigned int local_m;
108
109 /**
110 * Number of natted subnets.
111 *
112 */
113 unsigned int global_n;
114
115 /**
116 * Number of global known nodes.
117 *
118 */
119 unsigned int known;
120
121 /**
122 * The send handle for the helper
123 */
124 struct GNUNET_HELPER_SendHandle **shandle;
125
126 /**
127 * Size of the array NetJailState#shandle.
128 *
129 */
130 unsigned int n_shandle;
131
132 /**
133 * The messages send to the helper.
134 */
135 struct GNUNET_MessageHeader **msg;
136
137 /**
138 * Size of the array NetJailState#msg.
139 *
140 */
141 unsigned int n_msg;
142
143 /**
144 * Number of test environments started.
145 *
146 */
147 unsigned int number_of_testsystems_started;
148
149 /**
150 * Number of peers started.
151 *
152 */
153 unsigned int number_of_peers_started;
154
155 /**
156 * Number of local tests finished.
157 *
158 */
159 unsigned int number_of_local_test_finished;
160
161 /**
162 * Name of the test case plugin the helper will load.
163 *
164 */
165 char *plugin_name;
166
167 /**
168 * HEAD of the DLL containing TestingSystemCount.
169 *
170 */
171 struct TestingSystemCount *tbcs_head;
172
173 /**
174 * TAIL of the DLL containing TestingSystemCount.
175 *
176 */
177 struct TestingSystemCount *tbcs_tail;
178};
179
180/**
181 * Struct containing the number of the test environment and the NetJailState which
182 * will be handed to callbacks specific to a test environment.
183 */
184struct TestingSystemCount
185{
186 /**
187 * Kept in a DLL.
188 */
189 struct TestingSystemCount *next;
190
191 /**
192 * Kept in a DLL.
193 */
194 struct TestingSystemCount *prev;
195
196 /**
197 * The number of the test environment.
198 *
199 */
200 unsigned int count;
201
202 /**
203 * Struct to store information handed over to callbacks.
204 *
205 */
206 struct NetJailState *ns;
207};
208
209/**
210* Code to clean up resource this cmd used.
211*
212* @param cls closure
213*/
214static void
215netjail_exec_cleanup (void *cls)
216{
217 struct NetJailState *ns = cls;
218 struct HelperMessage *message_pos;
219 struct TestingSystemCount *tbc_pos;
220
221 while (NULL != (message_pos = ns->hp_messages_head))
222 {
223 GNUNET_CONTAINER_DLL_remove (ns->hp_messages_head,
224 ns->hp_messages_tail,
225 message_pos);
226 GNUNET_free (message_pos);
227 }
228 while (NULL != (tbc_pos = ns->tbcs_head))
229 {
230 GNUNET_CONTAINER_DLL_remove (ns->tbcs_head,
231 ns->tbcs_tail,
232 tbc_pos);
233 GNUNET_free (tbc_pos);
234 }
235 GNUNET_free (ns);
236}
237
238
239/**
240 * This function prepares an array with traits.
241 *
242 */
243static int
244netjail_exec_traits (void *cls,
245 const void **ret,
246 const char *trait,
247 unsigned int index)
248{
249 struct NetJailState *ns = cls;
250 struct GNUNET_HELPER_Handle **helper = ns->helper;
251 struct HelperMessage *hp_messages_head = ns->hp_messages_head;
252
253
254 struct GNUNET_TESTING_Trait traits[] = {
255 {
256 .index = 0,
257 .trait_name = "helper_handles",
258 .ptr = (const void *) helper,
259 },
260 {
261 .index = 1,
262 .trait_name = "hp_msgs_head",
263 .ptr = (const void *) hp_messages_head,
264 },
265 GNUNET_TESTING_trait_end ()
266 };
267
268 return GNUNET_TESTING_get_trait (traits,
269 ret,
270 trait,
271 index);
272}
273
274
275/**
276 * Offer handles to testing cmd helper from trait
277 *
278 * @param cmd command to extract the message from.
279 * @param pt pointer to message.
280 * @return #GNUNET_OK on success.
281 */
282int
283GNUNET_TESTING_get_trait_helper_handles_v2 (const struct
284 GNUNET_TESTING_Command *cmd,
285 struct GNUNET_HELPER_Handle ***
286 helper)
287{
288 return cmd->traits (cmd->cls,
289 (const void **) helper,
290 "helper_handles",
291 (unsigned int) 0);
292}
293
294
295/**
296 * Continuation function from GNUNET_HELPER_send()
297 *
298 * @param cls closure
299 * @param result GNUNET_OK on success,
300 * GNUNET_NO if helper process died
301 * GNUNET_SYSERR during GNUNET_HELPER_stop
302 */
303static void
304clear_msg (void *cls, int result)
305{
306 struct TestingSystemCount *tbc = cls;
307 struct NetJailState *ns = tbc->ns;
308
309 GNUNET_assert (NULL != ns->shandle[tbc->count - 1]);
310 ns->shandle[tbc->count - 1] = NULL;
311 GNUNET_free (ns->msg[tbc->count - 1]);
312 ns->msg[tbc->count - 1] = NULL;
313}
314
315
316/**
317 * Functions with this signature are called whenever a
318 * complete message is received by the tokenizer.
319 *
320 * Do not call GNUNET_SERVER_mst_destroy in callback
321 *
322 * @param cls closure
323 * @param client identification of the client
324 * @param message the actual message
325 *
326 * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
327 */
328static int
329helper_mst (void *cls, const struct GNUNET_MessageHeader *message)
330{
331 struct TestingSystemCount *tbc = cls;
332 struct NetJailState *ns = tbc->ns;
333 struct HelperMessage *hp_msg;
334
335 if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY == ntohs (message->type))
336 {
337 ns->number_of_testsystems_started++;
338 }
339 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED == ntohs (
340 message->type))
341 {
342 ns->number_of_peers_started++;
343 }
344 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED == ntohs (
345 message->type))
346 {
347 ns->number_of_local_test_finished++;
348 }
349 else
350 {
351 hp_msg = GNUNET_new (struct HelperMessage);
352 hp_msg->bytes_msg = message->size;
353 memcpy (&hp_msg[1], message, message->size);
354 GNUNET_CONTAINER_DLL_insert (ns->hp_messages_head, ns->hp_messages_tail,
355 hp_msg);
356 }
357
358 return GNUNET_OK;
359}
360
361
362/**
363 * Callback called if there was an exception during execution of the helper.
364 *
365 */
366static void
367exp_cb (void *cls)
368{
369 struct NetJailState *ns = cls;
370 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called exp_cb.\n");
371 *ns->rv = 1;
372}
373
374
375/**
376 * Function to initialize a init message for the helper.
377 *
378 * @param m_char The actual node in a namespace. //TODO Change this to unsigned int
379 * @param n_char The actual namespace. //TODO Change this to unsigned int
380 * @param plugin_name Name of the test case plugin the helper will load.
381 *
382 */
383static struct GNUNET_CMDS_HelperInit *
384create_helper_init_msg_ (const char *plugin_name)
385{
386 struct GNUNET_CMDS_HelperInit *msg;
387 uint16_t plugin_name_len;
388 uint16_t msg_size;
389
390 GNUNET_assert (NULL != plugin_name);
391 plugin_name_len = strlen (plugin_name);
392 msg_size = sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_len;
393 msg = GNUNET_malloc (msg_size);
394 msg->header.size = htons (msg_size);
395 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT);
396 msg->plugin_name_size = htons (plugin_name_len);
397 GNUNET_memcpy ((char *) &msg[1],
398 plugin_name,
399 plugin_name_len);
400 return msg;
401}
402
403
404/**
405 * Function which start a single helper process.
406 *
407 */
408static void
409start_helper (struct NetJailState *ns, struct
410 GNUNET_CONFIGURATION_Handle *config,
411 unsigned int m,
412 unsigned int n)
413{
414 struct GNUNET_HELPER_Handle *helper;
415 struct GNUNET_CMDS_HelperInit *msg;
416 struct TestingSystemCount *tbc;
417 char *m_char, *n_char, *global_n_char, *local_m_char, *known_char, *node_id,
418 *plugin;
419 pid_t pid;
420 unsigned int script_num;
421 struct GNUNET_ShortHashCode *hkey;
422 struct GNUNET_HashCode hc;
423 struct GNUNET_TESTING_NetjailTopology *topology = ns->topology;
424 struct GNUNET_TESTING_NetjailNode *node;
425 struct GNUNET_TESTING_NetjailNamespace *namespace;
426
427
428 if (0 == n)
429 script_num = m - 1;
430 else
431 script_num = n - 1 + (n - 1) * ns->local_m + m + ns->known;
432 pid = getpid ();
433
434 GNUNET_asprintf (&m_char, "%u", m);
435 GNUNET_asprintf (&n_char, "%u", n);
436 GNUNET_asprintf (&local_m_char, "%u", ns->local_m);
437 GNUNET_asprintf (&global_n_char, "%u",ns->global_n);
438 GNUNET_asprintf (&known_char, "%u",ns->known);
439 GNUNET_asprintf (&node_id, "%06x-%08x\n",
440 pid,
441 script_num);
442
443
444 char *const script_argv[] = {NETJAIL_EXEC_SCRIPT,
445 m_char,
446 n_char,
447 GNUNET_OS_get_libexec_binary_path (
448 HELPER_CMDS_BINARY),
449 global_n_char,
450 local_m_char,
451 node_id,
452 NULL};
453
454 unsigned int helper_check = GNUNET_OS_check_helper_binary (
455 NETJAIL_EXEC_SCRIPT,
456 GNUNET_YES,
457 NULL);
458
459 tbc = GNUNET_new (struct TestingSystemCount);
460 tbc->ns = ns;
461 if (0 == n)
462 tbc->count = m;
463 else
464 tbc->count = (n - 1) * ns->local_m + m + ns->known;
465
466 GNUNET_CONTAINER_DLL_insert (ns->tbcs_head, ns->tbcs_tail,
467 tbc);
468
469
470 if (GNUNET_NO == helper_check)
471 {
472 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
473 "No SUID for %s!\n",
474 NETJAIL_EXEC_SCRIPT);
475 *ns->rv = 1;
476 }
477 else if (GNUNET_NO == helper_check)
478 {
479 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
480 "%s not found!\n",
481 NETJAIL_EXEC_SCRIPT);
482 *ns->rv = 1;
483 }
484
485 GNUNET_array_append (ns->helper, ns->n_helper, GNUNET_HELPER_start (
486 GNUNET_YES,
487 NETJAIL_EXEC_SCRIPT,
488 script_argv,
489 &helper_mst,
490 &exp_cb,
491 tbc));
492
493 helper = ns->helper[tbc->count - 1];
494
495 hkey = GNUNET_new (struct GNUNET_ShortHashCode);
496
497 plugin = topology->plugin;
498
499 if (0 == m)
500 {
501
502 GNUNET_CRYPTO_hash (&n, sizeof(n), &hc);
503 memcpy (hkey,
504 &hc,
505 sizeof (*hkey));
506 if (1 == GNUNET_CONTAINER_multishortmap_contains (topology->map_globals,
507 hkey))
508 {
509 node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals,
510 hkey);
511 if (NULL != node->plugin)
512 plugin = node->plugin;
513 }
514
515 }
516 else
517 {
518 GNUNET_CRYPTO_hash (&m, sizeof(m), &hc);
519 memcpy (hkey,
520 &hc,
521 sizeof (*hkey));
522 if (1 == GNUNET_CONTAINER_multishortmap_contains (topology->map_namespaces,
523 hkey))
524 {
525 namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces,
526 hkey);
527 GNUNET_CRYPTO_hash (&n, sizeof(n), &hc);
528 memcpy (hkey,
529 &hc,
530 sizeof (*hkey));
531 if (1 == GNUNET_CONTAINER_multishortmap_contains (namespace->nodes,
532 hkey))
533 {
534 node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes,
535 hkey);
536 if (NULL != node->plugin)
537 plugin = node->plugin;
538 }
539 }
540
541
542 }
543
544 msg = create_helper_init_msg_ (plugin);
545
546 GNUNET_array_append (ns->msg, ns->n_msg, &msg->header);
547
548 GNUNET_array_append (ns->shandle, ns->n_shandle, GNUNET_HELPER_send (
549 helper,
550 &msg->header,
551 GNUNET_NO,
552 &clear_msg,
553 tbc));
554
555 if (NULL == ns->shandle[tbc->count - 1])
556 {
557 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
558 "Send handle is NULL!\n");
559 GNUNET_free (msg);
560 *ns->rv = 1;
561 }
562}
563
564
565/**
566* This function starts a helper process for each node.
567*
568* @param cls closure.
569* @param cmd CMD being run.
570* @param is interpreter state.
571*/
572static void
573netjail_exec_run (void *cls,
574 struct GNUNET_TESTING_Interpreter *is)
575{
576 struct NetJailState *ns = cls;
577 struct GNUNET_CONFIGURATION_Handle *config =
578 GNUNET_CONFIGURATION_create ();
579
580 for (int i = 1; i <= ns->known; i++)
581 {
582 start_helper (ns, config,
583 i,
584 0);
585 }
586
587 for (int i = 1; i <= ns->global_n; i++)
588 {
589 for (int j = 1; j <= ns->local_m; j++)
590 {
591 start_helper (ns, config,
592 j,
593 i);
594 }
595 }
596}
597
598
599static void
600send_all_peers_started (unsigned int i, unsigned int j, struct NetJailState *ns)
601{
602 unsigned int total_number = ns->local_m * ns->global_n + ns->known;
603 struct GNUNET_CMDS_ALL_PEERS_STARTED *reply;
604 size_t msg_length;
605 struct GNUNET_HELPER_Handle *helper;
606 struct TestingSystemCount *tbc;
607
608 tbc = GNUNET_new (struct TestingSystemCount);
609 tbc->ns = ns;
610 // TODO This needs to be more generic. As we send more messages back and forth, we can not grow the arrays again and again, because this is to error prone.
611 if (0 == i)
612 tbc->count = j + total_number;
613 else
614 tbc->count = (i - 1) * ns->local_m + j + total_number + ns->known;
615
616 helper = ns->helper[tbc->count - 1 - total_number];
617 msg_length = sizeof(struct GNUNET_CMDS_ALL_PEERS_STARTED);
618 reply = GNUNET_new (struct GNUNET_CMDS_ALL_PEERS_STARTED);
619 reply->header.type = htons (
620 GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED);
621 reply->header.size = htons ((uint16_t) msg_length);
622
623 GNUNET_array_append (ns->msg, ns->n_msg, &reply->header);
624
625 struct GNUNET_HELPER_SendHandle *sh = GNUNET_HELPER_send (
626 helper,
627 &reply->header,
628 GNUNET_NO,
629 &clear_msg,
630 tbc);
631
632 GNUNET_array_append (ns->shandle, ns->n_shandle, sh);
633}
634
635
636/**
637 * This function checks on three different information.
638 *
639 * 1. Did all helpers start. This is only logged.
640 * 2. Did all peer start.
641 * In this case a GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED is send to all peers.
642 * 3. Did all peers finished the test case. In this case interpreter_next will be called.
643 *
644 */
645// FIXME: must change completely!
646static int
647netjail_start_finish (void *cls,
648 GNUNET_SCHEDULER_TaskCallback cont,
649 void *cont_cls)
650{
651 unsigned int ret = GNUNET_NO;
652 struct NetJailState *ns = cls;
653 unsigned int total_number = ns->local_m * ns->global_n + ns->known;
654
655
656 if (ns->number_of_local_test_finished == total_number)
657 {
658 ret = GNUNET_YES;
659 cont (cont_cls);
660 }
661
662 if (ns->number_of_testsystems_started == total_number)
663 {
664 ns->number_of_testsystems_started = 0;
665 }
666
667 if (ns->number_of_peers_started == total_number)
668 {
669 for (int i = 1; i <= ns->known; i++)
670 {
671 send_all_peers_started (0,i, ns);
672 }
673
674 for (int i = 1; i <= ns->global_n; i++)
675 {
676 for (int j = 1; j <= ns->local_m; j++)
677 {
678 send_all_peers_started (i,j, ns);
679 }
680 }
681 ns->number_of_peers_started = 0;
682 }
683 return ret;
684}
685
686
687/**
688 * Create command.
689 *
690 * @param label Name for the command.
691 * @param topology_config Configuration file for the test topology.
692 * @param rv Pointer to the return value of the test.
693 * @return command.
694 */
695struct GNUNET_TESTING_Command
696GNUNET_TESTING_cmd_netjail_start_testing_system_v2 (const char *label,
697 const char *topology_config,
698 unsigned int *rv)
699{
700 struct NetJailState *ns;
701
702 struct GNUNET_TESTING_NetjailTopology *topology =
703 GNUNET_TESTING_get_topo_from_file (topology_config);
704
705 ns = GNUNET_new (struct NetJailState);
706 ns->rv = rv;
707 ns->local_m = topology->nodes_m;
708 ns->global_n = topology->namespaces_n;
709 ns->known = topology->nodes_x;
710 ns->plugin_name = topology->plugin;
711 ns->topology = topology;
712
713 struct GNUNET_TESTING_Command cmd = {
714 .cls = ns,
715 .label = label,
716 .run = &netjail_exec_run,
717 .ac = &ns->ac,
718 .cleanup = &netjail_exec_cleanup,
719 .traits = &netjail_exec_traits
720 };
721
722 return cmd;
723}