From f20218e73ecae27f9e9f9bf34e9798080de6f93d Mon Sep 17 00:00:00 2001
From: Přemysl Janouch
Date: Sun, 29 Mar 2015 01:55:10 +0100
Subject: Add more stuff
And break the API. All in the name of progress!
---
tests/liberty.c | 47 ++++++++++------
tests/proto.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 198 insertions(+), 16 deletions(-)
create mode 100644 tests/proto.c
(limited to 'tests')
diff --git a/tests/liberty.c b/tests/liberty.c
index 8956ed0..349ee78 100644
--- a/tests/liberty.c
+++ b/tests/liberty.c
@@ -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
diff --git a/tests/proto.c b/tests/proto.c
new file mode 100644
index 0000000..caa9cf2
--- /dev/null
+++ b/tests/proto.c
@@ -0,0 +1,167 @@
+/*
+ * tests/proto.c
+ *
+ * Copyright (c) 2015, Přemysl Janouch
+ * 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 (¶meters);
+ 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, ¶meters));
+ soft_assert (!strcasecmp_ascii (type, "text"));
+ soft_assert (!strcasecmp_ascii (subtype, "html"));
+ soft_assert (parameters.len == 1);
+ soft_assert (!strcmp (str_map_find (¶meters, "charset"), "utf-8"));
+ str_map_free (¶meters);
+
+ 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);
+}
--
cgit v1.2.3-70-g09d2