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