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 */