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