strtonum-tests.c revision 4a6a5421113ab662a665c62ed6a24b61a5a36950
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end/*
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end SSSD
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd InfoPipe
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end Copyright (C) Stephen Gallagher <sgallagh@redhat.com> 2009
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end This program is free software; you can redistribute it and/or modify
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end it under the terms of the GNU General Public License as published by
96ad5d81ee4a2cc66a4ae19893efc8aa6d06fae7jailletc the Free Software Foundation; either version 3 of the License, or
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end (at your option) any later version.
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen This program is distributed in the hope that it will be useful,
2e545ce2450a9953665f701bb05350f0d3f26275nd but WITHOUT ANY WARRANTY; without even the implied warranty of
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen GNU General Public License for more details.
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun You should have received a copy of the GNU General Public License
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen along with this program. If not, see <http://www.gnu.org/licenses/>.
3f08db06526d6901aa08c110b5bc7dde6bc39905nd*/
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end#include <stdlib.h>
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end#include <check.h>
3f08db06526d6901aa08c110b5bc7dde6bc39905nd#include <errno.h>
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end#include <popt.h>
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end#include "util/util.h"
c04f76acce77126cf88b09350e56ea8c6b4a064enilgun#include "util/strtonum.h"
a9d50067373f032c3c9678ad55de69bb3f9fcb70rbowen#include "tests/common.h"
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen/********************
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * Utility routines *
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end ********************/
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun#define EXPECT_UNSET_ERRNO(error) \
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun do { \
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun fail_unless(error == 0, "errno unexpectedly set to %d[%s]", \
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end error, strerror(error)); \
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end } while(0)
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
c04f76acce77126cf88b09350e56ea8c6b4a064enilgun#define CHECK_RESULT(expected, actual) \
a9d50067373f032c3c9678ad55de69bb3f9fcb70rbowen do { \
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen fail_unless(actual == expected, "Expected %ld, got %ld", \
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen expected, actual); \
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end } while(0)
205f749042ed530040a4f0080dbcb47ceae8a374rjung
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen#define CHECK_ERRNO(expected, actual) \
0d0ba3a410038e179b695446bb149cce6264e0abnd do { \
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd fail_unless(actual == expected, "Expected errno %d[%s], got %d[%s]", \
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd expected, strerror(expected), \
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd actual, strerror(actual)); \
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end } while(0)
#define CHECK_ENDPTR(expected, actual) \
do { \
fail_unless(actual == expected, "Expected endptr %p, got %p", \
expected, actual); \
} while(0)
#define CHECK_ZERO_ENDPTR(endptr) \
do { \
fail_unless(endptr && *endptr == '\0', "Invalid endptr"); \
} while(0)
/******************
* strtoint tests *
******************/
/* Base-10 */
START_TEST (test_strtoint32_pos_integer_base_10)
{
int32_t result;
const char *input = "123";
int32_t expected = 123;
char *endptr;
errno_t error;
result = strtoint32(input, &endptr, 10);
error = errno;
EXPECT_UNSET_ERRNO(error);
CHECK_ZERO_ENDPTR(endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtoint32_neg_integer_base_10)
{
int32_t result;
const char *input = "-123";
int32_t expected = -123;
char *endptr;
errno_t error;
result = strtoint32(input, &endptr, 10);
error = errno;
EXPECT_UNSET_ERRNO(error);
CHECK_ZERO_ENDPTR(endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtoint32_pos_integer_intmax_base_10)
{
int32_t result;
const char *input = "2147483647";
int32_t expected = INT32_MAX;
char *endptr;
errno_t error;
result = strtoint32(input, &endptr, 10);
error = errno;
EXPECT_UNSET_ERRNO(error);
CHECK_ZERO_ENDPTR(endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtoint32_neg_integer_intmin_base_10)
{
int32_t result;
const char *input = "-2147483648";
int32_t expected = INT32_MIN;
char *endptr;
errno_t error;
result = strtoint32(input, &endptr, 10);
error = errno;
EXPECT_UNSET_ERRNO(error);
CHECK_ZERO_ENDPTR(endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtoint32_pos_integer_overflow_base_10)
{
int32_t result;
const char *input = "8589934592";
int32_t expected = INT32_MAX;
char *endptr;
errno_t error;
result = strtoint32(input, &endptr, 10);
error = errno;
CHECK_ERRNO(ERANGE, error);
CHECK_ZERO_ENDPTR(endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtoint32_pos_integer_underflow_base_10)
{
int32_t result;
const char *input = "-8589934592";
int32_t expected = INT32_MIN;
char *endptr;
errno_t error;
result = strtoint32(input, &endptr, 10);
error = errno;
CHECK_ERRNO(ERANGE, error);
CHECK_ZERO_ENDPTR(endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtoint32_mixed_alphanumeric_base_10)
{
int32_t result;
const char *input = "12b13";
int32_t expected = 12;
char *endptr;
const char *expected_endptr = input+2;
errno_t error;
result = strtoint32(input, &endptr, 10);
error = errno;
EXPECT_UNSET_ERRNO(error);
CHECK_ENDPTR(expected_endptr, endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtoint32_alphaonly_base_10)
{
int32_t result;
const char *input = "alpha";
int32_t expected = 0;
char *endptr;
const char *expected_endptr = input;
errno_t error;
result = strtoint32(input, &endptr, 10);
error = errno;
EXPECT_UNSET_ERRNO(error);
CHECK_ENDPTR(expected_endptr, endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtoint32_alphastart_base_10)
{
int32_t result;
const char *input = "alpha12345";
int32_t expected = 0;
char *endptr;
const char *expected_endptr = input;
errno_t error;
result = strtoint32(input, &endptr, 10);
error = errno;
EXPECT_UNSET_ERRNO(error);
CHECK_ENDPTR(expected_endptr, endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtoint32_emptystring_base_10)
{
int32_t result;
const char *input = "";
int32_t expected = 0;
char *endptr;
const char *expected_endptr = input;
errno_t error;
result = strtoint32(input, &endptr, 10);
error = errno;
EXPECT_UNSET_ERRNO(error);
CHECK_ENDPTR(expected_endptr, endptr);
CHECK_RESULT(expected, result);
}
END_TEST
/*******************
* strtouint tests *
*******************/
/* Base-10 */
START_TEST (test_strtouint32_pos_integer_base_10)
{
uint32_t result;
const char *input = "123";
uint32_t expected = 123;
char *endptr;
errno_t error;
result = strtouint32(input, &endptr, 10);
error = errno;
EXPECT_UNSET_ERRNO(error);
CHECK_ZERO_ENDPTR(endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtouint32_neg_integer_base_10)
{
uint32_t result;
const char *input = "-123";
uint32_t expected = UINT32_MAX;
char *endptr;
errno_t error;
result = strtouint32(input, &endptr, 10);
error = errno;
CHECK_ERRNO(ERANGE, error);
CHECK_ZERO_ENDPTR(endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtouint32_pos_integer_uintmax_base_10)
{
uint32_t result;
const char *input = "4294967295";
uint32_t expected = UINT32_MAX;
char *endptr;
errno_t error;
result = strtouint32(input, &endptr, 10);
error = errno;
EXPECT_UNSET_ERRNO(error);
CHECK_ZERO_ENDPTR(endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtouint32_pos_integer_overflow_base_10)
{
uint32_t result;
const char *input = "8589934592";
uint32_t expected = UINT32_MAX;
char *endptr;
errno_t error;
result = strtouint32(input, &endptr, 10);
error = errno;
CHECK_ERRNO(ERANGE, error);
CHECK_ZERO_ENDPTR(endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtouint32_mixed_alphanumeric_base_10)
{
uint32_t result;
const char *input = "12b13";
uint32_t expected = 12;
char *endptr;
const char *expected_endptr = input+2;
errno_t error;
result = strtouint32(input, &endptr, 10);
error = errno;
EXPECT_UNSET_ERRNO(error);
CHECK_ENDPTR(expected_endptr, endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtouint32_alphaonly_base_10)
{
uint32_t result;
const char *input = "alpha";
uint32_t expected = 0;
char *endptr;
const char *expected_endptr = input;
errno_t error;
result = strtouint32(input, &endptr, 10);
error = errno;
EXPECT_UNSET_ERRNO(error);
CHECK_ENDPTR(expected_endptr, endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtouint32_alphastart_base_10)
{
uint32_t result;
const char *input = "alpha12345";
uint32_t expected = 0;
char *endptr;
const char *expected_endptr = input;
errno_t error;
result = strtouint32(input, &endptr, 10);
error = errno;
EXPECT_UNSET_ERRNO(error);
CHECK_ENDPTR(expected_endptr, endptr);
CHECK_RESULT(expected, result);
}
END_TEST
START_TEST (test_strtouint32_emptystring_base_10)
{
uint32_t result;
const char *input = "";
uint32_t expected = 0;
char *endptr;
const char *expected_endptr = input;
errno_t error;
result = strtouint32(input, &endptr, 10);
error = errno;
EXPECT_UNSET_ERRNO(error);
CHECK_ENDPTR(expected_endptr, endptr);
CHECK_RESULT(expected, result);
}
END_TEST
Suite *create_strtonum_suite(void)
{
Suite *s = suite_create("strtonum");
TCase *tc_strtoint32 = tcase_create("strtoint32 Tests");
tcase_add_test(tc_strtoint32, test_strtoint32_pos_integer_base_10);
tcase_add_test(tc_strtoint32, test_strtoint32_neg_integer_base_10);
tcase_add_test(tc_strtoint32, test_strtoint32_pos_integer_intmax_base_10);
tcase_add_test(tc_strtoint32, test_strtoint32_neg_integer_intmin_base_10);
tcase_add_test(tc_strtoint32, test_strtoint32_pos_integer_overflow_base_10);
tcase_add_test(tc_strtoint32, test_strtoint32_pos_integer_underflow_base_10);
tcase_add_test(tc_strtoint32, test_strtoint32_mixed_alphanumeric_base_10);
tcase_add_test(tc_strtoint32, test_strtoint32_alphaonly_base_10);
tcase_add_test(tc_strtoint32, test_strtoint32_alphastart_base_10);
tcase_add_test(tc_strtoint32, test_strtoint32_emptystring_base_10);
TCase *tc_strtouint32 = tcase_create("strtouint32 Tests");
tcase_add_test(tc_strtouint32, test_strtouint32_pos_integer_base_10);
tcase_add_test(tc_strtouint32, test_strtouint32_neg_integer_base_10);
tcase_add_test(tc_strtouint32, test_strtouint32_pos_integer_uintmax_base_10);
tcase_add_test(tc_strtouint32, test_strtouint32_pos_integer_overflow_base_10);
tcase_add_test(tc_strtouint32, test_strtouint32_mixed_alphanumeric_base_10);
tcase_add_test(tc_strtouint32, test_strtouint32_alphaonly_base_10);
tcase_add_test(tc_strtouint32, test_strtouint32_alphastart_base_10);
tcase_add_test(tc_strtouint32, test_strtouint32_emptystring_base_10);
/* Add all test cases to the suite */
suite_add_tcase(s, tc_strtoint32);
suite_add_tcase(s, tc_strtouint32);
return s;
}
int main(int argc, const char *argv[]) {
int opt;
poptContext pc;
int failure_count;
Suite *strtonum_suite;
SRunner *sr;
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_MAIN_OPTS
POPT_TABLEEND
};
/* Set debug level to invalid value so we can deside if -d 0 was used. */
debug_level = SSSDBG_INVALID;
pc = poptGetContext(argv[0], argc, argv, long_options, 0);
while((opt = poptGetNextOpt(pc)) != -1) {
switch(opt) {
default:
fprintf(stderr, "\nInvalid option %s: %s\n\n",
poptBadOption(pc, 0), poptStrerror(opt));
poptPrintUsage(pc, stderr, 0);
return 1;
}
}
poptFreeContext(pc);
CONVERT_AND_SET_DEBUG_LEVEL(debug_level);
tests_set_cwd();
strtonum_suite = create_strtonum_suite();
sr = srunner_create(strtonum_suite);
/* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */
srunner_run_all(sr, CK_ENV);
failure_count = srunner_ntests_failed(sr);
srunner_free(sr);
return (failure_count==0 ? EXIT_SUCCESS : EXIT_FAILURE);
}