diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-02-04 17:05:53 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-02-04 17:05:53 +0000 |
commit | 984c43f649651d610b6ee7c23c3b33bc96b62e8f (patch) | |
tree | 4ad5597ec84cb23abf52eb872e81eb2e5e4edcb5 /test/rspamd_http_test.c | |
parent | bed11b57981363694a6ed656941fe19b5acb1b87 (diff) | |
download | rspamd-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.c | 234 |
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); +} |