LCOV - code coverage report
Current view: top level - testing - testing_api_cmd_batch.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 53 64 82.8 %
Date: 2025-06-05 21:03:14 Functions: 7 8 87.5 %

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2014-2021 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             :  * @file testing/testing_api_cmd_batch.c
      21             :  * @brief Implement batch-execution of CMDs.
      22             :  * @author Marcello Stanisci
      23             :  */
      24             : #include "platform.h"
      25             : #include "taler_json_lib.h"
      26             : #include <gnunet/gnunet_curl_lib.h>
      27             : #include "taler_testing_lib.h"
      28             : 
      29             : 
      30             : /**
      31             :  * State for a "batch" CMD.
      32             :  */
      33             : struct BatchState
      34             : {
      35             :   /**
      36             :    * CMDs batch.
      37             :    */
      38             :   struct TALER_TESTING_Command *batch;
      39             : 
      40             :   /**
      41             :    * My command (the batch command).
      42             :    */
      43             :   const struct TALER_TESTING_Command *cmd;
      44             : 
      45             :   /**
      46             :    * Internal command pointer.
      47             :    */
      48             :   unsigned int batch_ip;
      49             : };
      50             : 
      51             : 
      52             : /**
      53             :  * Run the command.
      54             :  *
      55             :  * @param cls closure.
      56             :  * @param cmd the command being executed.
      57             :  * @param is the interpreter state.
      58             :  */
      59             : static void
      60         818 : batch_run (void *cls,
      61             :            const struct TALER_TESTING_Command *cmd,
      62             :            struct TALER_TESTING_Interpreter *is)
      63             : {
      64         818 :   struct BatchState *bs = cls;
      65         818 :   struct TALER_TESTING_Command *bcmd = &bs->batch[bs->batch_ip];
      66             : 
      67         818 :   bs->cmd = cmd;
      68         818 :   if (NULL != bcmd->label)
      69         752 :     TALER_LOG_INFO ("Running batched command: %s\n",
      70             :                     bcmd->label);
      71             : 
      72             :   /* hit end command, leap to next top-level command.  */
      73         818 :   if (NULL == bcmd->label)
      74             :   {
      75          66 :     TALER_LOG_INFO ("Exiting from batch: %s\n",
      76             :                     cmd->label);
      77          66 :     TALER_TESTING_interpreter_next (is);
      78          66 :     return;
      79             :   }
      80             :   bcmd->start_time
      81         752 :     = bcmd->last_req_time
      82         752 :       = GNUNET_TIME_absolute_get ();
      83         752 :   bcmd->num_tries++;
      84         752 :   TALER_TESTING_update_variables_ (is,
      85             :                                    bcmd);
      86         752 :   bcmd->run (bcmd->cls,
      87             :              bcmd,
      88             :              is);
      89             : }
      90             : 
      91             : 
      92             : /**
      93             :  * Cleanup the state from a "reserve status" CMD, and possibly
      94             :  * cancel a pending operation thereof.
      95             :  *
      96             :  * @param cls closure.
      97             :  * @param cmd the command which is being cleaned up.
      98             :  */
      99             : static void
     100          66 : batch_cleanup (void *cls,
     101             :                const struct TALER_TESTING_Command *cmd)
     102             : {
     103          66 :   struct BatchState *bs = cls;
     104             : 
     105             :   (void) cmd;
     106          66 :   for (unsigned int i = 0;
     107         818 :        NULL != bs->batch[i].label;
     108         752 :        i++)
     109         752 :     if (NULL != bs->batch[i].cleanup)
     110         752 :       bs->batch[i].cleanup (bs->batch[i].cls,
     111         752 :                             &bs->batch[i]);
     112          66 :   GNUNET_free (bs->batch);
     113          66 :   GNUNET_free (bs);
     114          66 : }
     115             : 
     116             : 
     117             : /**
     118             :  * Offer internal data from a "batch" CMD, to other commands.
     119             :  *
     120             :  * @param cls closure.
     121             :  * @param[out] ret result.
     122             :  * @param trait name of the trait.
     123             :  * @param index index number of the object to offer.
     124             :  * @return #GNUNET_OK on success.
     125             :  */
     126             : static enum GNUNET_GenericReturnValue
     127        2539 : batch_traits (void *cls,
     128             :               const void **ret,
     129             :               const char *trait,
     130             :               unsigned int index)
     131             : {
     132        2539 :   struct BatchState *bs = cls;
     133             :   struct TALER_TESTING_Trait traits[] = {
     134        2539 :     TALER_TESTING_make_trait_batch_cmds (bs->batch),
     135        2539 :     TALER_TESTING_trait_end ()
     136             :   };
     137             : 
     138             :   /* Always return current command.  */
     139        2539 :   return TALER_TESTING_get_trait (traits,
     140             :                                   ret,
     141             :                                   trait,
     142             :                                   index);
     143             : }
     144             : 
     145             : 
     146             : struct TALER_TESTING_Command
     147          66 : TALER_TESTING_cmd_batch (const char *label,
     148             :                          struct TALER_TESTING_Command *batch)
     149             : {
     150             :   struct BatchState *bs;
     151             :   unsigned int i;
     152             : 
     153          66 :   bs = GNUNET_new (struct BatchState);
     154             : 
     155             :   /* Get number of commands.  */
     156         818 :   for (i = 0; NULL != batch[i].label; i++)
     157             :     /* noop */
     158             :     ;
     159             : 
     160          66 :   bs->batch = GNUNET_new_array (i + 1,
     161             :                                 struct TALER_TESTING_Command);
     162          66 :   GNUNET_memcpy (bs->batch,
     163             :                  batch,
     164             :                  sizeof (struct TALER_TESTING_Command) * i);
     165             :   {
     166          66 :     struct TALER_TESTING_Command cmd = {
     167             :       .cls = bs,
     168             :       .label = label,
     169             :       .run = &batch_run,
     170             :       .cleanup = &batch_cleanup,
     171             :       .traits = &batch_traits
     172             :     };
     173             : 
     174          66 :     return cmd;
     175             :   }
     176             : }
     177             : 
     178             : 
     179             : bool
     180         818 : TALER_TESTING_cmd_batch_next (struct TALER_TESTING_Interpreter *is,
     181             :                               void *cls)
     182             : {
     183         818 :   struct BatchState *bs = cls;
     184         818 :   struct TALER_TESTING_Command *bcmd = &bs->batch[bs->batch_ip];
     185             : 
     186         818 :   if (NULL == bcmd->label)
     187             :   {
     188             :     /* This batch is done */
     189          66 :     return true;
     190             :   }
     191         752 :   if (TALER_TESTING_cmd_is_batch (bcmd))
     192             :   {
     193           0 :     if (TALER_TESTING_cmd_batch_next (is,
     194             :                                       bcmd->cls))
     195             :     {
     196             :       /* sub-batch is done */
     197           0 :       bcmd->finish_time = GNUNET_TIME_absolute_get ();
     198           0 :       bs->batch_ip++;
     199           0 :       return false;
     200             :     }
     201             :   }
     202             :   /* Simple command is done */
     203         752 :   bcmd->finish_time = GNUNET_TIME_absolute_get ();
     204         752 :   bs->batch_ip++;
     205         752 :   return false;
     206             : }
     207             : 
     208             : 
     209             : bool
     210        5934 : TALER_TESTING_cmd_is_batch (const struct TALER_TESTING_Command *cmd)
     211             : {
     212        5934 :   return cmd->run == &batch_run;
     213             : }
     214             : 
     215             : 
     216             : struct TALER_TESTING_Command *
     217        2763 : TALER_TESTING_cmd_batch_get_current (const struct TALER_TESTING_Command *cmd)
     218             : {
     219        2763 :   struct BatchState *bs = cmd->cls;
     220             : 
     221        2763 :   GNUNET_assert (cmd->run == &batch_run);
     222        2763 :   return &bs->batch[bs->batch_ip];
     223             : }
     224             : 
     225             : 
     226             : void
     227           0 : TALER_TESTING_cmd_batch_set_current (const struct TALER_TESTING_Command *cmd,
     228             :                                      unsigned int new_ip)
     229             : {
     230           0 :   struct BatchState *bs = cmd->cls;
     231             : 
     232             :   /* sanity checks */
     233           0 :   GNUNET_assert (cmd->run == &batch_run);
     234           0 :   for (unsigned int i = 0; i < new_ip; i++)
     235           0 :     GNUNET_assert (NULL != bs->batch[i].label);
     236             :   /* actual logic */
     237           0 :   bs->batch_ip = new_ip;
     238           0 : }

Generated by: LCOV version 1.16