test_auditordb_checkpoints.c (11503B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2016--2024 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file auditordb/test_auditordb_checkpoints.c 18 * @brief test cases for DB interaction functions 19 * @author Christian Grothoff 20 */ 21 #include "taler/platform.h" 22 #include <gnunet/gnunet_common.h> 23 #include <gnunet/gnunet_db_lib.h> 24 #include "taler/taler_auditordb_plugin.h" 25 26 /** 27 * Currency we use, must match CURRENCY in "test-auditor-db-postgres.conf". 28 */ 29 #define CURRENCY "EUR" 30 31 /** 32 * Report line of error if @a cond is true, and jump to label "drop". 33 */ 34 #define FAILIF(cond) \ 35 do { \ 36 if (! (cond)) { break;} \ 37 GNUNET_break (0); \ 38 goto drop; \ 39 } while (0) 40 41 /** 42 * Initializes @a ptr with random data. 43 */ 44 #define RND_BLK(ptr) \ 45 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, \ 46 sizeof (*ptr)) 47 48 /** 49 * Initializes @a ptr with zeros. 50 */ 51 #define ZR_BLK(ptr) \ 52 memset (ptr, 0, sizeof (*ptr)) 53 54 55 /** 56 * Global result from the testcase. 57 */ 58 static int result = -1; 59 60 /** 61 * Database plugin under test. 62 */ 63 static struct TALER_AUDITORDB_Plugin *plugin; 64 65 66 /** 67 * Main function that will be run by the scheduler. 68 * 69 * @param cls closure with config 70 */ 71 static void 72 run (void *cls) 73 { 74 struct GNUNET_CONFIGURATION_Handle *cfg = cls; 75 struct TALER_Amount a1; 76 struct TALER_Amount a2; 77 struct TALER_Amount a3; 78 79 GNUNET_assert (GNUNET_OK == 80 TALER_string_to_amount (CURRENCY ":11.245678", 81 &a1)); 82 GNUNET_assert (GNUNET_OK == 83 TALER_string_to_amount (CURRENCY ":2", 84 &a2)); 85 GNUNET_assert (GNUNET_OK == 86 TALER_string_to_amount (CURRENCY ":3", 87 &a3)); 88 89 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 90 "loading database plugin\n"); 91 if (NULL == 92 (plugin = TALER_AUDITORDB_plugin_load (cfg, 93 true))) 94 { 95 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 96 "Failed to connect to database\n"); 97 result = 77; 98 return; 99 } 100 101 (void) plugin->drop_tables (plugin->cls, 102 GNUNET_YES); 103 if (GNUNET_OK != 104 plugin->create_tables (plugin->cls, 105 false, 106 0)) 107 { 108 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 109 "Failed to 'create_tables'\n"); 110 result = 77; 111 goto unload; 112 } 113 if (GNUNET_SYSERR == 114 plugin->preflight (plugin->cls)) 115 { 116 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 117 "Failed preflight check\n"); 118 result = 77; 119 goto drop; 120 } 121 122 FAILIF (GNUNET_OK != 123 plugin->start (plugin->cls)); 124 125 /* Test inserting a blank value, should tell us one result */ 126 GNUNET_assert ( 127 GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == 128 plugin->insert_auditor_progress (plugin->cls, 129 "Test", 130 69, 131 NULL) 132 ); 133 /* Test re-inserting the same value; should yield no results */ 134 GNUNET_assert ( 135 GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == 136 plugin->insert_auditor_progress (plugin->cls, 137 "Test", 138 69, 139 NULL) 140 ); 141 /* Test inserting multiple values, with one already existing */ 142 GNUNET_assert ( 143 2 == plugin->insert_auditor_progress (plugin->cls, 144 "Test", 145 69, 146 "Test2", 147 123, 148 "Test3", 149 245, 150 NULL) 151 ); 152 /* Test re-re-inserting the same key with a different value; should also yield no results */ 153 GNUNET_assert ( 154 GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == 155 plugin->insert_auditor_progress (plugin->cls, 156 "Test", 157 42, 158 NULL) 159 ); 160 /* Test updating the same key (again) with a different value; should yield a result */ 161 GNUNET_assert ( 162 GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == 163 plugin->update_auditor_progress (plugin->cls, 164 "Test", 165 42, 166 NULL) 167 ); 168 /* Test updating a key that doesn't exist; should yield 0 */ 169 GNUNET_assert ( 170 GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == 171 plugin->update_auditor_progress (plugin->cls, 172 "NonexistentTest", 173 1, 174 NULL) 175 ); 176 177 /* Right now, the state should look like this: 178 * Test = 42 179 * Test2 = 123 180 * Test3 = 245 181 * Let's make sure that's the case! */ 182 { 183 uint64_t value; 184 uint64_t valueNX; 185 uint64_t value3; 186 187 GNUNET_assert ( 188 3 == 189 plugin->get_auditor_progress ( 190 plugin->cls, 191 "Test", 192 &value, 193 "TestNX", 194 &valueNX, 195 "Test3", 196 &value3, 197 NULL) 198 ); 199 GNUNET_assert (value == 42); 200 GNUNET_assert (valueNX == 0); 201 GNUNET_assert (value3 == 245); 202 } 203 /* Ensure the rest are also at their expected values */ 204 { 205 uint64_t value; 206 207 GNUNET_assert ( 208 GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == 209 plugin->get_auditor_progress ( 210 plugin->cls, 211 "Test2", 212 &value, 213 NULL) 214 ); 215 GNUNET_assert (value == 123); 216 } 217 { 218 uint64_t value; 219 220 GNUNET_assert ( 221 GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == 222 plugin->get_auditor_progress ( 223 plugin->cls, 224 "Test3", 225 &value, 226 NULL) 227 ); 228 GNUNET_assert (value == 245); 229 } 230 { 231 uint64_t value; 232 233 /* Try fetching value that does not exist */ 234 GNUNET_assert ( 235 GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == 236 plugin->get_auditor_progress ( 237 plugin->cls, 238 "TestNX", 239 &value, 240 NULL) 241 ); 242 GNUNET_assert (0 == value); 243 } 244 245 /* Test inserting a blank value, should tell us one result */ 246 GNUNET_assert ( 247 GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == 248 plugin->insert_balance (plugin->cls, 249 "Test", 250 &a1, 251 NULL) 252 ); 253 /* Test re-inserting the same value; should yield no results */ 254 GNUNET_assert ( 255 GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == 256 plugin->insert_balance (plugin->cls, 257 "Test", 258 &a1, 259 NULL) 260 ); 261 /* Test inserting multiple values, with one already existing */ 262 GNUNET_assert ( 263 2 == plugin->insert_balance (plugin->cls, 264 "Test", 265 &a1, 266 "Test2", 267 &a2, 268 "Test3", 269 &a3, 270 NULL) 271 ); 272 /* Test re-re-inserting the same key with a different value; should also yield no results */ 273 GNUNET_assert ( 274 GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == 275 plugin->insert_balance (plugin->cls, 276 "Test", 277 &a2, 278 NULL) 279 ); 280 /* Test updating the same key (again) with a different value; should yield a result */ 281 GNUNET_assert ( 282 GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == 283 plugin->update_balance (plugin->cls, 284 "Test", 285 &a2, 286 NULL) 287 ); 288 /* Test updating a key that doesn't exist; should yield 0 */ 289 GNUNET_assert ( 290 GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == 291 plugin->update_balance (plugin->cls, 292 "NonexistentTest", 293 &a2, 294 NULL) 295 ); 296 297 /* Right now, the state should look like this: 298 * Test = a2 299 * Test2 = a2 300 * Test3 = a3 301 * Let's make sure that's the case! */ 302 GNUNET_assert ( 303 GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == 304 plugin->get_balance ( 305 plugin->cls, 306 "Test", 307 &a1, 308 NULL) 309 ); 310 GNUNET_assert (0 == 311 TALER_amount_cmp (&a1, 312 &a2)); 313 314 /* Ensure the rest are also at their expected values */ 315 GNUNET_assert ( 316 GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == 317 plugin->get_balance ( 318 plugin->cls, 319 "Test2", 320 &a1, 321 NULL) 322 ); 323 GNUNET_assert (0 == 324 TALER_amount_cmp (&a1, 325 &a2)); 326 GNUNET_assert ( 327 GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == 328 plugin->get_balance ( 329 plugin->cls, 330 "Test3", 331 &a1, 332 NULL) 333 ); 334 GNUNET_assert (0 == 335 TALER_amount_cmp (&a1, 336 &a3)); 337 338 /* Try fetching value that does not exist */ 339 GNUNET_assert ( 340 GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == 341 plugin->get_balance ( 342 plugin->cls, 343 "TestNX", 344 &a1, 345 NULL) 346 ); 347 GNUNET_assert (TALER_amount_is_zero (&a1)); 348 349 result = 0; 350 GNUNET_break (0 <= 351 plugin->commit (plugin->cls)); 352 drop: 353 GNUNET_break (GNUNET_OK == 354 plugin->drop_tables (plugin->cls, 355 GNUNET_YES)); 356 unload: 357 TALER_AUDITORDB_plugin_unload (plugin); 358 plugin = NULL; 359 } 360 361 362 int 363 main (int argc, 364 char *const argv[]) 365 { 366 const char *plugin_name; 367 char *config_filename; 368 char *testname; 369 struct GNUNET_CONFIGURATION_Handle *cfg; 370 371 (void) argc; 372 result = -1; 373 GNUNET_log_setup (argv[0], 374 "INFO", 375 NULL); 376 if (NULL == (plugin_name = strrchr (argv[0], 377 (int) '-'))) 378 { 379 GNUNET_break (0); 380 return -1; 381 } 382 plugin_name++; 383 (void) GNUNET_asprintf (&testname, 384 "test-auditor-db-%s", 385 plugin_name); 386 (void) GNUNET_asprintf (&config_filename, 387 "%s.conf", 388 testname); 389 cfg = GNUNET_CONFIGURATION_create (TALER_AUDITOR_project_data ()); 390 if (GNUNET_OK != 391 GNUNET_CONFIGURATION_parse (cfg, 392 config_filename)) 393 { 394 GNUNET_break (0); 395 GNUNET_free (config_filename); 396 GNUNET_free (testname); 397 return 2; 398 } 399 GNUNET_SCHEDULER_run (&run, cfg); 400 GNUNET_CONFIGURATION_destroy (cfg); 401 GNUNET_free (config_filename); 402 GNUNET_free (testname); 403 return result; 404 }