From ff9c42e47ebfe33e6370ead93abd67b06ad2bc37 Mon Sep 17 00:00:00 2001 From: Ikey Doherty Date: Thu, 3 Nov 2016 13:37:16 +0000 Subject: [PATCH] Incorporate the nica test suite Much of our low coverage rate can be attributed to using an imported version of libnica, without the test suites. This change incorporate much of the nica test suite for the core types that we utilize. Signed-off-by: Ikey Doherty --- .gitignore | 6 + Makefile.am | 58 ++++- tests/check-array.c | 228 ++++++++++++++++++ tests/check-hashmap.c | 284 ++++++++++++++++++++++ tests/check-inifile.c | 134 +++++++++++ tests/check-list.c | 307 ++++++++++++++++++++++++ tests/data/ini/broken_section_end.ini | 7 + tests/data/ini/broken_section_start.ini | 7 + tests/data/ini/empty_key.ini | 7 + tests/data/ini/just_assign.ini | 7 + tests/data/ini/sectionless.ini | 2 + tests/data/ini/valid_padding.ini | 10 + tests/data/ini/wellformed.ini | 7 + 13 files changed, 1063 insertions(+), 1 deletion(-) create mode 100644 tests/check-array.c create mode 100644 tests/check-hashmap.c create mode 100644 tests/check-inifile.c create mode 100644 tests/check-list.c create mode 100644 tests/data/ini/broken_section_end.ini create mode 100644 tests/data/ini/broken_section_start.ini create mode 100644 tests/data/ini/empty_key.ini create mode 100644 tests/data/ini/just_assign.ini create mode 100644 tests/data/ini/sectionless.ini create mode 100644 tests/data/ini/valid_padding.ini create mode 100644 tests/data/ini/wellformed.ini diff --git a/.gitignore b/.gitignore index ad7502c..cf50ee5 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,9 @@ m4/lt~obsolete.m4 .libs *.la *.lo + +# Nica tests +check_array +check_hashmap +check_inifile +check_list diff --git a/Makefile.am b/Makefile.am index 481a62c..16b568a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,6 +11,13 @@ EXTRA_DIST = ${top_srcdir}/README.md \ ${top_srcdir}/tests/data/match1 \ ${top_srcdir}/tests/data/nomatch1 \ ${top_srcdir}/tests/data/nomatch2 \ + ${top_srcdir}/tests/data/ini/wellformed.ini \ + ${top_srcdir}/tests/data/ini/valid_padding.ini \ + ${top_srcdir}/tests/data/ini/sectionless.ini \ + ${top_srcdir}/tests/data/ini/empty_key.ini \ + ${top_srcdir}/tests/data/ini/just_assign.ini \ + ${top_srcdir}/tests/data/ini/broken_section_start.ini \ + ${top_srcdir}/tests/data/ini/broken_section_end.ini \ ${top_srcdir}/sgcheck.suppressions \ ${top_srcdir}/data/clr-boot-manager-booted.service \ ${top_srcdir}/compat/kernel_updater.sh \ @@ -158,7 +165,11 @@ distclean-local: TESTS = \ check_core \ check_files \ - check_updates + check_updates \ + check_array \ + check_list \ + check_hashmap \ + check_inifile check_PROGRAMS = $(TESTS) @@ -208,6 +219,51 @@ check_updates_LDADD = \ $(BLKID_LIBS) \ $(CHECK_LIBS) +# Nica tests +# Test array +check_array_SOURCES = \ + tests/check-array.c + +check_array_CFLAGS = \ + $(CHECK_CFLAGS) \ + $(AM_CFLAGS) + +check_array_LDADD = \ + $(CHECK_LIBS) + +# Test hashmap +check_hashmap_SOURCES = \ + tests/check-hashmap.c + +check_hashmap_CFLAGS = \ + $(CHECK_CFLAGS) \ + $(AM_CFLAGS) + +check_hashmap_LDADD = \ + $(CHECK_LIBS) + +# Test inifile +check_inifile_SOURCES = \ + tests/check-inifile.c + +check_inifile_CFLAGS = \ + $(CHECK_CFLAGS) \ + $(AM_CFLAGS) + +check_inifile_LDADD = \ + $(CHECK_LIBS) + +# Test list +check_list_SOURCES = \ + tests/check-list.c + +check_list_CFLAGS = \ + $(CHECK_CFLAGS) \ + $(AM_CFLAGS) + +check_list_LDADD = \ + $(CHECK_LIBS) + @VALGRIND_CHECK_RULES@ diff --git a/tests/check-array.c b/tests/check-array.c new file mode 100644 index 0000000..70d0273 --- /dev/null +++ b/tests/check-array.c @@ -0,0 +1,228 @@ +/* + * This file is part of libnica. + * + * Copyright (C) 2016 Intel Corporation + * + * libnica is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + */ + +#define _GNU_SOURCE +#include +#include +#include + +#include "nica/array.c" +#include "nica/util.c" + +START_TEST(nc_array_new_check) +{ + NcArray *array = NULL; + + array = nc_array_new(); + fail_if(!array, "Failed to allocate new array"); + fail_if(array->data, "array->data is not NULL after new"); + fail_if(array->len != 0, "array->len is not 0 after new"); + nc_array_free(&array, NULL); +} +END_TEST + +START_TEST(nc_array_free_check) +{ + NcArray *array = NULL; + + nc_array_free(&array, NULL); + fail_if(array, "Free changed NULL array to non NULL"); + /* Check to see if array free on NULL segfaults */ + nc_array_free(NULL, NULL); + array = nc_array_new(); + fail_if(!array, "Failed to allocate new array"); + nc_array_free(&array, NULL); + fail_if(array, "Failed to set array to NULL"); +} +END_TEST + +static inline void nc_array_free_fun(void *p) +{ + free(p); +} + +START_TEST(nc_array_add_check) +{ + NcArray *array = NULL; + int data1 = 1; + int data2 = 2; + int *data3 = NULL; + + fail_if(nc_array_add(NULL, &data1), "Added data to NULL array"); + array = nc_array_new(); + fail_if(!array, "Failed to allocate new array"); + fail_if(nc_array_add(array, NULL), "Added NULL data to array"); + fail_if(!nc_array_add(array, &data1), "Failed to add data1 to array"); + fail_if(!array->data, "Failed to allocate array->data"); + fail_if(array->len != 1, "Failed to update array->len with the size of the array"); + fail_if(*((int *)array->data[0]) != 1, "Failed to store correct data value to array"); + array->len = (uint16_t)(0 - 1); + fail_if(nc_array_add(array, &data1), "Able to add more than max number of elements"); + array->len = 1; + /* Test resize */ + fail_if(!nc_array_add(array, &data2), "Failed to add second element to array"); + fail_if(!array->data, "Failed to keep array->data"); + fail_if(array->len != 2, "Failed to update array->len with new size"); + fail_if(*((int *)array->data[0]) != 1, "Changed the first array element"); + fail_if(*((int *)array->data[1]) != 2, "Failed to set the second array element"); + nc_array_free(&array, NULL); + fail_if(array, "Failed to set array to NULL 1"); + data3 = malloc(sizeof(int)); + fail_if(!data3, "Failed to allocate data"); + *data3 = 3; + array = nc_array_new(); + fail_if(!array, "Failed to allocate new array"); + fail_if(!nc_array_add(array, data3), "Failed to add pointer data"); + fail_if(*((int *)array->data[0]) != 3, + "Failed to store correct pointer data value to array"); + nc_array_free(&array, nc_array_free_fun); + fail_if(array, "Failed to set array to NULL 2"); +} +END_TEST + +START_TEST(nc_array_get_check) +{ + NcArray *array = NULL; + int data1 = 1; + + array = nc_array_new(); + fail_if(!array, "Failed to allocate new array"); + fail_if(nc_array_get(NULL, 0), "Got data from NULL array"); + fail_if(nc_array_get(array, 0), "Got data from empty array"); + fail_if(!nc_array_add(array, &data1), "Failed to add data1 to array"); + fail_if(*((int *)nc_array_get(array, 0)) != 1, "Failed to get correct value for element 0"); + fail_if(nc_array_get(array, 1), "Got data past end of array"); + nc_array_free(&array, NULL); + fail_if(array, "Failed to set array to NULL"); +} +END_TEST + +START_TEST(nc_array_check) +{ + NcArray *array = NULL; + char *value; + char *element; + void *f; + bool r; + + array = nc_array_new(); + fail_if(array == NULL, "Failed to allocate memory for NcArray"); + element = strdup("test"); + fail_if(!element, "Failed to allocate memory for array item"); + r = nc_array_add(NULL, element); + fail_if(r, "Added element to NULL array"); + r = nc_array_add(array, NULL); + fail_if(r, "Added NULL element to array"); + r = nc_array_add(array, element); + fail_if(r == false, "Failed to add element to NcArray"); + fail_if(array->len != 1, "Failed to get correct value for number of elements in array"); + + f = nc_array_get(NULL, 0); + fail_if(f, "Got value from NULL array"); + f = nc_array_get(array, (uint16_t)(array->len + 1)); + fail_if(f, "Got value from index bigger than maximum index"); + value = (char *)nc_array_get(array, 0); + + fail_if(value == NULL, "Failed to get value from NcArray"); + + fail_if(strcmp(value, "test") != 0, "Failed to retrieve the stored value"); + + nc_array_free(&array, nc_array_free_fun); + fail_if(array != NULL, "Failed to free NcArray"); +} +END_TEST + +static int sort_strings(const void *a, const void *b) +{ + return strcmp(*(char **)a, *(char **)b); +} + +static int sort_strings_reverse(const void *a, const void *b) +{ + return strcmp(*(char **)b, *(char **)a); +} + +START_TEST(nc_array_sort_check) +{ + NcArray *array = NULL; + + array = nc_array_new(); + fail_if(!array, "Failed to allocate memory for NcArray"); + + fail_if(!nc_array_add(array, "gamma"), "Failed to add to array"); + fail_if(!nc_array_add(array, "delta"), "Failed to add to array"); + fail_if(!nc_array_add(array, "beta"), "Failed to add to array"); + fail_if(!nc_array_add(array, "alpha"), "Failed to add to array"); + + fail_if(array->len != 4, "Array length invalid"); + + fail_if(!streq(nc_array_get(array, 0), "gamma"), "Invalid ordering in array #1"); + fail_if(!streq(nc_array_get(array, 1), "delta"), "Invalid ordering in array #2"); + fail_if(!streq(nc_array_get(array, 2), "beta"), "Invalid ordering in array #3"); + fail_if(!streq(nc_array_get(array, 3), "alpha"), "Invalid ordering in array #4"); + + /* Alpha sort them */ + nc_array_qsort(array, sort_strings); + + fail_if(!streq(nc_array_get(array, 0), "alpha"), "Invalid sort ordering in array #1"); + fail_if(!streq(nc_array_get(array, 1), "beta"), "Invalid sort ordering in array #2"); + fail_if(!streq(nc_array_get(array, 2), "delta"), "Invalid sort ordering in array #3"); + fail_if(!streq(nc_array_get(array, 3), "gamma"), "Invalid sort ordering in array #4"); + + /* Flip them back now */ + nc_array_qsort(array, sort_strings_reverse); + fail_if(!streq(nc_array_get(array, 0), "gamma"), "Invalid reverse ordering in array #1"); + fail_if(!streq(nc_array_get(array, 1), "delta"), "Invalid reverse ordering in array #2"); + fail_if(!streq(nc_array_get(array, 2), "beta"), "Invalid reverse ordering in array #3"); + fail_if(!streq(nc_array_get(array, 3), "alpha"), "Invalid reverse ordering in array #4"); + + nc_array_free(&array, NULL); + fail_if(array != NULL, "Failed to free NcArray"); +} +END_TEST + +int main(void) +{ + int number_failed; + Suite *s; + SRunner *sr; + TCase *tc; + + s = suite_create("nc_array"); + tc = tcase_create("nc_array_functions"); + tcase_add_test(tc, nc_array_new_check); + tcase_add_test(tc, nc_array_free_check); + tcase_add_test(tc, nc_array_add_check); + tcase_add_test(tc, nc_array_get_check); + tcase_add_test(tc, nc_array_check); + tcase_add_test(tc, nc_array_sort_check); + suite_add_tcase(s, tc); + + sr = srunner_create(s); + srunner_run_all(sr, CK_VERBOSE); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=8 tabstop=8 expandtab: + * :indentSize=8:tabSize=8:noTabs=true: + */ diff --git a/tests/check-hashmap.c b/tests/check-hashmap.c new file mode 100644 index 0000000..5fc8e34 --- /dev/null +++ b/tests/check-hashmap.c @@ -0,0 +1,284 @@ +/* + * This file is part of libnica. + * + * Copyright (C) 2016 Intel Corporation + * + * libnica is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + */ + +#define _GNU_SOURCE +#include "nica/hashmap.c" +#include +#include + +START_TEST(nc_hashmap_new_check) +{ + NcHashmap *map = NULL; + + map = nc_hashmap_new(NULL, NULL); + fail_if(!map, "Failed to allocate new hashmap"); + fail_if(nc_hashmap_size(map) != 0, "Hashmap size is not 0 after new"); + nc_hashmap_free(map); +} +END_TEST + +START_TEST(nc_hashmap_simple_check) +{ + NcHashmap *map = NULL; + bool b; + void *val = NULL; + + map = nc_hashmap_new(nc_simple_hash, nc_simple_compare); + fail_if(!map, "Failed to allocate new hashmap"); + + for (int i = 0; i < 1000; i++) { + b = nc_hashmap_put(map, NC_HASH_KEY(i), NC_HASH_VALUE(i)); + fail_if(!b, "Failed to add integer to hashmap"); + } + fail_if(nc_hashmap_size(map) != 1000, "Hashmap size invalid after 1000 elements"); + + for (int i = 300; i < 700; i++) { + b = nc_hashmap_remove(map, NC_HASH_KEY(i)); + fail_if(!b, "Failed to remove known integer from from hashmap"); + } + + fail_if(nc_hashmap_size(map) != 600, "Hashmap size invalid after 400 removals"); + + val = nc_hashmap_get(map, NC_HASH_KEY(302)); + fail_if(val, "Value should not be returned from hashmap after removal"); + + val = nc_hashmap_get(map, NC_HASH_KEY(802)); + fail_if(!val, "Value should be returned from hashmap for known key"); + fail_if(NC_UNHASH_VALUE(val) != 802, "Value returned from hashmap was incorrect"); + + fail_if(!nc_hashmap_steal(map, NC_HASH_KEY(802)), "Failed to steal key/value"); + fail_if(nc_hashmap_contains(map, NC_HASH_KEY(802)), "Stolen key still exists"); + + nc_hashmap_free(map); + map = NULL; + + fail_if(nc_hashmap_size(map) >= 0, "Incorrect size returned for NULL hashmap"); +} +END_TEST + +START_TEST(nc_hashmap_dupe_check) +{ + NcHashmap *map = NULL; + void *val = NULL; + + map = nc_hashmap_new(nc_simple_hash, nc_simple_compare); + + fail_if(!nc_hashmap_put(map, "name", "not important"), + "Failed to put to hashmap first time!"); + val = nc_hashmap_get(map, "name"); + fail_if(!val, "Failed to get name!"); + fail_if(!streq(val, "not important"), "Returned value does not match"); + val = NULL; + + fail_if(!nc_hashmap_put(map, "name", "ikey"), "Failed to replace with second value"); + val = nc_hashmap_get(map, "name"); + fail_if(!streq(val, "ikey"), "Second return doesn't match expectation"); + nc_hashmap_free(map); +} +END_TEST + +START_TEST(nc_hashmap_dupe_alloc_check) +{ + NcHashmap *map = NULL; + void *val = NULL; + void *val2 = NULL; + + map = nc_hashmap_new_full(nc_string_hash, nc_string_compare, free, free); + + fail_if(!nc_hashmap_put(map, strdup("name"), strdup("not important")), + "Failed to put to hashmap first time!"); + val = nc_hashmap_get(map, "name"); + fail_if(!val, "Failed to get name!"); + fail_if(!streq(val, "not important"), "Returned value does not match"); + + fail_if(!nc_hashmap_put(map, strdup("name"), strdup("ikey")), + "Failed to replace with second value"); + val2 = nc_hashmap_get(map, "name"); + fail_if(!streq(val2, "ikey"), "Second return doesn't match expectation"); + nc_hashmap_free(map); +} +END_TEST + +START_TEST(nc_hashmap_string_check) +{ + NcHashmap *map = NULL; + bool b; + void *val = NULL; + + map = nc_hashmap_new(nc_string_hash, nc_string_compare); + fail_if(!map, "Failed to allocate new hashmap"); + + b = nc_hashmap_put(map, "John", NC_HASH_VALUE(12)); + fail_if(!b, "Failed to put entry into map"); + b = nc_hashmap_put(map, "Lucy", NC_HASH_VALUE(42)); + fail_if(!b, "Failed to put entry into map"); + b = nc_hashmap_put(map, "Bob", NC_HASH_VALUE(19012)); + fail_if(!b, "Failed to put entry into map"); + b = nc_hashmap_put(map, "Sarah", NC_HASH_VALUE(83)); + fail_if(!b, "Failed to put entry into map"); + + val = nc_hashmap_get(map, "John"); + fail_if(!val, "Failed to get known key from hashmap"); + fail_if(NC_UNHASH_VALUE(val) != 12, "Failed to get correct value from hashmap"); + + val = nc_hashmap_get(map, "Lucy"); + fail_if(!val, "Failed to get known key from hashmap"); + fail_if(NC_UNHASH_VALUE(val) != 42, "Failed to get correct value from hashmap"); + + val = nc_hashmap_get(map, "Bob"); + fail_if(!val, "Failed to get known key from hashmap"); + fail_if(NC_UNHASH_VALUE(val) != 19012, "Failed to get correct value from hashmap"); + + val = nc_hashmap_get(map, "Sarah"); + fail_if(!val, "Failed to get known key from hashmap"); + fail_if(NC_UNHASH_VALUE(val) != 83, "Failed to get correct value from hashmap"); + + nc_hashmap_free(map); +} +END_TEST + +START_TEST(nc_hashmap_iter_check) +{ + NcHashmap *map = NULL; + NcHashmapIter iter; + bool b; + int count = 0; + void *key = NULL; + void *value = NULL; + + map = nc_hashmap_new(NULL, NULL); + fail_if(!map, "Failed to allocate new hashmap"); + + for (int i = 0; i < 5000; i++) { + b = nc_hashmap_put(map, NC_HASH_KEY(i), NC_HASH_KEY(i)); + fail_if(!b, "Failed to insert key into hashmap"); + } + + fail_if(nc_hashmap_size(map) != 5000, "Invalid hashmap size after 5000 elements"); + + nc_hashmap_iter_init(map, &iter); + while (nc_hashmap_iter_next(&iter, (void **)&key, (void **)&value)) { + fail_if(NC_UNHASH_KEY(key) != NC_UNHASH_VALUE(value), + "Mismatched key/value pair in iteration"); + ++count; + } + fail_if(count != 5000, "Did not iterate all hashmap elements"); + + count = 0; + for (int i = 2000; i < 4000; i++) { + b = nc_hashmap_remove(map, NC_HASH_KEY(i)); + fail_if(!b, "Failed to remove known integer key from hashmap"); + } + + nc_hashmap_iter_init(map, &iter); + key = value = NULL; + while (nc_hashmap_iter_next(&iter, &key, &value)) { + unsigned int k = NC_UNHASH_KEY(key); + fail_if(NC_UNHASH_VALUE(value) != k, + "Mismatched post-removal key/value pair in iteration"); + fail_if(k >= 2000 && k < 4000, "Key/value not removed from hashtable"); + ++count; + } + fail_if(count != 3000, "Did not iterate all 2000 elements"); + fail_if(nc_hashmap_size(map) != 3000, "Invalid hashmap size after removals"); + + nc_hashmap_free(map); +} +END_TEST + +static int free_count = 0; + +static inline void free_helper(void *p) +{ + free((void *)p); + ++free_count; +} + +START_TEST(nc_hashmap_alloc_check) +{ + NcHashmap *map = NULL; + char *str = NULL; + void *val = NULL; + bool b; + + map = nc_hashmap_new_full(nc_string_hash, nc_string_compare, free_helper, NULL); + fail_if(!map, "Failed to allocate new hashmap"); + + fail_if(!(str = strdup("Key 1"), "Allocation problem")); + fail_if(!nc_hashmap_put(map, str, str), "Failed to insert into hashmap"); + + fail_if(!(str = strdup("Key 2"), "Allocation problem")); + fail_if(!nc_hashmap_put(map, str, str), "Failed to insert into hashmap"); + + val = nc_hashmap_get(map, "Key 1"); + fail_if(!val, "Failed to get known value from hashmap"); + fail_if(strcmp(val, "Key 1") != 0, "Key 1 does not match"); + val = NULL; + + val = nc_hashmap_get(map, "Key 2"); + fail_if(!val, "Failed to get known value from hashmap"); + fail_if(strcmp(val, "Key 2") != 0, "Key 2 does not match"); + + b = nc_hashmap_remove(map, "Key 2"); + fail_if(!b, "Failed to remove known key from hashmap"); + fail_if(free_count != 1, "Failed to free element from hashmap"); + + nc_hashmap_free(map); + fail_if(free_count != 2, "Failed to free last element from hashmap"); +} +END_TEST + +static Suite *nc_hashmap_suite(void) +{ + Suite *s = NULL; + TCase *tc = NULL; + + s = suite_create("nc_hashmap"); + tc = tcase_create("nc_hashmap_functions"); + tcase_add_test(tc, nc_hashmap_new_check); + tcase_add_test(tc, nc_hashmap_simple_check); + tcase_add_test(tc, nc_hashmap_string_check); + tcase_add_test(tc, nc_hashmap_iter_check); + tcase_add_test(tc, nc_hashmap_alloc_check); + tcase_add_test(tc, nc_hashmap_dupe_check); + tcase_add_test(tc, nc_hashmap_dupe_alloc_check); + suite_add_tcase(s, tc); + + return s; +} + +int main(void) +{ + int number_failed; + Suite *s; + SRunner *sr; + + s = nc_hashmap_suite(); + sr = srunner_create(s); + srunner_run_all(sr, CK_VERBOSE); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=8 tabstop=8 expandtab: + * :indentSize=8:tabSize=8:noTabs=true: + */ diff --git a/tests/check-inifile.c b/tests/check-inifile.c new file mode 100644 index 0000000..990a1e1 --- /dev/null +++ b/tests/check-inifile.c @@ -0,0 +1,134 @@ +/* + * This file is part of libnica. + * + * Copyright (C) 2016 Intel Corporation + * + * libnica is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include + +#include "nica/hashmap.c" +#include "nica/inifile.c" + +START_TEST(nc_inifile_open_test) +{ + autofree(NcHashmap) *f = NULL; + const char *t_path = TOP_DIR "/tests/data/ini/wellformed.ini"; + + f = nc_ini_file_parse(t_path); + fail_if(f == NULL, "Failed to parse wellformed.ini"); +} +END_TEST + +START_TEST(nc_inifile_good_test) +{ + const char *wellformed[] = { TOP_DIR "/tests/data/ini/wellformed.ini", + TOP_DIR "/tests/data/ini/valid_padding.ini" }; + + for (size_t i = 0; i < sizeof(wellformed) / sizeof(wellformed[0]); i++) { + autofree(NcHashmap) *f = NULL; + char *ret = NULL; + + f = nc_ini_file_parse(wellformed[i]); + fail_if(f == NULL, "Failed to parse wellformed.ini"); + + fail_if(!nc_hashmap_contains(f, "John"), "INI File missing \"John\" section"); + + ret = nc_hashmap_get(nc_hashmap_get(f, "John"), "alive"); + fail_if(!ret, "Failed to get known value from INI file"); + fail_if(!streq(ret, "true"), "Incorrect value in INI file"); + + fail_if(!nc_hashmap_contains(f, "Alice"), "INI File missing \"Alice\" section"); + ret = nc_hashmap_get(nc_hashmap_get(f, "Alice"), "alive"); + fail_if(!ret, "Failed to get known value from INI file"); + fail_if(!streq(ret, "false"), "Incorrect value in INI file #2"); + + ret = nc_hashmap_get(nc_hashmap_get(f, "John"), "Random"); + fail_if(ret, "Got unexpected key in section"); + + ret = nc_hashmap_get(nc_hashmap_get(f, "Bob"), "Random"); + fail_if(ret, "Got unexpected section"); + } +} +END_TEST + +START_TEST(nc_inifile_bad_test) +{ + const char *t_path = TOP_DIR "/tests/data/ini/sectionless.ini"; + autofree(NcHashmap) *f = NULL; + + f = nc_ini_file_parse(t_path); + fail_if(f != NULL, "Parsed illegal sectionless INI file"); + + t_path = TOP_DIR "/tests/data/ini/empty_key.ini"; + f = nc_ini_file_parse(t_path); + fail_if(f != NULL, "Parsed illegal INI file with empty keys"); + + t_path = TOP_DIR "/tests/data/ini/just_assign.ini"; + f = nc_ini_file_parse(t_path); + fail_if(f != NULL, "Parsed illegal assign-only INI file"); + + t_path = TOP_DIR "/tests/data/ini/broken_section_start.ini"; + f = nc_ini_file_parse(t_path); + fail_if(f != NULL, "Parsed illegal broken-section-start INI File"); + + t_path = TOP_DIR "/tests/data/ini/broken_section_end.ini"; + f = nc_ini_file_parse(t_path); + fail_if(f != NULL, "Parsed illegal broken-section-end INI File"); +} +END_TEST + +static Suite *core_suite(void) +{ + Suite *s = NULL; + TCase *tc = NULL; + + s = suite_create("nc_inifile"); + tc = tcase_create("nc_inifile_functions"); + tcase_add_test(tc, nc_inifile_open_test); + tcase_add_test(tc, nc_inifile_good_test); + tcase_add_test(tc, nc_inifile_bad_test); + suite_add_tcase(s, tc); + + return s; +} + +int main(void) +{ + Suite *s; + SRunner *sr; + int fail; + + s = core_suite(); + sr = srunner_create(s); + srunner_run_all(sr, CK_VERBOSE); + fail = srunner_ntests_failed(sr); + srunner_free(sr); + + if (fail > 0) { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=8 tabstop=8 expandtab: + * :indentSize=8:tabSize=8:noTabs=true: + */ diff --git a/tests/check-list.c b/tests/check-list.c new file mode 100644 index 0000000..33d9dff --- /dev/null +++ b/tests/check-list.c @@ -0,0 +1,307 @@ +/* + * This file is part of libnica. + * + * Copyright (C) 2016 Intel Corporation + * + * libnica is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nica/list.c" + +START_TEST(nc_list_append_check) +{ + NcList *list = NULL; + NcList *head = NULL; + int data1 = 1; + int data2 = 2; + + fail_if(!nc_list_append(&list, &data1), "Append for new list failed"); + head = list; + fail_if(list->tail != list, "list and list->tail do not match after new list append"); + fail_if(list->next, "list->next is not NULL after new list append"); + fail_if(*((int *)(list->data)) != 1, "list->data is incorrect after new list append"); + fail_if(list->size != 1, "list->size not 1 after new list append"); + + fail_if(!nc_list_append(&list, &data2), "Append for existing list failed"); + fail_if(head != list, "Append switched list head"); + fail_if(list->tail != list->next, + "list->next and list->tail do not match after two appends"); + fail_if(list->next->next, "list->next->next is not NULL after two appends"); + fail_if(*((int *)(list->data)) != 1, "list->data is incorrect after two list appends"); + fail_if(*((int *)(list->next->data)) != 2, + "list->next->data is incorrect after two list appends"); + fail_if(list->size != 2, "list->size not 2 after two list appends"); + + nc_list_free(&list); +} +END_TEST + +START_TEST(nc_list_prepend_check) +{ + NcList *list = NULL; + NcList *tail = NULL; + int data1 = 1; + int data2 = 2; + + fail_if(!nc_list_prepend(&list, &data1), "Prepend for new list failed"); + tail = list; + fail_if(list->tail != list, "list and list->tail do not match after new list prepend"); + fail_if(list->next, "list->next is not NULL after new list prepend"); + fail_if(*((int *)(list->data)) != 1, "list->data is incorrect after new list prepend"); + fail_if(list->size != 1, "list->size not 1 after new list prepend"); + + fail_if(!nc_list_prepend(&list, &data2), "Prepend for existing list failed"); + fail_if(tail != list->next, "Prepend switched list next"); + fail_if(tail != list->tail, "Prepend switched list tail"); + fail_if(list->tail != list->next, + "list->next and list->tail do not match after two prepends"); + fail_if(list->next->next, "list->next->next is not NULL after two prepends"); + fail_if(*((int *)(list->data)) != 2, "list->data is incorrect after two list prepends"); + fail_if(*((int *)(list->next->data)) != 1, + "list->next->data is incorrect after two list prepends"); + fail_if(list->size != 2, "list->size not 2 after two list prepends"); + + nc_list_free(&list); +} +END_TEST + +START_TEST(nc_list_remove_check) +{ + NcList *list = NULL; + int data1 = 1; + int data2 = 2; + int data3 = 3; + int *data4 = NULL; + int *data5 = NULL; + + fail_if(nc_list_remove(&list, &data1, false), "Removed from non existing list"); + fail_if(!nc_list_prepend(&list, &data1), "Prepend for new list failed"); + fail_if(nc_list_remove(&list, &data2, false), "Removed non existing element from list"); + fail_if(list->tail != list, "list and list->tail do not match after new list prepend"); + fail_if(list->next, "list->next is not NULL after new list prepend"); + fail_if(*((int *)(list->data)) != 1, "list->data is incorrect after new list prepend"); + fail_if(list->size != 1, "list->size not 1 after new list prepend"); + fail_if(!nc_list_remove(&list, &data1, false), "Unable to remove existing item from list"); + fail_if(list, "List not NULL after removal of only element"); + + data4 = malloc(sizeof(int)); + data5 = malloc(sizeof(int)); + fail_if(!data4 || !data5, "Failed to allocate"); + *data4 = 4; + *data5 = 5; + fail_if(!nc_list_prepend(&list, &data1), "Prepend 1 for list failed"); + fail_if(!nc_list_append(&list, &data2), "Append 1 for list failed"); + fail_if(!nc_list_prepend(&list, &data3), "Prepend 2 for list failed"); + fail_if(!nc_list_append(&list, data4), "Append 2 for list failed"); + fail_if(!nc_list_prepend(&list, data5), "Prepend 3 for list failed"); + /* the list is = (*5, 3, 1, 2, *4) */ + fail_if(!nc_list_remove(&list, &data1, false), "Unable to remove data1 from list"); + fail_if(nc_list_remove(&list, &data1, false), "Able to remove data1 from list again"); + /* the list is = (*5, 3, 2, *4) */ + fail_if(*((int *)(list->data)) != 5, "list->data value incorrect"); + fail_if(list->size != 4, "list->size incorrect"); + fail_if(*((int *)(list->next->next->data)) != 2, "list->next->next->data value incorrect"); + fail_if(*((int *)(list->tail->data)) != 4, "list->tail->data value incorrect"); + fail_if(list->tail != list->next->next->next, "list->tail is incorrect"); + fail_if(!nc_list_remove(&list, data4, true), "Failed to remove data4 from list"); + /* the list is = (*5, 3, 2) */ + fail_if(*((int *)(list->data)) != 5, "list->data value incorrect"); + fail_if(list->size != 3, "list->size incorrect"); + fail_if(*((int *)(list->tail->data)) != 2, "list->tail->data value incorrect"); + fail_if(list->tail != list->next->next, "list->tail is incorrect"); + fail_if(!nc_list_remove(&list, data5, true), "Failed to remove data5 from list"); + /* the list is = (3, 2) */ + fail_if(*((int *)(list->data)) != 3, "list->data value incorrect"); + fail_if(list->size != 2, "list->size incorrect"); + fail_if(*((int *)(list->tail->data)) != 2, "list->tail->data value incorrect"); + fail_if(list->tail != list->next, "list->tail is incorrect"); + fail_if(!nc_list_remove(&list, &data3, false), "Failed to remove data3 from list"); + /* the list is = (2) */ + fail_if(*((int *)(list->data)) != 2, "list->data value incorrect"); + fail_if(list->size != 1, "list->size incorrect"); + fail_if(*((int *)(list->tail->data)) != 2, "list->tail->data value incorrect"); + fail_if(list->tail != list, "list->tail is incorrect"); + fail_if(!nc_list_remove(&list, &data2, false), "Failed to remove data2 from list"); + /* the list is = () */ + fail_if(list, "list is not NULL"); +} +END_TEST + +START_TEST(nc_list_foreach_check) +{ + NcList *list = NULL; + NcList *i; + int data1 = 1; + int data2 = 2; + int data3 = 3; + int c = 1; + + fail_if(!nc_list_append(&list, &data1), "Append 1 for list failed"); + fail_if(!nc_list_append(&list, &data2), "Append 2 for list failed"); + fail_if(!nc_list_append(&list, &data3), "Append 3 for list failed"); + NC_LIST_FOREACH (list, i) { + fail_if(*((int *)(i->data)) != c, "Failed to iterate list"); + c++; + } + + nc_list_free(&list); +} +END_TEST + +START_TEST(nc_list_free_check) +{ + NcList *list = NULL; + int data1 = 1; + int data2 = 2; + int data3 = 3; + + nc_list_free(&list); + fail_if(list, "null list returned non null after free"); + fail_if(!nc_list_append(&list, &data1), "Append 1 for list failed"); + fail_if(!nc_list_append(&list, &data2), "Append 2 for list failed"); + fail_if(!nc_list_append(&list, &data3), "Append 3 for list failed"); + nc_list_free(&list); + fail_if(list, "non null list returned non null after free"); +} +END_TEST + +START_TEST(nc_list_free_all_check) +{ + NcList *list = NULL; + int *data1 = NULL; + int *data2 = NULL; + int *data3 = NULL; + + nc_list_free(&list); + fail_if(list, "null list returned non null after free"); + data1 = malloc(sizeof(int)); + data2 = malloc(sizeof(int)); + data3 = malloc(sizeof(int)); + fail_if(!data1 || !data2 || !data3, "malloc failed"); + fail_if(!nc_list_append(&list, data1), "Append 1 for list failed"); + fail_if(!nc_list_append(&list, data2), "Append 2 for list failed"); + fail_if(!nc_list_append(&list, data3), "Append 3 for list failed"); + nc_list_free_all(&list); + fail_if(list, "non null list returned non null after free"); +} +END_TEST + +START_TEST(nc_list_check) +{ + NcList *list = NULL; + uint i; + char *tmp = NULL; + char *head = ""; + char *head2 = ""; + char *data = ""; + + /* Append 10k strings. */ + uint DEFAULT_SIZE = (10 * 1000); + for (i = 0; i <= DEFAULT_SIZE; i++) { + if (i == 5) { + fail_if(nc_list_append(&list, data) == false, "Failed to append to NcList"); + } else { + int j = asprintf(&tmp, "i #%d", i); + fail_if(j < 0, "Failed to pass test due to allocation error"); + fail_if(nc_list_prepend(&list, tmp) == false, + "Failed to prepend to NcList"); + } + } + + fail_if(list->size != DEFAULT_SIZE + 1, "List size invalid"); + + /* Prepend head */ + fail_if(nc_list_prepend(&list, head) != true, "Prepend head failed"); + fail_if(list->size != DEFAULT_SIZE + 2, "Prepended head size invalid"); + + /* Prepend head2 */ + fail_if(nc_list_prepend(&list, head2) != true, "Prepend head2 failed"); + fail_if(list->size != DEFAULT_SIZE + 3, "Prepended head2 size invalid"); + + /* Remove from middle */ + fail_if(nc_list_remove(&list, data, false) != true, "List removal from middle failed"); + fail_if(list->size != DEFAULT_SIZE + 2, "List middle removal size invalid"); + + /* Remove from end */ + fail_if(nc_list_remove(&list, tmp, true) != true, "List tail removal failed"); + fail_if(list->size != DEFAULT_SIZE + 1, "List tail removal size invalid"); + + fail_if(nc_list_append(&list, "newend") != true, "List new tail append failed"); + fail_if(list->size != DEFAULT_SIZE + 2, "List new tail size invalid"); + fail_if(nc_list_remove(&list, "newend", false) != true, "List new tail removal failed"); + fail_if(list->size != DEFAULT_SIZE + 1, "List new tail size invalid (post removal)"); + + /* Fake remove */ + fail_if(nc_list_remove(&list, "nonexistent", false) == true, + "List non existent removal should fail"); + fail_if(list->size != DEFAULT_SIZE + 1, "List size invalid after no change"); + + /* Remove head */ + fail_if(nc_list_remove(&list, head, false) == false, "List remove head failed"); + fail_if(nc_list_remove(&list, head2, false) == false, "List remove head2 failed"); + fail_if(list->size != DEFAULT_SIZE - 1, "List post heads removal size invalid"); + + nc_list_free_all(&list); +} +END_TEST + +static Suite *nc_list_suite(void) +{ + Suite *s; + TCase *tc; + + s = suite_create("nc_list"); + tc = tcase_create("nc_list_functions"); + tcase_add_test(tc, nc_list_append_check); + tcase_add_test(tc, nc_list_prepend_check); + tcase_add_test(tc, nc_list_remove_check); + tcase_add_test(tc, nc_list_foreach_check); + tcase_add_test(tc, nc_list_free_check); + tcase_add_test(tc, nc_list_free_all_check); + tcase_add_test(tc, nc_list_check); + suite_add_tcase(s, tc); + + return s; +} + +int main(void) +{ + int number_failed; + Suite *s; + SRunner *sr; + + s = nc_list_suite(); + sr = srunner_create(s); + srunner_run_all(sr, CK_VERBOSE); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=8 tabstop=8 expandtab: + * :indentSize=8:tabSize=8:noTabs=true: + */ diff --git a/tests/data/ini/broken_section_end.ini b/tests/data/ini/broken_section_end.ini new file mode 100644 index 0000000..0723a8e --- /dev/null +++ b/tests/data/ini/broken_section_end.ini @@ -0,0 +1,7 @@ +[John +alive=true + +[Alice] +# Various comment types +; Sorry, Alice! +alive = false diff --git a/tests/data/ini/broken_section_start.ini b/tests/data/ini/broken_section_start.ini new file mode 100644 index 0000000..4e4a83c --- /dev/null +++ b/tests/data/ini/broken_section_start.ini @@ -0,0 +1,7 @@ +John] +alive=true + +[Alice] +# Various comment types +; Sorry, Alice! +alive = false diff --git a/tests/data/ini/empty_key.ini b/tests/data/ini/empty_key.ini new file mode 100644 index 0000000..2ae7111 --- /dev/null +++ b/tests/data/ini/empty_key.ini @@ -0,0 +1,7 @@ +[John] +=true + +[Alice] +# Various comment types +; Sorry, Alice! + = false diff --git a/tests/data/ini/just_assign.ini b/tests/data/ini/just_assign.ini new file mode 100644 index 0000000..7f12517 --- /dev/null +++ b/tests/data/ini/just_assign.ini @@ -0,0 +1,7 @@ +[John] += + +[Alice] +# Various comment types +; Sorry, Alice! + = diff --git a/tests/data/ini/sectionless.ini b/tests/data/ini/sectionless.ini new file mode 100644 index 0000000..9122d0a --- /dev/null +++ b/tests/data/ini/sectionless.ini @@ -0,0 +1,2 @@ +alive=true +alive = false diff --git a/tests/data/ini/valid_padding.ini b/tests/data/ini/valid_padding.ini new file mode 100644 index 0000000..4ac24ca --- /dev/null +++ b/tests/data/ini/valid_padding.ini @@ -0,0 +1,10 @@ +; This file is ugly but still valid INI as far as the parser +; is concerned. + +[John] + alive=true + + [Alice] + # Various comment types + ; Sorry, Alice! + alive = false diff --git a/tests/data/ini/wellformed.ini b/tests/data/ini/wellformed.ini new file mode 100644 index 0000000..565e430 --- /dev/null +++ b/tests/data/ini/wellformed.ini @@ -0,0 +1,7 @@ +[John] +alive=true + +[Alice] +# Various comment types +; Sorry, Alice! +alive = false