• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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