blob: bc4676a6f774bc0fbf15798c610322becc05d602 [file] [log] [blame]
/* SPDX-License-Identifier: BSD-2-Clause */
/***********************************************************************
* Copyright (c) 2017-2018, Intel Corporation
*
* All rights reserved.
***********************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <cmocka.h>
#include "util/key-value-parse.h"
/*
* Ensure that a simple key / value string is parsed into its component parts.
*/
static void
parse_key_value_simple_test (void **state)
{
bool ret;
char test_str[] = "key=value";
key_value_t key_value = KEY_VALUE_INIT;
ret = parse_key_value (test_str, &key_value);
assert_true (ret);
assert_string_equal (key_value.key, "key");
assert_string_equal (key_value.value, "value");
}
/*
* Ensure that a NULL key/value string causes parse_key_value to return false.
*/
static void
parse_key_value_NULL_string_test (void **state)
{
bool ret;
key_value_t key_value = KEY_VALUE_INIT;
ret = parse_key_value (NULL, &key_value);
assert_false (ret);
}
/*
* Ensure that a NULL key_value_t parameter causes parse_key_value to return
* false.
*/
static void
parse_key_value_NULL_key_value_test (void **state)
{
bool ret;
char test_str[] = "key=value";
ret = parse_key_value (test_str, NULL);
assert_false (ret);
}
/*
* Ensure that an incomplete key/value string with only the "key=" returns
* false.
*/
static void
parse_key_value_no_value_test (void **state)
{
bool ret;
char test_str[] = "key=";
key_value_t key_value = KEY_VALUE_INIT;
ret = parse_key_value (test_str, &key_value);
assert_false (ret);
}
/*
* Ensure that a key/value string with only the "=value" part returns false.
*/
static void
parse_key_value_no_key_test (void **state)
{
bool ret;
char test_str[] = "=value";
key_value_t key_value = KEY_VALUE_INIT;
ret = parse_key_value (test_str, &key_value);
assert_false (ret);
}
/*
* Ensure that a key/value string with the separators in the wrong place
* returns false.
*/
static void
parse_key_value_two_seps_test (void **state)
{
bool ret;
char test_str[] = "=foo=";
key_value_t key_value = KEY_VALUE_INIT;
ret = parse_key_value (test_str, &key_value);
assert_false (ret);
}
/*
* Ensure that a key/value string with all separators returns false.
*/
static void
parse_key_value_all_seps_test (void **state)
{
bool ret;
char test_str[] = "====";
key_value_t key_value = KEY_VALUE_INIT;
ret = parse_key_value (test_str, &key_value);
assert_false (ret);
}
/*
* Ensure that a key/value string that alternates strings and separators
* will parse the first two and ignore the rest.
*/
static void
parse_key_value_alt_seps_test (void **state)
{
bool ret;
char test_str[] = "key=value=key=value";
key_value_t key_value = KEY_VALUE_INIT;
ret = parse_key_value (test_str, &key_value);
assert_true (ret);
assert_string_equal (key_value.key, "key");
assert_string_equal (key_value.value, "value");
}
/*
* This is a simple data structure used to hold values parsed from a string
* of key/value pairs.
*/
#define TEST_DATA_INIT { \
.value0 = NULL, \
.value1 = NULL, \
}
typedef struct {
char *value0;
char *value1;
} test_data_t;
/*
* This is a callback function used to handle extracted key / value pairs.
*/
TSS2_RC
key_value_callback (const key_value_t *key_value,
void *user_data)
{
test_data_t *test_data = (test_data_t*)user_data;
if (strcmp ("key0", key_value->key) == 0) {
test_data->value0 = key_value->value;
return TSS2_RC_SUCCESS;
} else if (strcmp ("key1", key_value->key) == 0) {
test_data->value1 = key_value->value;
return TSS2_RC_SUCCESS;
} else {
return 1;
}
}
/*
* This tests the typical case for the parsing of a string of key / value
* pairs.
*/
static void
parse_key_value_string_good_test (void **state)
{
TSS2_RC rc;
char test_str[] = "key0=value0,key1=value1";
test_data_t test_data = TEST_DATA_INIT;
rc = parse_key_value_string (test_str, key_value_callback, &test_data);
assert_int_equal (rc, TSS2_RC_SUCCESS);
assert_string_equal (test_data.value0, "value0");
assert_string_equal (test_data.value1, "value1");
}
/*
* This test ensures that he parse_key_value_string function handles a failed
* call to parse a key/value pair properly.
*/
static void
parse_key_value_string_no_value_test (void **state)
{
TSS2_RC rc;
char test_str[] = "key0=,key1=value1";
test_data_t test_data = TEST_DATA_INIT;
rc = parse_key_value_string (test_str, key_value_callback, &test_data);
assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
}
/*
* This test ensures that the parse_key_value_string function handles a failed
* call to the user provided callback properly. The return value we get from
* the parse_key_value_string function is the same value returned by our
* callback.
*/
static void
parse_key_value_string_unknown_key_test (void **state)
{
TSS2_RC rc;
char test_str[] = "key0=foo=bar,baz=qux";
test_data_t test_data = TEST_DATA_INIT;
rc = parse_key_value_string (test_str, key_value_callback, &test_data);
assert_int_equal (rc, 1);
}
/*
* The following 3 tests ensures that NULL parameters produce an error.
*/
static void
parse_key_value_string_NULL_kv_string_test (void **state)
{
TSS2_RC rc;
test_data_t test_data = TEST_DATA_INIT;
rc = parse_key_value_string (NULL, key_value_callback, &test_data);
assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
}
static void
parse_key_value_string_NULL_callback_test (void **state)
{
TSS2_RC rc;
char test_str[] = "key0=foo=bar,baz=qux";
test_data_t test_data = TEST_DATA_INIT;
rc = parse_key_value_string (test_str, NULL, &test_data);
assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
}
static void
parse_key_value_string_NULL_user_data_test (void **state)
{
TSS2_RC rc;
char test_str[] = "key0=foo=bar,baz=qux";
rc = parse_key_value_string (test_str, key_value_callback, NULL);
assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
}
int
main(int argc, char* argv[])
{
const struct CMUnitTest tests[] = {
cmocka_unit_test (parse_key_value_simple_test),
cmocka_unit_test (parse_key_value_NULL_string_test),
cmocka_unit_test (parse_key_value_NULL_key_value_test),
cmocka_unit_test (parse_key_value_no_value_test),
cmocka_unit_test (parse_key_value_no_key_test),
cmocka_unit_test (parse_key_value_two_seps_test),
cmocka_unit_test (parse_key_value_all_seps_test),
cmocka_unit_test (parse_key_value_alt_seps_test),
cmocka_unit_test (parse_key_value_string_good_test),
cmocka_unit_test (parse_key_value_string_no_value_test),
cmocka_unit_test (parse_key_value_string_unknown_key_test),
cmocka_unit_test (parse_key_value_string_NULL_kv_string_test),
cmocka_unit_test (parse_key_value_string_NULL_callback_test),
cmocka_unit_test (parse_key_value_string_NULL_user_data_test),
};
return cmocka_run_group_tests (tests, NULL, NULL);
}