mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
16b616218c
unittests/uri_parser: Rework tests to be more verbose
668 lines
23 KiB
C
668 lines
23 KiB
C
/*
|
|
* Copyright (C) 2022 Bennet Blischke / HAW Hamburg
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @{
|
|
*
|
|
* @file
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
#include "container.h"
|
|
#include "embUnit.h"
|
|
|
|
#include "uri_parser.h"
|
|
|
|
#include "unittests-constants.h"
|
|
#include "tests-uri_parser.h"
|
|
|
|
typedef struct {
|
|
char *input_uri;
|
|
char *scheme;
|
|
char *userinfo;
|
|
char *host;
|
|
char *ipv6addr;
|
|
char *zoneid;
|
|
char *port_str;
|
|
uint16_t port;
|
|
char *path;
|
|
char *query;
|
|
} expected_uri_result_t;
|
|
|
|
static void _print_return_expectation(const char *uri, int expected, int observed)
|
|
{
|
|
printf("\nURI-Input: %s\n", uri);
|
|
printf("Expected return: %d\n", expected);
|
|
printf("Observed return: %d", observed);
|
|
}
|
|
|
|
/*
|
|
* The uri_parser returns a string-buffer (non zero terminated).
|
|
* This function compares a given string with a given uri_parser buffer + length.
|
|
* Additionally, it takes the original uri (from the test vector) and a name
|
|
* in order to print a precise and helpful error message if the buffer and string
|
|
* aren't identical.
|
|
*/
|
|
static int _compare_string_buffer(const char *name, const char *input_uri, const char *expected_str,
|
|
const char *actual_str, size_t actual_len)
|
|
{
|
|
if ((actual_len == strlen(expected_str)) &&
|
|
(strncmp(actual_str, expected_str, actual_len) == 0)) {
|
|
return 0;
|
|
}
|
|
printf(
|
|
"\nWith given input uri '%s', expected %s '%s' with length '%d' but got '%.*s' with length '%d'\n",
|
|
input_uri, name, expected_str, strlen(expected_str), actual_len, actual_str, actual_len);
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* Given a simple valid uri, this test checks that the parsing returns success
|
|
*/
|
|
static void _successful_parsing_of_valid_uri(void)
|
|
{
|
|
char *failure_msg = "Failure: The uri_parser failed to parse a correct and valid uri.";
|
|
int expected_ret = 0; /* Indicates a successful parsing */
|
|
|
|
char *simple_uri_1 = "coap://example.org/foo/bar";
|
|
char *simple_uri_2 = "ftp://riot-os.org/bar/foo";
|
|
char *simple_uri_3 = "ftp://riot-os.org:99/bar/foo";
|
|
char *simple_uri_4 = "http://riot-os.org:99/bar/foo";
|
|
char *simple_uri_5 = "https://riot-os.org/";
|
|
|
|
char *legacy_test_case_01 = "coap://RIOT:test@[fe80:db8::1%tap0]:5683/.well-known/core?v=1";
|
|
char *legacy_test_case_02 = "coap://[fe80::1]/foo%20bar";
|
|
char *legacy_test_case_03 = "/.well-known/core?v=1";
|
|
char *legacy_test_case_04 = "coap://R@[2001:db8::1]:5/v=1";
|
|
char *legacy_test_case_05 = "coap://R@[2001:db8::1]:5/:v=1";
|
|
char *legacy_test_case_06 = "cap://R@[2001:db8::1]:5/?v=1";
|
|
char *legacy_test_case_07 = "oap://Y2001:db8::1]:5/av=1";
|
|
char *legacy_test_case_08 = "//Rb[ʰ00J:d/5v=0";
|
|
char *legacy_test_case_09 = "coap:///R@[2008::1]:5own//R@[2008::1]:5own/?v=1";
|
|
char *legacy_test_case_10 = "coaP://R/RZ[2001[8:01[8::1]:5o:1]:5oTMv=1";
|
|
char *legacy_test_case_11 = "coap://R@////////////////7///v=1";
|
|
char *legacy_test_case_12 = "coa[:////[2001:db5ow:5own/Ov=1";
|
|
char *legacy_test_case_13 = "tel:+1-816-555-1212";
|
|
char *legacy_test_case_14 = "sms:+15105550101,+15105550102?body=hello%20there";
|
|
char *legacy_test_case_15 = "a";
|
|
char *legacy_test_case_16 = "mailto:test@example.com";
|
|
char *legacy_test_case_17 = "ftp://ftp.is.co.za/rfc/rfc1808.txt";
|
|
char *legacy_test_case_18 = "http://www.ietf.org/rfc/rfc2396.txt";
|
|
char *legacy_test_case_19 = "ldap://[2001:db8::7]/c=GB?objectClass?one";
|
|
char *legacy_test_case_20 = "mailto:John.Doe@example.com";
|
|
char *legacy_test_case_21 = "news:comp.infosystems.www.servers.unix";
|
|
char *legacy_test_case_22 = "tel:+1-816-555-1212";
|
|
char *legacy_test_case_23 = "telnet://192.0.2.16:80/";
|
|
char *legacy_test_case_24 = "urn:oasis:names:specification:docbook:dtd:xml:4.1.2";
|
|
char *legacy_test_case_25 = "/";
|
|
char *legacy_test_case_26 = "./this:that";
|
|
char *legacy_test_case_27 = "pP://";
|
|
char *legacy_test_case_28 = "A://@";
|
|
|
|
char *test_vec[] = {
|
|
simple_uri_1,
|
|
simple_uri_2,
|
|
simple_uri_3,
|
|
simple_uri_4,
|
|
simple_uri_5,
|
|
legacy_test_case_01,
|
|
legacy_test_case_02,
|
|
legacy_test_case_03,
|
|
legacy_test_case_04,
|
|
legacy_test_case_05,
|
|
legacy_test_case_06,
|
|
legacy_test_case_07,
|
|
legacy_test_case_08,
|
|
legacy_test_case_09,
|
|
legacy_test_case_10,
|
|
legacy_test_case_11,
|
|
legacy_test_case_12,
|
|
legacy_test_case_13,
|
|
legacy_test_case_14,
|
|
legacy_test_case_15,
|
|
legacy_test_case_16,
|
|
legacy_test_case_17,
|
|
legacy_test_case_18,
|
|
legacy_test_case_19,
|
|
legacy_test_case_20,
|
|
legacy_test_case_21,
|
|
legacy_test_case_22,
|
|
legacy_test_case_23,
|
|
legacy_test_case_24,
|
|
legacy_test_case_25,
|
|
legacy_test_case_26,
|
|
legacy_test_case_27,
|
|
legacy_test_case_28,
|
|
};
|
|
|
|
uri_parser_result_t uri_res;
|
|
int ret = 0;
|
|
|
|
for (unsigned int i = 0; i < ARRAY_SIZE(test_vec); ++i) {
|
|
ret = uri_parser_process_string(&uri_res, test_vec[i]);
|
|
if (ret != expected_ret) {
|
|
_print_return_expectation(test_vec[i], expected_ret, ret);
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Given a simple invalid uri, this test checks that the parsing returns an error
|
|
*/
|
|
static void _successful_rejecting_of_invalid_uri(void)
|
|
{
|
|
char *failure_msg = "Failure: The uri_parser failed to reject an invalid uri.";
|
|
int expected_ret = -1; /* Indicates an invalid uri */
|
|
|
|
char *trailing_percent = "coap://RIOT:test@[fe80:db8::1%]:5683/.well-known/core?v=1";
|
|
char *invalid_port = "coap://R@[2001:db8::1]:5own/v=1";
|
|
char *invalid_port_colon = "coap://R@[2001:db8::1]:5own/:v=1";
|
|
char *invalid_port_short_scheme = "cap://R@[2001:db8::1]:5own/?v=1";
|
|
char *invalid_host = "oap://Y2001:db8::1]:5own/av=1";
|
|
char *double_scheme = "coap://oap://P@[2001:b";
|
|
char *empty_input = "";
|
|
char *port_too_long = "coap://example.com:1234568910";
|
|
char *white_space_in_port = "coap://example.com: 12/foo";
|
|
char *hex_port = "coap://example.com:0x12/foo";
|
|
|
|
char *test_vec[] = {
|
|
trailing_percent,
|
|
invalid_port,
|
|
invalid_port_colon,
|
|
invalid_port_short_scheme,
|
|
invalid_host,
|
|
double_scheme,
|
|
empty_input,
|
|
port_too_long,
|
|
white_space_in_port,
|
|
hex_port,
|
|
};
|
|
|
|
uri_parser_result_t uri_res;
|
|
int ret = 0;
|
|
|
|
for (unsigned int i = 0; i < ARRAY_SIZE(test_vec); ++i) {
|
|
ret = uri_parser_process_string(&uri_res, test_vec[i]);
|
|
if (ret != expected_ret) {
|
|
_print_return_expectation(test_vec[i], expected_ret, ret);
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* This test checks if the uri_parser returns an error if the port length
|
|
* (as a string) is invalid, that is, longer than 5 characters.
|
|
* This differs from the RFC, where the port in an uri can be zero to infinite
|
|
* number of characters long; ABNF: *DIGIT
|
|
*/
|
|
static void _error_if_port_str_is_too_long(void)
|
|
{
|
|
char *failure_msg = "Failure: The uri_parser did not detect an invalid port-length as invalid.";
|
|
int expected_ret = -1; /* Indicates an invalid uri */
|
|
|
|
char *leading_zeroes_arent_ignored = "https://example.org:000456/foo/bar";
|
|
char *too_many_digits = "https://example.org:123456/foo/bar";
|
|
char *too_much_whitespace = "https://example.org: 23456/foo/bar";
|
|
|
|
char *test_vec[] = {
|
|
too_many_digits,
|
|
leading_zeroes_arent_ignored,
|
|
too_much_whitespace,
|
|
};
|
|
|
|
uri_parser_result_t uri_res;
|
|
int ret = 0;
|
|
|
|
for (unsigned int i = 0; i < ARRAY_SIZE(test_vec); ++i) {
|
|
ret = uri_parser_process_string(&uri_res, test_vec[i]);
|
|
if (ret != expected_ret) {
|
|
_print_return_expectation(test_vec[i], expected_ret, ret);
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* This test checks if the uri_parser returns an error if the port
|
|
* (as a string) is invalid, that is, containing illegal characters
|
|
*/
|
|
static void _error_if_port_str_contains_illegal_characters(void)
|
|
{
|
|
char *failure_msg = "Failure: The uri_parser did not detect an invalid port-string as invalid.";
|
|
int expected_ret = -1; /* Indicates an invalid uri */
|
|
|
|
char *letters_within_a_number = "https://example.org:12ff34/foo/bar";
|
|
char *hex_number_as_port = "https://example.org:0x1234/foo/bar";
|
|
char *bin_number_as_port = "https://example.org:0b1010/foo/bar";
|
|
char *negativ_port = "https://example.org:-12/foo/bar";
|
|
char *whitespace_within_port = "https://example.org:12 34/foo/bar";
|
|
char *bigger_than_max_port = "https://example.org:65536/foo/bar";
|
|
|
|
char *test_vec[] = {
|
|
letters_within_a_number,
|
|
hex_number_as_port,
|
|
bin_number_as_port,
|
|
negativ_port,
|
|
whitespace_within_port,
|
|
bigger_than_max_port
|
|
};
|
|
|
|
uri_parser_result_t uri_res;
|
|
int ret = 0;
|
|
|
|
for (unsigned int i = 0; i < ARRAY_SIZE(test_vec); ++i) {
|
|
ret = uri_parser_process_string(&uri_res, test_vec[i]);
|
|
if (ret != expected_ret) {
|
|
_print_return_expectation(test_vec[i], expected_ret, ret);
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Given a uri which contains a scheme, this test checks that the
|
|
* uri_parser can isolate that scheme successful.
|
|
*/
|
|
static void _result_component_scheme_matches_input_scheme(void)
|
|
{
|
|
char *failure_msg = "Failure: The uri_parser did not parse the scheme correctly.";
|
|
int expected_ret = 0;
|
|
|
|
expected_uri_result_t very_long_scheme = {
|
|
.input_uri = "wowlongcoap://example.org/foo/bar",
|
|
.scheme = "wowlongcoap",
|
|
};
|
|
expected_uri_result_t normal_scheme = {
|
|
.input_uri = "coap://example.org/foo/bar",
|
|
.scheme = "coap",
|
|
};
|
|
expected_uri_result_t short_scheme = {
|
|
.input_uri = "a://example.org/foo/bar",
|
|
.scheme = "a",
|
|
};
|
|
expected_uri_result_t digit_scheme = {
|
|
.input_uri = "a1b2://example.org/foo/bar",
|
|
.scheme = "a1b2",
|
|
};
|
|
|
|
expected_uri_result_t *test_vec[] = {
|
|
&very_long_scheme,
|
|
&normal_scheme,
|
|
&short_scheme,
|
|
&digit_scheme,
|
|
};
|
|
|
|
uri_parser_result_t uri_res;
|
|
int ret = 0;
|
|
|
|
for (unsigned int i = 0; i < ARRAY_SIZE(test_vec); ++i) {
|
|
ret = uri_parser_process_string(&uri_res, test_vec[i]->input_uri);
|
|
if (ret != expected_ret) {
|
|
/* if the uri_parser return indicates an error, this test fails */
|
|
_print_return_expectation(test_vec[i]->input_uri, expected_ret, ret);
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
else {
|
|
/* if the uri_parser return indicates success
|
|
* the length of the schemes must match.
|
|
* we can't use strlen on the result scheme as it is not null terminated,
|
|
* but the uri_parser provides the length separately*/
|
|
if (uri_res.scheme_len != strlen(test_vec[i]->scheme)) {
|
|
printf(
|
|
"With given input uri '%s', expected a scheme with the length '%d' but got '%d'\n",
|
|
test_vec[i]->input_uri, strlen(test_vec[i]->scheme), uri_res.scheme_len);
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
else {
|
|
/* If the schemes have the same length, they also should look identical */
|
|
if (strncmp(uri_res.scheme, test_vec[i]->scheme, uri_res.scheme_len) != 0) {
|
|
printf("With given input uri '%s', expected scheme '%s' but got '%.*s'\n",
|
|
test_vec[i]->input_uri, test_vec[i]->scheme, uri_res.scheme_len,
|
|
uri_res.scheme);
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Given a valid uri, this test checks that the
|
|
* uri_parser can isolate all parts of it successfully.
|
|
*/
|
|
static void _result_components_matches_input(void)
|
|
{
|
|
char *failure_msg = "Failure: The uri_parser did not parse the uri correctly.";
|
|
int expected_ret = 0;
|
|
|
|
expected_uri_result_t uri_0 = {
|
|
.input_uri = "coap://example.org/foo/bar",
|
|
.scheme = "coap",
|
|
.userinfo = "", /* This is an empty string because no userinfo has been set in this uri */
|
|
.host = "example.org",
|
|
.ipv6addr = "", /* This is an empty string because a hostname was used instead in this uri */
|
|
.zoneid = "", /* Not applicable without ipv6 */
|
|
.port_str = "", /* This is an empty string because no port has been set in this uri */
|
|
.port = 0, /* Remains zero when no port is given */
|
|
.path = "/foo/bar",
|
|
.query = "" /* This is an empty string because no query is present in this uri */
|
|
};
|
|
expected_uri_result_t uri_trailing_slash = {
|
|
.input_uri = "coap://example.org/",
|
|
.scheme = "coap",
|
|
.userinfo = "",
|
|
.host = "example.org",
|
|
.ipv6addr = "",
|
|
.zoneid = "",
|
|
.port_str = "",
|
|
.port = 0,
|
|
.path = "/",
|
|
.query = ""
|
|
};
|
|
expected_uri_result_t uri_without_trailing_slash = {
|
|
.input_uri = "coap://example.org",
|
|
.scheme = "coap",
|
|
.userinfo = "",
|
|
.host = "example.org",
|
|
.ipv6addr = "",
|
|
.zoneid = "",
|
|
.port_str = "",
|
|
.port = 0,
|
|
.path = "",
|
|
.query = ""
|
|
};
|
|
expected_uri_result_t uri_with_userinfo = {
|
|
.input_uri = "coap://user@example.org",
|
|
.scheme = "coap",
|
|
.userinfo = "user",
|
|
.host = "example.org",
|
|
.ipv6addr = "",
|
|
.zoneid = "",
|
|
.port_str = "",
|
|
.port = 0,
|
|
.path = "",
|
|
.query = ""
|
|
};
|
|
expected_uri_result_t uri_with_ipv6 = {
|
|
.input_uri = "coap://user@[2001:db8::1]",
|
|
.scheme = "coap",
|
|
.userinfo = "user",
|
|
.host = "[2001:db8::1]",
|
|
.ipv6addr = "2001:db8::1",
|
|
.zoneid = "",
|
|
.port_str = "",
|
|
.port = 0,
|
|
.path = "",
|
|
.query = ""
|
|
};
|
|
expected_uri_result_t uri_with_ipv6_and_port = {
|
|
.input_uri = "coap://user@[2001:db8::1]:12345",
|
|
.scheme = "coap",
|
|
.userinfo = "user",
|
|
.host = "[2001:db8::1]",
|
|
.ipv6addr = "2001:db8::1",
|
|
.zoneid = "",
|
|
.port_str = "12345",
|
|
.port = 12345,
|
|
.path = "",
|
|
.query = ""
|
|
};
|
|
expected_uri_result_t uri_with_ipv6_and_port_and_zoneid = {
|
|
.input_uri = "coap://user@[2001:db8::1%eth0]:12345",
|
|
.scheme = "coap",
|
|
.userinfo = "user",
|
|
.host = "[2001:db8::1%eth0]",
|
|
.ipv6addr = "2001:db8::1",
|
|
.zoneid = "eth0",
|
|
.port_str = "12345",
|
|
.port = 12345,
|
|
.path = "",
|
|
.query = ""
|
|
};
|
|
|
|
expected_uri_result_t *test_vec[] = {
|
|
&uri_0,
|
|
&uri_trailing_slash,
|
|
&uri_without_trailing_slash,
|
|
&uri_with_userinfo,
|
|
&uri_with_ipv6,
|
|
&uri_with_ipv6_and_port,
|
|
&uri_with_ipv6_and_port_and_zoneid,
|
|
};
|
|
|
|
uri_parser_result_t uri_res;
|
|
int ret = 0;
|
|
|
|
for (unsigned int i = 0; i < ARRAY_SIZE(test_vec); ++i) {
|
|
expected_uri_result_t *this_vec = test_vec[i];
|
|
|
|
ret = uri_parser_process_string(&uri_res, this_vec->input_uri);
|
|
if (ret != expected_ret) {
|
|
/* if the uri_parser return indicates an error, this test fails */
|
|
_print_return_expectation(this_vec->input_uri, expected_ret, ret);
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
else {
|
|
/* if the uri_parser return indicates success */
|
|
if (_compare_string_buffer("scheme", this_vec->input_uri, this_vec->scheme,
|
|
uri_res.scheme, uri_res.scheme_len) != 0) {
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
if (_compare_string_buffer("userinfo", this_vec->input_uri, this_vec->userinfo,
|
|
uri_res.userinfo, uri_res.userinfo_len) != 0) {
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
if (_compare_string_buffer("host", this_vec->input_uri, this_vec->host, uri_res.host,
|
|
uri_res.host_len) != 0) {
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
if (_compare_string_buffer("ipv6addr", this_vec->input_uri, this_vec->ipv6addr,
|
|
uri_res.ipv6addr, uri_res.ipv6addr_len) != 0) {
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
if (_compare_string_buffer("zoneid", this_vec->input_uri, this_vec->zoneid,
|
|
uri_res.zoneid, uri_res.zoneid_len) != 0) {
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
if (_compare_string_buffer("port_str", this_vec->input_uri, this_vec->port_str,
|
|
uri_res.port_str, uri_res.port_str_len) != 0) {
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
if (_compare_string_buffer("path", this_vec->input_uri, this_vec->path, uri_res.path,
|
|
uri_res.path_len) != 0) {
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
if (_compare_string_buffer("query", this_vec->input_uri, this_vec->query, uri_res.query,
|
|
uri_res.query_len) != 0) {
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void test_uri_parser__unterminated_string(void)
|
|
{
|
|
char *failure_msg =
|
|
"Failure: The uri_parser did not parse an unterminated uri string correctly.";
|
|
expected_uri_result_t this_vec = {
|
|
.input_uri = "coap://RIOT:test@[fe80:db8::1%eth2]:5683/.well-known/core?v=1",
|
|
.scheme = "coap",
|
|
.userinfo = "RIOT:test",
|
|
.host = "[fe80:db8::1%eth2]",
|
|
.ipv6addr = "fe80:db8::1",
|
|
.zoneid = "eth2",
|
|
.port_str = "5683",
|
|
.port = 5683,
|
|
.path = "/.well-known/core",
|
|
.query = "v=1"
|
|
};
|
|
|
|
uri_parser_result_t ures;
|
|
char uri[64];
|
|
|
|
/* initialize with a non-null character */
|
|
memset(uri, 'Z', sizeof(uri));
|
|
|
|
memcpy(uri, this_vec.input_uri, strlen(this_vec.input_uri));
|
|
|
|
int res = uri_parser_process(&ures, uri, strlen(this_vec.input_uri));
|
|
|
|
TEST_ASSERT_EQUAL_INT(0, res);
|
|
|
|
if (_compare_string_buffer("userinfo", this_vec.input_uri, this_vec.userinfo, ures.userinfo,
|
|
ures.userinfo_len) != 0) {
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
if (_compare_string_buffer("host", this_vec.input_uri, this_vec.host, ures.host,
|
|
ures.host_len) != 0) {
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
if (_compare_string_buffer("ipv6addr", this_vec.input_uri, this_vec.ipv6addr, ures.ipv6addr,
|
|
ures.ipv6addr_len) != 0) {
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
if (_compare_string_buffer("zoneid", this_vec.input_uri, this_vec.zoneid, ures.zoneid,
|
|
ures.zoneid_len) != 0) {
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
if (_compare_string_buffer("port_str", this_vec.input_uri, this_vec.port_str, ures.port_str,
|
|
ures.port_str_len) != 0) {
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
if (_compare_string_buffer("path", this_vec.input_uri, this_vec.path, ures.path,
|
|
ures.path_len) != 0) {
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
if (_compare_string_buffer("query", this_vec.input_uri, this_vec.query, ures.query,
|
|
ures.query_len) != 0) {
|
|
TEST_FAIL(failure_msg);
|
|
}
|
|
}
|
|
|
|
|
|
Test *tests_uri_parser_tests(void)
|
|
{
|
|
EMB_UNIT_TESTFIXTURES(fixtures) {
|
|
new_TestFixture(_successful_parsing_of_valid_uri),
|
|
new_TestFixture(_successful_rejecting_of_invalid_uri),
|
|
new_TestFixture(_error_if_port_str_is_too_long),
|
|
new_TestFixture(_error_if_port_str_contains_illegal_characters),
|
|
new_TestFixture(_result_component_scheme_matches_input_scheme),
|
|
new_TestFixture(_result_components_matches_input),
|
|
new_TestFixture(test_uri_parser__unterminated_string),
|
|
};
|
|
|
|
EMB_UNIT_TESTCALLER(uri_parser_tests, NULL, NULL, fixtures);
|
|
|
|
return (Test *)&uri_parser_tests;
|
|
}
|
|
|
|
#define PARAMS_NUMOF (4U)
|
|
#define INIT_URI_RESULTS(q) \
|
|
_uri_results.query = (q); \
|
|
_uri_results.query_len = sizeof(q) - 1
|
|
#define TEST_ASSERT_PARAM(exp, idx, comp) \
|
|
TEST_ASSERT_EQUAL_INT(sizeof(exp) - 1, _params[idx].comp ## _len); \
|
|
TEST_ASSERT_MESSAGE(!strncmp(exp, _params[idx].comp, _params[idx].comp ## _len), \
|
|
#comp " was not " exp);
|
|
|
|
static uri_parser_query_param_t _params[4U];
|
|
static uri_parser_result_t _uri_results;
|
|
|
|
static void _setup_query(void)
|
|
{
|
|
memset(_params, 0, sizeof(_params));
|
|
memset(&_uri_results, 0, sizeof(_uri_results));
|
|
}
|
|
|
|
static void test_split_query__broken_input(void)
|
|
{
|
|
int res;
|
|
|
|
INIT_URI_RESULTS("&");
|
|
res = uri_parser_split_query(&_uri_results, _params, ARRAY_SIZE(_params));
|
|
TEST_ASSERT_EQUAL_INT(-1, res);
|
|
|
|
INIT_URI_RESULTS("=&");
|
|
res = uri_parser_split_query(&_uri_results, _params, ARRAY_SIZE(_params));
|
|
TEST_ASSERT_EQUAL_INT(-1, res);
|
|
|
|
INIT_URI_RESULTS("=&&");
|
|
res = uri_parser_split_query(&_uri_results, _params, ARRAY_SIZE(_params));
|
|
TEST_ASSERT_EQUAL_INT(-1, res);
|
|
|
|
INIT_URI_RESULTS("==");
|
|
res = uri_parser_split_query(&_uri_results, _params, ARRAY_SIZE(_params));
|
|
TEST_ASSERT_EQUAL_INT(-1, res);
|
|
|
|
INIT_URI_RESULTS("key=value&name=value=another");
|
|
res = uri_parser_split_query(&_uri_results, _params, ARRAY_SIZE(_params));
|
|
TEST_ASSERT_EQUAL_INT(-1, res);
|
|
}
|
|
|
|
void test_split_query__truncated(void)
|
|
{
|
|
int res;
|
|
|
|
INIT_URI_RESULTS("this=0&is=1&a=very&long=3&query=foo");
|
|
TEST_ASSERT_EQUAL_INT(4, ARRAY_SIZE(_params));
|
|
res = uri_parser_split_query(&_uri_results, _params, ARRAY_SIZE(_params));
|
|
TEST_ASSERT_EQUAL_INT(-2, res);
|
|
TEST_ASSERT_PARAM("this", 0, name);
|
|
TEST_ASSERT_PARAM("0", 0, value);
|
|
TEST_ASSERT_PARAM("is", 1, name);
|
|
TEST_ASSERT_PARAM("1", 1, value);
|
|
TEST_ASSERT_PARAM("a", 2, name);
|
|
TEST_ASSERT_PARAM("very", 2, value);
|
|
TEST_ASSERT_PARAM("long", 3, name);
|
|
TEST_ASSERT_PARAM("3", 3, value);
|
|
}
|
|
|
|
void test_split_query__success(void)
|
|
{
|
|
int res;
|
|
|
|
INIT_URI_RESULTS("foo=&=&bar=1");
|
|
res = uri_parser_split_query(&_uri_results, _params, ARRAY_SIZE(_params));
|
|
TEST_ASSERT_EQUAL_INT(3, res);
|
|
TEST_ASSERT_PARAM("foo", 0, name);
|
|
TEST_ASSERT_PARAM("", 0, value);
|
|
TEST_ASSERT_PARAM("", 1, name);
|
|
TEST_ASSERT_PARAM("", 1, value);
|
|
TEST_ASSERT_PARAM("bar", 2, name);
|
|
TEST_ASSERT_PARAM("1", 2, value);
|
|
TEST_ASSERT_EQUAL_INT(0, _params[3].name_len);
|
|
TEST_ASSERT_NULL(_params[3].name);
|
|
TEST_ASSERT_EQUAL_INT(0, _params[3].value_len);
|
|
TEST_ASSERT_NULL(_params[3].value);
|
|
}
|
|
|
|
Test *tests_query_split_tests(void)
|
|
{
|
|
EMB_UNIT_TESTFIXTURES(fixtures) {
|
|
new_TestFixture(test_split_query__broken_input),
|
|
new_TestFixture(test_split_query__truncated),
|
|
new_TestFixture(test_split_query__success),
|
|
};
|
|
|
|
EMB_UNIT_TESTCALLER(query_split_tests, _setup_query, NULL, fixtures);
|
|
|
|
return (Test *)&query_split_tests;
|
|
}
|
|
|
|
void tests_uri_parser(void)
|
|
{
|
|
TESTS_RUN(tests_uri_parser_tests());
|
|
TESTS_RUN(tests_query_split_tests());
|
|
}
|
|
/** @} */
|