GNUnet 0.22.0
testing_api_loop.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021-2024 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
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_testing_lib.h"
31#include "testing_api_loop.h"
33
34
36{
39
44
46};
47
53{
58
63
67 void *rc_cls;
68
73
78
83
88
93
98
101
106
110 unsigned int cmds_n;
111
115 unsigned int n_helpers;
116
122 int ip;
123
129
134
139 bool skip;
140
141};
142
143
144const struct GNUNET_TESTING_Command *
147 const char *label)
148{
149 if (NULL == label)
150 {
152 "Attempt to lookup command for empty label\n");
153 return NULL;
154 }
155 for (int i = is->ip; i >= 0; i--)
156 {
157 const struct GNUNET_TESTING_Command *cmd = &is->commands[i];
158
159 /* Give precedence to top-level commands. */
160 if ( (NULL != cmd->run) &&
161 (0 == strcmp (cmd->label.value,
162 label)) )
163 return cmd;
164
166 {
167 struct GNUNET_TESTING_Command **batch;
168 const struct GNUNET_TESTING_Command *current;
169 const struct GNUNET_TESTING_Command *icmd;
170 const struct GNUNET_TESTING_Command *match;
171
174 &current));
177 &batch));
178 /* We must do the loop forward, but we can find the last match */
179 match = NULL;
180 for (unsigned int j = 0;
181 NULL != (icmd = &(*batch)[j])->run;
182 j++)
183 {
184 if (current == icmd)
185 break; /* do not go past current command */
186 if ( (NULL != icmd->run) &&
187 (0 == strcmp (icmd->label.value,
188 label)) )
189 match = icmd;
190 }
191 if (NULL != match)
192 return match;
193 }
194 }
196 "Command `%s' not found\n",
197 label);
198 return NULL;
199}
200
201
202const struct GNUNET_TESTING_Command *
205 const char *name)
206{
207 const struct GNUNET_TESTING_Command *cmd;
208 struct GNUNET_HashCode h_name = {0};
209
211 strlen (name),
212 &h_name);
214 &h_name);
215 if (NULL == cmd)
217 "Command not found by variable name: %s\n",
218 name);
219 return cmd;
220}
221
222
223static void
224send_finished (void *cls,
226{
227 struct SendContext *sctx = cls;
228 struct GNUNET_TESTING_Interpreter *is = sctx->is;
229
233 sctx);
234 GNUNET_free (sctx);
235}
236
237
238void
240 const struct GNUNET_MessageHeader *hdr)
241{
243 "Send notification to children of type %u\n",
244 (unsigned int) ntohs (hdr->type));
245 for (unsigned int i = 0; i<is->n_helpers; i++)
246 {
247 struct SendContext *sctx;
248
249 sctx = GNUNET_new (struct SendContext);
250 sctx->is = is;
253 sctx);
254 sctx->send_handle
256 hdr,
257 false, /* never drop */
259 sctx);
260 }
261}
262
263
264void
266 const struct GNUNET_MessageHeader *hdr)
267{
268 /* We must have a parent */
269 if (NULL == is->parent_writer)
271 is->parent_writer (hdr);
272}
273
274
280static void
281finish_test (void *cls)
282{
283 struct GNUNET_TESTING_Interpreter *is = cls;
284 struct GNUNET_TESTING_Command *cmd;
285 const char *label;
286
287 is->finishing = true;
288 is->final_task = NULL;
290 if (NULL == is->commands[is->ip].run)
291 label = "END";
293 "Interpreter finishes at `%s' with status %d\n",
294 label,
295 is->result);
296 for (unsigned int j = 0;
297 NULL != (cmd = &is->commands[j])->run;
298 j++)
299 if (NULL != cmd->cleanup)
300 cmd->cleanup (cmd->cls);
301 if (NULL != is->task)
302 {
304 is->task = NULL;
305 }
306 if (NULL != is->timeout_task)
307 {
309 is->timeout_task = NULL;
310 }
311 {
312 struct SendContext *sctx;
313
314 while (NULL != (sctx = is->sender_head))
315 {
318 sctx);
320 GNUNET_free (sctx);
321 }
322 }
324 is->rc (is->rc_cls,
325 is->skip ? GNUNET_NO : is->result);
326 if (NULL != is->barriers)
327 {
329 is->barriers = NULL;
330 }
331 if (NULL != is->vars)
332 {
334 is->vars = NULL;
335 }
337 GNUNET_free (is);
338}
339
340
346static void
347interpreter_run (void *cls);
348
349
350void
352{
353 static unsigned long long ipc;
354 static struct GNUNET_TIME_Absolute last_report;
355 struct GNUNET_TESTING_Interpreter *is = cls;
356 struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip];
357
358 if (GNUNET_SYSERR == is->result)
359 return; /* ignore, we already failed! */
360
362 {
364 {
365 /* batch is done */
367 is->ip++;
368 }
369 }
370 else
371 {
373 is->ip++;
374 }
375
376 if (0 == (ipc % 1000))
377 {
378 if (0 != ipc)
380 "Interpreter executed 1000 instructions in %s\n",
383 true));
384 last_report = GNUNET_TIME_absolute_get ();
385 }
386 ipc++;
388 is);
389}
390
391
392void
395 struct GNUNET_TESTING_Command *cmd)
396{
397 cmd->last_req_time
399 if (0 == cmd->num_tries)
400 cmd->start_time = cmd->last_req_time;
401 cmd->num_tries = 1;
402 if (NULL != cmd->name)
403 {
404 struct GNUNET_HashCode h_name = {0};
405
407 strlen (cmd->name),
408 &h_name);
410 is->vars,
411 &h_name,
412 cmd,
414 }
415 if (NULL != cmd->ac)
416 {
417 cmd->ac->is = is;
418 cmd->ac->finished = GNUNET_NO;
419 cmd->ac->next_called = false;
420 }
421 cmd->run (cmd->cls,
422 is);
423 if ( (! GNUNET_TESTING_cmd_is_batch_ (cmd)) &&
424 ( (NULL == cmd->ac) ||
425 (cmd->asynchronous_finish) ) )
426 {
427 if (NULL != cmd->ac)
428 cmd->ac->next_called = true;
430 }
431}
432
433
439static void
441{
442 struct GNUNET_TESTING_Interpreter *is = cls;
443 struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip];
444
445 is->task = NULL;
446 if (NULL == cmd->run)
447 {
449 "Running command END\n");
451 finish_test (is);
452 return;
453 }
455 "Running command `%s'\n",
456 cmd->label.value);
458 cmd);
459}
460
461
462void
464{
465 struct GNUNET_TESTING_Command *cmd
466 = &is->commands[is->ip];
467
468 if (GNUNET_SYSERR == is->result)
469 {
470 GNUNET_break (0);
471 return; /* ignore, we already failed! */
472 }
473 if (NULL == cmd)
474 {
476 "Failed with CMD being NULL!\n");
477 }
478 else
479 {
480 const struct GNUNET_TESTING_Command *pos = cmd;
481
483 "Failed during command `%s'\n",
484 cmd->label.value);
485 while (GNUNET_TESTING_cmd_is_batch_ (pos))
486 {
489 &pos));
491 "Failed in batch during command `%s'\n",
492 pos->label.value);
493 }
494 }
495 if (NULL != is->timeout_task)
496 {
498 is->timeout_task = NULL;
499 }
501 GNUNET_assert (NULL == is->final_task);
503 is);
504}
505
506
507void
510{
511 is->skip = true;
513}
514
515
516void
518{
522}
523
524
525void
527{
530 if (NULL != ac->notify_finished)
531 {
533 ac->notify_finished = NULL;
534 }
535 if (! ac->next_called)
536 {
537 ac->next_called = true;
539 }
540}
541
542
548static void
550{
551 struct GNUNET_TESTING_Interpreter *is = cls;
552
553 is->timeout_task = NULL;
555 "Terminating test due to global timeout\n");
557 finish_test (is);
558}
559
560
561static void
563 const struct GNUNET_TESTING_Command *bcommand,
564 const struct GNUNET_TESTING_Command *commands)
565{
566 unsigned int i;
567
569 false);
570 /* get the number of commands */
571 for (i = 0; NULL != commands[i].run; i++)
572 ;
573 if (NULL != bcommand)
574 i++;
575 is->cmds_n = i + 1;
577 "Got %u commands\n",
578 i);
580 (i + 1)
581 * sizeof (struct GNUNET_TESTING_Command));
582 GNUNET_assert (NULL != is->commands);
583 if (NULL == bcommand)
584 {
585 memcpy (is->commands,
586 commands,
587 sizeof (struct GNUNET_TESTING_Command) * i);
588 }
589 else
590 {
591 is->commands[0] = *bcommand;
592 memcpy (&is->commands[1],
593 commands,
594 sizeof (struct GNUNET_TESTING_Command) * i);
595 }
597 is);
598}
599
600
605 void *rc_cls)
606{
608
612 &do_timeout,
613 is);
614 is->rc = rc;
615 is->rc_cls = rc_cls;
616 setup_is (is,
617 NULL,
618 commands);
619 return is;
620}
621
622
623static struct GNUNET_TESTING_Interpreter *
625 void *cls,
626 const char *topology_data,
627 uint32_t inherited_barrier_count,
628 const struct GNUNET_ShortHashCode *inherited_barriers,
631 void *finish_cb_cls)
632{
633 const struct GNUNET_TESTING_Command *commands = cls;
635
637 if (0 != inherited_barrier_count)
638 {
639 is->barriers
640 = GNUNET_CONTAINER_multishortmap_create (inherited_barrier_count * 4 / 3,
641 true);
642 for (unsigned int j = 0; j<inherited_barrier_count; j++)
643 {
644 struct GNUNET_TESTING_Barrier *barrier;
645
646 barrier = GNUNET_new (struct GNUNET_TESTING_Barrier);
647 barrier->barrier_id = inherited_barriers[j];
648 barrier->inherited = true;
650 is->barriers,
651 &barrier->barrier_id,
652 barrier,
654 }
655 }
656 is->parent_writer = parent_writer;
657 is->rc = finish_cb;
658 is->rc_cls = finish_cb_cls;
659 {
660 struct GNUNET_TESTING_Command bcmd;
661
663 "topology",
665 "_boot_",
666 topology_data));
667 setup_is (is,
668 &bcmd,
669 commands);
670 }
671 return is;
672
673}
674
675
678 const struct GNUNET_TESTING_Command *commands)
679{
681 struct GNUNET_TESTING_Command *commands_copy;
682 unsigned int i;
683
684 for (i = 0; NULL != commands[i].run; i++)
685 ;
686 commands_copy = GNUNET_malloc_large ( (i + 1)
687 * sizeof (struct
689 memcpy (commands_copy,
690 commands,
691 sizeof (struct GNUNET_TESTING_Command) * i + 1);
692
694 api->cls = (void *) commands_copy;
696 return api;
697}
698
699
700void
702 struct GNUNET_HELPER_Handle *helper)
703{
705 is->n_helpers,
706 helper);
707}
708
709
712 const struct GNUNET_ShortHashCode *create_key)
713{
715 create_key);
716}
717
718
721 const char *barrier_name)
722{
723 struct GNUNET_ShortHashCode create_key;
724
725 if (NULL == is->barriers)
726 return NULL;
728 &create_key);
730 &create_key);
731}
732
733
734void
736 struct GNUNET_TESTING_Barrier *barrier)
737{
738 if (NULL == is->barriers)
739 is->barriers
741 true);
742 /* We always use the barrier we encountered
743 most recently under a given label, thus replace */
745 is->barriers,
746 &barrier->barrier_id,
747 barrier,
749}
750
751
752unsigned int
755{
757}
758
759
760void
764 void *cb_cls)
765{
766 if (NULL != is->barriers)
768 cb,
769 cb_cls);
770}
771
772
773void
776 bool asc,
778 void *cb_cls)
779{
780 unsigned int start;
781 unsigned int end;
782 int inc;
783
784 if (asc)
785 {
786 inc = 1;
787 start = 0;
788 end = is->ip;
789 }
790 else
791 {
792 inc = -1;
793 start = is->ip;
794 end = 0;
795 }
796 for (unsigned int off = start; off != end + inc; off += inc)
797 {
798 const struct GNUNET_TESTING_Command *cmd
799 = &is->commands[off];
800
801 cb (cb_cls,
802 cmd);
803 }
804}
805
806
807void
810{
813}
814
815
816void
819{
821}
822
823
824const char *
827{
828 return is->commands[is->ip].label.value;
829}
830
831
836{
840 const char *target_label;
841
847 unsigned int counter;
848};
849
850
863 const struct GNUNET_TESTING_Command *cmd,
864 const struct GNUNET_TESTING_Command *target)
865{
866 unsigned int new_ip;
867 struct GNUNET_TESTING_Command **batch;
868 const struct GNUNET_TESTING_Command *current;
869 const struct GNUNET_TESTING_Command *icmd;
870 bool found = false;
871
874 &current));
877 &batch));
878 for (new_ip = 0;
879 NULL != (icmd = &((*batch)[new_ip]))->run;
880 new_ip++)
881 {
882 if (current == target)
883 current = NULL;
884 if (icmd == target)
885 {
886 found = true;
887 break;
888 }
890 {
892 = seek_batch (is,
893 icmd,
894 target);
895 if (GNUNET_SYSERR == ret)
896 return GNUNET_SYSERR; /* failure! */
897 if (GNUNET_OK == ret)
898 {
899 found = true;
900 break;
901 }
902 }
903 }
904 if (! found)
905 return GNUNET_NO; /* not found */
906 if (NULL == current)
907 {
908 /* refuse to jump forward */
909 GNUNET_break (0);
911 return GNUNET_SYSERR;
912 }
914 new_ip);
915 return GNUNET_OK;
916}
917
918
926static void
929{
930 struct RewindIpState *ris = cls;
931 const struct GNUNET_TESTING_Command *target;
932 const struct GNUNET_TESTING_Command *icmd;
933 unsigned int new_ip;
934 bool found = false;
935
936 if (0 == ris->counter)
937 return;
938 target
940 ris->target_label);
941 if (NULL == target)
942 {
943 GNUNET_break (0);
945 return;
946 }
947 ris->counter--;
948 for (new_ip = 0;
949 NULL != (icmd = &is->commands[new_ip])->run;
950 new_ip++)
951 {
952 if (icmd == target)
953 {
954 found = true;
955 break;
956 }
958 {
960 = seek_batch (is,
961 icmd,
962 target);
963 if (GNUNET_SYSERR == ret)
964 {
965 /* failure! */
966 GNUNET_break (0);
968 return;
969 }
970 if (GNUNET_OK == ret)
971 {
972 /* counter subtraction below for batch */
973 found = true;
974 break;
975 }
976 }
977 }
978 if (! found)
979 {
980 GNUNET_break (0);
982 return;
983 }
984 if (new_ip > (unsigned int) is->ip)
985 {
986 /* refuse to jump forward */
987 GNUNET_break (0);
989 return;
990 }
991 is->ip = new_ip;
992}
993
994
995static void
997{
998 struct RewindIpState *ris = cls;
999
1000 GNUNET_free (ris);
1001}
1002
1003
1006 const char *target_label,
1007 unsigned int counter)
1008{
1009 struct RewindIpState *ris;
1010
1011 ris = GNUNET_new (struct RewindIpState);
1013 ris->counter = counter;
1014 return GNUNET_TESTING_command_new (ris,
1015 label,
1018 NULL);
1019}
1020
1021
1022/* end of testing_api_loop.c */
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:38
static int ret
Final status code.
Definition: gnunet-arm.c:93
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Main function that will be run by the scheduler.
Definition: gnunet-arm.c:916
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:118
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:33
static struct GNUNET_TESTING_Interpreter * is
static struct VoipCommand commands[]
List of supported commands.
static char * name
Name (label) of the records to list.
static int result
Global testing status.
#define GNUNET_TESTING_FAIL(is)
Print failing line number and trigger shutdown.
enum GNUNET_GenericReturnValue GNUNET_TESTING_get_trait_cmd(const struct GNUNET_TESTING_Command *cmd, const struct GNUNET_TESTING_Command **ret)
struct GNUNET_TESTING_Command GNUNET_TESTING_cmd_load_topology_from_string(const char *label, const char *topology_data)
void(* GNUNET_TESTING_CommandIterator)(void *cls, const struct GNUNET_TESTING_Command *cmd)
Callback over commands of an interpreter.
void(* GNUNET_TESTING_ResultCallback)(void *cls, enum GNUNET_GenericReturnValue rv)
Function called with the final result of the test.
#define GNUNET_TESTING_command_new(cls, label, run, cleanup, traits)
Create a new command.
struct GNUNET_TESTING_Command GNUNET_TESTING_cmd_set_var(const char *name, struct GNUNET_TESTING_Command cmd)
Set variable to command as side-effect of running a command.
enum GNUNET_GenericReturnValue GNUNET_TESTING_get_trait_batch_cmds(const struct GNUNET_TESTING_Command *cmd, struct GNUNET_TESTING_Command ***ret)
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
enum GNUNET_GenericReturnValue(* GNUNET_CONTAINER_ShortmapIterator)(void *cls, const struct GNUNET_ShortHashCode *key, void *value)
Iterator over hash map entries.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
struct GNUNET_CONTAINER_MultiShortmap * GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multishortmap_put(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void * GNUNET_CONTAINER_multishortmap_get(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Given a key find a value in the map matching the key.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multishortmap_iterate(struct GNUNET_CONTAINER_MultiShortmap *map, GNUNET_CONTAINER_ShortmapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
unsigned int GNUNET_CONTAINER_multishortmap_size(const struct GNUNET_CONTAINER_MultiShortmap *map)
Get the number of key-value pairs in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE
If a value with the given key exists, replace it.
void GNUNET_HELPER_send_cancel(struct GNUNET_HELPER_SendHandle *sh)
Cancel a GNUNET_HELPER_send operation.
Definition: helper.c:653
struct GNUNET_HELPER_SendHandle * GNUNET_HELPER_send(struct GNUNET_HELPER_Handle *h, const struct GNUNET_MessageHeader *msg, bool can_drop, GNUNET_HELPER_Continuation cont, void *cont_cls)
Send an message to the helper.
Definition: helper.c:613
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_log(kind,...)
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_MESSAGE
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_malloc_large(size)
Wrapper around malloc.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_array_append(arr, len, element)
Append an element to an array (growing the array by one).
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:979
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1303
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1276
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:438
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:579
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
Internal representation of the hash map.
Internal representation of the hash map.
The handle to a helper process.
Definition: helper.c:77
Entry in the queue of messages we need to transmit to the helper.
Definition: helper.c:35
A 512-bit hashcode.
Header for all communications.
Entry in list of pending tasks.
Definition: scheduler.c:135
A 256-bit hashcode.
State each asynchronous command must have in its closure.
GNUNET_SCHEDULER_TaskCallback notify_finished
Function to call when async operation is done.
bool next_called
Set to true if interpreter_next() has already been called for this command.
struct GNUNET_TESTING_Interpreter * is
Interpreter we are part of.
enum GNUNET_GenericReturnValue finished
Indication if the command finished (GNUNET_OK).
void * notify_finished_cls
Closure for notify_finished.
An entry for a barrier list.
bool inherited
Did we inherit the barrier from our parent loop?
struct GNUNET_ShortHashCode barrier_id
A command to be run by the interpreter.
GNUNET_TESTING_CommandCleanupRoutine cleanup
Clean up after the command.
struct GNUNET_TIME_Absolute finish_time
When did the execution of this command finish?
const char * name
Variable name for the command, NULL for none.
struct GNUNET_TESTING_CommandLabel label
Label for the command.
struct GNUNET_TIME_Absolute last_req_time
When did we start the last run of this command? Delta to finish_time gives the latency for the last s...
struct GNUNET_TESTING_AsyncContext * ac
Pointer to the asynchronous context in the command's closure.
bool asynchronous_finish
If "true", the interpreter should not immediately run the next command, even if this command did not ...
GNUNET_TESTING_CommandRunRoutine run
Runs the command.
unsigned int num_tries
How often did we try to execute this command? (In case it is a request that is repated....
struct GNUNET_TIME_Absolute start_time
When did the execution of this command start?
void * cls
Closure for all commands with command-specific context information.
Global state of the interpreter, used by a command to access information about other commands.
bool skip
Is the real result to "skip" because we could not get the environment working?
GNUNET_TESTING_ResultCallback rc
Function to call with the test result.
struct GNUNET_CONTAINER_MultiShortmap * barriers
Map with barriers for this loop.
unsigned int cmds_n
Number of GNUNET_TESTING_Command in commands.
GNUNET_TESTING_cmd_helper_write_cb parent_writer
Function to call to send messages to our parent.
void * rc_cls
Closure for rc.
struct GNUNET_CONTAINER_MultiHashMap * vars
Hash map mapping variable names to commands.
struct GNUNET_SCHEDULER_Task * final_task
Final task that returns the result.
struct GNUNET_SCHEDULER_Task * timeout_task
Task run on timeout.
int ip
Instruction pointer.
struct SendContext * sender_tail
struct GNUNET_SCHEDULER_Task * task
Interpreter task (if one is scheduled).
struct GNUNET_HELPER_Handle ** helpers
Array with handles of helper processes for communication with netjails.
struct SendContext * sender_head
struct GNUNET_TESTING_Command * commands
Commands the interpreter will run.
bool finishing
Is the interpreter finishing?
enum GNUNET_GenericReturnValue result
Result of the testcases, GNUNET_OK on success, GNUNET_SYSERR on failure, GNUNET_NO if undecided.
unsigned int n_helpers
Size of the array helpers.
The plugin API every test case plugin has to implement.
void * cls
Closure to pass to start_testcase.
struct GNUNET_TESTING_Interpreter *(* start_testcase)(void *cls, const char *topology_data, uint32_t barrier_count, const struct GNUNET_ShortHashCode *barriers, GNUNET_TESTING_cmd_helper_write_cb write_message, GNUNET_TESTING_ResultCallback finish_cb, void *finish_cb_cls)
Function to be implemented for each test case plugin which starts the test case on a netjail node.
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
State for a "rewind" CMD.
const char * target_label
Instruction pointer to set into the interpreter.
unsigned int counter
How many times this set should take place.
struct SendContext * next
struct SendContext * prev
struct GNUNET_HELPER_SendHandle * send_handle
Handle to a send op.
struct GNUNET_TESTING_Interpreter * is
void GNUNET_TESTING_barrier_name_hash_(const char *barrier_name, struct GNUNET_ShortHashCode *bkey)
void GNUNET_TESTING_cmd_batch_set_current_(const struct GNUNET_TESTING_Command *cmd, unsigned int new_ip)
Set what command the batch should be at.
bool GNUNET_TESTING_cmd_batch_next_(void *cls)
Advance internal pointer to next command.
bool GNUNET_TESTING_cmd_is_batch_(const struct GNUNET_TESTING_Command *cmd)
Test if this command is a batch command.
struct GNUNET_TESTING_Barrier * GNUNET_TESTING_get_barrier2_(struct GNUNET_TESTING_Interpreter *is, const struct GNUNET_ShortHashCode *create_key)
struct GNUNET_TESTING_Barrier * GNUNET_TESTING_get_barrier_(struct GNUNET_TESTING_Interpreter *is, const char *barrier_name)
void GNUNET_TESTING_async_finish(struct GNUNET_TESTING_AsyncContext *ac)
The asynchronous command of ac has finished.
unsigned int GNUNET_TESTING_barrier_count_(struct GNUNET_TESTING_Interpreter *is)
void GNUNET_TESTING_interpreter_current_cmd_touch(struct GNUNET_TESTING_Interpreter *is)
Update the last request time of the current command to the current time.
void GNUNET_TESTING_barrier_iterate_(struct GNUNET_TESTING_Interpreter *is, GNUNET_CONTAINER_ShortmapIterator cb, void *cb_cls)
void GNUNET_TESTING_async_fail(struct GNUNET_TESTING_AsyncContext *ac)
The asynchronous command of ac has failed.
struct GNUNET_TESTING_Command GNUNET_TESTING_cmd_rewind_ip(const char *label, const char *target_label, unsigned int counter)
Make the instruction pointer point to target_label only if counter is greater than zero.
static void setup_is(struct GNUNET_TESTING_Interpreter *is, const struct GNUNET_TESTING_Command *bcommand, const struct GNUNET_TESTING_Command *commands)
void GNUNET_TESTING_interpreter_commands_iterate(struct GNUNET_TESTING_Interpreter *is, bool asc, GNUNET_TESTING_CommandIterator cb, void *cb_cls)
Iterates over all of the top-level commands of an interpreter.
static void do_timeout(void *cls)
Function run when the test terminates (good or bad) with timeout.
static void interpreter_run(void *cls)
Run the main interpreter loop that performs exchange operations.
const char * GNUNET_TESTING_interpreter_current_cmd_get_label(struct GNUNET_TESTING_Interpreter *is)
Obtain label of the command being now run.
struct GNUNET_TESTING_Interpreter * GNUNET_TESTING_run(const struct GNUNET_TESTING_Command *commands, struct GNUNET_TIME_Relative timeout, GNUNET_TESTING_ResultCallback rc, void *rc_cls)
Run the testsuite.
const struct GNUNET_TESTING_Command * GNUNET_TESTING_interpreter_lookup_command(struct GNUNET_TESTING_Interpreter *is, const char *label)
Lookup command by label.
void GNUNET_TESTING_add_netjail_helper_(struct GNUNET_TESTING_Interpreter *is, struct GNUNET_HELPER_Handle *helper)
Adding a helper handle to the interpreter.
void GNUNET_TESTING_loop_notify_parent_(struct GNUNET_TESTING_Interpreter *is, const struct GNUNET_MessageHeader *hdr)
Send message to our parent.
void GNUNET_TESTING_interpreter_skip(struct GNUNET_TESTING_Interpreter *is)
Skips the current test, the environment is not prepared correctly.
static void send_finished(void *cls, enum GNUNET_GenericReturnValue result)
void GNUNET_TESTING_interpreter_current_cmd_inc_tries(struct GNUNET_TESTING_Interpreter *is)
Increment the 'num_tries' counter for the current command.
static struct GNUNET_TESTING_Interpreter * start_testcase(void *cls, const char *topology_data, uint32_t inherited_barrier_count, const struct GNUNET_ShortHashCode *inherited_barriers, GNUNET_TESTING_cmd_helper_write_cb parent_writer, GNUNET_TESTING_ResultCallback finish_cb, void *finish_cb_cls)
void GNUNET_TESTING_interpreter_run_cmd_(struct GNUNET_TESTING_Interpreter *is, struct GNUNET_TESTING_Command *cmd)
void GNUNET_TESTING_loop_notify_children_(struct GNUNET_TESTING_Interpreter *is, const struct GNUNET_MessageHeader *hdr)
Send message to all netjail children (if there are any).
struct GNUNET_TESTING_PluginFunctions * GNUNET_TESTING_make_plugin(const struct GNUNET_TESTING_Command *commands)
void GNUNET_TESTING_interpreter_fail(struct GNUNET_TESTING_Interpreter *is)
Current command failed, clean up and fail the test case.
void GNUNET_TESTING_add_barrier_(struct GNUNET_TESTING_Interpreter *is, struct GNUNET_TESTING_Barrier *barrier)
Add a barrier to the interpreter to share it with all children as an inherited barrier.
static void finish_test(void *cls)
Finish the test run, return the final result.
void GNUNET_TESTING_interpreter_next_(void *cls)
Current command is done, run the next one.
static void rewind_ip_run(void *cls, struct GNUNET_TESTING_Interpreter *is)
Run the "rewind" CMD.
static void rewind_ip_free(void *cls)
static enum GNUNET_GenericReturnValue seek_batch(struct GNUNET_TESTING_Interpreter *is, const struct GNUNET_TESTING_Command *cmd, const struct GNUNET_TESTING_Command *target)
Seek for the target command in batch (and rewind to it if successful).
const struct GNUNET_TESTING_Command * GNUNET_TESTING_interpreter_get_command(struct GNUNET_TESTING_Interpreter *is, const char *name)
Get command from hash map by variable name.
void(* GNUNET_TESTING_cmd_helper_write_cb)(const struct GNUNET_MessageHeader *message)
Callback function to write messages from the helper process running on a netjail node to the master p...