You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by pq...@apache.org on 2007/09/21 00:19:00 UTC
svn commit: r577948 - /apr/apr-util/trunk/test/testmemcache.c
Author: pquerna
Date: Thu Sep 20 15:18:58 2007
New Revision: 577948
URL: http://svn.apache.org/viewvc?rev=577948&view=rev
Log:
Update memcache test case to run if a memcache server is located on localhost with the default port.
Submitted By: Josh Rotenberg <joshrotenberg gmail.com>
PR: 42358
Modified:
apr/apr-util/trunk/test/testmemcache.c
Modified: apr/apr-util/trunk/test/testmemcache.c
URL: http://svn.apache.org/viewvc/apr/apr-util/trunk/test/testmemcache.c?rev=577948&r1=577947&r2=577948&view=diff
==============================================================================
--- apr/apr-util/trunk/test/testmemcache.c (original)
+++ apr/apr-util/trunk/test/testmemcache.c Thu Sep 20 15:18:58 2007
@@ -21,6 +21,7 @@
#include "apr_strings.h"
#include "apr_hash.h"
#include "apr_memcache.h"
+#include "apr_network_io.h"
#if APR_HAVE_STDLIB_H
#include <stdlib.h> /* for exit() */
@@ -32,9 +33,12 @@
/* the total number of items to use for set/get testing */
#define TDATA_SIZE 3000
-/* some smaller subset of TDATA_SIZE */
+/* some smaller subset of TDATA_SIZE used for multiget testing */
#define TDATA_SET 100
+/* our custom hash function just returns this all the time */
+#define HASH_FUNC_RESULT 510
+
/* all keys will be prefixed with this */
const char prefix[] = "testmemcache";
@@ -50,6 +54,58 @@
"convallis id, iaculis feugiat cras amet.";
/*
+ * this datatype is for our custom server determination function. this might
+ * be useful if you don't want to rely on simply hashing keys to determine
+ * where a key belongs, but instead want to write something fancy, or use some
+ * other kind of configuration data, i.e. a hash plus some data about a
+ * namespace, or whatever. see my_server_func, and test_memcache_user_funcs
+ * for the examples.
+ */
+typedef struct {
+ const char *someval;
+ apr_uint32_t which_server;
+} my_hash_server_baton;
+
+
+/* this could do something fancy and return some hash result.
+ * for simplicity, just return the same value, so we can test it later on.
+ * if you wanted to use some external hashing library or functions for
+ * consistent hashing, for example, this would be a good place to do it.
+ */
+apr_uint32_t my_hash_func(void *baton, const char *data,
+ apr_size_t data_len)
+{
+
+ return HASH_FUNC_RESULT;
+}
+
+/*
+ * a fancy function to determine which server to use given some kind of data
+ * and a hash value. this example actually ignores the hash value itself
+ * and pulls some number from the *baton, which is a struct that has some
+ * kind of meaningful stuff in it.
+ */
+apr_memcache_server_t *my_server_func(void *baton,
+ apr_memcache_t *mc,
+ const apr_uint32_t hash)
+{
+ apr_memcache_server_t *ms = NULL;
+ my_hash_server_baton *mhsb = (my_hash_server_baton *)baton;
+
+ if(mc->ntotal == 0) {
+ return NULL;
+ }
+
+ if(mc->ntotal < mhsb->which_server) {
+ return NULL;
+ }
+
+ ms = mc->live_servers[mhsb->which_server - 1];
+
+ return ms;
+}
+
+/*
* general test to make sure we can create the memcache struct and add
* some servers, but not more than we tell it we can add
*/
@@ -60,8 +116,8 @@
apr_status_t rv;
apr_memcache_t *memcache;
apr_memcache_server_t *server, *s;
- int max_servers = 10;
- int i;
+ apr_uint32_t max_servers = 10;
+ apr_uint32_t i;
apr_uint32_t hash;
rv = apr_memcache_create(pool, max_servers, 0, &memcache);
@@ -102,6 +158,55 @@
}
+/* install our own custom hashing and server selection routines. */
+
+static void test_memcache_user_funcs(abts_case * tc, void *data)
+{
+ apr_pool_t *pool = p;
+ apr_status_t rv;
+ apr_memcache_t *memcache;
+ apr_memcache_server_t *found, *server1, *server2;
+ apr_uint32_t max_servers = 10;
+ apr_uint32_t hres;
+ apr_port_t port;
+ apr_uint32_t i;
+ my_hash_server_baton *baton =
+ apr_pcalloc(pool, sizeof(my_hash_server_baton));
+
+ rv = apr_memcache_create(pool, max_servers, 0, &memcache);
+ ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);
+
+ /* as noted above, install our custom hash function, and call
+ * apr_memcache_hash. the return value should be our predefined number,
+ * and our function just ignores the other args, for simplicity.
+ */
+ memcache->hash_func = my_hash_func;
+
+ hres = apr_memcache_hash(memcache, "whatever", sizeof("whatever") - 1);
+ ABTS_INT_EQUAL(tc, hres, HASH_FUNC_RESULT);
+
+ /* add some servers */
+ for(i = 1; i <= 10; i++) {
+ apr_memcache_server_t *ms;
+
+ rv = apr_memcache_server_create(pool, HOST, i, 0, 1, 1, 60, &ms);
+ ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);
+
+ rv = apr_memcache_add_server(memcache, ms);
+ ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);
+ }
+
+ /*
+ * set 'which_server' in our server_baton to find the third server
+ * which should have the same port.
+ */
+ baton->which_server = 3;
+ memcache->server_func = my_server_func;
+ memcache->server_baton = baton;
+ found = apr_memcache_find_server_hash(memcache, 0);
+ ABTS_ASSERT(tc, "wrong server found", found->port == baton->which_server);
+}
+
/* test non data related commands like stats and version */
static void test_memcache_meta(abts_case * tc, void *data)
{
@@ -176,7 +281,7 @@
apr_hash_index_t *hi;
char *result;
apr_size_t len;
- int i;
+ apr_uint32_t i;
rv = apr_memcache_create(pool, 1, 0, &memcache);
ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);
@@ -225,6 +330,7 @@
}
}
+/* basic tests of the increment and decrement commands */
static void test_memcache_incrdecr(abts_case * tc, void *data)
{
apr_pool_t *pool = p;
@@ -234,7 +340,7 @@
apr_uint32_t new, next = 2;
char *result;
apr_size_t len;
- int i;
+ apr_uint32_t i;
rv = apr_memcache_create(pool, 1, 0, &memcache);
ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);
@@ -249,7 +355,7 @@
ABTS_ASSERT(tc, "set failed", rv == APR_SUCCESS);
for( i = 1; i <= TDATA_SIZE; i++) {
- int expect;
+ apr_uint32_t expect;
rv = apr_memcache_getp(memcache, pool, prefix, &result, &len, NULL);
ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS);
@@ -277,7 +383,6 @@
}
/* test the multiget functionality */
-
static void test_memcache_multiget(abts_case * tc, void *data)
{
apr_pool_t *pool = p;
@@ -287,7 +392,7 @@
apr_memcache_server_t *server;
apr_hash_t *tdata, *values;
apr_hash_index_t *hi;
- int i;
+ apr_uint32_t i;
rv = apr_memcache_create(pool, 1, 0, &memcache);
ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);
@@ -358,7 +463,7 @@
char *result, *k;
apr_size_t len;
apr_uint16_t flags;
- int i;
+ apr_uint32_t i;
rv = apr_memcache_create(pool, 1, 0, &memcache);
ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);
@@ -422,10 +527,10 @@
return i;
}
-int firsttime = 0;
-int randval(int high)
+apr_uint16_t firsttime = 0;
+int randval(apr_uint32_t high)
{
- unsigned int i = 0;
+ apr_uint32_t i = 0;
double d = 0;
if (firsttime == 0) {
@@ -439,17 +544,87 @@
return i > 0 ? i : 1;
}
+/* use apr_socket stuff to see if there is in fact a memcached server
+ * running on PORT.
+ */
+apr_status_t check_mc(void)
+{
+ apr_pool_t *pool = p;
+ apr_status_t rv;
+ apr_socket_t *sock = NULL;
+ apr_sockaddr_t *sa;
+ struct iovec vec[2];
+ apr_size_t written;
+ char buf[128];
+ apr_size_t len;
+
+ rv = apr_socket_create(&sock, APR_INET, SOCK_STREAM, 0, pool);
+ if(rv != APR_SUCCESS) {
+ return rv;
+ }
+
+ rv = apr_sockaddr_info_get(&sa, HOST, APR_INET, PORT, 0, pool);
+ if(rv != APR_SUCCESS) {
+ return rv;
+ }
+
+ rv = apr_socket_timeout_set(sock, 1 * APR_USEC_PER_SEC);
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+
+ rv = apr_socket_connect(sock, sa);
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+
+ rv = apr_socket_timeout_set(sock, -1);
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+
+ vec[0].iov_base = "version";
+ vec[0].iov_len = sizeof("version") - 1;
+
+ vec[1].iov_base = "\r\n";
+ vec[1].iov_len = sizeof("\r\n") -1;
+
+ rv = apr_socket_sendv(sock, vec, 2, &written);
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+
+ len = sizeof(buf);
+ rv = apr_socket_recv(sock, buf, &len);
+ if(rv != APR_SUCCESS) {
+ return rv;
+ }
+
+ if(strncmp(buf, "VERSION", sizeof("VERSION")-1) != 0) {
+ rv = APR_EGENERAL;
+ }
+
+ apr_socket_close(sock);
+ return rv;
+}
+
abts_suite *testmemcache(abts_suite * suite)
{
+ apr_status_t rv;
suite = ADD_SUITE(suite);
- /* TODO: Determine if a memcache server is online, before proceding. */
-#if 0
- abts_run_test(suite, test_memcache_create, NULL);
- abts_run_test(suite, test_memcache_meta, NULL);
- abts_run_test(suite, test_memcache_setget, NULL);
- abts_run_test(suite, test_memcache_multiget, NULL);
- abts_run_test(suite, test_memcache_addreplace, NULL);
- abts_run_test(suite, test_memcache_incrdecr, NULL);
-#endif
+ /* check for a running memcached on the typical port before
+ * trying to run the tests. succeed silently if we don't find one.
+ */
+ rv = check_mc();
+ if(rv == APR_SUCCESS) {
+ abts_run_test(suite, test_memcache_create, NULL);
+ abts_run_test(suite, test_memcache_user_funcs, NULL);
+ abts_run_test(suite, test_memcache_meta, NULL);
+ abts_run_test(suite, test_memcache_setget, NULL);
+ abts_run_test(suite, test_memcache_multiget, NULL);
+ abts_run_test(suite, test_memcache_addreplace, NULL);
+ abts_run_test(suite, test_memcache_incrdecr, NULL);
+ }
+
return suite;
}