#include <stdarg.h>
#include <setjmp.h>
#include <stdio.h>
+#include <string.h>
#include <stdlib.h>
#include <cmocka.h>
#include <assert.h>
#include <glib.h>
#include <errno.h>
#include <stdbool.h>
+#include <math.h>
#include "notifier.h"
#include "config-parser.h"
void *__real_malloc(size_t size);
void __real_free(void *ptr);
+char *__real_strdup(const char *s);
+char *__real_strndup(const char *s, size_t n);
GSList *__real_g_slist_append(GSList *list, gpointer data);
GSList *__real_g_slist_remove(GSList *list, gconstpointer data);
return 0;
}
+int config_parser_cb(struct parse_result *result, void *user_data)
+{
+ int t = mock_type(int);
+ if (t == 1)
+ return -1;
+ check_expected_ptr(user_data);
+
+ char *s = mock_ptr_type(char *);
+ char *k = mock_ptr_type(char *);
+ char *v = mock_ptr_type(char *);
+
+ assert(!strcmp(s, result->section));
+ assert(!strcmp(k, result->name));
+ assert(!strcmp(v, result->value));
+
+ (void) s;
+ (void) k;
+ (void) v;
+ return 0;
+}
+
+char *__wrap_strdup(const char *s)
+{
+ bool fake = mock_type(bool);
+ if (fake)
+ return NULL;
+
+ return __real_strdup(s);
+}
+
+char *__wrap_strndup(const char *s, size_t n)
+{
+ bool fake = mock_type(bool);
+ if (fake)
+ return NULL;
+
+ return __real_strndup(s, n);
+}
+
void __wrap_free(void *ptr)
{
bool check = mock_type(bool);
assert_int_equal(unregister_notifier(1, fptr), 0);
}
+static void test_config_parse(void **state)
+{
+ (void) state; /* unused */
+ const char *section = "section";
+ const char *key = "key";
+ const char *value = "value";
+ void *ptr = (void*)0xD00D1E;
+
+ /* null pointer test */
+ assert_int_equal(config_parse(NULL, config_parser_cb, NULL), -EINVAL);
+
+ /* null pointer test */
+ assert_int_equal(config_parse("/dev/null", NULL, NULL), -EINVAL);
+
+ /* non-existing file test */
+ assert_int_equal(config_parse("the_x_files", config_parser_cb, NULL), -EIO);
+
+ /* invalid section header test */
+ assert_int_equal(config_parse("../../tests/config_parser_test_1.conf", config_parser_cb, NULL), -EBADMSG);
+
+ /* key with no value test */
+ assert_int_equal(config_parse("../../tests/config_parser_test_2.conf", config_parser_cb, NULL), -EBADMSG);
+
+ /* callback return value test */
+ will_return(config_parser_cb, 1);
+ assert_int_equal(config_parse("../../tests/config_parser_test_3.conf", config_parser_cb, NULL), -EBADMSG);
+
+ /* positive test */
+ will_return(config_parser_cb, 0);
+ expect_value(config_parser_cb, user_data, cast_ptr_to_largest_integral_type(ptr));
+ will_return(config_parser_cb, cast_ptr_to_largest_integral_type(section));
+ will_return(config_parser_cb, cast_ptr_to_largest_integral_type(key));
+ will_return(config_parser_cb, cast_ptr_to_largest_integral_type(value));
+ assert_int_equal(config_parse("../../tests/config_parser_test_3.conf", config_parser_cb, ptr), 0);
+}
+
+static void test_config_parse_new(void **state)
+{
+ (void) state; /* unused */
+ ConfigTableItem dummy_items[] = {
+ { NULL, NULL, NULL, 0, NULL }
+ };
+
+ char *str = NULL;
+ bool b = false;
+ int i = 0;
+ float f = 100.0;
+ int bytes = 1;
+ ConfigTableItem items[] = {
+ { "section", "key_s", config_parse_string, 0, &str },
+ { "section", "key_b", config_parse_bool, 0, &b },
+ { "section", "key_i", config_parse_int, 0, &i },
+ { "section", "key_f", config_parse_float, 0, &f },
+ { "section", "key_bytes", config_parse_bytes, 0, &bytes },
+ { NULL, NULL, NULL, 0, NULL }
+ };
+
+ will_return_maybe(__wrap_free, false);
+ /* non-existing file test */
+ assert_int_equal(config_parse_new("the_x_files", NULL), -ENOENT);
+
+ /* invalid section header test */
+ assert_int_equal(config_parse_new("../../tests/config_parser_test_1.conf", NULL), -EBADMSG);
+
+ /* oom test 1 */
+ will_return(__wrap_strndup, true);
+ assert_int_equal(config_parse_new("../../tests/config_parser_test_2.conf", NULL), -ENOMEM);
+
+ /* oom test 2 */
+ will_return(__wrap_strndup, false);
+ will_return(__wrap_strndup, true);
+ assert_int_equal(config_parse_new("../../tests/config_parser_test_3.conf", NULL), -ENOMEM);
+
+ /* oom test 2 */
+ will_return(__wrap_strndup, false);
+ will_return(__wrap_strndup, false);
+ will_return(__wrap_strdup, true);
+ assert_int_equal(config_parse_new("../../tests/config_parser_test_3.conf", NULL), -ENOMEM);
+
+ /* too much data in a file test */
+ will_return_count(__wrap_strndup, false, 131);
+ will_return_count(__wrap_strdup, false, 65);
+ assert_int_equal(config_parse_new("../../tests/config_parser_test_4.conf", dummy_items), -EOVERFLOW);
+
+ /* lookup keys not present in config */
+ will_return_count(__wrap_strndup, false, 2);
+ will_return_count(__wrap_strdup, false, 1);
+ assert_int_equal(config_parse_new("../../tests/config_parser_test_3.conf", items), 0);
+ assert(str == NULL);
+ assert(b == false);
+ assert (i == 0);
+ assert(f == 100.0);
+ assert(bytes = 1);
+
+ /* positive test */
+ will_return_count(__wrap_strndup, false, 8);
+ will_return_count(__wrap_strdup, false, 7);
+ assert_int_equal(config_parse_new("../../tests/config_parser_test_5.conf", items), 0);
+ assert(str);
+ assert(!strcmp(str, "xD"));
+ assert(b == true);
+ assert(i == 123);
+ assert(fabsf(f - 1.23) < 1e-6);
+ assert(bytes == 10485760);
+}
+
static int test_setup(void **state)
{
will_return_maybe(__wrap_malloc, false);
cmocka_unit_test(test_register_notifier),
cmocka_unit_test(test_notify),
cmocka_unit_test(test_unregister_notifier),
-
+ cmocka_unit_test(test_config_parse),
+ cmocka_unit_test(test_config_parse_new),
};
return cmocka_run_group_tests(tests, test_setup, NULL);
}