Add more stuff

And break the API.  All in the name of progress!
This commit is contained in:
2015-03-29 01:55:10 +01:00
parent 2b3bc18269
commit f20218e73e
6 changed files with 1764 additions and 41 deletions

View File

@@ -236,21 +236,6 @@ test_error (void)
// --- Hash map ----------------------------------------------------------------
static int
tolower_ascii (int c)
{
return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c;
}
static size_t
tolower_strxfrm (char *dest, const char *src, size_t n)
{
size_t len = strlen (src);
while (n-- && (*dest++ = tolower_ascii (*src++)))
;
return len;
}
static void
free_counter (void *data)
{
@@ -280,7 +265,7 @@ test_str_map (void)
// Put two reference counted objects in the map under case-insensitive keys
struct str_map m;
str_map_init (&m);
m.key_xfrm = tolower_strxfrm;
m.key_xfrm = tolower_ascii_strxfrm;
m.free = free_counter;
int *a = make_counter ();
@@ -323,6 +308,34 @@ test_str_map (void)
free_counter (b);
}
static void
test_utf8 (void)
{
const char valid [] = "2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm";
const char invalid[] = "\xf0\x90\x28\xbc";
soft_assert ( utf8_validate (valid, sizeof valid));
soft_assert (!utf8_validate (invalid, sizeof invalid));
}
static void
test_base64 (void)
{
char data[65];
for (size_t i = 0; i < N_ELEMENTS (data); i++)
data[i] = i;
struct str encoded; str_init (&encoded);
struct str decoded; str_init (&decoded);
base64_encode (data, sizeof data, &encoded);
soft_assert (base64_decode (encoded.str, false, &decoded));
soft_assert (decoded.len == sizeof data);
soft_assert (!memcmp (decoded.str, data, sizeof data));
str_free (&encoded);
str_free (&decoded);
}
// --- Main --------------------------------------------------------------------
int
@@ -338,6 +351,8 @@ main (int argc, char *argv[])
test_add_simple (&test, "/str", NULL, test_str);
test_add_simple (&test, "/error", NULL, test_error);
test_add_simple (&test, "/str-map", NULL, test_str_map);
test_add_simple (&test, "/utf-8", NULL, test_utf8);
test_add_simple (&test, "/base64", NULL, test_base64);
// TODO: write tests for the rest of the library

167
tests/proto.c Normal file
View File

@@ -0,0 +1,167 @@
/*
* tests/proto.c
*
* Copyright (c) 2015, Přemysl Janouch <p.janouch@gmail.com>
* All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#define PROGRAM_NAME "test"
#define PROGRAM_VERSION "0"
#define LIBERTY_WANT_SSL
#define LIBERTY_WANT_PROTO_IRC
#define LIBERTY_WANT_PROTO_HTTP
#define LIBERTY_WANT_PROTO_SCGI
#define LIBERTY_WANT_PROTO_FASTCGI
#define LIBERTY_WANT_PROTO_WS
#include "../liberty.c"
// --- Tests -------------------------------------------------------------------
static void
test_http_parser (void)
{
struct str_map parameters;
str_map_init (&parameters);
parameters.key_xfrm = tolower_ascii_strxfrm;
char *type = NULL;
char *subtype = NULL;
soft_assert (http_parse_media_type ("TEXT/html; CHARset=\"utf\\-8\"",
&type, &subtype, &parameters));
soft_assert (!strcasecmp_ascii (type, "text"));
soft_assert (!strcasecmp_ascii (subtype, "html"));
soft_assert (parameters.len == 1);
soft_assert (!strcmp (str_map_find (&parameters, "charset"), "utf-8"));
str_map_free (&parameters);
struct http_protocol *protocols;
soft_assert (http_parse_upgrade ("websocket, HTTP/2.0, , ", &protocols));
soft_assert (!strcmp (protocols->name, "websocket"));
soft_assert (!protocols->version);
soft_assert (!strcmp (protocols->next->name, "HTTP"));
soft_assert (!strcmp (protocols->next->version, "2.0"));
soft_assert (!protocols->next->next);
LIST_FOR_EACH (struct http_protocol, iter, protocols)
http_protocol_destroy (iter);
}
static bool
test_scgi_parser_on_headers_read (void *user_data)
{
struct scgi_parser *parser = user_data;
soft_assert (parser->headers.len == 4);
soft_assert (!strcmp (str_map_find (&parser->headers,
"CONTENT_LENGTH"), "27"));
soft_assert (!strcmp (str_map_find (&parser->headers,
"SCGI"), "1"));
soft_assert (!strcmp (str_map_find (&parser->headers,
"REQUEST_METHOD"), "POST"));
soft_assert (!strcmp (str_map_find (&parser->headers,
"REQUEST_URI"), "/deepthought"));
return true;
}
static bool
test_scgi_parser_on_content (void *user_data, const void *data, size_t len)
{
(void) user_data;
soft_assert (!strncmp (data, "What is the answer to life?", len));
return true;
}
static void
test_scgi_parser (void)
{
struct scgi_parser parser;
scgi_parser_init (&parser);
parser.on_headers_read = test_scgi_parser_on_headers_read;
parser.on_content = test_scgi_parser_on_content;
parser.user_data = &parser;
// This is an example straight from the specification
const char example[] =
"70:"
"CONTENT_LENGTH" "\0" "27" "\0"
"SCGI" "\0" "1" "\0"
"REQUEST_METHOD" "\0" "POST" "\0"
"REQUEST_URI" "\0" "/deepthought" "\0"
","
"What is the answer to life?";
soft_assert (scgi_parser_push (&parser, example, sizeof example, NULL));
scgi_parser_free (&parser);
}
static bool
test_websockets_on_frame_header (void *user_data, const struct ws_parser *self)
{
(void) user_data;
soft_assert (self->is_fin);
soft_assert (self->is_masked);
soft_assert (self->opcode == WS_OPCODE_TEXT);
return true;
}
static bool
test_websockets_on_frame (void *user_data, const struct ws_parser *self)
{
(void) user_data;
soft_assert (self->input.len == self->payload_len);
soft_assert (!strncmp (self->input.str, "Hello", self->input.len));
return true;
}
static void
test_websockets (void)
{
char *accept = ws_encode_response_key ("dGhlIHNhbXBsZSBub25jZQ==");
soft_assert (!strcmp (accept, "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="));
free (accept);
struct ws_parser parser;
ws_parser_init (&parser);
parser.on_frame_header = test_websockets_on_frame_header;
parser.on_frame = test_websockets_on_frame;
parser.user_data = &parser;
const char frame[] = "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58";
soft_assert (ws_parser_push (&parser, frame, sizeof frame - 1));
ws_parser_free (&parser);
}
// --- Main --------------------------------------------------------------------
int
main (int argc, char *argv[])
{
struct test test;
test_init (&test, argc, argv);
test_add_simple (&test, "/http-parser", NULL, test_http_parser);
test_add_simple (&test, "/scgi-parser", NULL, test_scgi_parser);
test_add_simple (&test, "/websockets", NULL, test_websockets);
// TODO: test FastCGI
// TODO: test IRC
return test_run (&test);
}