GNUnet 0.21.2
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"
34#include "testing_cmds.h"
35
36
38{
41
46
48};
49
55{
60
65
69 void *rc_cls;
70
75
80
85
90
95
100
103
108
112 unsigned int cmds_n;
113
117 unsigned int n_helpers;
118
124 int ip;
125
131
136
141 bool skip;
142
143};
144
145
146const struct GNUNET_TESTING_Command *
149 const char *label)
150{
151 if (NULL == label)
152 {
154 "Attempt to lookup command for empty label\n");
155 return NULL;
156 }
157 for (int i = is->ip; i >= 0; i--)
158 {
159 const struct GNUNET_TESTING_Command *cmd = &is->commands[i];
160
161 /* Give precedence to top-level commands. */
162 if ( (NULL != cmd->run) &&
163 (0 == strcmp (cmd->label.value,
164 label)) )
165 return cmd;
166
168 {
169 struct GNUNET_TESTING_Command **batch;
170 const struct GNUNET_TESTING_Command *current;
171 const struct GNUNET_TESTING_Command *icmd;
172 const struct GNUNET_TESTING_Command *match;
173
176 &current));
179 &batch));
180 /* We must do the loop forward, but we can find the last match */
181 match = NULL;
182 for (unsigned int j = 0;
183 NULL != (icmd = &(*batch)[j])->run;
184 j++)
185 {
186 if (current == icmd)
187 break; /* do not go past current command */
188 if ( (NULL != icmd->run) &&
189 (0 == strcmp (icmd->label.value,
190 label)) )
191 match = icmd;
192 }
193 if (NULL != match)
194 return match;
195 }
196 }
198 "Command `%s' not found\n",
199 label);
200 return NULL;
201}
202
203
204const struct GNUNET_TESTING_Command *
207 const char *name)
208{
209 const struct GNUNET_TESTING_Command *cmd;
210 struct GNUNET_HashCode h_name;
211
213 strlen (name),
214 &h_name);
216 &h_name);
217 if (NULL == cmd)
219 "Command not found by variable name: %s\n",
220 name);
221 return cmd;
222}
223
224
225static void
226send_finished (void *cls,
228{
229 struct SendContext *sctx = cls;
230 struct GNUNET_TESTING_Interpreter *is = sctx->is;
231
235 sctx);
236 GNUNET_free (sctx);
237}
238
239
240void
242 const struct GNUNET_MessageHeader *hdr)
243{
245 "Send notification to children of type %u\n",
246 (unsigned int) ntohs (hdr->type));
247 for (unsigned int i = 0; i<is->n_helpers; i++)
248 {
249 struct SendContext *sctx;
250
251 sctx = GNUNET_new (struct SendContext);
252 sctx->is = is;
255 sctx);
256 sctx->send_handle
258 hdr,
259 false, /* never drop */
261 sctx);
262 }
263}
264
265
266void
268 const struct GNUNET_MessageHeader *hdr)
269{
270 /* We must have a parent */
271 if (NULL == is->parent_writer)
273 is->parent_writer (hdr);
274}
275
276
282static void
283finish_test (void *cls)
284{
285 struct GNUNET_TESTING_Interpreter *is = cls;
286 struct GNUNET_TESTING_Command *cmd;
287 const char *label;
288
289 is->finishing = true;
290 is->final_task = NULL;
292 if (NULL == is->commands[is->ip].run)
293 label = "END";
295 "Interpreter finishes at `%s' with status %d\n",
296 label,
297 is->result);
298 for (unsigned int j = 0;
299 NULL != (cmd = &is->commands[j])->run;
300 j++)
301 if (NULL != cmd->cleanup)
302 cmd->cleanup (cmd->cls);
303 if (NULL != is->task)
304 {
306 is->task = NULL;
307 }
308 if (NULL != is->timeout_task)
309 {
311 is->timeout_task = NULL;
312 }
313 {
314 struct SendContext *sctx;
315
316 while (NULL != (sctx = is->sender_head))
317 {
320 sctx);
322 GNUNET_free (sctx);
323 }
324 }
326 is->rc (is->rc_cls,
327 is->skip ? GNUNET_NO : is->result);
328 if (NULL != is->barriers)
329 {
331 is->barriers = NULL;
332 }
333 if (NULL != is->vars)
334 {
336 is->vars = NULL;
337 }
339 GNUNET_free (is);
340}
341
342
348static void
349interpreter_run (void *cls);
350
351
352void
354{
355 static unsigned long long ipc;
356 static struct GNUNET_TIME_Absolute last_report;
357 struct GNUNET_TESTING_Interpreter *is = cls;
358 struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip];
359
360 if (GNUNET_SYSERR == is->result)
361 return; /* ignore, we already failed! */
362
364 {
366 {
367 /* batch is done */
369 is->ip++;
370 }
371 }
372 else
373 {
375 is->ip++;
376 }
377
378 if (0 == (ipc % 1000))
379 {
380 if (0 != ipc)
382 "Interpreter executed 1000 instructions in %s\n",
385 true));
386 last_report = GNUNET_TIME_absolute_get ();
387 }
388 ipc++;
390 is);
391}
392
393
394void
397 struct GNUNET_TESTING_Command *cmd)
398{
399 cmd->last_req_time
401 if (0 == cmd->num_tries)
402 cmd->start_time = cmd->last_req_time;
403 cmd->num_tries = 1;
404 if (NULL != cmd->name)
405 {
406 struct GNUNET_HashCode h_name;
407
409 strlen (cmd->name),
410 &h_name);
412 is->vars,
413 &h_name,
414 cmd,
416 }
417 if (NULL != cmd->ac)
418 {
419 cmd->ac->is = is;
420 cmd->ac->finished = GNUNET_NO;
421 cmd->ac->next_called = false;
422 }
423 cmd->run (cmd->cls,
424 is);
425 if ( (! GNUNET_TESTING_cmd_is_batch_ (cmd)) &&
426 ( (NULL == cmd->ac) ||
427 (cmd->asynchronous_finish) ) )
428 {
429 if (NULL != cmd->ac)
430 cmd->ac->next_called = true;
432 }
433}
434
435
441static void
443{
444 struct GNUNET_TESTING_Interpreter *is = cls;
445 struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip];
446
447 is->task = NULL;
448 if (NULL == cmd->run)
449 {
451 "Running command END\n");
453 finish_test (is);
454 return;
455 }
457 "Running command `%s'\n",
458 cmd->label.value);
460 cmd);
461}
462
463
464void
466{
467 struct GNUNET_TESTING_Command *cmd
468 = &is->commands[is->ip];
469
470 if (GNUNET_SYSERR == is->result)
471 {
472 GNUNET_break (0);
473 return; /* ignore, we already failed! */
474 }
475 if (NULL == cmd)
476 {
478 "Failed with CMD being NULL!\n");
479 }
480 else
481 {
482 const struct GNUNET_TESTING_Command *pos = cmd;
483
485 "Failed during command `%s'\n",
486 cmd->label.value);
487 while (GNUNET_TESTING_cmd_is_batch_ (pos))
488 {
491 &pos));
493 "Failed in batch during command `%s'\n",
494 pos->label.value);
495 }
496 }
497 if (NULL != is->timeout_task)
498 {
500 is->timeout_task = NULL;
501 }
503 GNUNET_assert (NULL == is->final_task);
505 is);
506}
507
508
509void
512{
513 is->skip = true;
515}
516
517
518void
520{
524}
525
526
527void
529{
532 if (NULL != ac->notify_finished)
533 {
535 ac->notify_finished = NULL;
536 }
537 if (! ac->next_called)
538 {
539 ac->next_called = true;
541 }
542}
543
544
550static void
552{
553 struct GNUNET_TESTING_Interpreter *is = cls;
554
555 is->timeout_task = NULL;
557 "Terminating test due to global timeout\n");
559 finish_test (is);
560}
561
562
563static void
565 const struct GNUNET_TESTING_Command *bcommand,
566 const struct GNUNET_TESTING_Command *commands)
567{
568 unsigned int i;
569
571 false);
572 /* get the number of commands */
573 for (i = 0; NULL != commands[i].run; i++)
574 ;
575 if (NULL != bcommand)
576 i++;
577 is->cmds_n = i + 1;
579 "Got %u commands\n",
580 i);
582 (i + 1)
583 * sizeof (struct GNUNET_TESTING_Command));
584 GNUNET_assert (NULL != is->commands);
585 if (NULL == bcommand)
586 {
587 memcpy (is->commands,
588 commands,
589 sizeof (struct GNUNET_TESTING_Command) * i);
590 }
591 else
592 {
593 is->commands[0] = *bcommand;
594 memcpy (&is->commands[1],
595 commands,
596 sizeof (struct GNUNET_TESTING_Command) * i);
597 }
599 is);
600}
601
602
607 void *rc_cls)
608{
610
614 &do_timeout,
615 is);
616 is->rc = rc;
617 is->rc_cls = rc_cls;
618 setup_is (is,
619 NULL,
620 commands);
621 return is;
622}
623
624
625static struct GNUNET_TESTING_Interpreter *
627 void *cls,
628 const char *topology_data,
629 uint32_t inherited_barrier_count,
630 const struct GNUNET_ShortHashCode *inherited_barriers,
633 void *finish_cb_cls)
634{
635 const struct GNUNET_TESTING_Command *commands = cls;
637
639 if (0 != inherited_barrier_count)
640 {
641 is->barriers
642 = GNUNET_CONTAINER_multishortmap_create (inherited_barrier_count * 4 / 3,
643 true);
644 for (unsigned int j = 0; j<inherited_barrier_count; j++)
645 {
646 struct GNUNET_TESTING_Barrier *barrier;
647
648 barrier = GNUNET_new (struct GNUNET_TESTING_Barrier);
649 barrier->barrier_id = inherited_barriers[j];
650 barrier->inherited = true;
652 is->barriers,
653 &barrier->barrier_id,
654 barrier,
656 }
657 }
658 is->parent_writer = parent_writer;
659 is->rc = finish_cb;
660 is->rc_cls = finish_cb_cls;
661 {
662 struct GNUNET_TESTING_Command bcmd;
663
665 "topology",
667 "_boot_",
668 topology_data));
669 setup_is (is,
670 &bcmd,
671 commands);
672 }
673 return is;
674
675}
676
677
680 const struct GNUNET_TESTING_Command *commands)
681{
683 struct GNUNET_TESTING_Command *commands_copy;
684 unsigned int i;
685
686 for (i = 0; NULL != commands[i].run; i++)
687 ;
688 commands_copy = GNUNET_malloc_large ( (i + 1)
689 * sizeof (struct
691 memcpy (commands_copy,
692 commands,
693 sizeof (struct GNUNET_TESTING_Command) * i + 1);
694
696 api->cls = (void *) commands_copy;
698 return api;
699}
700
701
702void
704 struct GNUNET_HELPER_Handle *helper)
705{
707 is->n_helpers,
708 helper);
709}
710
711
714 const struct GNUNET_ShortHashCode *create_key)
715{
717 create_key);
718}
719
720
723 const char *barrier_name)
724{
725 struct GNUNET_ShortHashCode create_key;
726
727 if (NULL == is->barriers)
728 return NULL;
730 &create_key);
732 &create_key);
733}
734
735
736void
738 struct GNUNET_TESTING_Barrier *barrier)
739{
740 if (NULL == is->barriers)
741 is->barriers
743 true);
744 /* We always use the barrier we encountered
745 most recently under a given label, thus replace */
747 is->barriers,
748 &barrier->barrier_id,
749 barrier,
751}
752
753
754unsigned int
757{
759}
760
761
762void
766 void *cb_cls)
767{
768 if (NULL != is->barriers)
770 cb,
771 cb_cls);
772}
773
774
775void
778 bool asc,
780 void *cb_cls)
781{
782 unsigned int start;
783 unsigned int end;
784 int inc;
785
786 if (asc)
787 {
788 inc = 1;
789 start = 0;
790 end = is->ip;
791 }
792 else
793 {
794 inc = -1;
795 start = is->ip;
796 end = 0;
797 }
798 for (unsigned int off = start; off != end + inc; off += inc)
799 {
800 const struct GNUNET_TESTING_Command *cmd
801 = &is->commands[off];
802
803 cb (cb_cls,
804 cmd);
805 }
806}
807
808
809void
812{
815}
816
817
818void
821{
823}
824
825
826const char *
829{
830 return is->commands[is->ip].label.value;
831}
832
833
838{
842 const char *target_label;
843
849 unsigned int counter;
850};
851
852
865 const struct GNUNET_TESTING_Command *cmd,
866 const struct GNUNET_TESTING_Command *target)
867{
868 unsigned int new_ip;
869 struct GNUNET_TESTING_Command **batch;
870 const struct GNUNET_TESTING_Command *current;
871 const struct GNUNET_TESTING_Command *icmd;
872 bool found = false;
873
876 &current));
879 &batch));
880 for (new_ip = 0;
881 NULL != (icmd = &((*batch)[new_ip]))->run;
882 new_ip++)
883 {
884 if (current == target)
885 current = NULL;
886 if (icmd == target)
887 {
888 found = true;
889 break;
890 }
892 {
894 = seek_batch (is,
895 icmd,
896 target);
897 if (GNUNET_SYSERR == ret)
898 return GNUNET_SYSERR; /* failure! */
899 if (GNUNET_OK == ret)
900 {
901 found = true;
902 break;
903 }
904 }
905 }
906 if (! found)
907 return GNUNET_NO; /* not found */
908 if (NULL == current)
909 {
910 /* refuse to jump forward */
911 GNUNET_break (0);
913 return GNUNET_SYSERR;
914 }
916 new_ip);
917 return GNUNET_OK;
918}
919
920
928static void
931{
932 struct RewindIpState *ris = cls;
933 const struct GNUNET_TESTING_Command *target;
934 const struct GNUNET_TESTING_Command *icmd;
935 unsigned int new_ip;
936 bool found = false;
937
938 if (0 == ris->counter)
939 return;
940 target
942 ris->target_label);
943 if (NULL == target)
944 {
945 GNUNET_break (0);
947 return;
948 }
949 ris->counter--;
950 for (new_ip = 0;
951 NULL != (icmd = &is->commands[new_ip])->run;
952 new_ip++)
953 {
954 if (icmd == target)
955 {
956 found = true;
957 break;
958 }
960 {
962 = seek_batch (is,
963 icmd,
964 target);
965 if (GNUNET_SYSERR == ret)
966 {
967 /* failure! */
968 GNUNET_break (0);
970 return;
971 }
972 if (GNUNET_OK == ret)
973 {
974 /* counter subtraction below for batch */
975 found = true;
976 break;
977 }
978 }
979 }
980 if (! found)
981 {
982 GNUNET_break (0);
984 return;
985 }
986 if (new_ip > (unsigned int) is->ip)
987 {
988 /* refuse to jump forward */
989 GNUNET_break (0);
991 return;
992 }
993 is->ip = new_ip;
994}
995
996
997static void
999{
1000 struct RewindIpState *ris = cls;
1001
1002 GNUNET_free (ris);
1003}
1004
1005
1008 const char *target_label,
1009 unsigned int counter)
1010{
1011 struct RewindIpState *ris;
1012
1013 ris = GNUNET_new (struct RewindIpState);
1015 ris->counter = counter;
1016 return GNUNET_TESTING_command_new (ris,
1017 label,
1020 NULL);
1021}
1022
1023
1024/* end of testing_api_loop.c */
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static int ret
Final status code.
Definition: gnunet-arm.c:94
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:917
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:119
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
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:981
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:1305
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:1278
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:436
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:570
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:136
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...
Message formats for communication between testing cmds helper and testcase plugins.