aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <grothoff@gnunet.org>2021-10-04 18:15:21 +0200
committerChristian Grothoff <grothoff@gnunet.org>2021-10-04 18:15:21 +0200
commit23b5cf23674d557864284eff81d876ee1b5631bf (patch)
tree2cdabbf345395d0bbcd3e415ff2386d53a30d0d7 /src
parentf146e80752e73247acb9d6c7463188a82d26a774 (diff)
downloadgnunet-23b5cf23674d557864284eff81d876ee1b5631bf.tar.gz
gnunet-23b5cf23674d557864284eff81d876ee1b5631bf.zip
-basic santiy for testing API, breaks transport/ build
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_testing_ng_lib.h196
-rw-r--r--src/testing/Makefile.am6
-rw-r--r--src/testing/test_testing_plugin_testcmd.c19
-rw-r--r--src/testing/testing.h94
-rw-r--r--src/testing/testing_api_cmd_batch.c64
-rw-r--r--src/testing/testing_api_cmd_end.c39
-rw-r--r--src/testing/testing_api_loop.c290
7 files changed, 376 insertions, 332 deletions
diff --git a/src/include/gnunet_testing_ng_lib.h b/src/include/gnunet_testing_ng_lib.h
index 363c7ff0c..4ef9aac18 100644
--- a/src/include/gnunet_testing_ng_lib.h
+++ b/src/include/gnunet_testing_ng_lib.h
@@ -17,7 +17,6 @@
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19 */ 19 */
20
21/** 20/**
22 * @brief API for writing an interpreter to test GNUnet components 21 * @brief API for writing an interpreter to test GNUnet components
23 * @author Christian Grothoff <christian@grothoff.org> 22 * @author Christian Grothoff <christian@grothoff.org>
@@ -49,6 +48,7 @@
49 48
50/** 49/**
51 * Router of a network namespace. 50 * Router of a network namespace.
51 * // FIXME: this does not belong here!
52 */ 52 */
53struct GNUNET_TESTING_NetjailRouter 53struct GNUNET_TESTING_NetjailRouter
54{ 54{
@@ -63,8 +63,10 @@ struct GNUNET_TESTING_NetjailRouter
63 unsigned int udp_port; 63 unsigned int udp_port;
64}; 64};
65 65
66
66/** 67/**
67 * Enum for the different types of nodes. 68 * Enum for the different types of nodes.
69 * // FIXME: this does not belong here!
68 */ 70 */
69enum GNUNET_TESTING_NODE_TYPE 71enum GNUNET_TESTING_NODE_TYPE
70{ 72{
@@ -79,6 +81,8 @@ enum GNUNET_TESTING_NODE_TYPE
79 GNUNET_TESTING_GLOBAL_NODE 81 GNUNET_TESTING_GLOBAL_NODE
80}; 82};
81 83
84
85 // FIXME: this does not belong here!
82struct GNUNET_TESTING_ADDRESS_PREFIX 86struct GNUNET_TESTING_ADDRESS_PREFIX
83{ 87{
84 /** 88 /**
@@ -97,10 +101,13 @@ struct GNUNET_TESTING_ADDRESS_PREFIX
97 char *address_prefix; 101 char *address_prefix;
98}; 102};
99 103
104
105// FIXME: this does not belong here!
100struct GNUNET_TESTING_NetjailNode; 106struct GNUNET_TESTING_NetjailNode;
101 107
102/** 108/**
103 * Connection to another node. 109 * Connection to another node.
110 * // FIXME: this does not belong here!
104 */ 111 */
105struct GNUNET_TESTING_NodeConnection 112struct GNUNET_TESTING_NodeConnection
106{ 113{
@@ -148,6 +155,7 @@ struct GNUNET_TESTING_NodeConnection
148 155
149/** 156/**
150 * Node in the netjail topology. 157 * Node in the netjail topology.
158 * // FIXME: this does not belong here!
151 */ 159 */
152struct GNUNET_TESTING_NetjailNode 160struct GNUNET_TESTING_NetjailNode
153{ 161{
@@ -185,6 +193,7 @@ struct GNUNET_TESTING_NetjailNode
185 193
186/** 194/**
187 * Namespace in a topology. 195 * Namespace in a topology.
196 * // FIXME: this does not belong here!
188 */ 197 */
189struct GNUNET_TESTING_NetjailNamespace 198struct GNUNET_TESTING_NetjailNamespace
190{ 199{
@@ -206,6 +215,7 @@ struct GNUNET_TESTING_NetjailNamespace
206 215
207/** 216/**
208 * Toplogy of our netjail setup. 217 * Toplogy of our netjail setup.
218 * // FIXME: this does not belong here!
209 */ 219 */
210struct GNUNET_TESTING_NetjailTopology 220struct GNUNET_TESTING_NetjailTopology
211{ 221{
@@ -318,6 +328,9 @@ struct GNUNET_TESTING_Command
318 (*cleanup)(void *cls); 328 (*cleanup)(void *cls);
319 329
320 /** 330 /**
331 * FIXME: logic is often the same!
332 * => Think about refactoring API to reduce duplication!
333 *
321 * Extract information from a command that is useful for other 334 * Extract information from a command that is useful for other
322 * commands. 335 * commands.
323 * 336 *
@@ -356,13 +369,6 @@ struct GNUNET_TESTING_Command
356 struct GNUNET_TIME_Absolute last_req_time; 369 struct GNUNET_TIME_Absolute last_req_time;
357 370
358 /** 371 /**
359 * How often did we try to execute this command? (In case it is a request
360 * that is repated.) Note that a command must have some built-in retry
361 * mechanism for this value to be useful.
362 */
363 unsigned int num_tries;
364
365 /**
366 * In case @e asynchronous_finish is true, how long should we wait for this 372 * In case @e asynchronous_finish is true, how long should we wait for this
367 * command to complete? If @e finish did not complete after this amount of 373 * command to complete? If @e finish did not complete after this amount of
368 * time, the interpreter will fail. Should be set generously to ensure 374 * time, the interpreter will fail. Should be set generously to ensure
@@ -371,6 +377,13 @@ struct GNUNET_TESTING_Command
371 struct GNUNET_TIME_Relative default_timeout; 377 struct GNUNET_TIME_Relative default_timeout;
372 378
373 /** 379 /**
380 * How often did we try to execute this command? (In case it is a request
381 * that is repated.) Note that a command must have some built-in retry
382 * mechanism for this value to be useful.
383 */
384 unsigned int num_tries;
385
386 /**
374 * If "true", the interpreter should not immediately call 387 * If "true", the interpreter should not immediately call
375 * @e finish, even if @e finish is non-NULL. Otherwise, 388 * @e finish, even if @e finish is non-NULL. Otherwise,
376 * #TALER_TESTING_cmd_finish() must be used 389 * #TALER_TESTING_cmd_finish() must be used
@@ -466,22 +479,32 @@ GNUNET_TESTING_cmd_rewind_ip (const char *label,
466 479
467 480
468/** 481/**
482 * Function called with the final result of the test.
483 *
484 * @param cls closure
485 * @param rv #GNUNET_OK if the test passed
486 */
487typedef void
488(*GNUNET_TESTING_ResultCallback)(void *cls,
489 enum GNUNET_GenericReturnValue rv);
490
491
492/**
469 * Run the testsuite. Note, CMDs are copied into 493 * Run the testsuite. Note, CMDs are copied into
470 * the interpreter state because they are _usually_ 494 * the interpreter state because they are _usually_
471 * defined into the "run" method that returns after 495 * defined into the "run" method that returns after
472 * having scheduled the test interpreter. 496 * having scheduled the test interpreter.
473 * 497 *
474 * @param cfg_name name of configuration file to use
475 * @param commands the list of command to execute 498 * @param commands the list of command to execute
476 * @param timeout how long to wait for each command to execute 499 * @param timeout how long to wait for each command to execute
477 * @return #GNUNET_OK if all is okay, != #GNUNET_OK otherwise. 500 * @param rc function to call with the final result
478 * non-GNUNET_OK codes are #GNUNET_SYSERR most of the 501 * @param rc_cls closure for @a rc
479 * times.
480 */ 502 */
481enum GNUNET_GenericReturnValue 503void
482GNUNET_TESTING_run (const char *cfg_filename, 504GNUNET_TESTING_run (struct GNUNET_TESTING_Command *commands,
483 struct GNUNET_TESTING_Command *commands, 505 struct GNUNET_TIME_Relative timeout,
484 struct GNUNET_TIME_Relative timeout); 506 GNUNET_TESTING_ResultCallback rc,
507 void *rc_cls);
485 508
486 509
487/** 510/**
@@ -489,14 +512,12 @@ GNUNET_TESTING_run (const char *cfg_filename,
489 * run the testsuite. Return 0 upon success. 512 * run the testsuite. Return 0 upon success.
490 * Expected to be called directly from main(). 513 * Expected to be called directly from main().
491 * 514 *
492 * @param cfg_name name of configuration file to use
493 * @param commands the list of command to execute 515 * @param commands the list of command to execute
494 * @param timeout how long to wait for each command to execute 516 * @param timeout how long to wait for each command to execute
495 * @return EXIT_SUCCESS on success, EXIT_FAILURE on failure 517 * @return EXIT_SUCCESS on success, EXIT_FAILURE on failure
496 */ 518 */
497int 519int
498GNUNET_TESTING_main (const char *cfg_filename, 520GNUNET_TESTING_main (struct GNUNET_TESTING_Command *commands,
499 struct GNUNET_TESTING_Command *commands,
500 struct GNUNET_TIME_Relative timeout); 521 struct GNUNET_TIME_Relative timeout);
501 522
502 523
@@ -505,6 +526,8 @@ GNUNET_TESTING_main (const char *cfg_filename,
505 * 526 *
506 * @param prog program's name to look into 527 * @param prog program's name to look into
507 * @param marker chunk to find in @a prog 528 * @param marker chunk to find in @a prog
529 * // FIXME: this does not belong here! => libgnunetutil, maybe?
530 * // FIXME: return bool? document return value!
508 */ 531 */
509int 532int
510GNUNET_TESTING_has_in_name (const char *prog, 533GNUNET_TESTING_has_in_name (const char *prog,
@@ -518,7 +541,7 @@ GNUNET_TESTING_has_in_name (const char *prog,
518 * 541 *
519 * @param label command label. 542 * @param label command label.
520 * @param process_label label of a command that has a process trait 543 * @param process_label label of a command that has a process trait
521 * @param process_index index of the process trait at @a process_label 544 * @param process_index index of the process trait at @a process_label // FIXME: enum? needed?
522 * @param signal signal to send to @a process. 545 * @param signal signal to send to @a process.
523 * @return the command. 546 * @return the command.
524 */ 547 */
@@ -557,49 +580,8 @@ GNUNET_TESTING_cmd_batch (const char *label,
557 580
558 581
559/** 582/**
560 * Test if this command is a batch command.
561 *
562 * @return false if not, true if it is a batch command
563 */
564// TODO: figure out if this needs to be exposed in the public API.
565int
566GNUNET_TESTING_cmd_is_batch (const struct GNUNET_TESTING_Command *cmd);
567
568
569/**
570 * Advance internal pointer to next command.
571 *
572 * @param is interpreter state.
573 */
574// TODO: figure out if this needs to be exposed in the public API.
575void
576GNUNET_TESTING_cmd_batch_next (struct GNUNET_TESTING_Interpreter *is);
577
578
579/**
580 * Obtain what command the batch is at.
581 *
582 * @return cmd current batch command
583 */
584// TODO: figure out if this needs to be exposed in the public API.
585struct GNUNET_TESTING_Command *
586GNUNET_TESTING_cmd_batch_get_current (const struct GNUNET_TESTING_Command *cmd);
587
588
589/**
590 * Set what command the batch should be at.
591 *
592 * @param cmd current batch command
593 * @param new_ip where to move the IP
594 */
595// TODO: figure out if this needs to be exposed in the public API.
596void
597GNUNET_TESTING_cmd_batch_set_current (const struct GNUNET_TESTING_Command *cmd,
598 unsigned int new_ip);
599
600
601/**
602 * Performance counter. 583 * Performance counter.
584 * // FIXME: this might not belong here!
603 */ 585 */
604struct GNUNET_TESTING_Timer 586struct GNUNET_TESTING_Timer
605{ 587{
@@ -695,7 +677,7 @@ GNUNET_TESTING_trait_end (void);
695 * @param index index number of the trait to extract. 677 * @param index index number of the trait to extract.
696 * @return #GNUNET_OK when the trait is found. 678 * @return #GNUNET_OK when the trait is found.
697 */ 679 */
698int 680enum GNUNET_GenericReturnValue
699GNUNET_TESTING_get_trait (const struct GNUNET_TESTING_Trait *traits, 681GNUNET_TESTING_get_trait (const struct GNUNET_TESTING_Trait *traits,
700 const void **ret, 682 const void **ret,
701 const char *trait, 683 const char *trait,
@@ -709,12 +691,12 @@ GNUNET_TESTING_get_trait (const struct GNUNET_TESTING_Trait *traits,
709 * 691 *
710 * @param cmd command to extract trait from. 692 * @param cmd command to extract trait from.
711 * @param index which process to pick if @a cmd 693 * @param index which process to pick if @a cmd
712 * has multiple on offer. 694 * has multiple on offer. -- FIXME: remove?
713 * @param[out] processp set to the address of the pointer to the 695 * @param[out] processp set to the address of the pointer to the
714 * process. 696 * process.
715 * @return #GNUNET_OK on success. 697 * @return #GNUNET_OK on success.
716 */ 698 */
717int 699enum GNUNET_GenericReturnValue
718GNUNET_TESTING_get_trait_process (const struct GNUNET_TESTING_Command *cmd, 700GNUNET_TESTING_get_trait_process (const struct GNUNET_TESTING_Command *cmd,
719 unsigned int index, 701 unsigned int index,
720 struct GNUNET_OS_Process ***processp); 702 struct GNUNET_OS_Process ***processp);
@@ -724,7 +706,7 @@ GNUNET_TESTING_get_trait_process (const struct GNUNET_TESTING_Command *cmd,
724 * Offer location where a command stores a pointer to a process. 706 * Offer location where a command stores a pointer to a process.
725 * 707 *
726 * @param index offered location index number, in case there are 708 * @param index offered location index number, in case there are
727 * multiple on offer. 709 * multiple on offer. // FIXME: remove?
728 * @param processp process location to offer. 710 * @param processp process location to offer.
729 * @return the trait. 711 * @return the trait.
730 */ 712 */
@@ -736,7 +718,7 @@ GNUNET_TESTING_make_trait_process (unsigned int index,
736/** 718/**
737 * Offer number trait, 32-bit version. 719 * Offer number trait, 32-bit version.
738 * 720 *
739 * @param index the number's index number. 721 * @param index the number's index number. // FIXME: introduce enum?
740 * @param n number to offer. 722 * @param n number to offer.
741 */ 723 */
742struct GNUNET_TESTING_Trait 724struct GNUNET_TESTING_Trait
@@ -748,11 +730,11 @@ GNUNET_TESTING_make_trait_uint32 (unsigned int index,
748 * Obtain a "number" value from @a cmd, 32-bit version. 730 * Obtain a "number" value from @a cmd, 32-bit version.
749 * 731 *
750 * @param cmd command to extract the number from. 732 * @param cmd command to extract the number from.
751 * @param index the number's index number. 733 * @param index the number's index number. // FIXME: introduce enum?
752 * @param[out] n set to the number coming from @a cmd. 734 * @param[out] n set to the number coming from @a cmd.
753 * @return #GNUNET_OK on success. 735 * @return #GNUNET_OK on success.
754 */ 736 */
755int 737enum GNUNET_GenericReturnValue
756GNUNET_TESTING_get_trait_uint32 (const struct GNUNET_TESTING_Command *cmd, 738GNUNET_TESTING_get_trait_uint32 (const struct GNUNET_TESTING_Command *cmd,
757 unsigned int index, 739 unsigned int index,
758 const uint32_t **n); 740 const uint32_t **n);
@@ -761,7 +743,7 @@ GNUNET_TESTING_get_trait_uint32 (const struct GNUNET_TESTING_Command *cmd,
761/** 743/**
762 * Offer number trait, 64-bit version. 744 * Offer number trait, 64-bit version.
763 * 745 *
764 * @param index the number's index number. 746 * @param index the number's index number. // FIXME: introduce enum?
765 * @param n number to offer. 747 * @param n number to offer.
766 */ 748 */
767struct GNUNET_TESTING_Trait 749struct GNUNET_TESTING_Trait
@@ -773,11 +755,11 @@ GNUNET_TESTING_make_trait_uint64 (unsigned int index,
773 * Obtain a "number" value from @a cmd, 64-bit version. 755 * Obtain a "number" value from @a cmd, 64-bit version.
774 * 756 *
775 * @param cmd command to extract the number from. 757 * @param cmd command to extract the number from.
776 * @param index the number's index number. 758 * @param index the number's index number. // FIXME: introduce enum?
777 * @param[out] n set to the number coming from @a cmd. 759 * @param[out] n set to the number coming from @a cmd.
778 * @return #GNUNET_OK on success. 760 * @return #GNUNET_OK on success.
779 */ 761 */
780int 762enum GNUNET_GenericReturnValue
781GNUNET_TESTING_get_trait_uint64 (const struct GNUNET_TESTING_Command *cmd, 763GNUNET_TESTING_get_trait_uint64 (const struct GNUNET_TESTING_Command *cmd,
782 unsigned int index, 764 unsigned int index,
783 const uint64_t **n); 765 const uint64_t **n);
@@ -786,7 +768,7 @@ GNUNET_TESTING_get_trait_uint64 (const struct GNUNET_TESTING_Command *cmd,
786/** 768/**
787 * Offer number trait, 64-bit signed version. 769 * Offer number trait, 64-bit signed version.
788 * 770 *
789 * @param index the number's index number. 771 * @param index the number's index number. // FIXME: introduce enum?
790 * @param n number to offer. 772 * @param n number to offer.
791 */ 773 */
792struct GNUNET_TESTING_Trait 774struct GNUNET_TESTING_Trait
@@ -798,11 +780,11 @@ GNUNET_TESTING_make_trait_int64 (unsigned int index,
798 * Obtain a "number" value from @a cmd, 64-bit signed version. 780 * Obtain a "number" value from @a cmd, 64-bit signed version.
799 * 781 *
800 * @param cmd command to extract the number from. 782 * @param cmd command to extract the number from.
801 * @param index the number's index number. 783 * @param index the number's index number. // FIXME: introduce enum?
802 * @param[out] n set to the number coming from @a cmd. 784 * @param[out] n set to the number coming from @a cmd.
803 * @return #GNUNET_OK on success. 785 * @return #GNUNET_OK on success.
804 */ 786 */
805int 787enum GNUNET_GenericReturnValue
806GNUNET_TESTING_get_trait_int64 (const struct GNUNET_TESTING_Command *cmd, 788GNUNET_TESTING_get_trait_int64 (const struct GNUNET_TESTING_Command *cmd,
807 unsigned int index, 789 unsigned int index,
808 const int64_t **n); 790 const int64_t **n);
@@ -812,7 +794,7 @@ GNUNET_TESTING_get_trait_int64 (const struct GNUNET_TESTING_Command *cmd,
812 * Offer a number. 794 * Offer a number.
813 * 795 *
814 * @param index the number's index number. 796 * @param index the number's index number.
815 * @param n the number to offer. 797 * @param n the number to offer. // FIXME: introduce enum?
816 * @return #GNUNET_OK on success. 798 * @return #GNUNET_OK on success.
817 */ 799 */
818struct GNUNET_TESTING_Trait 800struct GNUNET_TESTING_Trait
@@ -824,11 +806,11 @@ GNUNET_TESTING_make_trait_uint (unsigned int index,
824 * Obtain a number from @a cmd. 806 * Obtain a number from @a cmd.
825 * 807 *
826 * @param cmd command to extract the number from. 808 * @param cmd command to extract the number from.
827 * @param index the number's index number. 809 * @param index the number's index number. // FIXME: introduce enum?
828 * @param[out] n set to the number coming from @a cmd. 810 * @param[out] n set to the number coming from @a cmd.
829 * @return #GNUNET_OK on success. 811 * @return #GNUNET_OK on success.
830 */ 812 */
831int 813enum GNUNET_GenericReturnValue
832GNUNET_TESTING_get_trait_uint (const struct GNUNET_TESTING_Command *cmd, 814GNUNET_TESTING_get_trait_uint (const struct GNUNET_TESTING_Command *cmd,
833 unsigned int index, 815 unsigned int index,
834 const unsigned int **n); 816 const unsigned int **n);
@@ -838,12 +820,12 @@ GNUNET_TESTING_get_trait_uint (const struct GNUNET_TESTING_Command *cmd,
838 * 820 *
839 * @param cmd command to extract the subject from. 821 * @param cmd command to extract the subject from.
840 * @param index index number associated with the transfer 822 * @param index index number associated with the transfer
841 * subject to offer. 823 * subject to offer. // FIXME: introduce enum?
842 * @param[out] s where to write the offered 824 * @param[out] s where to write the offered
843 * string. 825 * string.
844 * @return #GNUNET_OK on success. 826 * @return #GNUNET_OK on success.
845 */ 827 */
846int 828enum GNUNET_GenericReturnValue
847GNUNET_TESTING_get_trait_string ( 829GNUNET_TESTING_get_trait_string (
848 const struct GNUNET_TESTING_Command *cmd, 830 const struct GNUNET_TESTING_Command *cmd,
849 unsigned int index, 831 unsigned int index,
@@ -854,7 +836,7 @@ GNUNET_TESTING_get_trait_string (
854 * Offer string subject. 836 * Offer string subject.
855 * 837 *
856 * @param index index number associated with the transfer 838 * @param index index number associated with the transfer
857 * subject being offered. 839 * subject being offered. // FIXME: introduce enum?
858 * @param s string to offer. 840 * @param s string to offer.
859 * @return the trait. 841 * @return the trait.
860 */ 842 */
@@ -868,9 +850,8 @@ GNUNET_TESTING_make_trait_string (unsigned int index,
868 * @param index always zero. Commands offering this 850 * @param index always zero. Commands offering this
869 * kind of traits do not need this index. For 851 * kind of traits do not need this index. For
870 * example, a "meta" CMD returns always the 852 * example, a "meta" CMD returns always the
871 * CMD currently being executed. 853 * CMD currently being executed. FIXME: remove!
872 * @param cmd wire details to offer. 854 * @param cmd wire details to offer.
873 *
874 * @return the trait. 855 * @return the trait.
875 */ 856 */
876struct GNUNET_TESTING_Trait 857struct GNUNET_TESTING_Trait
@@ -885,11 +866,11 @@ GNUNET_TESTING_make_trait_cmd (unsigned int index,
885 * @param index always zero. Commands offering this 866 * @param index always zero. Commands offering this
886 * kind of traits do not need this index. For 867 * kind of traits do not need this index. For
887 * example, a "meta" CMD returns always the 868 * example, a "meta" CMD returns always the
888 * CMD currently being executed. 869 * CMD currently being executed. FIXME: remove!
889 * @param[out] _cmd where to write the wire details. 870 * @param[out] _cmd where to write the wire details.
890 * @return #GNUNET_OK on success. 871 * @return #GNUNET_OK on success.
891 */ 872 */
892int 873enum GNUNET_GenericReturnValue
893GNUNET_TESTING_get_trait_cmd (const struct GNUNET_TESTING_Command *cmd, 874GNUNET_TESTING_get_trait_cmd (const struct GNUNET_TESTING_Command *cmd,
894 unsigned int index, 875 unsigned int index,
895 struct GNUNET_TESTING_Command **_cmd); 876 struct GNUNET_TESTING_Command **_cmd);
@@ -900,11 +881,11 @@ GNUNET_TESTING_get_trait_cmd (const struct GNUNET_TESTING_Command *cmd,
900 * 881 *
901 * @param cmd command to extract the uuid from. 882 * @param cmd command to extract the uuid from.
902 * @param index which amount to pick if @a cmd has multiple 883 * @param index which amount to pick if @a cmd has multiple
903 * on offer 884 * on offer // FIXME: introduce enum?
904 * @param[out] uuid where to write the uuid. 885 * @param[out] uuid where to write the uuid.
905 * @return #GNUNET_OK on success. 886 * @return #GNUNET_OK on success.
906 */ 887 */
907int 888enum GNUNET_GenericReturnValue
908GNUNET_TESTING_get_trait_uuid (const struct GNUNET_TESTING_Command *cmd, 889GNUNET_TESTING_get_trait_uuid (const struct GNUNET_TESTING_Command *cmd,
909 unsigned int index, 890 unsigned int index,
910 struct GNUNET_Uuid **uuid); 891 struct GNUNET_Uuid **uuid);
@@ -914,9 +895,8 @@ GNUNET_TESTING_get_trait_uuid (const struct GNUNET_TESTING_Command *cmd,
914 * Offer a uuid in a trait. 895 * Offer a uuid in a trait.
915 * 896 *
916 * @param index which uuid to offer, in case there are 897 * @param index which uuid to offer, in case there are
917 * multiple available. 898 * multiple available. // FIXME: introduce enum?
918 * @param uuid the uuid to offer. 899 * @param uuid the uuid to offer.
919 *
920 * @return the trait. 900 * @return the trait.
921 */ 901 */
922struct GNUNET_TESTING_Trait 902struct GNUNET_TESTING_Trait
@@ -929,11 +909,11 @@ GNUNET_TESTING_make_trait_uuid (unsigned int index,
929 * 909 *
930 * @param cmd command to extract trait from 910 * @param cmd command to extract trait from
931 * @param index which time stamp to pick if 911 * @param index which time stamp to pick if
932 * @a cmd has multiple on offer. 912 * @a cmd has multiple on offer // FIXME: introduce enum?
933 * @param[out] time set to the wanted WTID. 913 * @param[out] time set to the wanted WTID.
934 * @return #GNUNET_OK on success 914 * @return #GNUNET_OK on success
935 */ 915 */
936int 916enum GNUNET_GenericReturnValue
937GNUNET_TESTING_get_trait_absolute_time ( 917GNUNET_TESTING_get_trait_absolute_time (
938 const struct GNUNET_TESTING_Command *cmd, 918 const struct GNUNET_TESTING_Command *cmd,
939 unsigned int index, 919 unsigned int index,
@@ -982,6 +962,9 @@ GNUNET_TESTING_make_trait_relative_time (
982 const struct GNUNET_TIME_Relative *time); 962 const struct GNUNET_TIME_Relative *time);
983 963
984 964
965// FIXME: move these commands into a separate libgnunetestingnetjail lib or so!
966
967
985/** 968/**
986 * Create command. 969 * Create command.
987 * 970 *
@@ -1133,7 +1116,9 @@ GNUNET_TESTING_cmd_stop_testing_system_v2 (const char *label,
1133 const char *topology_config); 1116 const char *topology_config);
1134 1117
1135 1118
1136int 1119
1120// FIXME: document!
1121enum GNUNET_GenericReturnValue
1137GNUNET_TESTING_get_trait_helper_handles (const struct 1122GNUNET_TESTING_get_trait_helper_handles (const struct
1138 GNUNET_TESTING_Command *cmd, 1123 GNUNET_TESTING_Command *cmd,
1139 struct GNUNET_HELPER_Handle ***helper); 1124 struct GNUNET_HELPER_Handle ***helper);
@@ -1146,31 +1131,30 @@ GNUNET_TESTING_get_trait_helper_handles (const struct
1146 * @param pt pointer to message. 1131 * @param pt pointer to message.
1147 * @return #GNUNET_OK on success. 1132 * @return #GNUNET_OK on success.
1148 */ 1133 */
1149int 1134enum GNUNET_GenericReturnValue
1150GNUNET_TESTING_get_trait_helper_handles_v2 (const struct 1135GNUNET_TESTING_get_trait_helper_handles_v2 (
1151 GNUNET_TESTING_Command *cmd, 1136 const struct GNUNET_TESTING_Command *cmd,
1152 struct GNUNET_HELPER_Handle *** 1137 struct GNUNET_HELPER_Handle ***helper);
1153 helper);
1154 1138
1155 1139
1156struct GNUNET_TESTING_Command 1140struct GNUNET_TESTING_Command
1157GNUNET_TESTING_cmd_block_until_all_peers_started (const char *label, 1141GNUNET_TESTING_cmd_block_until_all_peers_started (
1158 unsigned int * 1142 const char *label,
1159 all_peers_started); 1143 unsigned int *all_peers_started);
1160 1144
1161 1145
1162struct GNUNET_TESTING_Command 1146struct GNUNET_TESTING_Command
1163GNUNET_TESTING_cmd_block_until_external_trigger (const char *label, 1147GNUNET_TESTING_cmd_block_until_external_trigger (
1164 unsigned int * 1148 const char *label,
1165 stop_blocking); 1149 unsigned int *stop_blocking);
1166 1150
1167struct GNUNET_TESTING_Command 1151struct GNUNET_TESTING_Command
1168GNUNET_TESTING_cmd_send_peer_ready (const char *label, 1152GNUNET_TESTING_cmd_send_peer_ready (const char *label,
1169 TESTING_CMD_HELPER_write_cb write_message); 1153 TESTING_CMD_HELPER_write_cb write_message);
1170 1154
1171struct GNUNET_TESTING_Command 1155struct GNUNET_TESTING_Command
1172GNUNET_TESTING_cmd_local_test_finished (const char *label, 1156GNUNET_TESTING_cmd_local_test_finished (
1173 TESTING_CMD_HELPER_write_cb 1157 const char *label,
1174 write_message); 1158 TESTING_CMD_HELPER_write_cb write_message);
1175 1159
1176#endif 1160#endif
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am
index 3e0d4d443..2bb03d157 100644
--- a/src/testing/Makefile.am
+++ b/src/testing/Makefile.am
@@ -42,9 +42,11 @@ libgnunet_test_testing_plugin_testcmd_la_LIBADD = \
42libgnunet_test_testing_plugin_testcmd_la_LDFLAGS = \ 42libgnunet_test_testing_plugin_testcmd_la_LDFLAGS = \
43 $(GN_PLUGIN_LDFLAGS) 43 $(GN_PLUGIN_LDFLAGS)
44 44
45# testing_api_cmd_finish.c
46
45libgnunettesting_la_SOURCES = \ 47libgnunettesting_la_SOURCES = \
48 testing_api_cmd_end.c \
46 testing_api_cmd_local_test_finished.c \ 49 testing_api_cmd_local_test_finished.c \
47 testing_api_cmd_finish.c \
48 testing_api_cmd_send_peer_ready.c \ 50 testing_api_cmd_send_peer_ready.c \
49 testing_api_cmd_block_until_all_peers_started.c \ 51 testing_api_cmd_block_until_all_peers_started.c \
50 testing_api_cmd_block_until_external_trigger.c \ 52 testing_api_cmd_block_until_external_trigger.c \
@@ -56,7 +58,7 @@ libgnunettesting_la_SOURCES = \
56 testing_api_cmd_netjail_stop_testsystem_v2.c \ 58 testing_api_cmd_netjail_stop_testsystem_v2.c \
57 testing_api_cmd_netjail_stop.c \ 59 testing_api_cmd_netjail_stop.c \
58 testing_api_cmd_netjail_stop_v2.c \ 60 testing_api_cmd_netjail_stop_v2.c \
59 testing.c testing.h \ 61 testing.c \
60 testing_api_cmd_system_create.c \ 62 testing_api_cmd_system_create.c \
61 testing_api_cmd_system_destroy.c \ 63 testing_api_cmd_system_destroy.c \
62 testing_api_cmd_batch.c \ 64 testing_api_cmd_batch.c \
diff --git a/src/testing/test_testing_plugin_testcmd.c b/src/testing/test_testing_plugin_testcmd.c
index 444272fcd..32e2b38a7 100644
--- a/src/testing/test_testing_plugin_testcmd.c
+++ b/src/testing/test_testing_plugin_testcmd.c
@@ -17,11 +17,12 @@
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19 */ 19 */
20
21/** 20/**
22 * @file testbed/plugin_testcmd.c 21 * @file testbed/plugin_testcmd.c
23 * @brief a plugin to provide the API for running test cases. 22 * @brief a plugin to provide the API for running test cases.
24 * @author t3sserakt 23 * @author t3sserakt
24 *
25 * // FIXME: too verbose, no logic to return final status, will segv!
25 */ 26 */
26#include "platform.h" 27#include "platform.h"
27#include "gnunet_testing_ng_lib.h" 28#include "gnunet_testing_ng_lib.h"
@@ -33,8 +34,11 @@
33 */ 34 */
34#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) 35#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
35 36
37
38// FIXME: bad global!
36unsigned int are_all_peers_started; 39unsigned int are_all_peers_started;
37 40
41
38static void 42static void
39all_peers_started () 43all_peers_started ()
40{ 44{
@@ -44,8 +48,10 @@ all_peers_started ()
44 are_all_peers_started); 48 are_all_peers_started);
45} 49}
46 50
51
47static void 52static void
48start_testcase (TESTING_CMD_HELPER_write_cb write_message, char *router_ip, 53start_testcase (TESTING_CMD_HELPER_write_cb write_message,
54 char *router_ip,
49 char *node_ip, 55 char *node_ip,
50 char *n, 56 char *n,
51 char *m, 57 char *m,
@@ -70,9 +76,10 @@ start_testcase (TESTING_CMD_HELPER_write_cb write_message, char *router_ip,
70 write_message) 76 write_message)
71 }; 77 };
72 78
73 GNUNET_TESTING_run (NULL, 79 GNUNET_TESTING_run (commands,
74 commands, 80 GNUNET_TIME_UNIT_FOREVER_REL,
75 GNUNET_TIME_UNIT_FOREVER_REL); 81 NULL, /* FIXME: pass continuation! */
82 NULL);
76 LOG (GNUNET_ERROR_TYPE_ERROR, 83 LOG (GNUNET_ERROR_TYPE_ERROR,
77 "We got here 7!\n"); 84 "We got here 7!\n");
78 85
@@ -113,4 +120,4 @@ libgnunet_plugin_testcmd_done (void *cls)
113} 120}
114 121
115 122
116/* end of plugin_testcmd.c */ 123
diff --git a/src/testing/testing.h b/src/testing/testing.h
index b12466530..8aba09e4b 100644
--- a/src/testing/testing.h
+++ b/src/testing/testing.h
@@ -21,54 +21,54 @@
21/** 21/**
22 * @author t3sserakt 22 * @author t3sserakt
23 */ 23 */
24 24#ifndef TESTING_H
25#define TESTING_H
25#include "gnunet_util_lib.h" 26#include "gnunet_util_lib.h"
26 27
28
29/**
30 * Advance internal pointer to next command.
31 *
32 * @param cls batch internal state
33 * @return true if we could advance, false if the batch
34 * has completed and cannot advance anymore
35 */
36bool
37GNUNET_TESTING_cmd_batch_next_ (void *cls);
38
39
40/**
41 * Test if this command is a batch command.
42 *
43 * @return false if not, true if it is a batch command
44 */
45bool
46GNUNET_TESTING_cmd_is_batch_ (const struct GNUNET_TESTING_Command *cmd);
47
48
49/**
50 * Obtain what command the batch is at.
51 *
52 * @return cmd current batch command
53 */
54struct GNUNET_TESTING_Command *
55GNUNET_TESTING_cmd_batch_get_current_ (const struct GNUNET_TESTING_Command *cmd);
56
57
27/** 58/**
28 * Global state of the interpreter, used by a command 59 * Set what command the batch should be at. Needed for
29 * to access information about other commands. 60 * loops. We may want to change this to take a label
61 * and/or expose it in the public API in the future.
62 * Not used for now.
63 *
64 * @param cmd current batch command
65 * @param new_ip where to move the IP
30 */ 66 */
31// SUGGESTION: consider making this struct opaque (only known inside of libgnunettesting, 67void
32// say main loop and a few select commands, like next/fail/batch); + helper 68GNUNET_TESTING_cmd_batch_set_current_ (const struct GNUNET_TESTING_Command *cmd,
33// function to access 'cfg'? 69 unsigned int new_ip);
34struct GNUNET_TESTING_Interpreter 70
35{ 71
36 72
37 /** 73
38 * Commands the interpreter will run. 74#endif
39 */
40 struct GNUNET_TESTING_Command *commands;
41
42 /**
43 * Interpreter task (if one is scheduled).
44 */
45 struct GNUNET_SCHEDULER_Task *task;
46
47 /**
48 * Finish task of a blocking call to a commands finish method.
49 */
50 struct GNUNET_SCHEDULER_Task *finish_task;
51
52 /**
53 * Our configuration.
54 */
55 const struct GNUNET_CONFIGURATION_Handle *cfg;
56
57 /**
58 * Task run on timeout.
59 */
60 struct GNUNET_SCHEDULER_Task *timeout_task;
61
62 /**
63 * Instruction pointer. Tells #interpreter_run() which instruction to run
64 * next. Need (signed) int because it gets -1 when rewinding the
65 * interpreter to the first CMD.
66 */
67 int ip;
68
69 /**
70 * Result of the testcases, #GNUNET_OK on success
71 */
72 int result;
73
74};
diff --git a/src/testing/testing_api_cmd_batch.c b/src/testing/testing_api_cmd_batch.c
index e39489616..080a4880d 100644
--- a/src/testing/testing_api_cmd_batch.c
+++ b/src/testing/testing_api_cmd_batch.c
@@ -119,16 +119,15 @@ batch_traits (void *cls,
119 const char *trait, 119 const char *trait,
120 unsigned int index) 120 unsigned int index)
121{ 121{
122 struct BatchState *bs = cls;
123 // FIXME: these constants should be more global!
122#define CURRENT_CMD_INDEX 0 124#define CURRENT_CMD_INDEX 0
123#define BATCH_INDEX 1 125#define BATCH_INDEX 1
124
125 struct BatchState *bs = cls;
126
127 struct GNUNET_TESTING_Trait traits[] = { 126 struct GNUNET_TESTING_Trait traits[] = {
128 GNUNET_TESTING_make_trait_cmd 127 GNUNET_TESTING_make_trait_cmd (CURRENT_CMD_INDEX,
129 (CURRENT_CMD_INDEX, &bs->batch[bs->batch_ip]), 128 &bs->batch[bs->batch_ip]),
130 GNUNET_TESTING_make_trait_cmd 129 GNUNET_TESTING_make_trait_cmd (BATCH_INDEX,
131 (BATCH_INDEX, bs->batch), 130 bs->batch),
132 GNUNET_TESTING_trait_end () 131 GNUNET_TESTING_trait_end ()
133 }; 132 };
134 133
@@ -185,68 +184,45 @@ GNUNET_TESTING_cmd_batch (const char *label,
185} 184}
186 185
187 186
188/** 187bool
189 * Advance internal pointer to next command. 188GNUNET_TESTING_cmd_batch_next_ (void *cls)
190 *
191 * @param is interpreter state.
192 */
193void
194GNUNET_TESTING_cmd_batch_next (struct GNUNET_TESTING_Interpreter *is)
195{ 189{
196 struct BatchState *bs = is->commands[is->ip].cls; 190 struct BatchState *bs = cls;
197 191
198 if (NULL == bs->batch[bs->batch_ip].label) 192 if (NULL == bs->batch[bs->batch_ip].label)
199 { 193 return false;
200 is->commands[is->ip].finish_time = GNUNET_TIME_absolute_get (); 194 bs->batch[bs->batch_ip].finish_time
201 is->ip++; 195 = GNUNET_TIME_absolute_get ();
202 return;
203 }
204 bs->batch[bs->batch_ip].finish_time = GNUNET_TIME_absolute_get ();
205 bs->batch_ip++; 196 bs->batch_ip++;
197 return true;
206} 198}
207 199
208 200
209/** 201bool
210 * Test if this command is a batch command. 202GNUNET_TESTING_cmd_is_batch_ (const struct GNUNET_TESTING_Command *cmd)
211 *
212 * @return false if not, true if it is a batch command
213 */
214int
215GNUNET_TESTING_cmd_is_batch (const struct GNUNET_TESTING_Command *cmd)
216{ 203{
217 return cmd->run == &batch_run; 204 return cmd->run == &batch_run;
218} 205}
219 206
220 207
221/**
222 * Obtain what command the batch is at.
223 *
224 * @return cmd current batch command
225 */
226struct GNUNET_TESTING_Command * 208struct GNUNET_TESTING_Command *
227GNUNET_TESTING_cmd_batch_get_current (const struct GNUNET_TESTING_Command *cmd) 209GNUNET_TESTING_cmd_batch_get_current_ (const struct GNUNET_TESTING_Command *cmd)
228{ 210{
229 struct BatchState *bs = cmd->cls; 211 struct BatchState *bs = cmd->cls;
230 212
231 GNUNET_assert (cmd->run == &batch_run); 213 GNUNET_assert (GNUNET_TESTING_cmd_is_batch_ (cmd));
232 return &bs->batch[bs->batch_ip]; 214 return &bs->batch[bs->batch_ip];
233} 215}
234 216
235 217
236/**
237 * Set what command the batch should be at.
238 *
239 * @param cmd current batch command
240 * @param new_ip where to move the IP
241 */
242void 218void
243GNUNET_TESTING_cmd_batch_set_current (const struct GNUNET_TESTING_Command *cmd, 219GNUNET_TESTING_cmd_batch_set_current_ (const struct GNUNET_TESTING_Command *cmd,
244 unsigned int new_ip) 220 unsigned int new_ip)
245{ 221{
246 struct BatchState *bs = cmd->cls; 222 struct BatchState *bs = cmd->cls;
247 223
248 /* sanity checks */ 224 /* sanity checks */
249 GNUNET_assert (cmd->run == &batch_run); 225 GNUNET_assert (GNUNET_TESTING_cmd_is_batch_ (cmd));
250 for (unsigned int i = 0; i < new_ip; i++) 226 for (unsigned int i = 0; i < new_ip; i++)
251 GNUNET_assert (NULL != bs->batch[i].label); 227 GNUNET_assert (NULL != bs->batch[i].label);
252 /* actual logic */ 228 /* actual logic */
diff --git a/src/testing/testing_api_cmd_end.c b/src/testing/testing_api_cmd_end.c
new file mode 100644
index 000000000..f0f036429
--- /dev/null
+++ b/src/testing/testing_api_cmd_end.c
@@ -0,0 +1,39 @@
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 * @file testing/testing_api_cmd_end.c
22 * @brief command to end a command array
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26#include "gnunet_testing_ng_lib.h"
27
28
29struct GNUNET_TESTING_Command
30GNUNET_TESTING_cmd_end (void)
31{
32 static struct GNUNET_TESTING_Command cmd = {
33 .label = NULL
34 };
35
36 return cmd;
37}
38
39
diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c
index 1c8eb1db6..b21e01fcc 100644
--- a/src/testing/testing_api_loop.c
+++ b/src/testing/testing_api_loop.c
@@ -24,25 +24,64 @@
24 * @author Christian Grothoff (GNU Taler testing) 24 * @author Christian Grothoff (GNU Taler testing)
25 * @author Marcello Stanisci (GNU Taler testing) 25 * @author Marcello Stanisci (GNU Taler testing)
26 * @author t3sserakt 26 * @author t3sserakt
27 *
28 * FIXME:
29 * - interpreter failure is NOT returned properly yet!
30 * - abuse of shutdown logic for interpreter termination
31 * => API design flaw to be fixed!
32 */ 27 */
33#include "platform.h" 28#include "platform.h"
34#include "gnunet_util_lib.h" 29#include "gnunet_util_lib.h"
35#include "gnunet_testing_ng_lib.h" 30#include "gnunet_testing_ng_lib.h"
36#include "testing.h" 31#include "testing.h"
37 32
38
39/** 33/**
40 * Lookup command by label. 34 * Global state of the interpreter, used by a command
41 * 35 * to access information about other commands.
42 * @param is interpreter to lookup command in
43 * @param label label to look for
44 * @return NULL if command was not found
45 */ 36 */
37struct GNUNET_TESTING_Interpreter
38{
39
40 /**
41 * Function to call with the test result.
42 */
43 GNUNET_TESTING_ResultCallback rc;
44
45 /**
46 * Closure for @e rc.
47 */
48 void *rc_cls;
49
50 /**
51 * Commands the interpreter will run.
52 */
53 struct GNUNET_TESTING_Command *commands;
54
55 /**
56 * Interpreter task (if one is scheduled).
57 */
58 struct GNUNET_SCHEDULER_Task *task;
59
60 /**
61 * Final task that returns the result.
62 */
63 struct GNUNET_SCHEDULER_Task *final_task;
64
65 /**
66 * Task run on timeout.
67 */
68 struct GNUNET_SCHEDULER_Task *timeout_task;
69
70 /**
71 * Instruction pointer. Tells #interpreter_run() which instruction to run
72 * next. Need (signed) int because it gets -1 when rewinding the
73 * interpreter to the first CMD.
74 */
75 int ip;
76
77 /**
78 * Result of the testcases, #GNUNET_OK on success
79 */
80 enum GNUNET_GenericReturnValue result;
81
82};
83
84
46const struct GNUNET_TESTING_Command * 85const struct GNUNET_TESTING_Command *
47GNUNET_TESTING_interpreter_lookup_command ( 86GNUNET_TESTING_interpreter_lookup_command (
48 struct GNUNET_TESTING_Interpreter *is, 87 struct GNUNET_TESTING_Interpreter *is,
@@ -65,7 +104,7 @@ GNUNET_TESTING_interpreter_lookup_command (
65 label)) ) 104 label)) )
66 return cmd; 105 return cmd;
67 106
68 if (GNUNET_TESTING_cmd_is_batch (cmd)) 107 if (GNUNET_TESTING_cmd_is_batch_ (cmd))
69 { 108 {
70#define BATCH_INDEX 1 109#define BATCH_INDEX 1
71 struct GNUNET_TESTING_Command *batch; 110 struct GNUNET_TESTING_Command *batch;
@@ -73,7 +112,7 @@ GNUNET_TESTING_interpreter_lookup_command (
73 struct GNUNET_TESTING_Command *icmd; 112 struct GNUNET_TESTING_Command *icmd;
74 const struct GNUNET_TESTING_Command *match; 113 const struct GNUNET_TESTING_Command *match;
75 114
76 current = GNUNET_TESTING_cmd_batch_get_current (cmd); 115 current = GNUNET_TESTING_cmd_batch_get_current_ (cmd);
77 GNUNET_assert (GNUNET_OK == 116 GNUNET_assert (GNUNET_OK ==
78 GNUNET_TESTING_get_trait_cmd (cmd, 117 GNUNET_TESTING_get_trait_cmd (cmd,
79 BATCH_INDEX, 118 BATCH_INDEX,
@@ -96,10 +135,58 @@ GNUNET_TESTING_interpreter_lookup_command (
96 } 135 }
97 } 136 }
98 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 137 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
99 "Command not found: %s\n", 138 "Command `%s' not found\n",
100 label); 139 label);
101 return NULL; 140 return NULL;
141}
142
143
144/**
145 * Finish the test run, return the final result.
146 *
147 * @param cls the `struct GNUNET_TESTING_Interpreter`
148 */
149static void
150finish_test (void *cls)
151{
152 struct GNUNET_TESTING_Interpreter *is = cls;
153 struct GNUNET_TESTING_Command *cmd;
154 const char *label;
102 155
156 is->final_task = NULL;
157 label = is->commands[is->ip].label;
158 if (NULL == label)
159 label = "END";
160 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
161 "Interpreter finishes at `%s' with status %d\n",
162 label,
163 is->result);
164 for (unsigned int j = 0;
165 NULL != (cmd = &is->commands[j])->label;
166 j++)
167 {
168 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
169 "Cleaning up cmd %s\n",
170 cmd->label);
171 cmd->cleanup (cmd->cls);
172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
173 "Cleaned up cmd %s\n",
174 cmd->label);
175 }
176 if (NULL != is->task)
177 {
178 GNUNET_SCHEDULER_cancel (is->task);
179 is->task = NULL;
180 }
181 if (NULL != is->timeout_task)
182 {
183 GNUNET_SCHEDULER_cancel (is->timeout_task);
184 is->timeout_task = NULL;
185 }
186 GNUNET_free (is->commands);
187 is->rc (is->rc_cls,
188 is->result);
189 GNUNET_free (is);
103} 190}
104 191
105 192
@@ -125,15 +212,10 @@ interpreter_next (void *cls)
125 212
126 if (GNUNET_SYSERR == is->result) 213 if (GNUNET_SYSERR == is->result)
127 return; /* ignore, we already failed! */ 214 return; /* ignore, we already failed! */
128 if (GNUNET_TESTING_cmd_is_batch (cmd)) 215 cmd->finish_time = GNUNET_TIME_absolute_get ();
129 { 216 if ( (! GNUNET_TESTING_cmd_is_batch_ (cmd)) ||
130 GNUNET_TESTING_cmd_batch_next (is); 217 (! GNUNET_TESTING_cmd_batch_next_ (cmd->cls)) )
131 }
132 else
133 {
134 cmd->finish_time = GNUNET_TIME_absolute_get ();
135 is->ip++; 218 is->ip++;
136 }
137 if (0 == (ipc % 1000)) 219 if (0 == (ipc % 1000))
138 { 220 {
139 if (0 != ipc) 221 if (0 != ipc)
@@ -150,26 +232,24 @@ interpreter_next (void *cls)
150} 232}
151 233
152 234
153/**
154 * Current command failed, clean up and fail the test case.
155 *
156 * @param is interpreter of the test
157 */
158void 235void
159GNUNET_TESTING_interpreter_fail (struct GNUNET_TESTING_Interpreter *is) 236GNUNET_TESTING_interpreter_fail (struct GNUNET_TESTING_Interpreter *is)
160{ 237{
161 struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip]; 238 struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip];
162 239
163 if (GNUNET_SYSERR == is->result) 240 if (GNUNET_SYSERR == is->result)
241 {
242 GNUNET_break (0);
164 return; /* ignore, we already failed! */ 243 return; /* ignore, we already failed! */
244 }
165 if (NULL != cmd) 245 if (NULL != cmd)
166 { 246 {
167 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 247 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
168 "Failed at command `%s'\n", 248 "Failed at command `%s'\n",
169 cmd->label); 249 cmd->label);
170 while (GNUNET_TESTING_cmd_is_batch (cmd)) 250 while (GNUNET_TESTING_cmd_is_batch_ (cmd))
171 { 251 {
172 cmd = GNUNET_TESTING_cmd_batch_get_current (cmd); 252 cmd = GNUNET_TESTING_cmd_batch_get_current_ (cmd);
173 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 253 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
174 "Failed in batch at command `%s'\n", 254 "Failed in batch at command `%s'\n",
175 cmd->label); 255 cmd->label);
@@ -181,29 +261,12 @@ GNUNET_TESTING_interpreter_fail (struct GNUNET_TESTING_Interpreter *is)
181 "Failed with CMD being NULL!\n"); 261 "Failed with CMD being NULL!\n");
182 } 262 }
183 is->result = GNUNET_SYSERR; 263 is->result = GNUNET_SYSERR;
184 GNUNET_SCHEDULER_shutdown (); 264 GNUNET_assert (NULL == is->final_task);
185} 265 is->final_task = GNUNET_SCHEDULER_add_now (&finish_test,
186 266 is);
187
188/**
189 * Create command array terminator.
190 *
191 * @return a end-command.
192 */
193struct GNUNET_TESTING_Command
194GNUNET_TESTING_cmd_end (void)
195{
196 static struct GNUNET_TESTING_Command cmd = {
197 .label = NULL
198 };
199
200 return cmd;
201} 267}
202 268
203 269
204/**
205 * Obtain current label.
206 */
207const char * 270const char *
208GNUNET_TESTING_interpreter_get_current_label ( 271GNUNET_TESTING_interpreter_get_current_label (
209 struct GNUNET_TESTING_Interpreter *is) 272 struct GNUNET_TESTING_Interpreter *is)
@@ -234,12 +297,9 @@ interpreter_run (void *cls)
234 GNUNET_SCHEDULER_shutdown (); 297 GNUNET_SCHEDULER_shutdown ();
235 return; 298 return;
236 } 299 }
237 if (NULL != cmd) 300 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
238 { 301 "Running command `%s'\n",
239 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 302 cmd->label);
240 "Running command `%s'\n",
241 cmd->label);
242 }
243 cmd->start_time 303 cmd->start_time
244 = cmd->last_req_time 304 = cmd->last_req_time
245 = GNUNET_TIME_absolute_get (); 305 = GNUNET_TIME_absolute_get ();
@@ -261,57 +321,6 @@ interpreter_run (void *cls)
261 321
262 322
263/** 323/**
264 * Function run when the test terminates (good or bad).
265 * Cleans up our state.
266 *
267 * @param cls the interpreter state.
268 */
269static void
270do_shutdown (void *cls)
271{
272 struct GNUNET_TESTING_Interpreter *is = cls;
273 struct GNUNET_TESTING_Command *cmd;
274 const char *label;
275
276 label = is->commands[is->ip].label;
277 if (NULL == label)
278 label = "END";
279 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
280 "Executing shutdown at `%s'\n",
281 label);
282 for (unsigned int j = 0;
283 NULL != (cmd = &is->commands[j])->label;
284 j++)
285 {
286 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
287 "Cleaning up cmd %s\n",
288 cmd->label);
289 cmd->cleanup (cmd->cls);
290 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
291 "Cleaned up cmd %s\n",
292 cmd->label);
293 }
294 if (NULL != is->finish_task)
295 {
296 GNUNET_SCHEDULER_cancel (is->finish_task);
297 is->finish_task = NULL;
298 }
299 if (NULL != is->task)
300 {
301 GNUNET_SCHEDULER_cancel (is->task);
302 is->task = NULL;
303 }
304 if (NULL != is->timeout_task)
305 {
306 GNUNET_SCHEDULER_cancel (is->timeout_task);
307 is->timeout_task = NULL;
308 }
309 GNUNET_free (is->commands);
310 GNUNET_free (is);
311}
312
313
314/**
315 * Function run when the test terminates (good or bad) with timeout. 324 * Function run when the test terminates (good or bad) with timeout.
316 * 325 *
317 * @param cls the interpreter state 326 * @param cls the interpreter state
@@ -323,20 +332,24 @@ do_timeout (void *cls)
323 332
324 is->timeout_task = NULL; 333 is->timeout_task = NULL;
325 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 334 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
326 "Terminating test due to timeout\n"); 335 "Terminating test due to global timeout\n");
327 GNUNET_SCHEDULER_shutdown (); 336 is->result = GNUNET_SYSERR;
337 finish_test (is);
328} 338}
329 339
330 340
331enum GNUNET_GenericReturnValue 341void
332GNUNET_TESTING_run (const char *cfg_filename, 342GNUNET_TESTING_run (struct GNUNET_TESTING_Command *commands,
333 struct GNUNET_TESTING_Command *commands, 343 struct GNUNET_TIME_Relative timeout,
334 struct GNUNET_TIME_Relative timeout) 344 GNUNET_TESTING_ResultCallback rc,
345 void *rc_cls)
335{ 346{
336 struct GNUNET_TESTING_Interpreter *is; 347 struct GNUNET_TESTING_Interpreter *is;
337 unsigned int i; 348 unsigned int i;
338 349
339 is = GNUNET_new (struct GNUNET_TESTING_Interpreter); 350 is = GNUNET_new (struct GNUNET_TESTING_Interpreter);
351 is->rc = rc;
352 is->rc_cls = rc_cls;
340 /* get the number of commands */ 353 /* get the number of commands */
341 for (i = 0; NULL != commands[i].label; i++) 354 for (i = 0; NULL != commands[i].label; i++)
342 ; 355 ;
@@ -349,11 +362,8 @@ GNUNET_TESTING_run (const char *cfg_filename,
349 = GNUNET_SCHEDULER_add_delayed (timeout, 362 = GNUNET_SCHEDULER_add_delayed (timeout,
350 &do_timeout, 363 &do_timeout,
351 is); 364 is);
352 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
353 is);
354 is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, 365 is->task = GNUNET_SCHEDULER_add_now (&interpreter_run,
355 is); 366 is);
356 return GNUNET_OK;
357} 367}
358 368
359 369
@@ -362,14 +372,46 @@ GNUNET_TESTING_run (const char *cfg_filename,
362 */ 372 */
363struct MainParams 373struct MainParams
364{ 374{
365 const char *cfg_filename; 375
376 /**
377 * NULL-label terminated array of commands.
378 */
366 struct GNUNET_TESTING_Command *commands; 379 struct GNUNET_TESTING_Command *commands;
380
381 /**
382 * Global timeout for the test.
383 */
367 struct GNUNET_TIME_Relative timeout; 384 struct GNUNET_TIME_Relative timeout;
385
386 /**
387 * Set to #EXIT_FAILURE on error.
388 */
368 int rv; 389 int rv;
369}; 390};
370 391
371 392
372/** 393/**
394 * Function called with the final result of the test.
395 *
396 * @param cls the `struct MainParams`
397 * @param rv #GNUNET_OK if the test passed
398 */
399static void
400handle_result (void *cls,
401 enum GNUNET_GenericReturnValue rv)
402{
403 struct MainParams *mp = cls;
404
405 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
406 "Test exits with status %d\n",
407 rv);
408 if (GNUNET_OK != rv)
409 mp->rv = EXIT_FAILURE;
410 GNUNET_SCHEDULER_shutdown ();
411}
412
413
414/**
373 * Main function to run the test cases. 415 * Main function to run the test cases.
374 * 416 *
375 * @param cls a `struct MainParams *` 417 * @param cls a `struct MainParams *`
@@ -379,24 +421,18 @@ loop_run (void *cls)
379{ 421{
380 struct MainParams *mp = cls; 422 struct MainParams *mp = cls;
381 423
382 if (GNUNET_OK != 424 GNUNET_TESTING_run (mp->commands,
383 GNUNET_TESTING_run (mp->cfg_filename, 425 mp->timeout,
384 mp->commands, 426 &handle_result,
385 mp->timeout)) 427 mp);
386 {
387 GNUNET_break (0);
388 mp->rv = EXIT_FAILURE;
389 }
390} 428}
391 429
392 430
393int 431int
394GNUNET_TESTING_main (const char *cfg_filename, 432GNUNET_TESTING_main (struct GNUNET_TESTING_Command *commands,
395 struct GNUNET_TESTING_Command *commands,
396 struct GNUNET_TIME_Relative timeout) 433 struct GNUNET_TIME_Relative timeout)
397{ 434{
398 struct MainParams mp = { 435 struct MainParams mp = {
399 .cfg_filename = cfg_filename,
400 .commands = commands, 436 .commands = commands,
401 .timeout = timeout, 437 .timeout = timeout,
402 .rv = EXIT_SUCCESS 438 .rv = EXIT_SUCCESS