diff options
| author | Christian Grothoff <christian@grothoff.org> | 2015-04-13 17:20:46 +0200 | 
|---|---|---|
| committer | Christian Grothoff <christian@grothoff.org> | 2015-04-13 17:20:46 +0200 | 
| commit | 5827630699a725e24a59d94861b01bad310f6a02 (patch) | |
| tree | bc5c97ae6966c088d7bd7a9e9d8705816c8eea37 | |
| parent | 93bc450db36ebb41bfcc1c0d7edf5cfedbcf0741 (diff) | |
starting with tests for libtalerutil
| -rw-r--r-- | src/include/taler_amount_lib.h | 2 | ||||
| -rw-r--r-- | src/include/taler_crypto_lib.h | 1 | ||||
| -rw-r--r-- | src/include/taler_json_lib.h | 2 | ||||
| -rw-r--r-- | src/util/Makefile.am | 38 | ||||
| -rw-r--r-- | src/util/amount.c | 66 | ||||
| -rw-r--r-- | src/util/test_amount.c | 190 | ||||
| -rw-r--r-- | src/util/test_crypto.c | 38 | ||||
| -rw-r--r-- | src/util/test_json.c | 38 | ||||
| -rw-r--r-- | src/util/test_wireformats.c (renamed from src/util/test_json_validations.c) | 0 | 
9 files changed, 338 insertions, 37 deletions
| diff --git a/src/include/taler_amount_lib.h b/src/include/taler_amount_lib.h index 82952f0b..54eeda84 100644 --- a/src/include/taler_amount_lib.h +++ b/src/include/taler_amount_lib.h @@ -100,7 +100,7 @@ struct TALER_Amount  /** - * Parse denomination description, in the format "T : V : F". + * Parse denomination description, in the format "T:V.F".   *   * @param str denomination description   * @param denom denomination to write the result to diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index d7d12354..3c8aee55 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -489,5 +489,6 @@ TALER_refresh_link_encrypted_decode (const char *buf,                                       size_t buf_len); +/* FIXME: should also have _encode API... */  #endif diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index 9410d508..7e095568 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h @@ -1,6 +1,6 @@  /*    This file is part of TALER -  Copyright (C) 2014 Christian Grothoff (and other contributing authors) +  Copyright (C) 2014, 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 diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 2a5cdefe..804ff85a 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 fcf12692..74ffcd36 100644 --- a/src/util/amount.c +++ b/src/util/amount.c @@ -19,12 +19,7 @@   * @author Sree Harsha Totakura <sreeharsha@totakura.in>   * @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 00000000..4741bcf3 --- /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 <http://www.gnu.org/licenses/> +*/ + +/** + * @file util/test_amount.c + * @brief Tests for amount logic + * @author Christian Grothoff <christian@grothoff.org> + */ +#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 00000000..a375bcfb --- /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 <http://www.gnu.org/licenses/> +*/ + +/** + * @file util/test_crypto.c + * @brief Tests for Taler-specific crypto logic + * @author Christian Grothoff <christian@grothoff.org> + */ +#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 00000000..9eb72fb8 --- /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 <http://www.gnu.org/licenses/> +*/ + +/** + * @file util/test_json.c + * @brief Tests for Taler-specific crypto logic + * @author Christian Grothoff <christian@grothoff.org> + */ +#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_wireformats.c index 26ec4b79..26ec4b79 100644 --- a/src/util/test_json_validations.c +++ b/src/util/test_wireformats.c | 
