blob: 30017b87c5aadcce0e28152a2ee6600341829c87 [file] [log] [blame]
Radek Krejciaaf6d402018-09-20 15:14:47 +02001/*
2 * @file hash_table.c
3 * @author: Radek Krejci <rkrejci@cesnet.cz>
4 * @brief unit tests for functions from hash_table.c
5 *
6 * Copyright (c) 2018 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14
15#define _BSD_SOURCE
16#define _DEFAULT_SOURCE
17
18#include "tests/config.h"
19#include "../../src/hash_table.c"
20
21#include <stdarg.h>
22#include <stddef.h>
23#include <setjmp.h>
24#include <cmocka.h>
25
26#include <string.h>
27#include <stdio.h>
28
29#include "libyang.h"
30
31#define BUFSIZE 1024
32char logbuf[BUFSIZE] = {0};
33
34/* set to 0 to printing error messages to stderr instead of checking them in code */
35#define ENABLE_LOGGER_CHECKING 1
36
37static void
38logger(LY_LOG_LEVEL level, const char *msg, const char *path)
39{
40 (void) level; /* unused */
41 (void) path; /* unused */
42
43 strncpy(logbuf, msg, BUFSIZE - 1);
44}
45
46static int
47logger_setup(void **state)
48{
49 (void) state; /* unused */
50#if ENABLE_LOGGER_CHECKING
51 ly_set_log_clb(logger, 0);
52#endif
53 return 0;
54}
55
56void
57logbuf_clean(void)
58{
59 logbuf[0] = '\0';
60}
61
62#if ENABLE_LOGGER_CHECKING
63# define logbuf_assert(str) assert_string_equal(logbuf, str)
64#else
65# define logbuf_assert(str)
66#endif
67
68static void
69test_invalid_arguments(void **state)
70{
71 (void) state; /* unused */
72 struct ly_ctx *ctx;
73
74 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx));
75
76 assert_null(lydict_insert(NULL, NULL, 0));
77 logbuf_assert("Invalid argument ctx (lydict_insert()).");
78
79 assert_null(lydict_insert_zc(NULL, NULL));
80 logbuf_assert("Invalid argument ctx (lydict_insert_zc()).");
81 logbuf_clean();
82 assert_null(lydict_insert_zc(ctx, NULL));
83 logbuf_assert("");
84
85 ly_ctx_destroy(ctx, NULL);
86}
87
88static void
89test_dict_hit(void **state)
90{
91 (void) state; /* unused */
92
93 const char *str1, *str2;
94 struct ly_ctx *ctx;
95
96 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx));
97
98 /* insert 2 strings, one of them repeatedly */
99 str1 = lydict_insert(ctx, "test1", 0);
100 assert_non_null(str1);
101 /* via zerocopy we have to get the same pointer as provided */
102 assert_non_null(str2 = strdup("test2"));
103 assert_true(str2 == lydict_insert_zc(ctx, (char *)str2));
104 /* here we get the same pointer as in case the string was inserted first time */
105 str2 = lydict_insert(ctx, "test1", 0);
106 assert_non_null(str2);
107 assert_ptr_equal(str1, str2);
108
109 /* remove strings, but the repeatedly inserted only once */
110 lydict_remove(ctx, "test1");
111 lydict_remove(ctx, "test2");
112
113 /* destroy dictionary - should raise warning about data presence */
114 ly_ctx_destroy(ctx, NULL);
115 logbuf_assert("String \"test1\" not freed from the dictionary, refcount 1");
116
117#ifndef NDEBUG
118 /* cleanup */
119 free((char*)str1);
120#endif
121}
122
123int main(void)
124{
125 const struct CMUnitTest tests[] = {
126 cmocka_unit_test_setup(test_invalid_arguments, logger_setup),
127 cmocka_unit_test_setup(test_dict_hit, logger_setup),
128 };
129
130 return cmocka_run_group_tests(tests, NULL, NULL);
131}