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.c809
1 files changed, 0 insertions, 809 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 5e27a7a82..000000000
--- a/src/testing/testing_api_cmd_netjail_start_testsystem_v2.c
+++ /dev/null
@@ -1,809 +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 * Generic logging shortcut
34 */
35#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
36
37/**
38 * Struct to store messages send/received by the helper into a DLL
39 *
40 */
41struct HelperMessage
42{
43
44 /**
45 * Kept in a DLL.
46 */
47 struct HelperMessage *next;
48
49 /**
50 * Kept in a DLL.
51 */
52 struct HelperMessage *prev;
53
54 /**
55 * Size of the original message.
56 */
57 uint16_t bytes_msg;
58
59 /* Followed by @e bytes_msg of msg.*/
60};
61
62
63/**
64 * Struct to store information handed over to callbacks.
65 *
66 */
67struct NetJailState
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_tests_finished;
160
161 /**
162 * Number of local tests prepared to finish.
163 *
164 */
165 unsigned int number_of_local_tests_prepared;
166
167 /**
168 * Name of the test case plugin the helper will load.
169 *
170 */
171 char *plugin_name;
172
173 /**
174 * HEAD of the DLL containing TestingSystemCount.
175 *
176 */
177 struct TestingSystemCount *tbcs_head;
178
179 /**
180 * TAIL of the DLL containing TestingSystemCount.
181 *
182 */
183 struct TestingSystemCount *tbcs_tail;
184};
185
186/**
187 * Struct containing the number of the test environment and the NetJailState which
188 * will be handed to callbacks specific to a test environment.
189 */
190struct TestingSystemCount
191{
192 /**
193 * Kept in a DLL.
194 */
195 struct TestingSystemCount *next;
196
197 /**
198 * Kept in a DLL.
199 */
200 struct TestingSystemCount *prev;
201
202 /**
203 * The send handle for the helper
204 */
205 struct GNUNET_HELPER_SendHandle *shandle;// **shandle;
206
207 /**
208 * Size of the array NetJailState#shandle.
209 *
210 */
211 // unsigned int n_shandle;
212
213 /**
214 * The number of the test environment.
215 *
216 */
217 unsigned int count;
218
219 /**
220 * Struct to store information handed over to callbacks.
221 *
222 */
223 struct NetJailState *ns;
224};
225
226/**
227* Code to clean up resource this cmd used.
228*
229* @param cls closure
230* @param cmd current CMD being cleaned up.
231*/
232static void
233netjail_exec_cleanup (void *cls,
234 const struct GNUNET_TESTING_Command *cmd)
235{
236 struct NetJailState *ns = cls;
237 struct HelperMessage *message_pos;
238 struct TestingSystemCount *tbc_pos;
239
240 while (NULL != (message_pos = ns->hp_messages_head))
241 {
242 GNUNET_CONTAINER_DLL_remove (ns->hp_messages_head,
243 ns->hp_messages_tail,
244 message_pos);
245 GNUNET_free (message_pos);
246 }
247 while (NULL != (tbc_pos = ns->tbcs_head))
248 {
249 GNUNET_CONTAINER_DLL_remove (ns->tbcs_head,
250 ns->tbcs_tail,
251 tbc_pos);
252 GNUNET_free (tbc_pos);
253 }
254 GNUNET_free (ns);
255}
256
257
258/**
259 * This function prepares an array with traits.
260 *
261 */
262static int
263netjail_exec_traits (void *cls,
264 const void **ret,
265 const char *trait,
266 unsigned int index)
267{
268 struct NetJailState *ns = cls;
269 struct GNUNET_HELPER_Handle **helper = ns->helper;
270 struct HelperMessage *hp_messages_head = ns->hp_messages_head;
271
272
273 struct GNUNET_TESTING_Trait traits[] = {
274 {
275 .index = 0,
276 .trait_name = "helper_handles",
277 .ptr = (const void *) helper,
278 },
279 {
280 .index = 1,
281 .trait_name = "hp_msgs_head",
282 .ptr = (const void *) hp_messages_head,
283 },
284 GNUNET_TESTING_trait_end ()
285 };
286
287 return GNUNET_TESTING_get_trait (traits,
288 ret,
289 trait,
290 index);
291}
292
293
294/**
295 * Offer handles to testing cmd helper from trait
296 *
297 * @param cmd command to extract the message from.
298 * @param pt pointer to message.
299 * @return #GNUNET_OK on success.
300 */
301int
302GNUNET_TESTING_get_trait_helper_handles_v2 (
303 const struct GNUNET_TESTING_Command *cmd,
304 struct GNUNET_HELPER_Handle ***helper)
305{
306 return cmd->traits (cmd->cls,
307 (const void **) helper,
308 "helper_handles",
309 (unsigned int) 0);
310}
311
312
313/**
314 * Continuation function from GNUNET_HELPER_send()
315 *
316 * @param cls closure
317 * @param result #GNUNET_OK on success,
318 * #GNUNET_NO if helper process died
319 * #GNUNET_SYSERR during GNUNET_HELPER_stop
320 */
321static void
322clear_msg (void *cls,
323 int result)
324{
325 struct TestingSystemCount *tbc = cls;
326 struct NetJailState *ns = tbc->ns;
327
328 GNUNET_assert (NULL != tbc->shandle);// [tbc->count - 1]);
329 tbc->shandle = NULL;// [tbc->count - 1] = NULL;
330 GNUNET_free (ns->msg[tbc->count - 1]);
331 ns->msg[tbc->count - 1] = NULL;
332}
333
334
335/**
336 * Functions with this signature are called whenever a
337 * complete message is received by the tokenizer.
338 *
339 * Do not call GNUNET_SERVER_mst_destroy in callback
340 *
341 * @param cls closure
342 * @param client identification of the client
343 * @param message the actual message
344 *
345 * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
346 */
347static int
348helper_mst (void *cls,
349 const struct GNUNET_MessageHeader *message)
350{
351 // struct TestingSystemCount *tbc = cls;
352 struct NetJailState *ns = cls;// tbc->ns;
353 struct HelperMessage *hp_msg;
354
355 if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY == ntohs (message->type))
356 {
357 ns->number_of_testsystems_started++;
358 }
359 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED == ntohs (
360 message->type))
361 {
362 ns->number_of_peers_started++;
363 }
364 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED == ntohs (
365 message->type))
366 {
367 LOG (GNUNET_ERROR_TYPE_DEBUG,
368 "received prepare msg %u\n",
369 ns->number_of_local_tests_prepared);
370 ns->number_of_local_tests_prepared++;
371 }
372 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED == ntohs (
373 message->type))
374 {
375 ns->number_of_local_tests_finished++;
376 }
377 else
378 {
379 hp_msg = GNUNET_new (struct HelperMessage);
380 hp_msg->bytes_msg = message->size;
381 memcpy (&hp_msg[1], message, message->size);
382 GNUNET_CONTAINER_DLL_insert (ns->hp_messages_head, ns->hp_messages_tail,
383 hp_msg);
384 }
385
386 return GNUNET_OK;
387}
388
389
390/**
391 * Callback called if there was an exception during execution of the helper.
392 *
393 */
394static void
395exp_cb (void *cls)
396{
397 struct NetJailState *ns = cls;
398 unsigned int *rv = ns->rv;
399
400 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called exp_cb.\n");
401 *rv = 1;
402}
403
404
405/**
406 * Function to initialize a init message for the helper.
407 *
408 * @param m_char The actual node in a namespace. //TODO Change this to unsigned int
409 * @param n_char The actual namespace. //TODO Change this to unsigned int
410 * @param plugin_name Name of the test case plugin the helper will load.
411 *
412 */
413static struct GNUNET_CMDS_HelperInit *
414create_helper_init_msg_ (const char *plugin_name)
415{
416 struct GNUNET_CMDS_HelperInit *msg;
417 uint16_t plugin_name_len;
418 uint16_t msg_size;
419
420 GNUNET_assert (NULL != plugin_name);
421 plugin_name_len = strlen (plugin_name);
422 msg_size = sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_len;
423 msg = GNUNET_malloc (msg_size);
424 msg->header.size = htons (msg_size);
425 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT);
426 msg->plugin_name_size = htons (plugin_name_len);
427 GNUNET_memcpy ((char *) &msg[1],
428 plugin_name,
429 plugin_name_len);
430 return msg;
431}
432
433
434/**
435 * Function which start a single helper process.
436 *
437 */
438static void
439start_helper (struct NetJailState *ns, struct
440 GNUNET_CONFIGURATION_Handle *config,
441 unsigned int m,
442 unsigned int n)
443{
444 struct GNUNET_HELPER_Handle *helper;
445 struct GNUNET_CMDS_HelperInit *msg;
446 struct TestingSystemCount *tbc;
447 char *m_char, *n_char, *global_n_char, *local_m_char, *known_char, *node_id,
448 *plugin;
449 pid_t pid;
450 unsigned int script_num;
451 struct GNUNET_ShortHashCode *hkey;
452 struct GNUNET_HashCode hc;
453 struct GNUNET_TESTING_NetjailTopology *topology = ns->topology;
454 struct GNUNET_TESTING_NetjailNode *node;
455 struct GNUNET_TESTING_NetjailNamespace *namespace;
456 unsigned int *rv = ns->rv;
457
458
459 if (0 == n)
460 script_num = m - 1;
461 else
462 script_num = n - 1 + (n - 1) * ns->local_m + m + ns->known;
463 pid = getpid ();
464
465 GNUNET_asprintf (&m_char, "%u", m);
466 GNUNET_asprintf (&n_char, "%u", n);
467 GNUNET_asprintf (&local_m_char, "%u", ns->local_m);
468 GNUNET_asprintf (&global_n_char, "%u",ns->global_n);
469 GNUNET_asprintf (&known_char, "%u",ns->known);
470 GNUNET_asprintf (&node_id, "%06x-%08x\n",
471 pid,
472 script_num);
473
474
475 char *const script_argv[] = {NETJAIL_EXEC_SCRIPT,
476 m_char,
477 n_char,
478 GNUNET_OS_get_libexec_binary_path (
479 HELPER_CMDS_BINARY),
480 global_n_char,
481 local_m_char,
482 node_id,
483 NULL};
484
485 unsigned int helper_check = GNUNET_OS_check_helper_binary (
486 NETJAIL_EXEC_SCRIPT,
487 GNUNET_YES,
488 NULL);
489
490 tbc = GNUNET_new (struct TestingSystemCount);
491 tbc->ns = ns;
492 if (0 == n)
493 tbc->count = m;
494 else
495 tbc->count = (n - 1) * ns->local_m + m + ns->known;
496
497 GNUNET_CONTAINER_DLL_insert (ns->tbcs_head,
498 ns->tbcs_tail,
499 tbc);
500
501
502 if (GNUNET_NO == helper_check)
503 {
504 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
505 "No SUID for %s!\n",
506 NETJAIL_EXEC_SCRIPT);
507 *rv = 1;
508 }
509 else if (GNUNET_NO == helper_check)
510 {
511 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
512 "%s not found!\n",
513 NETJAIL_EXEC_SCRIPT);
514 *rv = 1;
515 }
516
517 GNUNET_array_append (ns->helper, ns->n_helper, GNUNET_HELPER_start (
518 GNUNET_YES,
519 NETJAIL_EXEC_SCRIPT,
520 script_argv,
521 &helper_mst,
522 &exp_cb,
523 ns));
524
525 helper = ns->helper[tbc->count - 1];
526
527 hkey = GNUNET_new (struct GNUNET_ShortHashCode);
528
529 plugin = topology->plugin;
530
531 if (0 == m)
532 {
533
534 GNUNET_CRYPTO_hash (&n, sizeof(n), &hc);
535 memcpy (hkey,
536 &hc,
537 sizeof (*hkey));
538 if (1 == GNUNET_CONTAINER_multishortmap_contains (topology->map_globals,
539 hkey))
540 {
541 node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals,
542 hkey);
543 if (NULL != node->plugin)
544 plugin = node->plugin;
545 }
546
547 }
548 else
549 {
550 GNUNET_CRYPTO_hash (&m, sizeof(m), &hc);
551 memcpy (hkey,
552 &hc,
553 sizeof (*hkey));
554 if (1 == GNUNET_CONTAINER_multishortmap_contains (topology->map_namespaces,
555 hkey))
556 {
557 namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces,
558 hkey);
559 GNUNET_CRYPTO_hash (&n, sizeof(n), &hc);
560 memcpy (hkey,
561 &hc,
562 sizeof (*hkey));
563 if (1 == GNUNET_CONTAINER_multishortmap_contains (namespace->nodes,
564 hkey))
565 {
566 node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes,
567 hkey);
568 if (NULL != node->plugin)
569 plugin = node->plugin;
570 }
571 }
572
573
574 }
575
576 msg = create_helper_init_msg_ (plugin);
577
578 GNUNET_array_append (ns->msg, ns->n_msg, &msg->header);
579
580 // GNUNET_array_append (tbc->shandle, tbc->n_shandle,
581 tbc->shandle = GNUNET_HELPER_send (
582 helper,
583 &msg->header,
584 GNUNET_NO,
585 &clear_msg,
586 tbc); // );
587
588 if (NULL == tbc->shandle)// [tbc->count - 1])
589 {
590 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
591 "Send handle is NULL!\n");
592 GNUNET_free (msg);
593 *rv = 1;
594 }
595}
596
597
598/**
599* This function starts a helper process for each node.
600*
601* @param cls closure.
602* @param cmd CMD being run.
603* @param is interpreter state.
604*/
605static void
606netjail_exec_run (void *cls,
607 const struct GNUNET_TESTING_Command *cmd,
608 struct GNUNET_TESTING_Interpreter *is)
609{
610 struct NetJailState *ns = cls;
611 struct GNUNET_CONFIGURATION_Handle *config =
612 GNUNET_CONFIGURATION_create ();
613
614 for (int i = 1; i <= ns->known; i++)
615 {
616 start_helper (ns, config,
617 i,
618 0);
619 }
620
621 for (int i = 1; i <= ns->global_n; i++)
622 {
623 for (int j = 1; j <= ns->local_m; j++)
624 {
625 start_helper (ns, config,
626 j,
627 i);
628 }
629 }
630}
631
632
633static void
634send_message_to_locals (
635 unsigned int i,
636 unsigned int j,
637 struct NetJailState *ns,
638 struct GNUNET_MessageHeader *header
639 )
640{
641 // unsigned int total_number = ns->local_m * ns->global_n + ns->known;
642 struct GNUNET_HELPER_Handle *helper;
643 struct TestingSystemCount *tbc;
644
645 LOG (GNUNET_ERROR_TYPE_DEBUG,
646 "send message to locals\n");
647 tbc = GNUNET_new (struct TestingSystemCount);
648 tbc->ns = ns;
649 // 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.
650 if (0 == i)
651 tbc->count = j; // + total_number;
652 else
653 tbc->count = (i - 1) * ns->local_m + j + ns->known; // + total_number ;
654
655 helper = ns->helper[tbc->count - 1];// - total_number];
656
657 GNUNET_array_append (ns->msg, ns->n_msg, header);
658
659 struct GNUNET_HELPER_SendHandle *sh = GNUNET_HELPER_send (
660 helper,
661 header,
662 GNUNET_NO,
663 &clear_msg,
664 tbc);
665
666 tbc->shandle = sh;
667 // GNUNET_array_append (tbc->shandle, tbc->n_shandle, sh);
668}
669
670
671static void
672send_all_local_tests_prepared (unsigned int i, unsigned int j, struct
673 NetJailState *ns)
674{
675 struct GNUNET_CMDS_ALL_LOCAL_TESTS_PREPARED *reply;
676 size_t msg_length;
677
678
679 msg_length = sizeof(struct GNUNET_CMDS_ALL_LOCAL_TESTS_PREPARED);
680 reply = GNUNET_new (struct GNUNET_CMDS_ALL_LOCAL_TESTS_PREPARED);
681 reply->header.type = htons (
682 GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED);
683 reply->header.size = htons ((uint16_t) msg_length);
684
685 send_message_to_locals (i, j, ns, &reply->header);
686}
687
688
689static void
690send_all_peers_started (unsigned int i, unsigned int j, struct NetJailState *ns)
691{
692
693 struct GNUNET_CMDS_ALL_PEERS_STARTED *reply;
694 size_t msg_length;
695
696
697 msg_length = sizeof(struct GNUNET_CMDS_ALL_PEERS_STARTED);
698 reply = GNUNET_new (struct GNUNET_CMDS_ALL_PEERS_STARTED);
699 reply->header.type = htons (
700 GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED);
701 reply->header.size = htons ((uint16_t) msg_length);
702
703 send_message_to_locals (i, j, ns, &reply->header);
704}
705
706
707/**
708 * This function checks on three different information.
709 *
710 * 1. Did all helpers start. This is only logged.
711 * 2. Did all peer start.
712 * In this case a GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED is send to all peers.
713 * 3. Did all peers finished the test case. In this case interpreter_next will be called.
714 *
715 */
716static int
717netjail_start_finish (void *cls,
718 GNUNET_SCHEDULER_TaskCallback cont,
719 void *cont_cls)
720{
721 unsigned int ret = GNUNET_NO;
722 struct NetJailState *ns = cls;
723 unsigned int total_number = ns->local_m * ns->global_n + ns->known;
724
725
726 if (ns->number_of_local_tests_finished == total_number)
727 {
728 ret = GNUNET_YES;
729 cont (cont_cls);
730 }
731
732 if (ns->number_of_local_tests_prepared == total_number)
733 {
734 for (int i = 1; i <= ns->known; i++)
735 {
736 send_all_local_tests_prepared (0,i, ns);
737 }
738
739 for (int i = 1; i <= ns->global_n; i++)
740 {
741 for (int j = 1; j <= ns->local_m; j++)
742 {
743 send_all_local_tests_prepared (i,j, ns);
744 }
745 }
746 }
747
748 if (ns->number_of_testsystems_started == total_number)
749 {
750 ns->number_of_testsystems_started = 0;
751 }
752
753 if (ns->number_of_peers_started == total_number)
754 {
755 for (int i = 1; i <= ns->known; i++)
756 {
757 send_all_peers_started (0,i, ns);
758 }
759
760 for (int i = 1; i <= ns->global_n; i++)
761 {
762 for (int j = 1; j <= ns->local_m; j++)
763 {
764 send_all_peers_started (i,j, ns);
765 }
766 }
767 ns->number_of_peers_started = 0;
768 }
769 return ret;
770}
771
772
773/**
774 * Create command.
775 *
776 * @param label Name for the command.
777 * @param topology_config Configuration file for the test topology.
778 * @param rv Pointer to the return value of the test.
779 * @return command.
780 */
781struct GNUNET_TESTING_Command
782GNUNET_TESTING_cmd_netjail_start_testing_system_v2 (const char *label,
783 const char *topology_config,
784 unsigned int *rv)
785{
786 struct NetJailState *ns;
787
788 struct GNUNET_TESTING_NetjailTopology *topology =
789 GNUNET_TESTING_get_topo_from_file (topology_config);
790
791 ns = GNUNET_new (struct NetJailState);
792 ns->rv = rv;
793 ns->local_m = topology->nodes_m;
794 ns->global_n = topology->namespaces_n;
795 ns->known = topology->nodes_x;
796 ns->plugin_name = topology->plugin;
797 ns->topology = topology;
798
799 struct GNUNET_TESTING_Command cmd = {
800 .cls = ns,
801 .label = label,
802 .run = &netjail_exec_run,
803 .finish = &netjail_start_finish,
804 .cleanup = &netjail_exec_cleanup,
805 .traits = &netjail_exec_traits
806 };
807
808 return cmd;
809}