/* libcoap unit tests * * Copyright (C) 2012,2015 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see * README for terms of use. */ #include "coap_config.h" #include "test_uri.h" #include #include static void t_parse_uri1(void) { char teststr[] = "coap://[::1]/.well-known/core"; int result; coap_uri_t uri; result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri); if (result == 0) { CU_ASSERT(uri.host.length == 3); CU_ASSERT_NSTRING_EQUAL(uri.host.s, "::1", 3); CU_ASSERT(uri.port == COAP_DEFAULT_PORT); CU_ASSERT(uri.path.length == 16); CU_ASSERT_NSTRING_EQUAL(uri.path.s, ".well-known/core", 16); CU_ASSERT(uri.query.length == 0); CU_ASSERT(uri.query.s == NULL); } else { CU_FAIL("uri parser error"); } } static void t_parse_uri2(void) { char teststr[] = "coap://[::1]:8000/.well-known/core"; int result; coap_uri_t uri; result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri); if (result == 0) { CU_ASSERT(uri.host.length == 3); CU_ASSERT_NSTRING_EQUAL(uri.host.s, "::1", 3); CU_ASSERT(uri.port == 8000); CU_ASSERT(uri.path.length == 16); CU_ASSERT_NSTRING_EQUAL(uri.path.s, ".well-known/core", 16); CU_ASSERT(uri.query.length == 0); CU_ASSERT(uri.query.s == NULL); } else { CU_FAIL("uri parser error"); } } static void t_parse_uri3(void) { char teststr[] = "coap://localhost/?foo&bla=fasel"; int result; coap_uri_t uri; result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri); if (result == 0) { CU_ASSERT(uri.host.length == 9); CU_ASSERT_NSTRING_EQUAL(uri.host.s, "localhost", 9); CU_ASSERT(uri.port == COAP_DEFAULT_PORT); CU_ASSERT(uri.path.length == 0); CU_ASSERT(uri.query.length == 13); CU_ASSERT_NSTRING_EQUAL(uri.query.s, "foo&bla=fasel", 13); } else { CU_FAIL("uri parser error"); } } static void t_parse_uri4(void) { char teststr[] = "coap://:100000"; int result; coap_uri_t uri; result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri); CU_ASSERT(result < 0); } static void t_parse_uri5(void) { char teststr[] = "coap://foo:100000"; int result; coap_uri_t uri; result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri); if (result == 0) { CU_ASSERT(uri.host.length == 3); CU_ASSERT_NSTRING_EQUAL(uri.host.s, "foo", 3); CU_ASSERT(uri.path.length == 0); CU_ASSERT(uri.path.s == NULL); CU_ASSERT(uri.query.length == 0); CU_ASSERT(uri.query.s == NULL); CU_FAIL("invalid port not detected"); } else { CU_PASS("detected invalid port"); } } static void t_parse_uri6(void) { char teststr[] = "coap://134.102.218.2/.well-known/core"; int result; coap_uri_t uri; result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri); if (result == 0) { CU_ASSERT(uri.host.length == 13); CU_ASSERT_NSTRING_EQUAL(uri.host.s, "134.102.218.2", 13); CU_ASSERT(uri.port == COAP_DEFAULT_PORT); CU_ASSERT(uri.path.length == 16); CU_ASSERT_NSTRING_EQUAL(uri.path.s, ".well-known/core", 16); CU_ASSERT(uri.query.length == 0); CU_ASSERT(uri.query.s == NULL); } else { CU_FAIL("uri parser error"); } } static void t_parse_uri7(void) { char teststr[] = "coap://foo.bar:5683/some_resource/with/multiple/segments"; int result; coap_uri_t uri; unsigned char buf[40]; size_t buflen = sizeof(buf); /* The list of path segments to check against. Each segment is preceded by a dummy option indicating that holds the (dummy) delta value 0 and the actual segment length. */ const unsigned char checkbuf[] = { 0x0d, 0x00, 's', 'o', 'm', 'e', '_', 'r', 'e', 's', 'o', 'u', 'r', 'c', 'e', 0x04, 'w', 'i', 't', 'h', 0x08, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 0x08, 's', 'e', 'g', 'm', 'e', 'n', 't', 's' }; result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri); if (result == 0) { CU_ASSERT(uri.host.length == 7); CU_ASSERT_NSTRING_EQUAL(uri.host.s, "foo.bar", 7); CU_ASSERT(uri.port == 5683); CU_ASSERT(uri.path.length == 36); CU_ASSERT_NSTRING_EQUAL(uri.path.s, "some_resource/with/multiple/segments", 36); CU_ASSERT(uri.query.length == 0); CU_ASSERT(uri.query.s == NULL); /* check path segments */ result = coap_split_path(uri.path.s, uri.path.length, buf, &buflen); CU_ASSERT(result == 4); CU_ASSERT(buflen == sizeof(checkbuf)); CU_ASSERT_NSTRING_EQUAL(buf, checkbuf, buflen); } else { CU_FAIL("uri parser error"); } } static void t_parse_uri8(void) { char teststr[] = "http://example.com/%7E%AB%13"; int result; coap_uri_t uri; result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri); if (result < 0) { CU_PASS("detected non-coap URI"); } else { CU_FAIL("non-coap URI not recognized"); } } static void t_parse_uri9(void) { char teststr[] = "http://example.com/%x"; int result; coap_uri_t uri; result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri); if (result < 0) { CU_PASS("detected non-coap URI"); } else { CU_FAIL("non-coap URI not recognized"); } } static void t_parse_uri10(void) { char teststr[] = "/absolute/path"; int result; coap_uri_t uri; result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri); if (result == 0) { CU_ASSERT(uri.host.length == 0); CU_ASSERT(uri.host.s == NULL); CU_ASSERT(uri.port == COAP_DEFAULT_PORT); CU_ASSERT(uri.path.length == 13); CU_ASSERT_NSTRING_EQUAL(uri.path.s, "absolute/path", 13); CU_ASSERT(uri.query.length == 0); CU_ASSERT(uri.query.s == NULL); } else { CU_FAIL("uri parser error"); } } static void t_parse_uri11(void) { char teststr[] = "coap://xn--18j4d.example/%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF"; int result; coap_uri_t uri; unsigned char buf[40]; size_t buflen = sizeof(buf); /* The list of path segments to check against. Each segment is preceded by a dummy option indicating that holds the (dummy) delta value 0 and the actual segment length. */ const unsigned char checkbuf[] = { 0x0d, 0x02, 0xE3, 0x81, 0x93, 0xE3, 0x82, 0x93, 0xE3, 0x81, 0xAB, 0xE3, 0x81, 0xA1, 0xE3, 0x81, 0xAF }; result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri); if (result == 0) { CU_ASSERT(uri.host.length == 17); CU_ASSERT_NSTRING_EQUAL(uri.host.s, "xn--18j4d.example", 17); CU_ASSERT(uri.port == COAP_DEFAULT_PORT); CU_ASSERT(uri.path.length == 45); CU_ASSERT_NSTRING_EQUAL(uri.path.s, "%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF", 45); CU_ASSERT(uri.query.length == 0); CU_ASSERT(uri.query.s == NULL); /* check path segments */ result = coap_split_path(uri.path.s, uri.path.length, buf, &buflen); CU_ASSERT(result == 1); CU_ASSERT(buflen == sizeof(checkbuf)); CU_ASSERT_NSTRING_EQUAL(buf, checkbuf, buflen); } else { CU_FAIL("uri parser error"); } } static void t_parse_uri12(void) { char teststr[] = "coap://198.51.100.1:61616//%2F//?%2F%2F&?%26"; int result; coap_uri_t uri; unsigned char buf[40]; size_t buflen = sizeof(buf); /* The list of path segments to check against. Each segment is preceded by a dummy option indicating that holds the (dummy) delta value 0 and the actual segment length. */ const unsigned char uricheckbuf[] = { 0x00, 0x01, 0x2f, 0x00, 0x00 }; const unsigned char querycheckbuf[] = { 0x02, 0x2f, 0x2f, 0x02, 0x3f, 0x26 }; result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri); if (result == 0) { CU_ASSERT(uri.host.length == 12); CU_ASSERT_NSTRING_EQUAL(uri.host.s, "198.51.100.1", 12); CU_ASSERT(uri.port == 61616); CU_ASSERT(uri.path.length == 6); CU_ASSERT_NSTRING_EQUAL(uri.path.s, "/%2F//", 6); CU_ASSERT(uri.query.length == 11); CU_ASSERT_NSTRING_EQUAL(uri.query.s, "%2F%2F&?%26", 11); /* check path segments */ result = coap_split_path(uri.path.s, uri.path.length, buf, &buflen); CU_ASSERT(result == 4); CU_ASSERT(buflen == sizeof(uricheckbuf)); CU_ASSERT_NSTRING_EQUAL(buf, uricheckbuf, buflen); /* check query segments */ buflen = sizeof(buf); result = coap_split_query(uri.query.s, uri.query.length, buf, &buflen); CU_ASSERT(result == 2); CU_ASSERT(buflen == sizeof(querycheckbuf)); CU_ASSERT_NSTRING_EQUAL(buf, querycheckbuf, buflen); } else { CU_FAIL("uri parser error"); } } static void t_parse_uri13(void) { uint8_t teststr[] __attribute__ ((aligned (8))) = { 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 'f', 'o', 'o', 0x3b, '.', 'w', 'e', 'l', 'l', '-', 'k', 'n', 'o', 'w', 'n', 0x04, 'c', 'o', 'r', 'e' }; coap_pdu_t pdu = { .max_size = sizeof(teststr), .hdr = (coap_hdr_t *)teststr, .length = sizeof(teststr) }; coap_key_t key; coap_hash_request_uri(&pdu, key); CU_ASSERT(sizeof(key) == sizeof(COAP_DEFAULT_WKC_HASHKEY) - 1); CU_ASSERT_NSTRING_EQUAL(key, COAP_DEFAULT_WKC_HASHKEY, sizeof(key)); } CU_pSuite t_init_uri_tests(void) { CU_pSuite suite; suite = CU_add_suite("uri parser", NULL, NULL); if (!suite) { /* signal error */ fprintf(stderr, "W: cannot add uri parser test suite (%s)\n", CU_get_error_msg()); return NULL; } #define URI_TEST(s,t) \ if (!CU_ADD_TEST(s,t)) { \ fprintf(stderr, "W: cannot add uri parser test (%s)\n", \ CU_get_error_msg()); \ } URI_TEST(suite, t_parse_uri1); URI_TEST(suite, t_parse_uri2); URI_TEST(suite, t_parse_uri3); URI_TEST(suite, t_parse_uri4); URI_TEST(suite, t_parse_uri5); URI_TEST(suite, t_parse_uri6); URI_TEST(suite, t_parse_uri7); URI_TEST(suite, t_parse_uri8); URI_TEST(suite, t_parse_uri9); URI_TEST(suite, t_parse_uri10); URI_TEST(suite, t_parse_uri11); URI_TEST(suite, t_parse_uri12); URI_TEST(suite, t_parse_uri13); return suite; }