aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authort3sserakt <t3ss@posteo.de>2023-07-14 16:59:30 +0200
committert3sserakt <t3ss@posteo.de>2023-07-14 16:59:30 +0200
commit40a5a650d3b61aca9474692416adeba7272e61b3 (patch)
tree0b02421352144cb978a9016ccb1c61f7f1d9519b /src
parentb138491b9e4878607ea954254f84f1106202017b (diff)
downloadgnunet-40a5a650d3b61aca9474692416adeba7272e61b3.tar.gz
gnunet-40a5a650d3b61aca9474692416adeba7272e61b3.zip
NEWS: Added command to execute a script.
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_testing_ng_lib.h206
-rw-r--r--src/testing/testing_api_cmd_exec_bash_script.c217
2 files changed, 422 insertions, 1 deletions
diff --git a/src/include/gnunet_testing_ng_lib.h b/src/include/gnunet_testing_ng_lib.h
index 77e9bd74a..98ba65b59 100644
--- a/src/include/gnunet_testing_ng_lib.h
+++ b/src/include/gnunet_testing_ng_lib.h
@@ -519,6 +519,20 @@ struct GNUNET_TESTING_Timer
519 unsigned int num_retries; 519 unsigned int num_retries;
520}; 520};
521 521
522/**
523 * Command to execute a script synchronously.
524 *
525 * @param label Label of the command.
526 * @param script The name of the script.
527 * @param script_argv The arguments of the script.
528*/
529const struct GNUNET_TESTING_Command
530GNUNET_TESTING_cmd_exec_bash_script (const char *label,
531 const char *script,
532 char *const script_argv[],
533 int argc,
534 GNUNET_ChildCompletedCallback cb);
535
522 536
523/** 537/**
524 * Retrieve peer identity from the test system with the unique node id. 538 * Retrieve peer identity from the test system with the unique node id.
@@ -603,6 +617,188 @@ GNUNET_TESTING_get_trait (const struct GNUNET_TESTING_Trait *traits,
603/* ****** Specific traits supported by this component ******* */ 617/* ****** Specific traits supported by this component ******* */
604 618
605 619
620typedef void *
621(*GNUNET_TESTING_notify_connect_cb) (struct GNUNET_TESTING_Interpreter *is,
622 const struct GNUNET_PeerIdentity *peer);
623
624
625/**
626 * Struct to store information needed in callbacks.
627 *
628 */
629struct ConnectPeersState
630{
631 /**
632 * Context for our asynchronous completion.
633 */
634 struct GNUNET_TESTING_AsyncContext ac;
635
636 GNUNET_TESTING_notify_connect_cb notify_connect;
637
638 /**
639 * The testing system of this node.
640 */
641 const struct GNUNET_TESTING_System *tl_system;
642
643 // Label of the cmd which started the test system.
644 const char *create_label;
645
646 /**
647 * Number globally identifying the node.
648 *
649 */
650 uint32_t num;
651
652 /**
653 * Label of the cmd to start a peer.
654 *
655 */
656 const char *start_peer_label;
657
658 /**
659 * The topology of the test setup.
660 */
661 struct GNUNET_TESTING_NetjailTopology *topology;
662
663 /**
664 * Connections to other peers.
665 */
666 struct GNUNET_TESTING_NodeConnection *node_connections_head;
667
668 struct GNUNET_TESTING_Interpreter *is;
669
670 /**
671 * Number of connections.
672 */
673 unsigned int con_num;
674
675 /**
676 * Number of additional connects this cmd will wait for not triggered by this cmd.
677 */
678 unsigned int additional_connects;
679
680 /**
681 * Number of connections we already have a notification for.
682 */
683 unsigned int con_num_notified;
684
685 /**
686 * Number of additional connects this cmd will wait for not triggered by this cmd we already have a notification for.
687 */
688 unsigned int additional_connects_notified;
689
690 /**
691 * Flag indicating, whether the command is waiting for peers to connect that are configured to connect.
692 */
693 unsigned int wait_for_connect;
694};
695
696
697struct GNUNET_TESTING_StartPeerState
698{
699 /**
700 * Context for our asynchronous completion.
701 */
702 struct GNUNET_TESTING_AsyncContext ac;
703
704 /**
705 * The ip of a node.
706 */
707 char *node_ip;
708
709 /**
710 * Receive callback
711 */
712 struct GNUNET_MQ_MessageHandler *handlers;
713
714 /**
715 * GNUnet configuration file used to start a peer.
716 */
717 char *cfgname;
718
719 /**
720 * Peer's configuration
721 */
722 struct GNUNET_CONFIGURATION_Handle *cfg;
723
724 /**
725 * struct GNUNET_TESTING_Peer returned by GNUNET_TESTING_peer_configure.
726 */
727 struct GNUNET_TESTING_Peer *peer;
728
729 /**
730 * Peer identity
731 */
732 struct GNUNET_PeerIdentity id;
733
734 /**
735 * Peer's transport service handle
736 */
737 struct GNUNET_TRANSPORT_CoreHandle *th;
738
739 /**
740 * Application handle
741 */
742 struct GNUNET_TRANSPORT_ApplicationHandle *ah;
743
744 /**
745 * Peer's PEERSTORE Handle
746 */
747 struct GNUNET_PEERSTORE_Handle *ph;
748
749 /**
750 * Hello get task
751 */
752 struct GNUNET_SCHEDULER_Task *rh_task;
753
754 /**
755 * Peer's transport get hello handle to retrieve peer's HELLO message
756 */
757 struct GNUNET_PEERSTORE_IterateContext *pic;
758
759 /**
760 * Hello
761 */
762 char *hello;
763
764 /**
765 * Hello size
766 */
767 size_t hello_size;
768
769 /**
770 * The label of the command which was started by calling GNUNET_TESTING_cmd_system_create.
771 */
772 char *system_label;
773
774 /**
775 * An unique number to identify the peer
776 */
777 unsigned int no;
778
779 /**
780 * A map with struct GNUNET_MQ_Handle values for each peer this peer
781 * is connected to.
782 */
783 struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map;
784
785 /**
786 * Test setup for this peer.
787 */
788 const struct GNUNET_TESTING_System *tl_system;
789
790 /**
791 * Callback which is called on neighbour connect events.
792 */
793 GNUNET_TESTING_notify_connect_cb notify_connect;
794
795 /**
796 * Flag indicating, if udp broadcast should be switched on.
797 */
798 enum GNUNET_GenericReturnValue broadcast;
799};
800
801
606/** 802/**
607 * Create headers for a trait with name @a name for 803 * Create headers for a trait with name @a name for
608 * statically allocated data of type @a type. 804 * statically allocated data of type @a type.
@@ -697,7 +893,15 @@ GNUNET_TESTING_get_trait (const struct GNUNET_TESTING_Trait *traits,
697 */ 893 */
698#define GNUNET_TESTING_SIMPLE_TRAITS(op) \ 894#define GNUNET_TESTING_SIMPLE_TRAITS(op) \
699 op (batch_cmds, struct GNUNET_TESTING_Command *) \ 895 op (batch_cmds, struct GNUNET_TESTING_Command *) \
700 op (process, struct GNUNET_OS_Process *) 896 op (process, struct GNUNET_OS_Process *) \
897 op (peer_id, const struct GNUNET_PeerIdentity) \
898 op (connected_peers_map, const struct GNUNET_CONTAINER_MultiShortmap) \
899 op (hello_size, const size_t) \
900 op (hello, const char) \
901 op (application_handle, const struct GNUNET_TRANSPORT_ApplicationHandle) \
902 op (connect_peer_state, const struct ConnectPeersState) \
903 op (state, const struct GNUNET_TESTING_StartPeerState) \
904 op (broadcast, const enum GNUNET_GenericReturnValue)
701 905
702 906
703/** 907/**
diff --git a/src/testing/testing_api_cmd_exec_bash_script.c b/src/testing/testing_api_cmd_exec_bash_script.c
new file mode 100644
index 000000000..5b9f5cbbb
--- /dev/null
+++ b/src/testing/testing_api_cmd_exec_bash_script.c
@@ -0,0 +1,217 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2023 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_api_cmd_local_test_prepared.c
23 * @brief cmd to block the interpreter loop until all peers started.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29
30#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
31
32struct BashScriptState
33{
34 /**
35 * Context for our asynchronous completion.
36 */
37 struct GNUNET_TESTING_AsyncContext ac;
38
39 /**
40 * Callback handed over to the command, which should
41 * be called upon death or completion of the script.
42 */
43 GNUNET_ChildCompletedCallback cb;
44
45 // Child Wait handle
46 struct GNUNET_ChildWaitHandle *cwh;
47
48 /**
49 * The process id of the script.
50 */
51 struct GNUNET_OS_Process *start_proc;
52
53 /**
54 * Script this cmd will execute.
55 */
56 const char *script;
57
58
59 /**
60 * Arguments for the script
61 */
62 char **script_argv;
63
64 /**
65 * Size of script_argv.
66 */
67 int argc;
68};
69
70/**
71 * The cleanup function of this cmd frees resources the cmd allocated.
72 *
73 */
74static void
75exec_bash_script_cleanup (void *cls)
76{
77 struct BashScriptState *bss = cls;
78
79 if (NULL != bss->cwh)
80 {
81 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
82 "Cancel child\n");
83 GNUNET_wait_child_cancel (bss->cwh);
84 bss->cwh = NULL;
85 }
86 if (NULL != bss->start_proc)
87 {
88 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
89 "Kill process\n");
90 GNUNET_assert (0 ==
91 GNUNET_OS_process_kill (bss->start_proc,
92 SIGKILL));
93 GNUNET_assert (GNUNET_OK ==
94 GNUNET_OS_process_wait (bss->start_proc));
95 GNUNET_OS_process_destroy (bss->start_proc);
96 bss->start_proc = NULL;
97 }
98 GNUNET_free (bss);
99}
100
101/**
102 * Callback which will be called if the setup script finished.
103 *
104 */
105static void
106child_completed_callback (void *cls,
107 enum GNUNET_OS_ProcessStatusType type,
108 long unsigned int exit_code)
109{
110 struct BashScriptState *bss = cls;
111
112 GNUNET_OS_process_destroy (bss->start_proc);
113 bss->start_proc = NULL;
114 bss->cwh = NULL;
115 if (0 == exit_code)
116 {
117 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
118 "Child succeeded!\n",
119 exit_code);
120 GNUNET_TESTING_async_finish (&bss->ac);
121 }
122 else
123 {
124 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
125 "Child failed with error %lu!\n",
126 exit_code);
127 GNUNET_TESTING_async_fail (&bss->ac);
128 }
129 bss->cb (cls, type, exit_code);
130}
131
132/**
133 * Run method of the command created by the interpreter to wait for another
134 * command to finish.
135 *
136 */
137static void
138exec_bash_script_run (void *cls,
139 struct GNUNET_TESTING_Interpreter *is)
140{
141 struct BashScriptState *bss = cls;
142 enum GNUNET_GenericReturnValue helper_check;
143 char *argv[bss->argc + 2];
144
145 char *data_dir;
146 char *script_name;
147
148 data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
149 GNUNET_asprintf (&script_name, "%s%s", data_dir, bss->script);
150
151 helper_check = GNUNET_OS_check_helper_binary (
152 script_name,
153 GNUNET_YES,
154 NULL);
155
156 LOG (GNUNET_ERROR_TYPE_DEBUG,
157 "script_name %s\n",
158 script_name);
159
160 if (GNUNET_NO == helper_check)
161 {
162 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
163 "No SUID for %s!\n",
164 script_name);
165 GNUNET_TESTING_interpreter_fail (is);
166 return;
167 }
168 if (GNUNET_SYSERR == helper_check)
169 {
170 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
171 "%s not found!\n",
172 script_name);
173 GNUNET_TESTING_interpreter_fail (is);
174 return;
175 }
176 argv[0] = script_name;
177 if (NULL != bss->script_argv)
178 {
179 for (int i = 0; i < bss->argc;i++)
180 argv[i + 1] = bss->script_argv[i];
181 }
182 argv[bss->argc] = NULL;
183
184 bss->start_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR,
185 NULL,
186 NULL,
187 NULL,
188 script_name,
189 argv);
190 bss->cwh = GNUNET_wait_child (bss->start_proc,
191 &child_completed_callback,
192 bss);
193 GNUNET_break (NULL != bss->cwh);
194}
195
196const struct GNUNET_TESTING_Command
197GNUNET_TESTING_cmd_exec_bash_script (const char *label,
198 const char *script,
199 char *const script_argv[],
200 int argc,
201 GNUNET_ChildCompletedCallback cb)
202{
203 struct BashScriptState *bss;
204
205 bss = GNUNET_new (struct BashScriptState);
206 bss->script = script;
207 bss->script_argv = script_argv;
208 bss->argc = argc;
209 bss->cb = cb;
210
211 return GNUNET_TESTING_command_new (bss,
212 label,
213 &exec_bash_script_run,
214 &exec_bash_script_cleanup,
215 NULL,
216 &bss->ac);
217}