diff options
Diffstat (limited to 'sca-cpp/trunk/components/cache')
-rw-r--r-- | sca-cpp/trunk/components/cache/mcache-client-test.cpp | 138 | ||||
-rw-r--r-- | sca-cpp/trunk/components/cache/mcache-test.cpp | 10 | ||||
-rw-r--r-- | sca-cpp/trunk/components/cache/mcache.composite | 2 | ||||
-rw-r--r-- | sca-cpp/trunk/components/cache/mcache.cpp | 10 | ||||
-rw-r--r-- | sca-cpp/trunk/components/cache/mcache.hpp | 47 | ||||
-rwxr-xr-x | sca-cpp/trunk/components/cache/memcached-server-test | 47 | ||||
-rwxr-xr-x | sca-cpp/trunk/components/cache/memcached-test | 6 |
7 files changed, 236 insertions, 24 deletions
diff --git a/sca-cpp/trunk/components/cache/mcache-client-test.cpp b/sca-cpp/trunk/components/cache/mcache-client-test.cpp new file mode 100644 index 0000000000..0a560bc05f --- /dev/null +++ b/sca-cpp/trunk/components/cache/mcache-client-test.cpp @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* $Rev$ $Date$ */ + +/** + * Test Memcached access functions. + */ + +#include <assert.h> +#include <sys/time.h> +#include <time.h> +#include <iostream> +#include <string> + +#include "list.hpp" +#include "value.hpp" +#include "monad.hpp" +#include "../../modules/http/curl.hpp" + +namespace tuscany { +namespace cache { + +const std::string url("http://localhost:8090/mcache"); + +bool testCache() { + http::CURLSession cs; + + const list<value> i = list<value>() + << (list<value>() << "name" << std::string("Apple")) + << (list<value>() << "price" << std::string("$2.99")); + const list<value> a = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); + + const failable<value, std::string> id = http::post(a, url, cs); + assert(hasContent(id)); + { + const failable<value, std::string> val = http::get(url + "/" + std::string(content(id)), cs); + assert(hasContent(val)); + assert(content(val) == a); + } + + const list<value> j = list<value>() + << (list<value>() << "name" << std::string("Apple")) + << (list<value>() << "price" << std::string("$3.55")); + const list<value> b = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), j); + + { + const failable<value, std::string> r = http::put(b, url + "/" + std::string(content(id)), cs); + assert(hasContent(r)); + assert(content(r) == value(true)); + } + { + const failable<value, std::string> val = http::get(url + "/" + std::string(content(id)), cs); + assert(hasContent(val)); + assert(content(val) == b); + } + { + const failable<value, std::string> r = http::del(url + "/" + std::string(content(id)), cs); + assert(hasContent(r)); + assert(content(r) == value(true)); + } + { + const failable<value, std::string> val = http::get(url + "/" + std::string(content(id)), cs); + assert(!hasContent(val)); + } + + return true; +} + +const double duration(struct timeval start, struct timeval end, int count) { + long t = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000); + return (double)t / (double)count; +} + +bool testGetLoop(const int count, const value& id, const value& entry, http::CURLSession& cs) { + if (count == 0) + return true; + const failable<value, std::string> val = http::get(url + "/" + std::string(id), cs); + assert(hasContent(val)); + assert(content(val) == entry); + return testGetLoop(count - 1, id, entry, cs); +} + +bool testGetPerf() { + const int count = 50; + struct timeval start; + struct timeval end; + { + const list<value> i = list<value>() + << (list<value>() << "name" << std::string("Apple")) + << (list<value>() << "price" << std::string("$4.55")); + const list<value> a = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); + + http::CURLSession cs; + const failable<value, std::string> id = http::post(a, url, cs); + assert(hasContent(id)); + + testGetLoop(5, content(id), a, cs); + + gettimeofday(&start, NULL); + + testGetLoop(count, content(id), a, cs); + + gettimeofday(&end, NULL); + std::cout << "Cache get test " << duration(start, end, count) << " ms" << std::endl; + } + return true; +} + +} +} + +int main() { + std::cout << "Testing..." << std::endl; + + tuscany::cache::testCache(); + tuscany::cache::testGetPerf(); + + std::cout << "OK" << std::endl; + + return 0; +} diff --git a/sca-cpp/trunk/components/cache/mcache-test.cpp b/sca-cpp/trunk/components/cache/mcache-test.cpp index 3f02b649d6..78f0da0465 100644 --- a/sca-cpp/trunk/components/cache/mcache-test.cpp +++ b/sca-cpp/trunk/components/cache/mcache-test.cpp @@ -35,11 +35,11 @@ namespace tuscany { namespace cache { bool testMemCached() { - MemCached ch("localhost", 11311); + MemCached ch; - assert(hasContent(post("a", "AAA", ch))); + assert(hasContent(post("a", std::string("AAA"), ch))); assert(get("a", ch) == value(std::string("AAA"))); - assert(hasContent(put("a", "aaa", ch))); + assert(hasContent(put("a", std::string("aaa"), ch))); assert(get("a", ch) == value(std::string("aaa"))); assert(hasContent(del("a", ch))); assert(!hasContent(get("a", ch))); @@ -64,8 +64,8 @@ bool testGetPerf() { struct timeval start; struct timeval end; { - MemCached ch("localhost", 11311); - assert(hasContent(post("c", "CCC", ch))); + MemCached ch; + assert(hasContent(post("c", std::string("CCC"), ch))); testGetLoop(5, ch); diff --git a/sca-cpp/trunk/components/cache/mcache.composite b/sca-cpp/trunk/components/cache/mcache.composite index ccbced6fb4..99364104fb 100644 --- a/sca-cpp/trunk/components/cache/mcache.composite +++ b/sca-cpp/trunk/components/cache/mcache.composite @@ -23,7 +23,7 @@ name="mcache"> <component name="mcache"> - <t:implementation.cpp uri="libmcache"/> + <t:implementation.cpp uri=".libs/libmcache"/> <service name="mcache"> <t:binding.http uri="mcache"/> </service> diff --git a/sca-cpp/trunk/components/cache/mcache.cpp b/sca-cpp/trunk/components/cache/mcache.cpp index af51f508e2..b60301bbf2 100644 --- a/sca-cpp/trunk/components/cache/mcache.cpp +++ b/sca-cpp/trunk/components/cache/mcache.cpp @@ -20,7 +20,7 @@ /* $Rev$ $Date$ */ /** - * memcached-based cache component implementation. + * Memcached-based cache component implementation. */ #include <apr_uuid.h> @@ -45,6 +45,9 @@ const failable<value, std::string> get(const list<value>& params) { return cache::get(car(params), ch); } +/** + * Post an item to the cache. + */ const value uuidValue() { apr_uuid_t uuid; apr_uuid_get(&uuid); @@ -53,9 +56,6 @@ const value uuidValue() { return value(std::string(buf, APR_UUID_FORMATTED_LENGTH)); } -/** - * Post an item to the cache. - */ const failable<value, std::string> post(const list<value>& params) { const value id = uuidValue(); const failable<bool, std::string> val = cache::post(id, car(params), ch); @@ -96,7 +96,7 @@ const tuscany::failable<tuscany::value, std::string> eval(const tuscany::value& return tuscany::cache::post(params); if (func == "put") return tuscany::cache::put(params); - if (func == "del") + if (func == "delete") return tuscany::cache::del(params); return tuscany::mkfailure<tuscany::value, std::string>(std::string("Function not supported: ") + std::string(func)); } diff --git a/sca-cpp/trunk/components/cache/mcache.hpp b/sca-cpp/trunk/components/cache/mcache.hpp index aae298d80d..d1fe182946 100644 --- a/sca-cpp/trunk/components/cache/mcache.hpp +++ b/sca-cpp/trunk/components/cache/mcache.hpp @@ -35,9 +35,12 @@ #include "apr_network_io.h" #include <string> +#include <sstream> #include "list.hpp" #include "value.hpp" #include "monad.hpp" +#include "debug.hpp" +#include "../../modules/eval/eval.hpp" namespace tuscany { namespace cache { @@ -77,7 +80,7 @@ private: */ const failable<bool, std::string> init(const std::string& host, const int port) { apr_memcache_server_t *server; - const apr_status_t sc = apr_memcache_server_create(pool, host.c_str(), port, 0, 1, 1, 60, &server); + const apr_status_t sc = apr_memcache_server_create(pool, host.c_str(), (apr_port_t)port, 0, 1, 1, 60, &server); if (sc != APR_SUCCESS) return mkfailure<bool, std::string>("Could not create server"); const apr_status_t as = apr_memcache_add_server(mc, server); @@ -92,21 +95,33 @@ private: * Post a new item to the cache. */ const failable<bool, std::string> post(const value& key, const value& val, const MemCached& cache) { - const std::string v(val); - const apr_status_t rc = apr_memcache_add(cache.mc, std::string(key).c_str(), const_cast<char*>(v.c_str()), v.size(), 0, 27); + debug(key, "cache::post::key"); + debug(val, "cache::post::value"); + + const std::string ks(eval::writeValue(key)); + const std::string vs(eval::writeValue(val)); + const apr_status_t rc = apr_memcache_add(cache.mc, ks.c_str(), const_cast<char*>(vs.c_str()), vs.size(), 0, 27); if (rc != APR_SUCCESS) return mkfailure<bool, std::string>("Could not add entry"); + + debug(true, "cache::post::result"); return true; } /** - * Update an item in the cache. + * Update an item in the cache. If the item doesn't exist it is added. */ const failable<bool, std::string> put(const value& key, const value& val, const MemCached& cache) { - const std::string v(val); - const apr_status_t rc = apr_memcache_replace(cache.mc, std::string(key).c_str(), const_cast<char*>(v.c_str()), v.size(), 0, 27); + debug(key, "cache::put::key"); + debug(val, "cache::put::value"); + + const std::string ks(eval::writeValue(key)); + const std::string vs(eval::writeValue(val)); + const apr_status_t rc = apr_memcache_set(cache.mc, ks.c_str(), const_cast<char*>(vs.c_str()), vs.size(), 0, 27); if (rc != APR_SUCCESS) return mkfailure<bool, std::string>("Could not add entry"); + + debug(true, "cache::put::result"); return true; } @@ -114,6 +129,10 @@ const failable<bool, std::string> put(const value& key, const value& val, const * Get an item from the cache. */ const failable<value, std::string> get(const value& key, const MemCached& cache) { + debug(key, "cache::get::key"); + + const std::string ks(eval::writeValue(key)); + apr_pool_t* vpool; const apr_status_t pc = apr_pool_create(&vpool, cache.pool); if (pc != APR_SUCCESS) @@ -121,14 +140,16 @@ const failable<value, std::string> get(const value& key, const MemCached& cache) char *data; apr_size_t size; - const apr_status_t rc = apr_memcache_getp(cache.mc, cache.pool, std::string(key).c_str(), &data, &size, NULL); + const apr_status_t rc = apr_memcache_getp(cache.mc, cache.pool, ks.c_str(), &data, &size, NULL); if (rc != APR_SUCCESS) { apr_pool_destroy(vpool); return mkfailure<value, std::string>("Could not get entry"); } - const value val(std::string(data, size)); + const value val(eval::readValue(std::string(data, size))); apr_pool_destroy(vpool); + + debug(val, "cache::get::result"); return val; } @@ -136,9 +157,15 @@ const failable<value, std::string> get(const value& key, const MemCached& cache) * Delete an item from the cache */ const failable<bool, std::string> del(const value& key, const MemCached& cache) { - const apr_status_t rc = apr_memcache_delete(cache.mc, std::string(key).c_str(), 0); + debug(key, "cache::delete::key"); + + std::ostringstream kos; + kos << key; + const apr_status_t rc = apr_memcache_delete(cache.mc, kos.str().c_str(), 0); if (rc != APR_SUCCESS) - return mkfailure<bool, std::string>("Could not add entry"); + return mkfailure<bool, std::string>("Could not delete entry"); + + debug(true, "cache::delete::result"); return true; } diff --git a/sca-cpp/trunk/components/cache/memcached-server-test b/sca-cpp/trunk/components/cache/memcached-server-test new file mode 100755 index 0000000000..2da53fbdb4 --- /dev/null +++ b/sca-cpp/trunk/components/cache/memcached-server-test @@ -0,0 +1,47 @@ +#!/bin/sh + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Setup +../../modules/http/httpd-conf tmp 8090 ../../modules/http/htdocs +../../modules/server/server-conf tmp +cat >>tmp/conf/httpd.conf <<EOF + +<Location /mcache> +SetHandler mod_tuscany_eval +SCAContribution `pwd`/ +SCAComposite mcache.composite +SCAComponent mcache +</Location> +EOF + +apachectl -k start -d `pwd`/tmp + +mc="memcached -l 127.0.0.1 -m 4 -p 11211" +$mc & +sleep 1 + +# Test +./mcache-client-test +rc=$? + +# Cleanup +kill `ps -f | grep -v grep | grep "$mc" | awk '{ print $2 }'` +apachectl -k stop -d `pwd`/tmp +sleep 1 +return $rc diff --git a/sca-cpp/trunk/components/cache/memcached-test b/sca-cpp/trunk/components/cache/memcached-test index 6ca779cce5..df21d32a57 100755 --- a/sca-cpp/trunk/components/cache/memcached-test +++ b/sca-cpp/trunk/components/cache/memcached-test @@ -18,8 +18,8 @@ # under the License. # Setup -cmd="memcached -l 127.0.0.1 -m 4 -p 11311" -$cmd & +mc="memcached -l 127.0.0.1 -m 4 -p 11211" +$mc & sleep 1 # Test @@ -27,5 +27,5 @@ sleep 1 rc=$? # Cleanup -ps -f | grep -v grep | grep "$cmd" | awk '{ print $2 }' | xargs kill +kill `ps -f | grep -v grep | grep "$mc" | awk '{ print $2 }'` return $rc |