Line data Source code
1 : /*
2 : This file is part of TALER
3 : (C) 2016-2020 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 : /**
18 : * @file testing/test_taler_exchange_aggregator.c
19 : * @brief Tests for taler-exchange-aggregator logic
20 : * @author Christian Grothoff <christian@grothoff.org>
21 : * @author Marcello Stanisci
22 : */
23 : #include "taler/taler_util.h"
24 : #include <gnunet/gnunet_json_lib.h>
25 : #include "taler/taler_json_lib.h"
26 : #include "taler/taler_exchangedb_lib.h"
27 : #include <microhttpd.h>
28 : #include "taler/taler_testing_lib.h"
29 :
30 :
31 : /**
32 : * Our credentials.
33 : */
34 : struct TALER_TESTING_Credentials cred;
35 :
36 : /**
37 : * Name of the configuration file to use.
38 : */
39 : static char *config_filename;
40 :
41 : #define USER42_ACCOUNT "42"
42 : #define USER43_ACCOUNT "43"
43 : #define USER44_ACCOUNT "44"
44 :
45 :
46 : /**
47 : * Execute the taler-exchange-aggregator, closer and transfer commands with
48 : * our configuration file.
49 : *
50 : * @param label label to use for the command.
51 : * @param cfg_fn configuration file to use
52 : */
53 : #define CMD_EXEC_AGGREGATOR(label, cfg_fn) \
54 : TALER_TESTING_cmd_exec_aggregator (label "-aggregator", cfg_fn), \
55 : TALER_TESTING_cmd_exec_transfer (label "-transfer", cfg_fn)
56 :
57 :
58 : /**
59 : * Collects all the tests.
60 : */
61 : static void
62 1 : run (void *cls,
63 : struct TALER_TESTING_Interpreter *is)
64 : {
65 : struct TALER_TESTING_Command all[] = {
66 1 : TALER_TESTING_cmd_run_fakebank ("run-fakebank",
67 1 : cred.cfg,
68 : "exchange-account-1"),
69 1 : TALER_TESTING_cmd_system_start ("start-taler",
70 : config_filename,
71 : "-e",
72 : NULL),
73 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-on-empty-db",
74 : config_filename),
75 1 : TALER_TESTING_cmd_check_bank_empty ("expect-empty-transactions-on-start"),
76 :
77 : /* check aggregation happens on the simplest case:
78 : one deposit into the database. */
79 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-1",
80 1 : cred.cfg,
81 : "bob",
82 : USER42_ACCOUNT,
83 : GNUNET_TIME_timestamp_get (),
84 1 : GNUNET_TIME_UNIT_ZERO,
85 : "EUR:1",
86 : "EUR:0.1"),
87 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-on-deposit-1",
88 : config_filename),
89 :
90 1 : TALER_TESTING_cmd_check_bank_transfer ("expect-deposit-1",
91 1 : cred.exchange_url,
92 : "EUR:0.89",
93 : cred.exchange_payto,
94 : cred.user42_payto),
95 1 : TALER_TESTING_cmd_check_bank_empty ("expect-empty-transactions-after-1"),
96 :
97 : /* check aggregation accumulates well. */
98 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-2a",
99 1 : cred.cfg,
100 : "bob",
101 : USER42_ACCOUNT,
102 : GNUNET_TIME_timestamp_get (),
103 1 : GNUNET_TIME_UNIT_ZERO,
104 : "EUR:1",
105 : "EUR:0.1"),
106 :
107 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-2b",
108 1 : cred.cfg,
109 : "bob",
110 : USER42_ACCOUNT,
111 : GNUNET_TIME_timestamp_get (),
112 1 : GNUNET_TIME_UNIT_ZERO,
113 : "EUR:1",
114 : "EUR:0.1"),
115 :
116 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-2",
117 : config_filename),
118 :
119 1 : TALER_TESTING_cmd_check_bank_transfer ("expect-deposit-2",
120 1 : cred.exchange_url,
121 : "EUR:1.79",
122 : cred.exchange_payto,
123 : cred.user42_payto),
124 1 : TALER_TESTING_cmd_check_bank_empty ("expect-empty-transactions-after-2"),
125 :
126 : /* check that different merchants stem different aggregations. */
127 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-3a",
128 1 : cred.cfg,
129 : "bob",
130 : USER43_ACCOUNT,
131 : GNUNET_TIME_timestamp_get (),
132 1 : GNUNET_TIME_UNIT_ZERO,
133 : "EUR:1",
134 : "EUR:0.1"),
135 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-3b",
136 1 : cred.cfg,
137 : "bob",
138 : USER44_ACCOUNT,
139 : GNUNET_TIME_timestamp_get (),
140 1 : GNUNET_TIME_UNIT_ZERO,
141 : "EUR:1",
142 : "EUR:0.1"),
143 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-3c",
144 1 : cred.cfg,
145 : "alice",
146 : USER43_ACCOUNT,
147 : GNUNET_TIME_timestamp_get (),
148 1 : GNUNET_TIME_UNIT_ZERO,
149 : "EUR:1",
150 : "EUR:0.1"),
151 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-3",
152 : config_filename),
153 :
154 1 : TALER_TESTING_cmd_check_bank_transfer ("expect-deposit-3a",
155 1 : cred.exchange_url,
156 : "EUR:0.89",
157 : cred.exchange_payto,
158 : cred.user43_payto),
159 1 : TALER_TESTING_cmd_check_bank_transfer ("expect-deposit-3b",
160 1 : cred.exchange_url,
161 : "EUR:0.89",
162 : cred.exchange_payto,
163 : cred.user43_payto),
164 1 : TALER_TESTING_cmd_check_bank_transfer ("expect-deposit-3c",
165 1 : cred.exchange_url,
166 : "EUR:0.89",
167 : cred.exchange_payto,
168 : cred.user44_payto),
169 1 : TALER_TESTING_cmd_check_bank_empty ("expect-empty-transactions-after-3"),
170 :
171 : /* checking that aggregator waits for the deadline. */
172 1 : TALER_TESTING_cmd_insert_deposit ("do-deposit-4a",
173 1 : cred.cfg,
174 : "bob",
175 : USER42_ACCOUNT,
176 : GNUNET_TIME_timestamp_get (),
177 : GNUNET_TIME_relative_multiply
178 : (GNUNET_TIME_UNIT_SECONDS,
179 : 5),
180 : "EUR:0.2",
181 : "EUR:0.1"),
182 1 : TALER_TESTING_cmd_insert_deposit ("do-deposit-4b",
183 1 : cred.cfg,
184 : "bob",
185 : USER42_ACCOUNT,
186 : GNUNET_TIME_timestamp_get (),
187 : GNUNET_TIME_relative_multiply
188 : (GNUNET_TIME_UNIT_SECONDS,
189 : 5),
190 : "EUR:0.2",
191 : "EUR:0.1"),
192 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-4-early",
193 : config_filename),
194 1 : TALER_TESTING_cmd_check_bank_empty (
195 : "expect-empty-transactions-after-4-fast"),
196 :
197 1 : TALER_TESTING_cmd_sleep ("wait (5s)", 5),
198 :
199 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-4-delayed",
200 : config_filename),
201 1 : TALER_TESTING_cmd_check_bank_transfer ("expect-deposit-4",
202 1 : cred.exchange_url,
203 : "EUR:0.19",
204 : cred.exchange_payto,
205 : cred.user42_payto),
206 :
207 : // test picking all deposits at earliest deadline
208 1 : TALER_TESTING_cmd_insert_deposit ("do-deposit-5a",
209 1 : cred.cfg,
210 : "bob",
211 : USER42_ACCOUNT,
212 : GNUNET_TIME_timestamp_get (),
213 : GNUNET_TIME_relative_multiply
214 : (GNUNET_TIME_UNIT_SECONDS,
215 : 10),
216 : "EUR:0.2",
217 : "EUR:0.1"),
218 :
219 1 : TALER_TESTING_cmd_insert_deposit ("do-deposit-5b",
220 1 : cred.cfg,
221 : "bob",
222 : USER42_ACCOUNT,
223 : GNUNET_TIME_timestamp_get (),
224 : GNUNET_TIME_relative_multiply
225 : (GNUNET_TIME_UNIT_SECONDS,
226 : 5),
227 : "EUR:0.2",
228 : "EUR:0.1"),
229 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-5-early",
230 : config_filename),
231 :
232 1 : TALER_TESTING_cmd_check_bank_empty (
233 : "expect-empty-transactions-after-5-early"),
234 1 : TALER_TESTING_cmd_sleep ("wait (5s)", 5),
235 :
236 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-5-delayed",
237 : config_filename),
238 1 : TALER_TESTING_cmd_check_bank_transfer ("expect-deposit-5",
239 1 : cred.exchange_url,
240 : "EUR:0.19",
241 : cred.exchange_payto,
242 : cred.user42_payto),
243 : /* Test NEVER running 'tiny' unless they make up minimum unit */
244 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-6a",
245 1 : cred.cfg,
246 : "bob",
247 : USER42_ACCOUNT,
248 : GNUNET_TIME_timestamp_get (),
249 1 : GNUNET_TIME_UNIT_ZERO,
250 : "EUR:0.102",
251 : "EUR:0.1"),
252 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-6a-tiny",
253 : config_filename),
254 1 : TALER_TESTING_cmd_check_bank_empty (
255 : "expect-empty-transactions-after-6a-tiny"),
256 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-6b",
257 1 : cred.cfg,
258 : "bob",
259 : USER42_ACCOUNT,
260 : GNUNET_TIME_timestamp_get (),
261 1 : GNUNET_TIME_UNIT_ZERO,
262 : "EUR:0.102",
263 : "EUR:0.1"),
264 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-6c",
265 1 : cred.cfg,
266 : "bob",
267 : USER42_ACCOUNT,
268 : GNUNET_TIME_timestamp_get (),
269 1 : GNUNET_TIME_UNIT_ZERO,
270 : "EUR:0.102",
271 : "EUR:0.1"),
272 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-6c-tiny",
273 : config_filename),
274 1 : TALER_TESTING_cmd_check_bank_empty (
275 : "expect-empty-transactions-after-6c-tiny"),
276 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-6d",
277 1 : cred.cfg,
278 : "bob",
279 : USER42_ACCOUNT,
280 : GNUNET_TIME_timestamp_get (),
281 1 : GNUNET_TIME_UNIT_ZERO,
282 : "EUR:0.102",
283 : "EUR:0.1"),
284 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-6d-tiny",
285 : config_filename),
286 1 : TALER_TESTING_cmd_check_bank_empty (
287 : "expect-empty-transactions-after-6d-tiny"),
288 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-6e",
289 1 : cred.cfg,
290 : "bob",
291 : USER42_ACCOUNT,
292 : GNUNET_TIME_timestamp_get (),
293 1 : GNUNET_TIME_UNIT_ZERO,
294 : "EUR:0.112",
295 : "EUR:0.1"),
296 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-6e",
297 : config_filename),
298 1 : TALER_TESTING_cmd_check_bank_transfer ("expect-deposit-6",
299 1 : cred.exchange_url,
300 : "EUR:0.01",
301 : cred.exchange_payto,
302 : cred.user42_payto),
303 :
304 : /* Test profiteering if wire deadline is short */
305 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-7a",
306 1 : cred.cfg,
307 : "bob",
308 : USER42_ACCOUNT,
309 : GNUNET_TIME_timestamp_get (),
310 1 : GNUNET_TIME_UNIT_ZERO,
311 : "EUR:0.109",
312 : "EUR:0.1"),
313 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-7a-tiny",
314 : config_filename),
315 1 : TALER_TESTING_cmd_check_bank_empty (
316 : "expect-empty-transactions-after-7a-tiny"),
317 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-7b",
318 1 : cred.cfg,
319 : "bob",
320 : USER42_ACCOUNT,
321 : GNUNET_TIME_timestamp_get (),
322 1 : GNUNET_TIME_UNIT_ZERO,
323 : "EUR:0.119",
324 : "EUR:0.1"),
325 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-7-profit",
326 : config_filename),
327 1 : TALER_TESTING_cmd_check_bank_transfer ("expect-deposit-7",
328 1 : cred.exchange_url,
329 : "EUR:0.01",
330 : cred.exchange_payto,
331 : cred.user42_payto),
332 :
333 : /* Now check profit was actually taken */
334 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-7c",
335 1 : cred.cfg,
336 : "bob",
337 : USER42_ACCOUNT,
338 : GNUNET_TIME_timestamp_get (),
339 1 : GNUNET_TIME_UNIT_ZERO,
340 : "EUR:0.122",
341 : "EUR:0.1"),
342 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-7-loss",
343 : config_filename),
344 1 : TALER_TESTING_cmd_check_bank_transfer ("expect-deposit-7",
345 1 : cred.exchange_url,
346 : "EUR:0.01",
347 : cred.exchange_payto,
348 : cred.user42_payto),
349 :
350 : /* Test that aggregation would happen fully if wire deadline is long */
351 1 : TALER_TESTING_cmd_insert_deposit ("do-deposit-8a",
352 1 : cred.cfg,
353 : "bob",
354 : USER42_ACCOUNT,
355 : GNUNET_TIME_timestamp_get (),
356 : GNUNET_TIME_relative_multiply
357 : (GNUNET_TIME_UNIT_SECONDS,
358 : 5),
359 : "EUR:0.109",
360 : "EUR:0.1"),
361 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-8a-tiny",
362 : config_filename),
363 1 : TALER_TESTING_cmd_check_bank_empty (
364 : "expect-empty-transactions-after-8a-tiny"),
365 1 : TALER_TESTING_cmd_insert_deposit ("do-deposit-8b",
366 1 : cred.cfg,
367 : "bob",
368 : USER42_ACCOUNT,
369 : GNUNET_TIME_timestamp_get (),
370 : GNUNET_TIME_relative_multiply
371 : (GNUNET_TIME_UNIT_SECONDS,
372 : 5),
373 : "EUR:0.109",
374 : "EUR:0.1"),
375 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-8b-tiny",
376 : config_filename),
377 1 : TALER_TESTING_cmd_check_bank_empty (
378 : "expect-empty-transactions-after-8b-tiny"),
379 :
380 : /* now trigger aggregate with large transaction and short deadline */
381 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-8c",
382 1 : cred.cfg,
383 : "bob",
384 : USER42_ACCOUNT,
385 : GNUNET_TIME_timestamp_get (),
386 1 : GNUNET_TIME_UNIT_ZERO,
387 : "EUR:0.122",
388 : "EUR:0.1"),
389 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-8",
390 : config_filename),
391 1 : TALER_TESTING_cmd_check_bank_transfer ("expect-deposit-8",
392 1 : cred.exchange_url,
393 : "EUR:0.03",
394 : cred.exchange_payto,
395 : cred.user42_payto),
396 :
397 : /* Test aggregation with fees and rounding profits. */
398 1 : TALER_TESTING_cmd_insert_deposit ("do-deposit-9a",
399 1 : cred.cfg,
400 : "bob",
401 : USER42_ACCOUNT,
402 : GNUNET_TIME_timestamp_get (),
403 : GNUNET_TIME_relative_multiply
404 : (GNUNET_TIME_UNIT_SECONDS,
405 : 5),
406 : "EUR:0.104",
407 : "EUR:0.1"),
408 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-9a-tiny",
409 : config_filename),
410 1 : TALER_TESTING_cmd_check_bank_empty (
411 : "expect-empty-transactions-after-9a-tiny"),
412 1 : TALER_TESTING_cmd_insert_deposit ("do-deposit-9b",
413 1 : cred.cfg,
414 : "bob",
415 : USER42_ACCOUNT,
416 : GNUNET_TIME_timestamp_get (),
417 : GNUNET_TIME_relative_multiply
418 : (GNUNET_TIME_UNIT_SECONDS,
419 : 5),
420 : "EUR:0.105",
421 : "EUR:0.1"),
422 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-9b-tiny",
423 : config_filename),
424 1 : TALER_TESTING_cmd_check_bank_empty (
425 : "expect-empty-transactions-after-9b-tiny"),
426 :
427 : /* now trigger aggregate with large transaction and short deadline */
428 2 : TALER_TESTING_cmd_insert_deposit ("do-deposit-9c",
429 1 : cred.cfg,
430 : "bob",
431 : USER42_ACCOUNT,
432 : GNUNET_TIME_timestamp_get (),
433 1 : GNUNET_TIME_UNIT_ZERO,
434 : "EUR:0.112",
435 : "EUR:0.1"),
436 1 : CMD_EXEC_AGGREGATOR ("run-aggregator-deposit-9",
437 : config_filename),
438 : /* 0.009 + 0.009 + 0.022 - 0.001 - 0.002 - 0.008 = 0.029 => 0.02 */
439 1 : TALER_TESTING_cmd_check_bank_transfer ("expect-deposit-9",
440 1 : cred.exchange_url,
441 : "EUR:0.01",
442 : cred.exchange_payto,
443 : cred.user42_payto),
444 1 : TALER_TESTING_cmd_end ()
445 : };
446 :
447 1 : TALER_TESTING_run (is,
448 : all);
449 1 : }
450 :
451 :
452 : int
453 1 : main (int argc,
454 : char *const argv[])
455 : {
456 : const char *plugin_name;
457 :
458 1 : if (NULL == (plugin_name = strrchr (argv[0], (int) '-')))
459 : {
460 0 : GNUNET_break (0);
461 0 : return -1;
462 : }
463 1 : plugin_name++;
464 1 : (void) GNUNET_asprintf (&config_filename,
465 : "test-taler-exchange-aggregator-%s.conf",
466 : plugin_name);
467 1 : return TALER_TESTING_main (argv,
468 : "INFO",
469 : config_filename,
470 : "exchange-account-1",
471 : TALER_TESTING_BS_FAKEBANK,
472 : &cred,
473 : &run,
474 : NULL);
475 : }
476 :
477 :
478 : /* end of test_taler_exchange_aggregator.c */
|