From 5827630699a725e24a59d94861b01bad310f6a02 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 13 Apr 2015 17:20:46 +0200 Subject: starting with tests for libtalerutil --- src/util/Makefile.am | 38 ++++++-- src/util/amount.c | 66 ++++++++------ src/util/test_amount.c | 190 +++++++++++++++++++++++++++++++++++++++ src/util/test_crypto.c | 38 ++++++++ src/util/test_json.c | 38 ++++++++ src/util/test_json_validations.c | 54 ----------- src/util/test_wireformats.c | 54 +++++++++++ 7 files changed, 389 insertions(+), 89 deletions(-) create mode 100644 src/util/test_amount.c create mode 100644 src/util/test_crypto.c create mode 100644 src/util/test_json.c delete mode 100644 src/util/test_json_validations.c create mode 100644 src/util/test_wireformats.c (limited to 'src/util') diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 2a5cdefef..804ff85a2 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -28,14 +28,40 @@ libtalerutil_la_LDFLAGS = \ -export-dynamic -no-undefined TESTS = \ - test-json-validations + test_amount \ + test_crypto \ + test_json \ + test_wireformats -check_PROGRAMS=\ - test-json-validations +check_PROGRAMS= \ + test_amount \ + test_crypto \ + test_json \ + test_wireformats -test_json_validations_SOURCES = \ - test_json_validations.c -test_json_validations_LDADD = \ + +test_amount_SOURCES = \ + test_amount.c +test_amount_LDADD = \ + -lgnunetutil \ + libtalerutil.la + +test_crypto_SOURCES = \ + test_crypto.c +test_crypto_LDADD = \ + -lgnunetutil \ + libtalerutil.la + +test_json_SOURCES = \ + test_json.c +test_json_LDADD = \ + -lgnunetutil \ + -ljansson \ + libtalerutil.la + +test_wireformats_SOURCES = \ + test_wireformats.c +test_wireformats_LDADD = \ -lgnunetutil \ -ljansson \ libtalerutil.la diff --git a/src/util/amount.c b/src/util/amount.c index fcf12692f..74ffcd36f 100644 --- a/src/util/amount.c +++ b/src/util/amount.c @@ -19,12 +19,7 @@ * @author Sree Harsha Totakura * @author Florian Dold * @author Benedikt Mueller - * - * TODO: - * - the way this library currently deals with underflow/overflow - * is insufficient; just going for UINT32_MAX on overflow - * will not do; similar issues for incompatible currencies; - * we need some more explicit logic to say 'bogus value', + * @author Christian Grothoff */ #include "platform.h" #include "taler_util.h" @@ -91,14 +86,14 @@ TALER_string_to_amount (const char *str, { return GNUNET_OK; } - if ( (str[i] < '0') || (str[i] > '9') ) + if ( (value[i] < '0') || (value[i] > '9') ) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid character `%c'\n", - str[i]); + value[i]); goto fail; } - n = str[i] - '0'; + n = value[i] - '0'; if (denom->value * 10 + n < denom->value) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -113,29 +108,29 @@ TALER_string_to_amount (const char *str, i++; /* parse fraction */ - if ('\0' == str[i]) + if ('\0' == value[i]) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Null after dot"); + "Null after dot\n"); goto fail; } b = TALER_AMOUNT_FRAC_BASE / 10; - while ('\0' != str[i]) + while ('\0' != value[i]) { if (0 == b) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Fractional value too small (only %u digits supported)", + "Fractional value too small (only %u digits supported)\n", (unsigned int) TALER_AMOUNT_FRAC_LEN); goto fail; } - if ( (str[i] < '0') || (str[i] > '9') ) + if ( (value[i] < '0') || (value[i] > '9') ) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Error after comma"); + "Error after dot\n"); goto fail; } - n = str[i] - '0'; + n = value[i] - '0'; denom->fraction += n * b; b /= 10; i++; @@ -258,8 +253,8 @@ TALER_amount_cmp_currency (const struct TALER_Amount *a1, if ( (GNUNET_NO == test_valid (a1)) || (GNUNET_NO == test_valid (a2)) ) return GNUNET_SYSERR; - if (0 == strcmp (a1->currency, - a2->currency)) + if (0 == strcasecmp (a1->currency, + a2->currency)) return GNUNET_YES; return GNUNET_NO; } @@ -286,8 +281,10 @@ TALER_amount_cmp (const struct TALER_Amount *a1, TALER_amount_cmp_currency (a1, a2)); n1 = *a1; n2 = *a2; - TALER_amount_normalize (&n1); - TALER_amount_normalize (&n2); + GNUNET_assert (GNUNET_SYSERR != + TALER_amount_normalize (&n1)); + GNUNET_assert (GNUNET_SYSERR != + TALER_amount_normalize (&n2)); if (n1.value == n2.value) { if (n1.fraction < n2.fraction) @@ -329,8 +326,12 @@ TALER_amount_subtract (struct TALER_Amount *diff, } n1 = *a1; n2 = *a2; - TALER_amount_normalize (&n1); - TALER_amount_normalize (&n2); + if ( (GNUNET_SYSERR == TALER_amount_normalize (&n1)) || + (GNUNET_SYSERR == TALER_amount_normalize (&n2)) ) + { + invalidate (diff); + return GNUNET_SYSERR; + } if (n1.fraction < n2.fraction) { @@ -377,6 +378,7 @@ TALER_amount_add (struct TALER_Amount *sum, { struct TALER_Amount n1; struct TALER_Amount n2; + struct TALER_Amount res; if (GNUNET_YES != TALER_amount_cmp_currency (a1, a2)) @@ -386,27 +388,32 @@ TALER_amount_add (struct TALER_Amount *sum, } n1 = *a1; n2 = *a2; - TALER_amount_normalize (&n1); - TALER_amount_normalize (&n2); + if ( (GNUNET_SYSERR == TALER_amount_normalize (&n1)) || + (GNUNET_SYSERR == TALER_amount_normalize (&n2)) ) + { + invalidate (sum); + return GNUNET_SYSERR; + } GNUNET_assert (GNUNET_OK == TALER_amount_get_zero (a1->currency, - sum)); - sum->value = n1.value + n2.value; - if (sum->value < n1.value) + &res)); + res.value = n1.value + n2.value; + if (res.value < n1.value) { /* integer overflow */ invalidate (sum); return GNUNET_SYSERR; } - sum->fraction = n1.fraction + n2.fraction; + res.fraction = n1.fraction + n2.fraction; if (GNUNET_SYSERR == - TALER_amount_normalize (sum)) + TALER_amount_normalize (&res)) { /* integer overflow via carry from fraction */ invalidate (sum); return GNUNET_SYSERR; } + *sum = res; return GNUNET_OK; } @@ -438,6 +445,7 @@ TALER_amount_normalize (struct TALER_Amount *amount) { /* failed to normalize, adding up fractions caused main value to overflow! */ + invalidate (amount); return GNUNET_SYSERR; } return ret; diff --git a/src/util/test_amount.c b/src/util/test_amount.c new file mode 100644 index 000000000..4741bcf36 --- /dev/null +++ b/src/util/test_amount.c @@ -0,0 +1,190 @@ +/* + This file is part of TALER + (C) 2015 Christian Grothoff (and other contributing authors) + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, If not, see +*/ + +/** + * @file util/test_amount.c + * @brief Tests for amount logic + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_util.h" +#include "taler_amount_lib.h" + + +int +main(int argc, + const char *const argv[]) +{ + struct TALER_Amount a1; + struct TALER_Amount a2; + struct TALER_Amount a3; + char *c; + + GNUNET_log_setup ("test-amout", + "WARNING", + NULL); + /* test invalid conversions */ + GNUNET_log_skip (6, GNUNET_NO); + /* non-numeric */ + GNUNET_assert (GNUNET_SYSERR == + TALER_string_to_amount ("EUR:4a", + &a1)); + /* non-numeric */ + GNUNET_assert (GNUNET_SYSERR == + TALER_string_to_amount ("EUR:4.4a", + &a1)); + /* non-numeric */ + GNUNET_assert (GNUNET_SYSERR == + TALER_string_to_amount ("EUR:4.a4", + &a1)); + /* no currency */ + GNUNET_assert (GNUNET_SYSERR == + TALER_string_to_amount (":4.a4", + &a1)); + /* precision too high */ + GNUNET_assert (GNUNET_SYSERR == + TALER_string_to_amount ("EUR:4.1234567", + &a1)); + /* value too big */ + GNUNET_assert (GNUNET_SYSERR == + TALER_string_to_amount ("EUR:1234567890123456789012345678901234567890123456789012345678901234567890", + &a1)); + GNUNET_log_skip (0, GNUNET_YES); + + /* test conversion without fraction */ + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("EUR:4", + &a1)); + GNUNET_assert (0 == strcasecmp ("EUR", + a1.currency)); + GNUNET_assert (4 == a1.value); + GNUNET_assert (0 == a1.fraction); + + /* test conversion with leading space and with fraction */ + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount (" eur:4.12", + &a2)); + GNUNET_assert (0 == strcasecmp ("eur", + a2.currency)); + GNUNET_assert (4 == a2.value); + GNUNET_assert (TALER_AMOUNT_FRAC_BASE / 100 * 12 == a2.fraction); + + /* test use of local currency */ + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount (" *LOCAL:4444.1000", + &a3)); + GNUNET_assert (0 == strcasecmp ("*LOCAL", + a3.currency)); + GNUNET_assert (4444 == a3.value); + GNUNET_assert (TALER_AMOUNT_FRAC_BASE / 10 == a3.fraction); + + /* test CMP with equal and unequal currencies */ + GNUNET_assert (GNUNET_NO == + TALER_amount_cmp_currency (&a1, + &a3)); + GNUNET_assert (GNUNET_YES == + TALER_amount_cmp_currency (&a1, + &a2)); + + /* test subtraction failure (currency missmatch) */ + GNUNET_assert (GNUNET_SYSERR == + TALER_amount_subtract (&a3, + &a3, + &a2)); + GNUNET_assert (GNUNET_SYSERR == + TALER_amount_normalize (&a3)); + + /* test subtraction failure (negative result) */ + GNUNET_assert (GNUNET_SYSERR == + TALER_amount_subtract (&a3, + &a1, + &a2)); + GNUNET_assert (GNUNET_SYSERR == + TALER_amount_normalize (&a3)); + + /* test subtraction success cases */ + GNUNET_assert (GNUNET_YES == + TALER_amount_subtract (&a3, + &a2, + &a1)); + GNUNET_assert (GNUNET_NO == + TALER_amount_subtract (&a3, + &a1, + &a1)); + GNUNET_assert (0 == a3.value); + GNUNET_assert (0 == a3.fraction); + GNUNET_assert (GNUNET_NO == + TALER_amount_normalize (&a3)); + + /* test addition success */ + GNUNET_assert (GNUNET_OK == + TALER_amount_add (&a3, + &a3, + &a2)); + GNUNET_assert (GNUNET_NO == + TALER_amount_normalize (&a3)); + + /* test normalization */ + a3.fraction = 2 * TALER_AMOUNT_FRAC_BASE; + a3.value = 4; + GNUNET_assert (GNUNET_YES == + TALER_amount_normalize (&a3)); + + /* test conversion to string */ + c = TALER_amount_to_string (&a3); + GNUNET_assert (0 == strcmp ("EUR:6", + c)); + GNUNET_free (c); + + /* test normalization with fraction overflow */ + a3.fraction = 2 * TALER_AMOUNT_FRAC_BASE + 1; + a3.value = 4; + GNUNET_assert (GNUNET_YES == + TALER_amount_normalize (&a3)); + c = TALER_amount_to_string (&a3); + GNUNET_assert (0 == strcmp ("EUR:6.000001", + c)); + GNUNET_free (c); + + /* test normalization with overflow */ + a3.fraction = 2 * TALER_AMOUNT_FRAC_BASE + 1; + a3.value = UINT64_MAX - 1; + GNUNET_assert (GNUNET_SYSERR == + TALER_amount_normalize (&a3)); + c = TALER_amount_to_string (&a3); + GNUNET_assert (NULL == c); + + /* test addition with overflow */ + a1.fraction = TALER_AMOUNT_FRAC_BASE - 1; + a1.value = UINT64_MAX - 5; + a2.fraction = 2; + a2.value = 5; + GNUNET_assert (GNUNET_SYSERR == + TALER_amount_add (&a3, &a1, &a2)); + + /* test addition with underflow on fraction */ + a1.fraction = 1; + a1.value = UINT64_MAX; + a2.fraction = 2; + a2.value = 0; + GNUNET_assert (GNUNET_OK == + TALER_amount_subtract (&a3, &a1, &a2)); + GNUNET_assert (UINT64_MAX - 1 == a3.value); + GNUNET_assert (TALER_AMOUNT_FRAC_BASE - 1 == a3.fraction); + return 0; +} + +/* end of test_amount.c */ diff --git a/src/util/test_crypto.c b/src/util/test_crypto.c new file mode 100644 index 000000000..a375bcfbb --- /dev/null +++ b/src/util/test_crypto.c @@ -0,0 +1,38 @@ +/* + This file is part of TALER + (C) 2015 Christian Grothoff (and other contributing authors) + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, If not, see +*/ + +/** + * @file util/test_crypto.c + * @brief Tests for Taler-specific crypto logic + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_util.h" +#include "taler_crypto_lib.h" + + +int +main(int argc, + const char *const argv[]) +{ + GNUNET_log_setup ("test-crypto", + "WARNING", + NULL); + /* FIXME: implement test... */ + return 0; +} + +/* end of test_crypto.c */ diff --git a/src/util/test_json.c b/src/util/test_json.c new file mode 100644 index 000000000..9eb72fb8c --- /dev/null +++ b/src/util/test_json.c @@ -0,0 +1,38 @@ +/* + This file is part of TALER + (C) 2015 Christian Grothoff (and other contributing authors) + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, If not, see +*/ + +/** + * @file util/test_json.c + * @brief Tests for Taler-specific crypto logic + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_util.h" +#include "taler_json_lib.h" + + +int +main(int argc, + const char *const argv[]) +{ + GNUNET_log_setup ("test-json", + "WARNING", + NULL); + /* FIXME: implement test... */ + return 0; +} + +/* end of test_json.c */ diff --git a/src/util/test_json_validations.c b/src/util/test_json_validations.c deleted file mode 100644 index 26ec4b79f..000000000 --- a/src/util/test_json_validations.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - This file is part of TALER - (C) 2014 Christian Grothoff (and other contributing authors) - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - TALER; see the file COPYING. If not, If not, see -*/ - -/** - * @file util/test_json_validations.c - * @brief Tests for JSON validations - * @author Sree Harsha Totakura - */ - -#include "platform.h" -#include "taler_util.h" -#include "taler_json_lib.h" - -static const char * const json_wire_str = - "{ \"type\":\"SEPA\", \ -\"IBAN\":\"DE67830654080004822650\", \ -\"name\":\"GNUnet e.V.\", \ -\"bic\":\"GENODEF1SLR\", \ -\"edate\":\"1449930207000\", \ -\"r\":123456789, \ -\"address\": \"foobar\"}"; - -int main(int argc, const char *const argv[]) -{ - json_t *wire; - json_error_t error; - int ret; - - GNUNET_log_setup ("test-json-validations", "WARNING", NULL); - (void) memset(&error, 0, sizeof(error)); - wire = json_loads (json_wire_str, 0, &error); - if (NULL == wire) - { - TALER_json_warn (error); - return 2; - } - ret = TALER_json_validate_wireformat ("SEPA", wire); - if (1 == ret) - return 0; - return 1; -} diff --git a/src/util/test_wireformats.c b/src/util/test_wireformats.c new file mode 100644 index 000000000..26ec4b79f --- /dev/null +++ b/src/util/test_wireformats.c @@ -0,0 +1,54 @@ +/* + This file is part of TALER + (C) 2014 Christian Grothoff (and other contributing authors) + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, If not, see +*/ + +/** + * @file util/test_json_validations.c + * @brief Tests for JSON validations + * @author Sree Harsha Totakura + */ + +#include "platform.h" +#include "taler_util.h" +#include "taler_json_lib.h" + +static const char * const json_wire_str = + "{ \"type\":\"SEPA\", \ +\"IBAN\":\"DE67830654080004822650\", \ +\"name\":\"GNUnet e.V.\", \ +\"bic\":\"GENODEF1SLR\", \ +\"edate\":\"1449930207000\", \ +\"r\":123456789, \ +\"address\": \"foobar\"}"; + +int main(int argc, const char *const argv[]) +{ + json_t *wire; + json_error_t error; + int ret; + + GNUNET_log_setup ("test-json-validations", "WARNING", NULL); + (void) memset(&error, 0, sizeof(error)); + wire = json_loads (json_wire_str, 0, &error); + if (NULL == wire) + { + TALER_json_warn (error); + return 2; + } + ret = TALER_json_validate_wireformat ("SEPA", wire); + if (1 == ret) + return 0; + return 1; +} -- cgit v1.2.3