exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

testing_api_cmd_twister_exec_client.c (25329B)


      1 /*
      2   This file is part of TALER
      3   (C) 2018 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify
      6   it under the terms of the GNU General Public License as
      7   published by the Free Software Foundation; either version 3, or
      8   (at your option) any later version.
      9 
     10   TALER 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
     13   GNU General Public License for more details.
     14 
     15   You should have received a copy of the GNU General Public
     16   License along with TALER; see the file COPYING.  If not, see
     17   <http://www.gnu.org/licenses/>
     18 */
     19 
     20 /**
     21  * @file testing_api_cmd_twister_exec_client.c
     22  * @brief test commands aimed to call the CLI twister client
     23  *        to drive its behaviour.
     24  * @author Christian Grothoff <christian@grothoff.org>
     25  * @author Marcello Stanisci
     26  */
     27 
     28 #include "taler/platform.h"
     29 #include "taler/taler_testing_lib.h"
     30 #include "taler/taler_twister_testing_lib.h"
     31 
     32 
     33 /**
     34  * State for a "modify object" CMD.
     35  */
     36 struct ModifyObjectState
     37 {
     38   /**
     39    * Process handle for the twister CLI client.
     40    */
     41   struct GNUNET_OS_Process *proc;
     42 
     43   /**
     44    * Object-like notation to the object to delete.
     45    */
     46   const char *path;
     47 
     48 
     49   /**
     50    * Value to substitute to the original one.
     51    */
     52   const char *value;
     53 
     54   /**
     55    * Config file name to pass to the CLI client.
     56    */
     57   const char *config_filename;
     58 };
     59 
     60 
     61 /**
     62  * State for a "flip object" CMD.
     63  */
     64 struct FlipObjectState
     65 {
     66   /**
     67    * Process handle for the twister CLI client.
     68    */
     69   struct GNUNET_OS_Process *proc;
     70 
     71   /**
     72    * Object-like notation to the string-object to flip.
     73    */
     74   const char *path;
     75 
     76   /**
     77    * Config file name to pass to the CLI client.
     78    */
     79   const char *config_filename;
     80 };
     81 
     82 
     83 /**
     84  * State for a "delete object" CMD.
     85  */
     86 struct DeleteObjectState
     87 {
     88   /**
     89    * Process handle for the twister CLI client.
     90    */
     91   struct GNUNET_OS_Process *proc;
     92 
     93   /**
     94    * Object-like notation to the object to delete.
     95    */
     96   const char *path;
     97 
     98   /**
     99    * Config file name to pass to the CLI client.
    100    */
    101   const char *config_filename;
    102 };
    103 
    104 
    105 /**
    106  * State for a "malform request" CMD.
    107  */
    108 struct MalformRequestState
    109 {
    110   /**
    111    * Process handle for the twister CLI client.
    112    */
    113   struct GNUNET_OS_Process *proc;
    114 
    115   /**
    116    * Config file name to pass to the CLI client.
    117    */
    118   const char *config_filename;
    119 };
    120 
    121 
    122 /**
    123  * State for a "malform response" CMD.
    124  */
    125 struct MalformResponseState
    126 {
    127   /**
    128    * Process handle for the twister CLI client.
    129    */
    130   struct GNUNET_OS_Process *proc;
    131 
    132   /**
    133    * Config file name to pass to the CLI client.
    134    */
    135   const char *config_filename;
    136 };
    137 
    138 
    139 /**
    140  * State for a "hack response code" CMD.
    141  */
    142 struct HackResponseCodeState
    143 {
    144   /**
    145    * Process handle for the twister CLI client.
    146    */
    147   struct GNUNET_OS_Process *proc;
    148 
    149   /**
    150    * HTTP status code to substitute to the original one.
    151    */
    152   unsigned int http_status;
    153 
    154   /**
    155    * Config file name to pass to the CLI client.
    156    */
    157   const char *config_filename;
    158 };
    159 
    160 
    161 /**
    162  * Free the state from a "hack response code" CMD, and
    163  * possibly kill its process if it did not terminate yet.
    164  *
    165  * @param cls closure.
    166  * @param cmd the command being cleaned up.
    167  */
    168 static void
    169 hack_response_code_cleanup
    170   (void *cls,
    171   const struct TALER_TESTING_Command *cmd)
    172 {
    173   struct HackResponseCodeState *hrcs = cls;
    174 
    175   if (NULL != hrcs->proc)
    176   {
    177     GNUNET_break (0 == GNUNET_OS_process_kill (hrcs->proc,
    178                                                SIGKILL));
    179     GNUNET_OS_process_wait (hrcs->proc);
    180     GNUNET_OS_process_destroy (hrcs->proc);
    181     hrcs->proc = NULL;
    182   }
    183   GNUNET_free (hrcs);
    184 }
    185 
    186 
    187 /**
    188  * Offer data internal to a "hack response code" CMD,
    189  * to other commands.
    190  *
    191  * @param cls closure
    192  * @param[out] ret result (could be anything)
    193  * @param trait name of the trait
    194  * @param index index number of the object to offer.
    195  * @return #GNUNET_OK on success
    196  */
    197 static enum GNUNET_GenericReturnValue
    198 hack_response_code_traits (void *cls,
    199                            const void **ret,
    200                            const char *trait,
    201                            unsigned int index)
    202 {
    203 
    204   struct HackResponseCodeState *hrcs = cls;
    205   struct TALER_TESTING_Trait traits[] = {
    206     TALER_TESTING_make_trait_process (&hrcs->proc),
    207     TALER_TESTING_trait_end ()
    208   };
    209 
    210   return TALER_TESTING_get_trait (traits,
    211                                   ret,
    212                                   trait,
    213                                   index);
    214 }
    215 
    216 
    217 /**
    218  * Run a "hack response code" CMD.
    219  *
    220  * @param cls closure.
    221  * @param cmd the command being run.
    222  * @param is the interpreter state.
    223  */
    224 static void
    225 hack_response_code_run (void *cls,
    226                         const struct TALER_TESTING_Command *cmd,
    227                         struct TALER_TESTING_Interpreter *is)
    228 {
    229   struct HackResponseCodeState *hrcs = cls;
    230   char *http_status;
    231 
    232   GNUNET_asprintf (&http_status, "%u",
    233                    hrcs->http_status);
    234 
    235   hrcs->proc = GNUNET_OS_start_process (
    236     GNUNET_OS_INHERIT_STD_ALL,
    237     NULL, NULL, NULL,
    238     "taler-twister",
    239     "taler-twister",
    240     "-c", hrcs->config_filename,
    241     "--responsecode", http_status,
    242     NULL);
    243   if (NULL == hrcs->proc)
    244   {
    245     GNUNET_break (0);
    246     TALER_TESTING_interpreter_fail (is);
    247     return;
    248   }
    249   TALER_TESTING_wait_for_sigchld (is);
    250   GNUNET_free (http_status);
    251 }
    252 
    253 
    254 struct TALER_TESTING_Command
    255 TALER_TESTING_cmd_hack_response_code (const char *label,
    256                                       const char *config_filename,
    257                                       unsigned int http_status)
    258 {
    259   struct HackResponseCodeState *hrcs;
    260 
    261   hrcs = GNUNET_new (struct HackResponseCodeState);
    262   hrcs->http_status = http_status;
    263   hrcs->config_filename = config_filename;
    264   {
    265     struct TALER_TESTING_Command cmd = {
    266       .label = label,
    267       .run = &hack_response_code_run,
    268       .cleanup = &hack_response_code_cleanup,
    269       .traits = &hack_response_code_traits,
    270       .cls = hrcs
    271     };
    272 
    273     return cmd;
    274   }
    275 }
    276 
    277 
    278 /**
    279  * Free the state from a "delete object" CMD, and
    280  * possibly kill its process if it did not terminate yet.
    281  *
    282  * @param cls closure.
    283  * @param cmd the command being cleaned up.
    284  */
    285 static void
    286 delete_object_cleanup
    287   (void *cls,
    288   const struct TALER_TESTING_Command *cmd)
    289 {
    290   struct DeleteObjectState *dos = cls;
    291 
    292   if (NULL != dos->proc)
    293   {
    294     GNUNET_break (0 == GNUNET_OS_process_kill (dos->proc,
    295                                                SIGKILL));
    296     GNUNET_OS_process_wait (dos->proc);
    297     GNUNET_OS_process_destroy (dos->proc);
    298     dos->proc = NULL;
    299   }
    300   GNUNET_free (dos);
    301 }
    302 
    303 
    304 /**
    305  * Offer data internal to a "delete object" CMD,
    306  * to other commands.
    307  *
    308  * @param cls closure
    309  * @param[out] ret result (could be anything)
    310  * @param trait name of the trait
    311  * @param index index number of the object to offer.
    312  * @return #GNUNET_OK on success
    313  */
    314 static enum GNUNET_GenericReturnValue
    315 delete_object_traits (void *cls,
    316                       const void **ret,
    317                       const char *trait,
    318                       unsigned int index)
    319 {
    320 
    321   struct DeleteObjectState *dos = cls;
    322   struct TALER_TESTING_Trait traits[] = {
    323     TALER_TESTING_make_trait_process (&dos->proc),
    324     TALER_TESTING_trait_end ()
    325   };
    326 
    327   return TALER_TESTING_get_trait (traits,
    328                                   ret,
    329                                   trait,
    330                                   index);
    331 }
    332 
    333 
    334 /**
    335  * Run a "delete object" CMD.
    336  *
    337  * @param cls closure.
    338  * @param cmd the command being run.
    339  * @param is the interpreter state.
    340  */
    341 static void
    342 delete_object_run (void *cls,
    343                    const struct TALER_TESTING_Command *cmd,
    344                    struct TALER_TESTING_Interpreter *is)
    345 {
    346   struct DeleteObjectState *dos = cls;
    347 
    348   dos->proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
    349                                        NULL, NULL, NULL,
    350                                        "taler-twister",
    351                                        "taler-twister",
    352                                        "-c", dos->config_filename,
    353                                        "--deleteobject", dos->path,
    354                                        NULL);
    355   if (NULL == dos->proc)
    356   {
    357     GNUNET_break (0);
    358     TALER_TESTING_interpreter_fail (is);
    359     return;
    360   }
    361   TALER_TESTING_wait_for_sigchld (is);
    362 }
    363 
    364 
    365 /**
    366  * Free the state from a "modify object" CMD, and
    367  * possibly kill its process if it did not terminate yet.
    368  *
    369  * @param cls closure.
    370  * @param cmd the command being cleaned up.
    371  */
    372 static void
    373 modify_object_cleanup (void *cls,
    374                        const struct TALER_TESTING_Command *cmd)
    375 {
    376   struct ModifyObjectState *mos = cls;
    377 
    378   if (NULL != mos->proc)
    379   {
    380     GNUNET_break (0 == GNUNET_OS_process_kill (mos->proc,
    381                                                SIGKILL));
    382     GNUNET_OS_process_wait (mos->proc);
    383     GNUNET_OS_process_destroy (mos->proc);
    384     mos->proc = NULL;
    385   }
    386   GNUNET_free (mos);
    387 }
    388 
    389 
    390 /**
    391  * Offer data internal to a "modify object" CMD,
    392  * to other commands.
    393  *
    394  * @param cls closure
    395  * @param[out] ret result (could be anything)
    396  * @param trait name of the trait
    397  * @param index index number of the object to offer.
    398  * @return #GNUNET_OK on success
    399  */
    400 static enum GNUNET_GenericReturnValue
    401 modify_object_traits (void *cls,
    402                       const void **ret,
    403                       const char *trait,
    404                       unsigned int index)
    405 {
    406 
    407   struct ModifyObjectState *mos = cls;
    408   struct TALER_TESTING_Trait traits[] = {
    409     TALER_TESTING_make_trait_process (&mos->proc),
    410     TALER_TESTING_trait_end ()
    411   };
    412 
    413   return TALER_TESTING_get_trait (traits,
    414                                   ret,
    415                                   trait,
    416                                   index);
    417 }
    418 
    419 
    420 /**
    421  * Run a "modify object" CMD.  The "download fashion" of it.
    422  *
    423  * @param cls closure.
    424  * @param cmd the command being run.
    425  * @param is the interpreter state.
    426  */
    427 static void
    428 modify_object_dl_run (void *cls,
    429                       const struct TALER_TESTING_Command *cmd,
    430                       struct TALER_TESTING_Interpreter *is)
    431 {
    432   struct ModifyObjectState *mos = cls;
    433 
    434   mos->proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
    435                                        NULL, NULL, NULL,
    436                                        "taler-twister",
    437                                        "taler-twister",
    438                                        "-c", mos->config_filename,
    439                                        "-m", mos->path,
    440                                        "--value", mos->value,
    441                                        NULL);
    442   if (NULL == mos->proc)
    443   {
    444     GNUNET_break (0);
    445     TALER_TESTING_interpreter_fail (is);
    446     return;
    447   }
    448   TALER_TESTING_wait_for_sigchld (is);
    449 }
    450 
    451 
    452 /**
    453  * Run a "modify object" CMD, the "upload fashion" of it.
    454  *
    455  * @param cls closure.
    456  * @param cmd the command being run.
    457  * @param is the interpreter state.
    458  */
    459 static void
    460 modify_object_ul_run (void *cls,
    461                       const struct TALER_TESTING_Command *cmd,
    462                       struct TALER_TESTING_Interpreter *is)
    463 {
    464   struct ModifyObjectState *mos = cls;
    465 
    466   mos->proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
    467                                        NULL, NULL, NULL,
    468                                        "taler-twister",
    469                                        "taler-twister",
    470                                        "-c", mos->config_filename,
    471                                        "-X", mos->path,
    472                                        "--value", mos->value,
    473                                        NULL);
    474   if (NULL == mos->proc)
    475   {
    476     GNUNET_break (0);
    477     TALER_TESTING_interpreter_fail (is);
    478     return;
    479   }
    480   TALER_TESTING_wait_for_sigchld (is);
    481 }
    482 
    483 
    484 /**
    485  * Run a "modify header" CMD
    486  *
    487  * @param cls closure.
    488  * @param cmd the command being run.
    489  * @param is the interpreter state.
    490  */
    491 static void
    492 modify_header_dl_run (void *cls,
    493                       const struct TALER_TESTING_Command *cmd,
    494                       struct TALER_TESTING_Interpreter *is)
    495 {
    496   struct ModifyObjectState *mos = cls;
    497 
    498   mos->proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
    499                                        NULL, NULL, NULL,
    500                                        "taler-twister",
    501                                        "taler-twister",
    502                                        "-H", mos->path,
    503                                        "--value", mos->value,
    504                                        "-c", mos->config_filename,
    505                                        NULL);
    506   if (NULL == mos->proc)
    507   {
    508     GNUNET_break (0);
    509     TALER_TESTING_interpreter_fail (is);
    510     return;
    511   }
    512   TALER_TESTING_wait_for_sigchld (is);
    513 }
    514 
    515 
    516 struct TALER_TESTING_Command
    517 TALER_TESTING_cmd_delete_object (const char *label,
    518                                  const char *config_filename,
    519                                  const char *path)
    520 {
    521   struct DeleteObjectState *dos;
    522 
    523   dos = GNUNET_new (struct DeleteObjectState);
    524   dos->path = path;
    525   dos->config_filename = config_filename;
    526   {
    527     struct TALER_TESTING_Command cmd = {
    528       .label = label,
    529       .run = &delete_object_run,
    530       .cleanup = &delete_object_cleanup,
    531       .traits = &delete_object_traits,
    532       .cls = dos
    533     };
    534 
    535     return cmd;
    536   }
    537 }
    538 
    539 
    540 /**
    541  * Free the state from a "flip object" CMD, and
    542  * possibly kill its process if it did not terminate yet.
    543  *
    544  * @param cls closure.
    545  * @param cmd the command being cleaned up.
    546  */
    547 static void
    548 flip_object_cleanup
    549   (void *cls,
    550   const struct TALER_TESTING_Command *cmd)
    551 {
    552   struct FlipObjectState *fos = cls;
    553 
    554   if (NULL != fos->proc)
    555   {
    556     GNUNET_break (0 == GNUNET_OS_process_kill (fos->proc,
    557                                                SIGKILL));
    558     GNUNET_OS_process_wait (fos->proc);
    559     GNUNET_OS_process_destroy (fos->proc);
    560     fos->proc = NULL;
    561   }
    562   GNUNET_free (fos);
    563 }
    564 
    565 
    566 /**
    567  * Offer data internal to a "flip object" CMD,
    568  * to other commands.
    569  *
    570  * @param cls closure
    571  * @param[out] ret result (could be anything)
    572  * @param trait name of the trait
    573  * @param index index number of the object to offer.
    574  * @return #GNUNET_OK on success
    575  */
    576 static enum GNUNET_GenericReturnValue
    577 flip_object_traits (void *cls,
    578                     const void **ret,
    579                     const char *trait,
    580                     unsigned int index)
    581 {
    582   struct FlipObjectState *fos = cls;
    583   struct TALER_TESTING_Trait traits[] = {
    584     TALER_TESTING_make_trait_process (&fos->proc),
    585     TALER_TESTING_trait_end ()
    586   };
    587 
    588   return TALER_TESTING_get_trait (traits,
    589                                   ret,
    590                                   trait,
    591                                   index);
    592 }
    593 
    594 
    595 /**
    596  * Run a "flip object" CMD, the upload fashion of it.
    597  *
    598  * @param cls closure.
    599  * @param cmd the command being run.
    600  * @param is the interpreter state.
    601  */
    602 static void
    603 flip_upload_run (void *cls,
    604                  const struct TALER_TESTING_Command *cmd,
    605                  struct TALER_TESTING_Interpreter *is)
    606 {
    607   struct FlipObjectState *fos = cls;
    608 
    609   fos->proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
    610                                        NULL, NULL, NULL,
    611                                        "taler-twister",
    612                                        "taler-twister",
    613                                        "-c", fos->config_filename,
    614                                        "--flip-ul", fos->path,
    615                                        NULL);
    616   if (NULL == fos->proc)
    617   {
    618     GNUNET_break (0);
    619     TALER_TESTING_interpreter_fail (is);
    620     return;
    621   }
    622   TALER_TESTING_wait_for_sigchld (is);
    623 }
    624 
    625 
    626 /**
    627  * Run a "flip object" CMD, the download fashion of it.
    628  *
    629  * @param cls closure.
    630  * @param cmd the command being run.
    631  * @param is the interpreter state.
    632  */
    633 static void
    634 flip_download_run (void *cls,
    635                    const struct TALER_TESTING_Command *cmd,
    636                    struct TALER_TESTING_Interpreter *is)
    637 {
    638   struct FlipObjectState *fos = cls;
    639 
    640   fos->proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
    641                                        NULL, NULL, NULL,
    642                                        "taler-twister",
    643                                        "taler-twister",
    644                                        "-c", fos->config_filename,
    645                                        "--flip-dl", fos->path,
    646                                        NULL);
    647   if (NULL == fos->proc)
    648   {
    649     GNUNET_break (0);
    650     TALER_TESTING_interpreter_fail (is);
    651     return;
    652   }
    653   TALER_TESTING_wait_for_sigchld (is);
    654 }
    655 
    656 
    657 struct TALER_TESTING_Command
    658 TALER_TESTING_cmd_flip_upload (const char *label,
    659                                const char *config_filename,
    660                                const char *path)
    661 {
    662   struct FlipObjectState *dos;
    663 
    664   dos = GNUNET_new (struct FlipObjectState);
    665   dos->path = path;
    666   dos->config_filename = config_filename;
    667   {
    668     struct TALER_TESTING_Command cmd = {
    669       .label = label,
    670       .run = &flip_upload_run,
    671       .cleanup = &flip_object_cleanup,
    672       .traits = &flip_object_traits,
    673       .cls = dos
    674     };
    675 
    676     return cmd;
    677   }
    678 }
    679 
    680 
    681 struct TALER_TESTING_Command
    682 TALER_TESTING_cmd_flip_download (const char *label,
    683                                  const char *config_filename,
    684                                  const char *path)
    685 {
    686   struct FlipObjectState *dos;
    687 
    688   dos = GNUNET_new (struct FlipObjectState);
    689   dos->path = path;
    690   dos->config_filename = config_filename;
    691   {
    692     struct TALER_TESTING_Command cmd = {
    693       .label = label,
    694       .run = &flip_download_run,
    695       .cleanup = &flip_object_cleanup,
    696       .traits = &flip_object_traits,
    697       .cls = dos
    698     };
    699 
    700     return cmd;
    701   }
    702 }
    703 
    704 
    705 /**
    706  * Free the state from a "malform request" CMD, and
    707  * possibly kill its process if it did not terminate yet.
    708  *
    709  * @param cls closure.
    710  * @param cmd the command being cleaned up.
    711  */
    712 static void
    713 malform_request_cleanup (void *cls,
    714                          const struct TALER_TESTING_Command *cmd)
    715 {
    716   struct MalformRequestState *mrs = cls;
    717 
    718   if (NULL != mrs->proc)
    719   {
    720     GNUNET_break (0 == GNUNET_OS_process_kill (mrs->proc,
    721                                                SIGKILL));
    722     GNUNET_OS_process_wait (mrs->proc);
    723     GNUNET_OS_process_destroy (mrs->proc);
    724     mrs->proc = NULL;
    725   }
    726   GNUNET_free (mrs);
    727 }
    728 
    729 
    730 /**
    731  * Offer data internal to a "malform request" CMD,
    732  * to other commands.
    733  *
    734  * @param cls closure
    735  * @param[out] ret result (could be anything)
    736  * @param trait name of the trait
    737  * @param index index number of the object to offer.
    738  * @return #GNUNET_OK on success
    739  */
    740 static enum GNUNET_GenericReturnValue
    741 malform_request_traits (void *cls,
    742                         const void **ret,
    743                         const char *trait,
    744                         unsigned int index)
    745 {
    746   struct MalformRequestState *mrs = cls;
    747   struct TALER_TESTING_Trait traits[] = {
    748     TALER_TESTING_make_trait_process (&mrs->proc),
    749     TALER_TESTING_trait_end ()
    750   };
    751 
    752   return TALER_TESTING_get_trait (traits,
    753                                   ret,
    754                                   trait,
    755                                   index);
    756 }
    757 
    758 
    759 /**
    760  * Run a "malform request" CMD.
    761  *
    762  * @param cls closure.
    763  * @param cmd the command being run.
    764  * @param is the interpreter state.
    765  */
    766 static void
    767 malform_request_run (void *cls,
    768                      const struct TALER_TESTING_Command *cmd,
    769                      struct TALER_TESTING_Interpreter *is)
    770 {
    771   struct MalformRequestState *mrs = cls;
    772 
    773   mrs->proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
    774                                        NULL, NULL, NULL,
    775                                        "taler-twister",
    776                                        "taler-twister",
    777                                        "-c", mrs->config_filename,
    778                                        "--malformupload",
    779                                        NULL);
    780   if (NULL == mrs->proc)
    781   {
    782     GNUNET_break (0);
    783     TALER_TESTING_interpreter_fail (is);
    784     return;
    785   }
    786   TALER_TESTING_wait_for_sigchld (is);
    787 }
    788 
    789 
    790 /**
    791  * Free the state from a "malform response" CMD, and
    792  * possibly kill its process if it did not terminate yet.
    793  *
    794  * @param cls closure.
    795  * @param cmd the command being cleaned up.
    796  */
    797 static void
    798 malform_response_cleanup (void *cls,
    799                           const struct TALER_TESTING_Command *cmd)
    800 {
    801   struct MalformResponseState *mrs = cls;
    802 
    803   if (NULL != mrs->proc)
    804   {
    805     GNUNET_break (0 == GNUNET_OS_process_kill (mrs->proc,
    806                                                SIGKILL));
    807     GNUNET_OS_process_wait (mrs->proc);
    808     GNUNET_OS_process_destroy (mrs->proc);
    809     mrs->proc = NULL;
    810   }
    811   GNUNET_free (mrs);
    812 }
    813 
    814 
    815 /**
    816  * Offer data internal to a "malform response" CMD,
    817  * to other commands.
    818  *
    819  * @param cls closure
    820  * @param[out] ret result (could be anything)
    821  * @param trait name of the trait
    822  * @param index index number of the object to offer.
    823  * @return #GNUNET_OK on success
    824  */
    825 static enum GNUNET_GenericReturnValue
    826 malform_response_traits (void *cls,
    827                          const void **ret,
    828                          const char *trait,
    829                          unsigned int index)
    830 {
    831   struct MalformResponseState *mrs = cls;
    832   struct TALER_TESTING_Trait traits[] = {
    833     TALER_TESTING_make_trait_process (&mrs->proc),
    834     TALER_TESTING_trait_end ()
    835   };
    836 
    837   return TALER_TESTING_get_trait (traits,
    838                                   ret,
    839                                   trait,
    840                                   index);
    841 }
    842 
    843 
    844 /**
    845  * Run a "malform response" CMD.
    846  *
    847  * @param cls closure.
    848  * @param cmd the command being run.
    849  * @param is the interpreter state.
    850  */
    851 static void
    852 malform_response_run (void *cls,
    853                       const struct TALER_TESTING_Command *cmd,
    854                       struct TALER_TESTING_Interpreter *is)
    855 {
    856   struct MalformResponseState *mrs = cls;
    857 
    858   mrs->proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
    859                                        NULL, NULL, NULL,
    860                                        "taler-twister",
    861                                        "taler-twister",
    862                                        "-c", mrs->config_filename,
    863                                        "--malform",
    864                                        NULL);
    865   if (NULL == mrs->proc)
    866   {
    867     GNUNET_break (0);
    868     TALER_TESTING_interpreter_fail (is);
    869     return;
    870   }
    871   TALER_TESTING_wait_for_sigchld (is);
    872 }
    873 
    874 
    875 struct TALER_TESTING_Command
    876 TALER_TESTING_cmd_malform_request (const char *label,
    877                                    const char *config_filename)
    878 {
    879   struct MalformRequestState *mrs;
    880 
    881   mrs = GNUNET_new (struct MalformRequestState);
    882   mrs->config_filename = config_filename;
    883   {
    884     struct TALER_TESTING_Command cmd = {
    885       .label = label,
    886       .run = &malform_request_run,
    887       .cleanup = &malform_request_cleanup,
    888       .traits = &malform_request_traits,
    889       .cls = mrs
    890     };
    891 
    892     return cmd;
    893   }
    894 }
    895 
    896 
    897 struct TALER_TESTING_Command
    898 TALER_TESTING_cmd_malform_response (const char *label,
    899                                     const char *config_filename)
    900 {
    901   struct MalformResponseState *mrs;
    902 
    903   mrs = GNUNET_new (struct MalformResponseState);
    904   mrs->config_filename = config_filename;
    905   {
    906     struct TALER_TESTING_Command cmd = {
    907       .label = label,
    908       .run = &malform_response_run,
    909       .cleanup = &malform_response_cleanup,
    910       .traits = &malform_response_traits,
    911       .cls = mrs
    912     };
    913 
    914     return cmd;
    915   }
    916 }
    917 
    918 
    919 struct TALER_TESTING_Command
    920 TALER_TESTING_cmd_modify_object_dl (const char *label,
    921                                     const char *config_filename,
    922                                     const char *path,
    923                                     const char *value)
    924 {
    925   struct ModifyObjectState *mos;
    926 
    927   mos = GNUNET_new (struct ModifyObjectState);
    928   mos->path = path;
    929   mos->value = value;
    930   mos->config_filename = config_filename;
    931   {
    932     struct TALER_TESTING_Command cmd = {
    933       .label = label,
    934       .run = &modify_object_dl_run,
    935       .cleanup = &modify_object_cleanup,
    936       .traits = &modify_object_traits,
    937       .cls = mos
    938     };
    939 
    940     return cmd;
    941   }
    942 }
    943 
    944 
    945 struct TALER_TESTING_Command
    946 TALER_TESTING_cmd_modify_object_ul (const char *label,
    947                                     const char *config_filename,
    948                                     const char *path,
    949                                     const char *value)
    950 {
    951   struct ModifyObjectState *mos;
    952 
    953   mos = GNUNET_new (struct ModifyObjectState);
    954   mos->path = path;
    955   mos->value = value;
    956   mos->config_filename = config_filename;
    957   {
    958     struct TALER_TESTING_Command cmd = {
    959       .label = label,
    960       .run = &modify_object_ul_run,
    961       .cleanup = &modify_object_cleanup,
    962       .traits = &modify_object_traits,
    963       .cls = mos
    964     };
    965 
    966     return cmd;
    967   }
    968 }
    969 
    970 
    971 struct TALER_TESTING_Command
    972 TALER_TESTING_cmd_modify_header_dl (const char *label,
    973                                     const char *config_filename,
    974                                     const char *path,
    975                                     const char *value)
    976 {
    977   struct ModifyObjectState *mos;
    978 
    979   mos = GNUNET_new (struct ModifyObjectState);
    980   mos->path = path;
    981   mos->value = value;
    982   mos->config_filename = config_filename;
    983   {
    984     struct TALER_TESTING_Command cmd = {
    985       .label = label,
    986       .run = &modify_header_dl_run,
    987       .cleanup = &modify_object_cleanup,
    988       .traits = &modify_object_traits,
    989       .cls = mos
    990     };
    991 
    992     return cmd;
    993   }
    994 }
    995 
    996 
    997 /* end of testing_api_cmd_exec_client.c */