test_auditordb.c (19293B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2016--2022 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.c 18 * @brief test cases for DB interaction functions 19 * @author Gabor X Toth 20 * @author Christian Grothoff 21 */ 22 #include "taler/platform.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, sizeof (* \ 46 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 * Hash of denomination public key. 62 */ 63 static struct TALER_DenominationHashP denom_pub_hash; 64 65 /** 66 * Another hash of a denomination public key. 67 */ 68 static struct TALER_DenominationHashP rnd_hash; 69 70 /** 71 * Current time. 72 */ 73 static struct GNUNET_TIME_Timestamp now; 74 75 /** 76 * Timestamp in the past. 77 */ 78 static struct GNUNET_TIME_Timestamp past; 79 80 /** 81 * Timestamp in the future. 82 */ 83 static struct GNUNET_TIME_Timestamp future; 84 85 /** 86 * Database plugin under test. 87 */ 88 static struct TALER_AUDITORDB_Plugin *plugin; 89 90 /** 91 * Historic denomination revenue value. 92 */ 93 static struct TALER_Amount rbalance; 94 95 /** 96 * Historic denomination loss value. 97 */ 98 static struct TALER_Amount rloss; 99 100 /** 101 * Reserve profit value we are using. 102 */ 103 static struct TALER_Amount reserve_profits; 104 105 106 static enum GNUNET_GenericReturnValue 107 select_historic_denom_revenue_result ( 108 void *cls, 109 uint64_t rowid, 110 const struct TALER_DenominationHashP *denom_pub_hash2, 111 struct GNUNET_TIME_Timestamp revenue_timestamp2, 112 const struct TALER_Amount *revenue_balance2, 113 const struct TALER_Amount *loss2) 114 { 115 static int n = 0; 116 117 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 118 "select_historic_denom_revenue_result: row %u\n", n); 119 120 if ( (2 <= n++) 121 || (cls != NULL) 122 || ((0 != GNUNET_memcmp (&revenue_timestamp2, 123 &past)) 124 && (0 != GNUNET_memcmp (&revenue_timestamp2, 125 &now))) 126 || ((0 != GNUNET_memcmp (denom_pub_hash2, 127 &denom_pub_hash)) 128 && (0 != GNUNET_memcmp (denom_pub_hash2, 129 &rnd_hash))) 130 || (0 != TALER_amount_cmp (revenue_balance2, 131 &rbalance)) 132 || (0 != TALER_amount_cmp (loss2, 133 &rloss))) 134 { 135 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 136 "select_historic_denom_revenue_result: result does not match\n") 137 ; 138 GNUNET_break (0); 139 return GNUNET_SYSERR; 140 } 141 return GNUNET_OK; 142 } 143 144 145 static enum GNUNET_GenericReturnValue 146 select_historic_reserve_revenue_result ( 147 void *cls, 148 uint64_t rowid, 149 struct GNUNET_TIME_Timestamp start_time2, 150 struct GNUNET_TIME_Timestamp end_time2, 151 const struct TALER_Amount *reserve_profits2) 152 { 153 static int n = 0; 154 155 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 156 "select_historic_reserve_revenue_result: row %u\n", n); 157 158 if ((2 <= n++) 159 || (cls != NULL) 160 || ((0 != GNUNET_memcmp (&start_time2, 161 &past)) 162 && (0 != GNUNET_memcmp (&start_time2, 163 &now))) 164 || (0 != GNUNET_memcmp (&end_time2, 165 &future)) 166 || (0 != TALER_amount_cmp (reserve_profits2, 167 &reserve_profits))) 168 { 169 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 170 "select_historic_reserve_revenue_result: result does not match\n"); 171 GNUNET_break (0); 172 return GNUNET_SYSERR; 173 } 174 return GNUNET_OK; 175 } 176 177 178 /** 179 * Main function that will be run by the scheduler. 180 * 181 * @param cls closure with config 182 */ 183 static void 184 run (void *cls) 185 { 186 struct GNUNET_CONFIGURATION_Handle *cfg = cls; 187 uint64_t rowid; 188 struct TALER_Amount value; 189 struct TALER_Amount fee_withdraw; 190 struct TALER_Amount fee_deposit; 191 struct TALER_Amount fee_refresh; 192 struct TALER_Amount fee_refund; 193 struct TALER_ReservePublicKeyP reserve_pub; 194 struct TALER_DenominationPrivateKey denom_priv; 195 struct TALER_DenominationPublicKey denom_pub; 196 struct GNUNET_TIME_Timestamp date; 197 198 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 199 "loading database plugin\n"); 200 201 if (NULL == 202 (plugin = TALER_AUDITORDB_plugin_load (cfg, 203 true))) 204 { 205 result = 77; 206 return; 207 } 208 209 (void) plugin->drop_tables (plugin->cls, 210 GNUNET_YES); 211 if (GNUNET_OK != 212 plugin->create_tables (plugin->cls, 213 false, 214 0)) 215 { 216 result = 77; 217 goto unload; 218 } 219 if (GNUNET_SYSERR == 220 plugin->preflight (plugin->cls)) 221 { 222 result = 77; 223 goto drop; 224 } 225 226 FAILIF (GNUNET_OK != 227 plugin->start (plugin->cls)); 228 229 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 230 "initializing\n"); 231 232 GNUNET_assert (GNUNET_OK == 233 TALER_string_to_amount (CURRENCY ":1.000010", 234 &value)); 235 GNUNET_assert (GNUNET_OK == 236 TALER_string_to_amount (CURRENCY ":0.000011", 237 &fee_withdraw)); 238 GNUNET_assert (GNUNET_OK == 239 TALER_string_to_amount (CURRENCY ":0.000012", 240 &fee_deposit)); 241 GNUNET_assert (GNUNET_OK == 242 TALER_string_to_amount (CURRENCY ":0.000013", 243 &fee_refresh)); 244 GNUNET_assert (GNUNET_OK == 245 TALER_string_to_amount (CURRENCY ":0.000014", 246 &fee_refund)); 247 RND_BLK (&reserve_pub); 248 RND_BLK (&rnd_hash); 249 GNUNET_assert (GNUNET_OK == 250 TALER_denom_priv_create (&denom_priv, 251 &denom_pub, 252 GNUNET_CRYPTO_BSA_RSA, 253 1024)); 254 TALER_denom_pub_hash (&denom_pub, 255 &denom_pub_hash); 256 TALER_denom_priv_free (&denom_priv); 257 TALER_denom_pub_free (&denom_pub); 258 259 now = GNUNET_TIME_timestamp_get (); 260 past = GNUNET_TIME_absolute_to_timestamp ( 261 GNUNET_TIME_absolute_subtract (now.abs_time, 262 GNUNET_TIME_relative_multiply ( 263 GNUNET_TIME_UNIT_HOURS, 264 4))); 265 future = GNUNET_TIME_absolute_to_timestamp ( 266 GNUNET_TIME_absolute_add (now.abs_time, 267 GNUNET_TIME_relative_multiply ( 268 GNUNET_TIME_UNIT_HOURS, 269 4))); 270 271 { 272 struct TALER_AUDITORDB_ReserveFeeBalance rfb; 273 struct TALER_AUDITORDB_ReserveFeeBalance rfb2; 274 275 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 276 "Test: insert_reserve_info\n"); 277 GNUNET_assert (GNUNET_OK == 278 TALER_string_to_amount (CURRENCY ":12.345678", 279 &rfb.reserve_balance)); 280 GNUNET_assert (GNUNET_OK == 281 TALER_string_to_amount (CURRENCY ":11.245678", 282 &rfb.reserve_loss)); 283 GNUNET_assert (GNUNET_OK == 284 TALER_string_to_amount (CURRENCY ":23.456789", 285 &rfb.withdraw_fee_balance)); 286 GNUNET_assert (GNUNET_OK == 287 TALER_string_to_amount (CURRENCY ":23.456719", 288 &rfb.close_fee_balance)); 289 GNUNET_assert (GNUNET_OK == 290 TALER_string_to_amount (CURRENCY ":33.456789", 291 &rfb.purse_fee_balance)); 292 GNUNET_assert (GNUNET_OK == 293 TALER_string_to_amount (CURRENCY ":43.456789", 294 &rfb.open_fee_balance)); 295 GNUNET_assert (GNUNET_OK == 296 TALER_string_to_amount (CURRENCY ":53.456789", 297 &rfb.history_fee_balance)); 298 { 299 struct TALER_FullPayto pt = { 300 .full_payto = (char *) "payto://bla/blub?receiver-name=blub" 301 }; 302 303 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 304 plugin->insert_reserve_info (plugin->cls, 305 &reserve_pub, 306 &rfb, 307 past, 308 pt)); 309 } 310 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 311 "Test: update_reserve_info\n"); 312 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 313 plugin->update_reserve_info (plugin->cls, 314 &reserve_pub, 315 &rfb, 316 future)); 317 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 318 "Test: get_reserve_info\n"); 319 { 320 struct TALER_FullPayto payto; 321 322 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 323 plugin->get_reserve_info (plugin->cls, 324 &reserve_pub, 325 &rowid, 326 &rfb2, 327 &date, 328 &payto)); 329 FAILIF (0 != strcmp (payto.full_payto, 330 "payto://bla/blub?receiver-name=blub")); 331 GNUNET_free (payto.full_payto); 332 } 333 FAILIF ( (0 != GNUNET_memcmp (&date, 334 &future)) 335 || (0 != TALER_amount_cmp (&rfb2.reserve_balance, 336 &rfb.reserve_balance)) 337 || (0 != TALER_amount_cmp (&rfb2.withdraw_fee_balance, 338 &rfb.withdraw_fee_balance)) 339 || (0 != TALER_amount_cmp (&rfb2.close_fee_balance, 340 &rfb.close_fee_balance)) 341 || (0 != TALER_amount_cmp (&rfb2.purse_fee_balance, 342 &rfb.purse_fee_balance)) 343 || (0 != TALER_amount_cmp (&rfb2.open_fee_balance, 344 &rfb.open_fee_balance)) 345 || (0 != TALER_amount_cmp (&rfb2.history_fee_balance, 346 &rfb.history_fee_balance)) 347 ); 348 } 349 350 { 351 struct TALER_AUDITORDB_ClosureLags cl = { 352 .problem_row_id = 42 353 }; 354 355 GNUNET_assert (GNUNET_OK == 356 TALER_string_to_amount (CURRENCY ":12.345678", 357 &cl.amount)); 358 cl.account.full_payto 359 = (char *) "payto://unspec/foo?receiver-name=bar"; 360 memset (&cl.wtid, 361 42, 362 sizeof (cl.wtid)); 363 cl.deadline = GNUNET_TIME_absolute_get (); 364 FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != 365 plugin->delete_auditor_closure_lag (plugin->cls, 366 &cl.amount, 367 &cl.wtid, 368 cl.account)); 369 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 370 plugin->insert_auditor_closure_lags (plugin->cls, 371 &cl)); 372 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 373 plugin->delete_auditor_closure_lag (plugin->cls, 374 &cl.amount, 375 &cl.wtid, 376 cl.account)); 377 } 378 379 { 380 struct TALER_AUDITORDB_DenominationCirculationData dcd; 381 struct TALER_AUDITORDB_DenominationCirculationData dcd2; 382 383 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 384 "Test: insert_denomination_balance\n"); 385 GNUNET_assert (GNUNET_OK == 386 TALER_string_to_amount (CURRENCY ":12.345678", 387 &dcd.denom_balance)); 388 GNUNET_assert (GNUNET_OK == 389 TALER_string_to_amount (CURRENCY ":0.1", 390 &dcd.denom_loss)); 391 GNUNET_assert (GNUNET_OK == 392 TALER_string_to_amount (CURRENCY ":13.57986", 393 &dcd.denom_risk)); 394 GNUNET_assert (GNUNET_OK == 395 TALER_string_to_amount (CURRENCY ":12.57986", 396 &dcd.recoup_loss)); 397 dcd.num_issued = 62; 398 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 399 plugin->insert_denomination_balance (plugin->cls, 400 &denom_pub_hash, 401 &dcd)); 402 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 403 "Test: update_denomination_balance\n"); 404 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 405 plugin->update_denomination_balance (plugin->cls, 406 &denom_pub_hash, 407 &dcd)); 408 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 409 "Test: get_denomination_balance\n"); 410 411 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 412 plugin->get_denomination_balance (plugin->cls, 413 &denom_pub_hash, 414 &dcd2)); 415 FAILIF (0 != TALER_amount_cmp (&dcd2.denom_balance, 416 &dcd.denom_balance)); 417 FAILIF (0 != TALER_amount_cmp (&dcd2.denom_loss, 418 &dcd.denom_loss)); 419 FAILIF (0 != TALER_amount_cmp (&dcd2.denom_risk, 420 &dcd.denom_risk)); 421 FAILIF (0 != TALER_amount_cmp (&dcd2.recoup_loss, 422 &dcd.recoup_loss)); 423 FAILIF (dcd2.num_issued != dcd.num_issued); 424 } 425 426 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 427 "Test: insert_historic_denom_revenue\n"); 428 GNUNET_assert (GNUNET_OK == 429 TALER_string_to_amount (CURRENCY ":12.345678", 430 &rbalance)); 431 GNUNET_assert (GNUNET_OK == 432 TALER_string_to_amount (CURRENCY ":23.456789", 433 &rloss)); 434 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 435 plugin->insert_historic_denom_revenue (plugin->cls, 436 &denom_pub_hash, 437 past, 438 &rbalance, 439 &rloss)); 440 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 441 plugin->insert_historic_denom_revenue (plugin->cls, 442 &rnd_hash, 443 now, 444 &rbalance, 445 &rloss)); 446 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 447 "Test: select_historic_denom_revenue\n"); 448 FAILIF (0 >= 449 plugin->select_historic_denom_revenue ( 450 plugin->cls, 451 1024, /* limit */ 452 0, /* offset */ 453 &select_historic_denom_revenue_result, 454 NULL)); 455 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 456 "Test: insert_historic_reserve_revenue\n"); 457 GNUNET_assert (GNUNET_OK == 458 TALER_string_to_amount (CURRENCY ":56.789012", 459 &reserve_profits)); 460 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 461 plugin->insert_historic_reserve_revenue (plugin->cls, 462 past, 463 future, 464 &reserve_profits)); 465 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 466 plugin->insert_historic_reserve_revenue (plugin->cls, 467 now, 468 future, 469 &reserve_profits)); 470 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 471 "Test: select_historic_reserve_revenue\n"); 472 FAILIF (0 >= 473 plugin->select_historic_reserve_revenue ( 474 plugin->cls, 475 1024, /* limit */ 476 0, /* offset */ 477 &select_historic_reserve_revenue_result, 478 NULL)); 479 480 FAILIF (0 > 481 plugin->commit (plugin->cls)); 482 483 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 484 plugin->del_reserve_info (plugin->cls, 485 &reserve_pub)); 486 487 #if GC_IMPLEMENTED 488 FAILIF (GNUNET_OK != 489 plugin->gc (plugin->cls)); 490 #endif 491 492 result = 0; 493 494 drop: 495 plugin->rollback (plugin->cls); 496 GNUNET_break (GNUNET_OK == 497 plugin->drop_tables (plugin->cls, 498 GNUNET_YES)); 499 unload: 500 TALER_AUDITORDB_plugin_unload (plugin); 501 plugin = NULL; 502 } 503 504 505 int 506 main (int argc, 507 char *const argv[]) 508 { 509 const char *plugin_name; 510 char *config_filename; 511 char *testname; 512 struct GNUNET_CONFIGURATION_Handle *cfg; 513 514 (void) argc; 515 result = -1; 516 GNUNET_log_setup (argv[0], 517 "WARNING", 518 NULL); 519 if (NULL == (plugin_name = strrchr (argv[0], 520 (int) '-'))) 521 { 522 GNUNET_break (0); 523 return -1; 524 } 525 plugin_name++; 526 (void) GNUNET_asprintf (&testname, 527 "test-auditor-db-%s", 528 plugin_name); 529 (void) GNUNET_asprintf (&config_filename, 530 "%s.conf", testname); 531 cfg = GNUNET_CONFIGURATION_create (TALER_AUDITOR_project_data ()); 532 if (GNUNET_OK != 533 GNUNET_CONFIGURATION_parse (cfg, 534 config_filename)) 535 { 536 GNUNET_break (0); 537 GNUNET_free (config_filename); 538 GNUNET_free (testname); 539 return 2; 540 } 541 GNUNET_SCHEDULER_run (&run, 542 cfg); 543 GNUNET_CONFIGURATION_destroy (cfg); 544 GNUNET_free (config_filename); 545 GNUNET_free (testname); 546 return result; 547 }