aboutsummaryrefslogtreecommitdiffstats
path: root/test/rspamd_http_test.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-02-04 17:05:53 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-02-04 17:05:53 +0000
commit984c43f649651d610b6ee7c23c3b33bc96b62e8f (patch)
tree4ad5597ec84cb23abf52eb872e81eb2e5e4edcb5 /test/rspamd_http_test.c
parentbed11b57981363694a6ed656941fe19b5acb1b87 (diff)
downloadrspamd-984c43f649651d610b6ee7c23c3b33bc96b62e8f.tar.gz
rspamd-984c43f649651d610b6ee7c23c3b33bc96b62e8f.zip
Add HTTP connections speed test.
Diffstat (limited to 'test/rspamd_http_test.c')
-rw-r--r--test/rspamd_http_test.c234
1 files changed, 234 insertions, 0 deletions
diff --git a/test/rspamd_http_test.c b/test/rspamd_http_test.c
new file mode 100644
index 000000000..e835a7208
--- /dev/null
+++ b/test/rspamd_http_test.c
@@ -0,0 +1,234 @@
+/* Copyright (c) 2015, Vsevolod Stakhov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "main.h"
+#include "util.h"
+#include "http.h"
+#include "tests.h"
+#include "ottery.h"
+
+static const int file_blocks = 1;
+static const int pconns = 100;
+static const int ntests = 100;
+
+static void
+rspamd_server_error (struct rspamd_http_connection_entry *conn_ent,
+ GError *err)
+{
+ msg_err ("http error occurred: %s", err->message);
+ g_assert (0);
+}
+
+static void
+rspamd_server_finish (struct rspamd_http_connection_entry *conn_ent)
+{
+ /* Do nothing here */
+}
+
+static void
+rspamd_server_accept (gint fd, short what, void *arg)
+{
+ struct rspamd_http_connection_router *rt = arg;
+ rspamd_inet_addr_t addr;
+ gint nfd;
+
+ if ((nfd =
+ rspamd_accept_from_socket (fd, &addr)) == -1) {
+ msg_warn ("accept failed: %s", strerror (errno));
+ return;
+ }
+ /* Check for EAGAIN */
+ if (nfd == 0) {
+ return;
+ }
+
+ rspamd_http_router_handle_socket (rt, nfd, NULL);
+}
+
+static void
+rspamd_http_server_func (const gchar *path, rspamd_inet_addr_t *addr,
+ rspamd_mempool_mutex_t *mtx, gpointer kp)
+{
+ struct rspamd_http_connection_router *rt;
+ struct event_base *ev_base = event_init ();
+ struct event accept_ev;
+ gint fd;
+
+ rt = rspamd_http_router_new (rspamd_server_error, rspamd_server_finish,
+ NULL, ev_base, path);
+ g_assert (rt != NULL);
+
+ rspamd_http_router_set_key (rt, kp);
+
+ g_assert ((fd = rspamd_inet_address_listen (addr, SOCK_STREAM, TRUE)) != -1);
+ event_set (&accept_ev, fd, EV_READ | EV_PERSIST, rspamd_server_accept, rt);
+ event_base_set (ev_base, &accept_ev);
+ event_add (&accept_ev, NULL);
+
+
+ rspamd_mempool_unlock_mutex (mtx);
+ event_base_loop (ev_base, 0);
+}
+
+
+static void
+rspamd_client_err (struct rspamd_http_connection *conn, GError *err)
+{
+ msg_info ("abnormally closing connection from: error: %s",
+ err->message);
+
+ close (conn->fd);
+ rspamd_http_connection_unref (conn);
+}
+
+static gint
+rspamd_client_finish (struct rspamd_http_connection *conn,
+ struct rspamd_http_message *msg)
+{
+ close (conn->fd);
+ rspamd_http_connection_unref (conn);
+
+ return 0;
+}
+
+static void
+rspamd_http_client_func (const gchar *path, rspamd_inet_addr_t *addr,
+ gpointer kp, gpointer peer_kp, struct rspamd_keypair_cache *c,
+ struct event_base *ev_base)
+{
+ struct rspamd_http_message *msg;
+ struct rspamd_http_connection *conn;
+ gchar urlbuf[PATH_MAX];
+ gint fd;
+
+ g_assert ((fd = rspamd_inet_address_connect (addr, SOCK_STREAM, TRUE)) != -1);
+ conn = rspamd_http_connection_new (NULL, rspamd_client_err,
+ rspamd_client_finish, RSPAMD_HTTP_CLIENT_SIMPLE,
+ RSPAMD_HTTP_CLIENT, c);
+ rspamd_snprintf (urlbuf, sizeof (urlbuf), "http://127.0.0.1/%s", path);
+ msg = rspamd_http_message_from_url (urlbuf);
+
+ g_assert (conn != NULL && msg != NULL);
+
+ if (kp != NULL) {
+ rspamd_http_connection_set_key (conn, kp);
+ msg->peer_key = peer_kp;
+ }
+
+ rspamd_http_connection_write_message (conn, msg, NULL, NULL, NULL,
+ fd, NULL, ev_base);
+}
+
+void
+rspamd_http_test_func (void)
+{
+ struct event_base *ev_base = event_init ();
+ rspamd_mempool_t *pool = rspamd_mempool_new (rspamd_mempool_suggest_size ());
+ gpointer serv_key, client_key;
+ struct rspamd_keypair_cache *c;
+ rspamd_mempool_mutex_t *mtx;
+ rspamd_inet_addr_t addr;
+ struct timespec ts1, ts2;
+ gchar filepath[PATH_MAX], buf[4096];
+ gint fd, i, j;
+ pid_t sfd;
+ GString *b32_key;
+ double diff, total_diff = 0.0;
+
+ rspamd_snprintf (filepath, sizeof (filepath), "/tmp/http-test-XXXXXX");
+ g_assert ((fd = mkstemp (filepath)) != -1);
+
+
+ for (i = 0; i < file_blocks; i ++) {
+ memset (buf, 0, sizeof (buf));
+ g_assert (write (fd, buf, sizeof (buf)) == sizeof (buf));
+ }
+
+ mtx = rspamd_mempool_get_mutex (pool);
+
+ rspamd_parse_inet_address (&addr, "127.0.0.1");
+ rspamd_inet_address_set_port (&addr, ottery_rand_range (30000) + 32768);
+ serv_key = rspamd_http_connection_gen_key ();
+ client_key = rspamd_http_connection_gen_key ();
+ c = rspamd_keypair_cache_new (16);
+
+ rspamd_mempool_lock_mutex (mtx);
+ sfd = fork ();
+ g_assert (sfd != -1);
+
+ if (sfd == 0) {
+ rspamd_http_server_func ("/tmp/", &addr, mtx, serv_key);
+ exit (EXIT_SUCCESS);
+ }
+
+ rspamd_mempool_lock_mutex (mtx);
+
+ /* Do client stuff */
+ for (i = 0; i < ntests; i ++) {
+ for (j = 0; j < pconns; j ++) {
+ rspamd_http_client_func (filepath + sizeof ("/tmp") - 1, &addr,
+ NULL, NULL, c, ev_base);
+ }
+ clock_gettime (CLOCK_MONOTONIC, &ts1);
+ event_base_loop (ev_base, 0);
+ clock_gettime (CLOCK_MONOTONIC, &ts2);
+ diff = (ts2.tv_sec - ts1.tv_sec) * 1000. + /* Seconds */
+ (ts2.tv_nsec - ts1.tv_nsec) / 1000000.; /* Nanoseconds */
+ total_diff += diff;
+ }
+
+
+ msg_info ("Made %d connections of size %d in %.6f ms, %.6f cps",
+ ntests * pconns,
+ sizeof (buf) * file_blocks,
+ total_diff, ntests * pconns / total_diff * 1000.);
+
+ /* Now test encrypted */
+ b32_key = rspamd_http_connection_print_key (serv_key,
+ RSPAMD_KEYPAIR_PUBKEY|RSPAMD_KEYPAIR_BASE32);
+ g_assert (b32_key != NULL);
+ total_diff = 0.0;
+
+ for (i = 0; i < ntests; i ++) {
+ for (j = 0; j < pconns; j ++) {
+ rspamd_http_client_func (filepath + sizeof ("/tmp") - 1, &addr,
+ client_key, b32_key->str, c, ev_base);
+ }
+ clock_gettime (CLOCK_MONOTONIC, &ts1);
+ event_base_loop (ev_base, 0);
+ clock_gettime (CLOCK_MONOTONIC, &ts2);
+ diff = (ts2.tv_sec - ts1.tv_sec) * 1000. + /* Seconds */
+ (ts2.tv_nsec - ts1.tv_nsec) / 1000000.; /* Nanoseconds */
+ total_diff += diff;
+ }
+
+ msg_info ("Made %d encrypted connections of size %d in %.6f ms, %.6f cps",
+ ntests * pconns,
+ sizeof (buf) * file_blocks,
+ total_diff, ntests * pconns / total_diff * 1000.);
+
+ close (fd);
+ unlink (filepath);
+ kill (sfd, SIGKILL);
+}