sync

Backup service to store encrypted wallet databases (experimental)
Log | Files | Refs | Submodules | README | LICENSE

testing_api_cmd_object_fetch.c (6575B)


      1 /*
      2   This file is part of SYNC
      3   Copyright (C) 2026 Taler Systems SA
      4 
      5   SYNC 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   SYNC 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 SYNC; see the file COPYING.  If not, see
     17   <http://www.gnu.org/licenses/>
     18 */
     19 /**
     20  * @file testing/testing_api_cmd_object_fetch.c
     21  * @brief command to fetch an object from the sync backend service.
     22  * @author Iván Ávalos
     23  */
     24 #include "platform.h"
     25 #include "sync/sync_service.h"
     26 #include "sync/sync_testing_lib.h"
     27 #include <sync/sync_util.h>
     28 #include <taler/taler_util.h>
     29 #include <taler/taler_signatures.h>
     30 #include <taler/taler_testing_lib.h>
     31 #include <gnunet/gnunet_curl_lib.h>
     32 
     33 
     34 /**
     35  * State for an "object fetch" CMD.
     36  */
     37 struct ObjectFetchState
     38 {
     39 
     40   /**
     41    * URL of the sync backend.
     42    */
     43   const char *sync_url;
     44 
     45   /**
     46    * Reference to a command that provides account keys.
     47    */
     48   const char *account_reference;
     49 
     50   /**
     51    * Eddsa public key.
     52    */
     53   struct SYNC_AccountPublicKeyP sync_pub;
     54 
     55   /**
     56    * UID of the object to fetch.
     57    */
     58   struct SYNC_ObjectUID uid;
     59 
     60   /**
     61    * Expected object data.
     62    */
     63   const void *expected_data;
     64 
     65   /**
     66    * Number of bytes in @e expected_data.
     67    */
     68   size_t expected_data_size;
     69 
     70   /**
     71    * Expected HTTP status code.
     72    */
     73   unsigned int http_status;
     74 
     75   /**
     76    * The interpreter state.
     77    */
     78   struct TALER_TESTING_Interpreter *is;
     79 
     80   /**
     81    * Handle for the library object fetch operation.
     82    */
     83   struct SYNC_ObjectFetchOperation *fop;
     84 
     85 };
     86 
     87 
     88 /**
     89  * Function called when we're done processing the
     90  * object fetch.
     91  *
     92  * @param cls the `struct ObjectFetchState`
     93  * @param http_status HTTP status code
     94  * @param ec error code
     95  * @param uid UID of the fetched object
     96  * @param data_size number of bytes in @a data
     97  * @param data object data
     98  */
     99 static void
    100 object_fetch_finished (void *cls,
    101                        unsigned int http_status,
    102                        enum TALER_ErrorCode ec,
    103                        const struct SYNC_ObjectUID *uid,
    104                        size_t data_size,
    105                        const void *data)
    106 {
    107   struct ObjectFetchState *ofs = cls;
    108 
    109   ofs->fop = NULL;
    110   if (http_status != ofs->http_status)
    111   {
    112     TALER_TESTING_unexpected_status (ofs->is,
    113                                      http_status,
    114                                      ofs->http_status);
    115     return;
    116   }
    117   if (MHD_HTTP_OK == http_status)
    118   {
    119     if (data_size != ofs->expected_data_size)
    120     {
    121       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    122                   "Object fetch data size mismatch: expected %zu, got %zu\n",
    123                   ofs->expected_data_size,
    124                   data_size);
    125       GNUNET_break_op (0);
    126       TALER_TESTING_interpreter_fail (ofs->is);
    127       return;
    128     }
    129     if (0 != memcmp (data,
    130                      ofs->expected_data,
    131                      ofs->expected_data_size))
    132     {
    133       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    134                   "Object fetch data content mismatch\n");
    135       GNUNET_break_op (0);
    136       TALER_TESTING_interpreter_fail (ofs->is);
    137       return;
    138     }
    139     if (NULL != uid)
    140     {
    141       if (0 != GNUNET_memcmp (uid,
    142                               &ofs->uid))
    143       {
    144         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    145                     "Object fetch UID mismatch\n");
    146         GNUNET_break_op (0);
    147         TALER_TESTING_interpreter_fail (ofs->is);
    148         return;
    149       }
    150     }
    151   }
    152   TALER_TESTING_interpreter_next (ofs->is);
    153 }
    154 
    155 
    156 /**
    157  * Run an "object fetch" CMD.
    158  *
    159  * @param cls closure.
    160  * @param cmd command currently being run.
    161  * @param is interpreter state.
    162  */
    163 static void
    164 object_fetch_run (void *cls,
    165                   const struct TALER_TESTING_Command *cmd,
    166                   struct TALER_TESTING_Interpreter *is)
    167 {
    168   struct ObjectFetchState *ofs = cls;
    169 
    170   (void) cmd;
    171   ofs->is = is;
    172 
    173   {
    174     const struct TALER_TESTING_Command *ref;
    175     const struct SYNC_AccountPublicKeyP *pub;
    176 
    177     ref = TALER_TESTING_interpreter_lookup_command (is,
    178                                                     ofs->account_reference);
    179     if (NULL == ref)
    180     {
    181       GNUNET_break (0);
    182       goto fail;
    183     }
    184     if (GNUNET_OK !=
    185         TALER_TESTING_get_trait_sync_account_pub (ref,
    186                                                   &pub))
    187     {
    188       GNUNET_break (0);
    189       goto fail;
    190     }
    191     ofs->sync_pub = *pub;
    192   }
    193 
    194   ofs->fop = SYNC_object_fetch (
    195     TALER_TESTING_interpreter_get_context (is),
    196     ofs->sync_url,
    197     &ofs->sync_pub,
    198     &ofs->uid,
    199     &object_fetch_finished,
    200     ofs);
    201   if (NULL == ofs->fop)
    202     goto fail;
    203 
    204   return;
    205 
    206 fail:
    207   GNUNET_break (0);
    208   TALER_TESTING_interpreter_fail (is);
    209 }
    210 
    211 
    212 /**
    213  * Free the state of an "object fetch" CMD, and possibly
    214  * cancel it if it did not complete.
    215  *
    216  * @param cls closure.
    217  * @param cmd command being freed.
    218  */
    219 static void
    220 object_fetch_cleanup (void *cls,
    221                       const struct TALER_TESTING_Command *cmd)
    222 {
    223   struct ObjectFetchState *ofs = cls;
    224 
    225   if (NULL != ofs->fop)
    226   {
    227     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
    228                 "Command '%s' did not complete (object fetch)\n",
    229                 cmd->label);
    230     SYNC_object_fetch_cancel (ofs->fop);
    231     ofs->fop = NULL;
    232   }
    233   GNUNET_free (ofs);
    234 }
    235 
    236 
    237 struct TALER_TESTING_Command
    238 SYNC_TESTING_cmd_object_fetch (const char *label,
    239                                const char *sync_url,
    240                                const char *account_reference,
    241                                const struct SYNC_ObjectUID *uid,
    242                                unsigned int http_status,
    243                                const void *expected_data,
    244                                size_t expected_data_size)
    245 {
    246   struct ObjectFetchState *ofs;
    247 
    248   ofs = GNUNET_new (struct ObjectFetchState);
    249   ofs->sync_url = sync_url;
    250   ofs->account_reference = account_reference;
    251   if (NULL != uid)
    252     ofs->uid = *uid;
    253   ofs->http_status = http_status;
    254   ofs->expected_data = expected_data;
    255   ofs->expected_data_size = expected_data_size;
    256   {
    257     struct TALER_TESTING_Command cmd = {
    258       .cls = ofs,
    259       .label = label,
    260       .run = &object_fetch_run,
    261       .cleanup = &object_fetch_cleanup,
    262       .traits = NULL
    263     };
    264 
    265     return cmd;
    266   }
    267 }
    268 
    269 
    270 /* end of testing_api_cmd_object_fetch.c */