#include #include #include #include "gnunet_uri_lib.h" #define KNRM "\x1B[0m" #define KBLU "\x1B[34m" #define KGRN "\x1B[32m" #define KERR "\x1B[5;31;50m" /* macro to print out the header for a new group of tests */ #define mu_group(name) printf ("%s • %s%s\n", KBLU, name, KNRM) /* macro for asserting a statement */ #define mu_assert(message, test) do { \ if (!(test)) { \ printf ("\t%s× %s%s\n", KERR, message, KNRM); \ return message; \ } \ printf ("\t%s• %s%s\n", KGRN, message, KNRM); \ } while (0) /* macro for asserting a statement without printing it unless it is a failure */ #define mu_silent_assert(message, test) do { \ if (!(test)) { \ printf ("\t\t%s× %s%s\n", KERR, message, KNRM); \ return message; \ } \ } while (0) /* run a test function and return result */ #define mu_run_test(test) do { \ char *message = test (); tests_run++; \ if (message) { return message; } \ } while (0) int tests_run; static int strcmp_wrap (const char *str, const char *str2) { if (NULL == str && NULL == str2) { return 0; } if (NULL == str) { return 1; } if (NULL == str2) { return -1; } return strcmp (str, str2); } #define assert_struct(as_url, \ as_scheme, \ as_user, \ as_pass, \ as_host, \ as_port, \ as_path, \ as_query, \ as_fragment) \ mu_silent_assert ("should set the scheme attribute correctly", \ 0 == strcmp_wrap (as_url.scheme, as_scheme)); \ mu_silent_assert ("should set the username attribute correctly", \ 0 == strcmp_wrap (as_url.username, as_user)); \ mu_silent_assert ("should set the password attribute correctly", \ 0 == strcmp_wrap (as_url.password, as_pass)); \ mu_silent_assert ("should set the host attribute correctly", \ 0 == strcmp_wrap (as_url.host, as_host)); \ mu_silent_assert ("should set the port attribute correctly", \ as_port == as_url.port); \ mu_silent_assert ("should set the path attribute correctly", \ 0 == strcmp_wrap (as_url.path, as_path)); \ mu_silent_assert ("should set the query attribute correctly", \ 0 == strcmp_wrap (as_url.query, as_query)); \ mu_silent_assert ("should set the fragment attribute correctly", \ 0 == strcmp_wrap (as_url.fragment, as_fragment)); static char * test_parse_http_url_ok (void) { int rc; struct GNUNET_Uri url; char *url_string; /* Minimal URL */ url_string = strdup ("http://example.com"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("minimal HTTP URL", -1 != rc); assert_struct (url, "http", NULL, NULL, "example.com", 0, NULL, NULL, NULL); free (url_string); /* With path (/) */ url_string = strdup ("http://example.com/"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with path ('/')", -1 != rc); assert_struct (url, "http", NULL, NULL, "example.com", 0, "", NULL, NULL); free (url_string); /* With path */ url_string = strdup ("http://example.com/path"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with path ('/path')", -1 != rc); assert_struct (url, "http", NULL, NULL, "example.com", 0, "path", NULL, NULL); free (url_string); /* With port */ url_string = strdup ("http://example.com:80"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with port only", -1 != rc); assert_struct (url, "http", NULL, NULL, "example.com", 80, NULL, NULL, NULL); free (url_string); /* With query */ url_string = strdup ("http://example.com?query=only"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with query only", -1 != rc); assert_struct (url, "http", NULL, NULL, "example.com", 0, NULL, "query=only", NULL); free (url_string); /* With fragment */ url_string = strdup ("http://example.com#frag=f1"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with fragment only", -1 != rc); assert_struct (url, "http", NULL, NULL, "example.com", 0, NULL, NULL, "frag=f1"); free (url_string); /* With credentials */ url_string = strdup ("http://u:p@example.com"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with credentials only", -1 != rc); assert_struct (url, "http", "u", "p", "example.com", 0, NULL, NULL, NULL); free (url_string); /* With port and path */ url_string = strdup ("http://example.com:8080/port/and/path"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with port and path", -1 != rc); assert_struct (url, "http", NULL, NULL, "example.com", 8080, "port/and/path", NULL, NULL); free (url_string); /* With port and query */ url_string = strdup ("http://example.com:8080?query=portANDquery"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with port and query", -1 != rc); assert_struct (url, "http", NULL, NULL, "example.com", 8080, NULL, "query=portANDquery", NULL); free (url_string); /* With port and fragment */ url_string = strdup ("http://example.com:8080#f1"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with port and fragment", -1 != rc); assert_struct (url, "http", NULL, NULL, "example.com", 8080, NULL, NULL, "f1"); free (url_string); /* With port and credentials */ url_string = strdup ("http://u:p@example.com:8080"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with port and credentials", -1 != rc); assert_struct (url, "http", "u", "p", "example.com", 8080, NULL, NULL, NULL); free (url_string); /* With path and query */ url_string = strdup ("http://example.com/path/and/query?q=yes"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with path and query", -1 != rc); assert_struct (url, "http", NULL, NULL, "example.com", 0, "path/and/query", "q=yes", NULL); free (url_string); /* With path and fragment */ url_string = strdup ("http://example.com/path/and#fragment"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with path and fragment", -1 != rc); assert_struct (url, "http", NULL, NULL, "example.com", 0, "path/and", NULL, "fragment"); free (url_string); /* With query and fragment */ url_string = strdup ("http://example.com?q=yes#f1"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with query and fragment", -1 != rc); assert_struct (url, "http", NULL, NULL, "example.com", 0, NULL, "q=yes", "f1"); free (url_string); /* With query and credentials */ url_string = strdup ("http://u:p@example.com?q=yes"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with query and credentials", -1 != rc); assert_struct (url, "http", "u", "p", "example.com", 0, NULL, "q=yes", NULL); free (url_string); /* With empty credentials */ url_string = strdup ("http://:@example.com"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with empty credentials", -1 != rc); assert_struct (url, "http", "", "", "example.com", 0, NULL, NULL, NULL); free (url_string); /* With empty credentials and port */ url_string = strdup ("http://:@example.com:89"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with empty credentials and port", -1 != rc); assert_struct (url, "http", "", "", "example.com", 89, NULL, NULL, NULL); free (url_string); /* Full URL */ url_string = strdup ("https://jack:password@localhost:8989/path/to/test?query=yes&q=jack#fragment1"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("with port, path and query", -1 != rc); assert_struct (url, "https", "jack", "password", "localhost", 8989, "path/to/test", "query=yes&q=jack", "fragment1"); free (url_string); return NULL; } static char * test_parse_http_rel_url_ok (void) { int rc; struct GNUNET_Uri url; char *url_string; /* Minimal relative URL */ url_string = strdup ("/"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("minimal relative URL", -1 != rc); assert_struct (url, NULL, NULL, NULL, NULL, 0, "", NULL, NULL); free (url_string); /* Path only */ url_string = strdup ("/hejsan"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("path only", -1 != rc); assert_struct (url, NULL, NULL, NULL, NULL, 0, "hejsan", NULL, NULL); free (url_string); /* Path and query */ url_string = strdup ("/hejsan?q=yes"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("path only", -1 != rc); assert_struct (url, NULL, NULL, NULL, NULL, 0, "hejsan", "q=yes", NULL); free (url_string); /* Path and fragment */ url_string = strdup ("/hejsan#fragment"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("path and fragment", -1 != rc); assert_struct (url, NULL, NULL, NULL, NULL, 0, "hejsan", NULL, "fragment"); free (url_string); /* Path, query and fragment */ url_string = strdup ("/?q=yes&q2=no#fragment"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("path, query and fragment", -1 != rc); assert_struct (url, NULL, NULL, NULL, NULL, 0, "", "q=yes&q2=no", "fragment"); free (url_string); return NULL; } static char * test_parse_url_fail (void) { int rc; struct GNUNET_Uri url; char *url_string; /* Empty */ url_string = strdup (""); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("empty string should return -1", -1 == rc); free (url_string); /* Scheme only */ url_string = strdup ("rtsp://"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("scheme only should return -1", -1 == rc); free (url_string); /* Hostname only */ url_string = strdup ("hostname"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("hostname only should return -1", -1 == rc); free (url_string); /* Query only */ url_string = strdup ("?query=only"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("query only should return -1", -1 == rc); free (url_string); /* Missing scheme */ url_string = strdup ("://"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("missing scheme should return -1", -1 == rc); free (url_string); /* Missing hostname */ url_string = strdup ("rtsp://:8910/path"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("missing hostname should return -1", -1 == rc); free (url_string); /* Missing credentials */ url_string = strdup ("rtsp://@hostname:8910/path"); rc = GNUNET_uri_parse (&url, url_string); mu_assert ("missing credentials should return -1", -1 == rc); free (url_string); return NULL; } static char * test_split_path_ok (void) { int rc; char *path; char *parts[10]; /* Simple path */ path = strdup ("/this/is/a/path"); rc = GNUNET_uri_split_path (path, parts, 10); mu_assert ("should be able to parse a regular path", 4 == rc); mu_silent_assert ("first part should be 'this'", 0 == strcmp ("this", parts[0])); mu_silent_assert ("second part should be 'is'", 0 == strcmp ("is", parts[1])); mu_silent_assert ("third part should be 'a'", 0 == strcmp ("a", parts[2])); mu_silent_assert ("fourth part should be 'path'", 0 == strcmp ("path", parts[3])); free (path); /* Relative path */ path = strdup ("this/is/a/path"); rc = GNUNET_uri_split_path (path, parts, 10); mu_assert ("should be able to parse a relative path", 4 == rc); mu_silent_assert ("first part should be 'this'", 0 == strcmp ("this", parts[0])); mu_silent_assert ("second part should be 'is'", 0 == strcmp ("is", parts[1])); mu_silent_assert ("third part should be 'a'", 0 == strcmp ("a", parts[2])); mu_silent_assert ("fourth part should be 'path'", 0 == strcmp ("path", parts[3])); free (path); /* Path with empty parts */ path = strdup ("//this//is/a/path/"); rc = GNUNET_uri_split_path (path, parts, 10); mu_assert ("should treat multiple slashes as one", 4 == rc); mu_silent_assert ("first part should be 'this'", 0 == strcmp("this", parts[0])); mu_silent_assert ("second part should be 'is'", 0 == strcmp("is", parts[1])); mu_silent_assert ("third part should be 'a'", 0 == strcmp("a", parts[2])); mu_silent_assert ("fourth part should be 'path'", 0 == strcmp("path", parts[3])); free (path); /* Just one level */ path = strdup("/one_level"); rc = GNUNET_uri_split_path(path, parts, 10); mu_assert("should be able to parse a path with one level", 1 == rc); mu_silent_assert("first part should be 'this'", 0 == strcmp("one_level", parts[0])); free(path); return NULL; } static char * test_parse_query_ok (void) { int rc; char *q; struct GNUNET_UriParam params[10]; /* One param query */ q = strdup ("q=yes"); rc = GNUNET_uri_parse_query (q, '&', params, 10); mu_assert ("single parameter with value", 1 == rc); mu_silent_assert ("first param key should be 'q'", 0 == strcmp ("q", params[0].key)); mu_silent_assert ("first param val should be 'yes'", 0 == strcmp ("yes", params[0].val)); free (q); /* One param query without value */ q = strdup ("q"); rc = GNUNET_uri_parse_query (q, '&', params, 10); mu_assert ("single parameter without value", 1 == rc); mu_silent_assert ("first param key should be 'q'", 0 == strcmp ("q", params[0].key)); mu_silent_assert ("first param val should be NULL", NULL == params[0].val); free (q); /* Two param query */ q = strdup ("query=yes&a1=hello"); rc = GNUNET_uri_parse_query (q, '&', params, 10); mu_assert ("multiple params with value", 2 == rc); mu_silent_assert ("first param key should be 'query'", 0 == strcmp ("query", params[0].key)); mu_silent_assert ("first param val should be 'yes'", 0 == strcmp ("yes", params[0].val)); mu_silent_assert ("second param key should be 'a1'", 0 == strcmp ("a1", params[1].key)); mu_silent_assert ("second param val should be 'hello'", 0 == strcmp ("hello", params[1].val)); free (q); /* Two param query, one without value */ q = strdup ("query=yes&forceHttps"); rc = GNUNET_uri_parse_query (q, '&', params, 10); mu_assert ("multiple params one without value", 2 == rc); mu_silent_assert ("first param key should be 'query'", 0 == strcmp ("query", params[0].key)); mu_silent_assert ("first param val should be 'yes'", 0 == strcmp ("yes", params[0].val)); mu_silent_assert ("second param key should be 'forceHttps'", 0 == strcmp ("forceHttps", params[1].key)); mu_silent_assert ("second param val should be NULL", NULL == params[1].val); free (q); /* Three param query, all without value */ q = strdup ("query&forceHttps&log"); rc = GNUNET_uri_parse_query (q, '&', params, 10); mu_assert ("multiple params all without value", 3 == rc); mu_silent_assert ("first param key should be 'query'", 0 == strcmp ("query", params[0].key)); mu_silent_assert ("first param val should be NULL", NULL == params[0].val); mu_silent_assert ("second param key should be 'forceHttps'", 0 == strcmp ("forceHttps", params[1].key)); mu_silent_assert ("second param val should be NULL", NULL == params[1].val); mu_silent_assert ("third param key should be 'log'", 0 == strcmp ("log", params[2].key)); mu_silent_assert ("third param val should be NULL", NULL == params[2].val); free (q); /* Param with empty value */ q = strdup ("param=&query=no"); rc = GNUNET_uri_parse_query (q, '&', params, 10); mu_assert ("param with empty value", 2 == rc); mu_silent_assert ("first param key should be 'param'", 0 == strcmp ("param", params[0].key)); mu_silent_assert ("first param val should be ''", 0 == strcmp ("", params[0].val)); mu_silent_assert ("second param key should be 'query'", 0 == strcmp ("query", params[1].key)); mu_silent_assert ("second param val should be 'no'", 0 == strcmp ("no", params[1].val)); free (q); /* Double delimiter */ q = strdup ("param=jack&&query=no"); rc = GNUNET_uri_parse_query (q, '&', params, 10); mu_assert ("double delimiter", 3 == rc); mu_silent_assert ("first param key should be 'param'", 0 == strcmp ("param", params[0].key)); mu_silent_assert ("first param val should be 'jack'", 0 == strcmp ("jack", params[0].val)); mu_silent_assert ("second param key should be ''", 0 == strcmp ("", params[1].key)); mu_silent_assert ("second param val should be NULL", NULL == params[1].val); mu_silent_assert ("third param key should be 'query'", 0 == strcmp ("query", params[2].key)); mu_silent_assert ("third param val should be 'no'", 0 == strcmp ("no", params[2].val)); free (q); /* Delimiter in beginning */ q = strdup ("¶m=jack&query=no"); rc = GNUNET_uri_parse_query (q, '&', params, 10); mu_assert ("delimiter in beginning", 3 == rc); mu_silent_assert ("first param key should be ''", 0 == strcmp ("", params[0].key)); mu_silent_assert ("first param val should be NULL", NULL == params[0].val); mu_silent_assert ("second param key should be 'param'", 0 == strcmp ("param", params[1].key)); mu_silent_assert ("second param val should be 'jack'", 0 == strcmp ("jack", params[1].val)); mu_silent_assert ("third param key should be 'query'", 0 == strcmp ("query", params[2].key)); mu_silent_assert ("third param val should be 'no'", 0 == strcmp ("no", params[2].val)); free (q); /* Delimiter at the end */ q = strdup ("param=jack&query=no&"); rc = GNUNET_uri_parse_query (q, '&', params, 10); mu_assert ("delimiter at the end", 3 == rc); mu_silent_assert ("first param key should be 'param'", 0 == strcmp ("param", params[0].key)); mu_silent_assert ("first param val should be 'jack'", 0 == strcmp ("jack", params[0].val)); mu_silent_assert ("second param key should be 'query'", 0 == strcmp ("query", params[1].key)); mu_silent_assert ("second param val should be 'no'", 0 == strcmp ("no", params[1].val)); mu_silent_assert ("third param key should be ''", 0 == strcmp ("", params[2].key)); mu_silent_assert ("third param val should be NULL", NULL == params[2].val); free (q); return NULL; } static char * all_tests (void) { mu_group ("GNUNET_uri_parse () with an HTTP URL"); mu_run_test (test_parse_http_url_ok); mu_group ("GNUNET_uri_parse () with an relative URL"); mu_run_test (test_parse_http_rel_url_ok); mu_group ("GNUNET_uri_parse () with faulty values"); mu_run_test (test_parse_url_fail); mu_group ("GNUNET_uri_split_path ()"); mu_run_test (test_split_path_ok); mu_group ("GNUNET_uri_parse_query ()"); mu_run_test (test_parse_query_ok); return NULL; } int main (void) { char *result; result = all_tests (); if (result != NULL) { exit (EXIT_FAILURE); } exit (EXIT_SUCCESS); }