1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /***********************************************************************
3 * Copyright (c) 2017-2018, Intel Corporation
4 *
5 * All rights reserved.
6 ***********************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <stdbool.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16
17 #include <setjmp.h>
18 #include <cmocka.h>
19
20 #include "util/key-value-parse.h"
21
22 /*
23 * Ensure that a simple key / value string is parsed into its component parts.
24 */
25 static void
parse_key_value_simple_test(void ** state)26 parse_key_value_simple_test (void **state)
27 {
28 bool ret;
29 char test_str[] = "key=value";
30 key_value_t key_value = KEY_VALUE_INIT;
31
32 ret = parse_key_value (test_str, &key_value);
33 assert_true (ret);
34 assert_string_equal (key_value.key, "key");
35 assert_string_equal (key_value.value, "value");
36 }
37 /*
38 * Ensure that a NULL key/value string causes parse_key_value to return false.
39 */
40 static void
parse_key_value_NULL_string_test(void ** state)41 parse_key_value_NULL_string_test (void **state)
42 {
43 bool ret;
44 key_value_t key_value = KEY_VALUE_INIT;
45
46 ret = parse_key_value (NULL, &key_value);
47 assert_false (ret);
48 }
49 /*
50 * Ensure that a NULL key_value_t parameter causes parse_key_value to return
51 * false.
52 */
53 static void
parse_key_value_NULL_key_value_test(void ** state)54 parse_key_value_NULL_key_value_test (void **state)
55 {
56 bool ret;
57 char test_str[] = "key=value";
58
59 ret = parse_key_value (test_str, NULL);
60 assert_false (ret);
61 }
62 /*
63 * Ensure that an incomplete key/value string with only the "key=" returns
64 * false.
65 */
66 static void
parse_key_value_no_value_test(void ** state)67 parse_key_value_no_value_test (void **state)
68 {
69 bool ret;
70 char test_str[] = "key=";
71 key_value_t key_value = KEY_VALUE_INIT;
72
73 ret = parse_key_value (test_str, &key_value);
74 assert_false (ret);
75 }
76 /*
77 * Ensure that a key/value string with only the "=value" part returns false.
78 */
79 static void
parse_key_value_no_key_test(void ** state)80 parse_key_value_no_key_test (void **state)
81 {
82 bool ret;
83 char test_str[] = "=value";
84 key_value_t key_value = KEY_VALUE_INIT;
85
86 ret = parse_key_value (test_str, &key_value);
87 assert_false (ret);
88 }
89 /*
90 * Ensure that a key/value string with the separators in the wrong place
91 * returns false.
92 */
93 static void
parse_key_value_two_seps_test(void ** state)94 parse_key_value_two_seps_test (void **state)
95 {
96 bool ret;
97 char test_str[] = "=foo=";
98 key_value_t key_value = KEY_VALUE_INIT;
99
100 ret = parse_key_value (test_str, &key_value);
101 assert_false (ret);
102 }
103 /*
104 * Ensure that a key/value string with all separators returns false.
105 */
106 static void
parse_key_value_all_seps_test(void ** state)107 parse_key_value_all_seps_test (void **state)
108 {
109 bool ret;
110 char test_str[] = "====";
111 key_value_t key_value = KEY_VALUE_INIT;
112
113 ret = parse_key_value (test_str, &key_value);
114 assert_false (ret);
115 }
116 /*
117 * Ensure that a key/value string that alternates strings and separators
118 * will parse the first two and ignore the rest.
119 */
120 static void
parse_key_value_alt_seps_test(void ** state)121 parse_key_value_alt_seps_test (void **state)
122 {
123 bool ret;
124 char test_str[] = "key=value=key=value";
125 key_value_t key_value = KEY_VALUE_INIT;
126
127 ret = parse_key_value (test_str, &key_value);
128 assert_true (ret);
129 assert_string_equal (key_value.key, "key");
130 assert_string_equal (key_value.value, "value");
131 }
132 /*
133 * This is a simple data structure used to hold values parsed from a string
134 * of key/value pairs.
135 */
136 #define TEST_DATA_INIT { \
137 .value0 = NULL, \
138 .value1 = NULL, \
139 }
140 typedef struct {
141 char *value0;
142 char *value1;
143 } test_data_t;
144 /*
145 * This is a callback function used to handle extracted key / value pairs.
146 */
147 TSS2_RC
key_value_callback(const key_value_t * key_value,void * user_data)148 key_value_callback (const key_value_t *key_value,
149 void *user_data)
150 {
151 test_data_t *test_data = (test_data_t*)user_data;
152
153 if (strcmp ("key0", key_value->key) == 0) {
154 test_data->value0 = key_value->value;
155 return TSS2_RC_SUCCESS;
156 } else if (strcmp ("key1", key_value->key) == 0) {
157 test_data->value1 = key_value->value;
158 return TSS2_RC_SUCCESS;
159 } else {
160 return 1;
161 }
162 }
163 /*
164 * This tests the typical case for the parsing of a string of key / value
165 * pairs.
166 */
167 static void
parse_key_value_string_good_test(void ** state)168 parse_key_value_string_good_test (void **state)
169 {
170 TSS2_RC rc;
171 char test_str[] = "key0=value0,key1=value1";
172 test_data_t test_data = TEST_DATA_INIT;
173
174 rc = parse_key_value_string (test_str, key_value_callback, &test_data);
175 assert_int_equal (rc, TSS2_RC_SUCCESS);
176 assert_string_equal (test_data.value0, "value0");
177 assert_string_equal (test_data.value1, "value1");
178 }
179 /*
180 * This test ensures that he parse_key_value_string function handles a failed
181 * call to parse a key/value pair properly.
182 */
183 static void
parse_key_value_string_no_value_test(void ** state)184 parse_key_value_string_no_value_test (void **state)
185 {
186 TSS2_RC rc;
187 char test_str[] = "key0=,key1=value1";
188 test_data_t test_data = TEST_DATA_INIT;
189
190 rc = parse_key_value_string (test_str, key_value_callback, &test_data);
191 assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
192 }
193 /*
194 * This test ensures that the parse_key_value_string function handles a failed
195 * call to the user provided callback properly. The return value we get from
196 * the parse_key_value_string function is the same value returned by our
197 * callback.
198 */
199 static void
parse_key_value_string_unknown_key_test(void ** state)200 parse_key_value_string_unknown_key_test (void **state)
201 {
202 TSS2_RC rc;
203 char test_str[] = "key0=foo=bar,baz=qux";
204 test_data_t test_data = TEST_DATA_INIT;
205
206 rc = parse_key_value_string (test_str, key_value_callback, &test_data);
207 assert_int_equal (rc, 1);
208 }
209 /*
210 * The following 3 tests ensures that NULL parameters produce an error.
211 */
212 static void
parse_key_value_string_NULL_kv_string_test(void ** state)213 parse_key_value_string_NULL_kv_string_test (void **state)
214 {
215 TSS2_RC rc;
216 test_data_t test_data = TEST_DATA_INIT;
217
218 rc = parse_key_value_string (NULL, key_value_callback, &test_data);
219 assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
220 }
221 static void
parse_key_value_string_NULL_callback_test(void ** state)222 parse_key_value_string_NULL_callback_test (void **state)
223 {
224 TSS2_RC rc;
225 char test_str[] = "key0=foo=bar,baz=qux";
226 test_data_t test_data = TEST_DATA_INIT;
227
228 rc = parse_key_value_string (test_str, NULL, &test_data);
229 assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
230 }
231 static void
parse_key_value_string_NULL_user_data_test(void ** state)232 parse_key_value_string_NULL_user_data_test (void **state)
233 {
234 TSS2_RC rc;
235 char test_str[] = "key0=foo=bar,baz=qux";
236
237 rc = parse_key_value_string (test_str, key_value_callback, NULL);
238 assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
239 }
240
241 int
main(int argc,char * argv[])242 main(int argc, char* argv[])
243 {
244 const struct CMUnitTest tests[] = {
245 cmocka_unit_test (parse_key_value_simple_test),
246 cmocka_unit_test (parse_key_value_NULL_string_test),
247 cmocka_unit_test (parse_key_value_NULL_key_value_test),
248 cmocka_unit_test (parse_key_value_no_value_test),
249 cmocka_unit_test (parse_key_value_no_key_test),
250 cmocka_unit_test (parse_key_value_two_seps_test),
251 cmocka_unit_test (parse_key_value_all_seps_test),
252 cmocka_unit_test (parse_key_value_alt_seps_test),
253 cmocka_unit_test (parse_key_value_string_good_test),
254 cmocka_unit_test (parse_key_value_string_no_value_test),
255 cmocka_unit_test (parse_key_value_string_unknown_key_test),
256 cmocka_unit_test (parse_key_value_string_NULL_kv_string_test),
257 cmocka_unit_test (parse_key_value_string_NULL_callback_test),
258 cmocka_unit_test (parse_key_value_string_NULL_user_data_test),
259 };
260 return cmocka_run_group_tests (tests, NULL, NULL);
261 }
262