test/string.c: remove hardcoded limit values

Unit tests for spdk_strtol/spdk_strtoll use hard coded strings for
arithmetic constants (LONG_MIN/MAX etc). These are only valid
on platforms where both long and long long are 64-bit values.

Replace the hardcoded values with strings generated from limits.h.
The tests use values that are outside of the MIN/MAX range, which
cannot be represented as int64_t. These are calculated in two parts
to avoid overflow and recombined as a string.

Verified using the unit tests on two different architectures and with
test code to check that the generated string is the same as the
hardcoded value on x86 Linux. Used a small test program to calculate
+/-30 around each limit value to check carry handling and boundary
conditions.

Signed-off-by: Nick Connolly <nick.connolly@mayadata.io>
Change-Id: I990ff354f568a0b35853ecc849dd2a452bb1048b
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6048
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
This commit is contained in:
Nick Connolly 2021-01-22 11:46:22 +00:00 committed by Tomasz Zawadzki
parent 4249dc1010
commit 240fdd7dd1

View File

@ -248,24 +248,36 @@ test_sprintf_append_realloc(void)
free(str3);
free(str4);
}
static void
generate_string(char *str, size_t len, int64_t limit, int adjust)
{
/* There isn't a portable way of handling the arithmetic, so */
/* perform the calculation in two parts to avoid overflow */
int64_t hi = (limit / 10) + (adjust / 10);
int64_t lo = (limit % 10) + (adjust % 10);
/* limit is large and adjust is small, so hi part will be */
/* non-zero even if there is a carry, but check it */
CU_ASSERT(hi < -1 || hi > 1);
/* Correct a difference in sign */
if ((hi < 0) != (lo < 0) && lo != 0) {
lo += (hi < 0) ? -10 : 10;
hi += (hi < 0) ? 1 : -1;
}
snprintf(str, len, "%" PRId64 "%01" PRId64, hi + (lo / 10),
(lo < 0) ? (-lo % 10) : (lo % 10));
}
static void
test_strtol(void)
{
long int val;
char str[256];
const char *val1 = "no_digits";
/* LLONG_MIN - 1 */
const char *val2 = "-9223372036854775809";
/* LONG_MIN */
const char *val3 = "-9223372036854775808";
/* LONG_MIN + 1 */
const char *val4 = "-9223372036854775807";
/* LONG_MAX - 1 */
const char *val5 = "9223372036854775806";
/* LONG_MAX */
const char *val6 = "9223372036854775807";
/* LONG_MAX + 1 */
const char *val7 = "9223372036854775808";
/* digits + chars */
const char *val8 = "10_is_ten";
/* chars + digits */
@ -278,22 +290,34 @@ test_strtol(void)
val = spdk_strtol(val1, 10);
CU_ASSERT(val == -EINVAL);
val = spdk_strtol(val2, 10);
/* LONG_MIN - 1 */
generate_string(str, sizeof(str), LONG_MIN, -1);
val = spdk_strtol(str, 10);
CU_ASSERT(val == -ERANGE);
val = spdk_strtol(val3, 10);
/* LONG_MIN */
generate_string(str, sizeof(str), LONG_MIN, 0);
val = spdk_strtol(str, 10);
CU_ASSERT(val == -ERANGE);
val = spdk_strtol(val4, 10);
/* LONG_MIN + 1 */
generate_string(str, sizeof(str), LONG_MIN, +1);
val = spdk_strtol(str, 10);
CU_ASSERT(val == -ERANGE);
val = spdk_strtol(val5, 10);
/* LONG_MAX - 1 */
generate_string(str, sizeof(str), LONG_MAX, -1);
val = spdk_strtol(str, 10);
CU_ASSERT(val == LONG_MAX - 1);
val = spdk_strtol(val6, 10);
/* LONG_MAX */
generate_string(str, sizeof(str), LONG_MAX, 0);
val = spdk_strtol(str, 10);
CU_ASSERT(val == LONG_MAX);
val = spdk_strtol(val7, 10);
/* LONG_MAX + 1 */
generate_string(str, sizeof(str), LONG_MAX, +1);
val = spdk_strtol(str, 10);
CU_ASSERT(val == -ERANGE);
val = spdk_strtol(val8, 10);
@ -317,20 +341,9 @@ static void
test_strtoll(void)
{
long long int val;
char str[256];
const char *val1 = "no_digits";
/* LLONG_MIN - 1 */
const char *val2 = "-9223372036854775809";
/* LLONG_MIN */
const char *val3 = "-9223372036854775808";
/* LLONG_MIN + 1 */
const char *val4 = "-9223372036854775807";
/* LLONG_MAX - 1 */
const char *val5 = "9223372036854775806";
/* LLONG_MAX */
const char *val6 = "9223372036854775807";
/* LLONG_MAX + 1 */
const char *val7 = "9223372036854775808";
/* digits + chars */
const char *val8 = "10_is_ten";
/* chars + digits */
@ -343,22 +356,34 @@ test_strtoll(void)
val = spdk_strtoll(val1, 10);
CU_ASSERT(val == -EINVAL);
val = spdk_strtoll(val2, 10);
/* LLONG_MIN - 1 */
generate_string(str, sizeof(str), LLONG_MIN, -1);
val = spdk_strtoll(str, 10);
CU_ASSERT(val == -ERANGE);
val = spdk_strtoll(val3, 10);
/* LLONG_MIN */
generate_string(str, sizeof(str), LLONG_MIN, 0);
val = spdk_strtoll(str, 10);
CU_ASSERT(val == -ERANGE);
val = spdk_strtoll(val4, 10);
/* LLONG_MIN + 1 */
generate_string(str, sizeof(str), LLONG_MIN, +1);
val = spdk_strtoll(str, 10);
CU_ASSERT(val == -ERANGE);
val = spdk_strtoll(val5, 10);
/* LLONG_MAX - 1 */
generate_string(str, sizeof(str), LLONG_MAX, -1);
val = spdk_strtoll(str, 10);
CU_ASSERT(val == LLONG_MAX - 1);
val = spdk_strtoll(val6, 10);
/* LLONG_MAX */
generate_string(str, sizeof(str), LLONG_MAX, 0);
val = spdk_strtoll(str, 10);
CU_ASSERT(val == LLONG_MAX);
val = spdk_strtoll(val7, 10);
/* LLONG_MAX + 1 */
generate_string(str, sizeof(str), LLONG_MAX, +1);
val = spdk_strtoll(str, 10);
CU_ASSERT(val == -ERANGE);
val = spdk_strtoll(val8, 10);