libmoost
/home/mhx/git/github/libmoost/test/kvstore/kvstore_client_test.cpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00028 #include <boost/test/unit_test.hpp>
00029 #include <boost/test/test_tools.hpp>
00030 
00031 #include <stdexcept>
00032 #include <set>
00033 #include <iostream>
00034 #include <string>
00035 #include <vector>
00036 
00037 #include "../../include/moost/kvstore/kyoto_tycoon_client.hpp"
00038 #include "../../include/moost/kvstore/mock_connection.hpp"
00039 
00040 using namespace moost::kvstore;
00041 
00042 BOOST_AUTO_TEST_SUITE( kvstore_client_test )
00043 
00044 struct Fixture
00045 {
00046    Fixture()
00047    {
00048    }
00049 
00050    ~Fixture()
00051    {
00052    }
00053 };
00054 
00055 struct StringLiteralToPodTypePolicy
00056 {
00057    template <class T>
00058    static T& get(T& str)
00059    {
00060       return str;
00061    }
00062 };
00063 
00064 struct StringLiteralToStringPolicy
00065 {
00066    template <class T>
00067    static std::string get(T& str)
00068    {
00069       return std::string(str);
00070    }
00071 };
00072 
00073 template <typename TClient, typename TConnection, typename TKeyTransformPolicy>
00074 class ClientTester
00075 {
00076    struct pod
00077    {
00078       int i;
00079       double d;
00080       bool b;
00081    };
00082 
00083    void test_equal(const pod& lhs, const pod& rhs) const
00084    {
00085       BOOST_REQUIRE_EQUAL(lhs.i, rhs.i);
00086       BOOST_REQUIRE_CLOSE(lhs.d, rhs.d, 0.000000001);
00087       BOOST_REQUIRE_EQUAL(lhs.b, rhs.b);
00088    }
00089 
00090    void test_set_get_intrinsic() const
00091    {
00092       TConnection conn;
00093       conn.open("", 0, 0);
00094 
00095       TClient client(conn);
00096 
00097       client.set(TKeyTransformPolicy::get("one"), 1);
00098       int i = 0;
00099       client.get(TKeyTransformPolicy::get("one"), i);
00100       BOOST_REQUIRE_EQUAL(1, i);
00101 
00102       client.set(TKeyTransformPolicy::get("two"), 2.0);
00103       double d = 0;
00104       client.get(TKeyTransformPolicy::get("two"), d);
00105       BOOST_REQUIRE_CLOSE(2.0, d, 0.0001);
00106    }
00107 
00108    void test_set_get_vector_intrinsic() const
00109    {
00110       TConnection conn;
00111       conn.open("", 0, 0);
00112 
00113       TClient client(conn);
00114 
00115       std::vector<int> three;
00116       three.push_back(1);
00117       three.push_back(2);
00118       three.push_back(3);
00119       client.set(TKeyTransformPolicy::get("three"), three);
00120       std::vector<int> v;
00121       client.get(TKeyTransformPolicy::get("three"), v);
00122       BOOST_REQUIRE_EQUAL(three.size(), v.size());
00123       for (size_t i = 0; i < three.size(); ++i)
00124          BOOST_REQUIRE_EQUAL(three[i], v[i]);
00125    }
00126 
00127    void test_set_get_pod() const
00128    {
00129       TConnection conn;
00130       conn.open("", 0, 0);
00131 
00132       TClient client(conn);
00133 
00134       pod p = { 1, 2.0, true }, q = { 3, 4.0, false };
00135       client.set(TKeyTransformPolicy::get("p"), p);
00136       client.set(TKeyTransformPolicy::get("q"), q);
00137 
00138       pod p2, q2;
00139       client.get(TKeyTransformPolicy::get("p"), p2);
00140       client.get(TKeyTransformPolicy::get("q"), q2);
00141       test_equal(p, p2);
00142       test_equal(q, q2);
00143    }
00144 
00145 public:
00146 
00147    void run() const
00148    {
00149       test_set_get_intrinsic();
00150       test_set_get_pod();
00151       test_set_get_vector_intrinsic();
00152    }
00153 };
00154 
00155 class UnitTestAccessPolicy
00156 {
00157 public:
00158    template <class StoreT>
00159    static boost::shared_array<char> get(StoreT& store, const char* pkey, size_t ksize, size_t& vsize)
00160    {
00161       std::string key(pkey, ksize);
00162       return store.get(key, vsize);
00163    }
00164 
00165    // throws on failure, supply key "fail" to force failure
00166    template <class StoreT>
00167    static void set(StoreT& store, const char* pkey, size_t ksize, const char* pval, size_t vsize)
00168    {
00169       std::string key(pkey, ksize);
00170 
00171       if ("fail" == key) { throw std::runtime_error("set failed"); }
00172 
00173       store.set(key, pval, vsize);
00174    }
00175 
00176    // throws on failure, supply key "fail" to force failure
00177    template <class StoreT>
00178    static void cache(StoreT& store, const char* pkey, size_t ksize, const char* pval, size_t vsize, boost::int64_t expiryTime)
00179    {
00180       std::string key(pkey, ksize);
00181 
00182       if ("fail" == key) { throw std::runtime_error("cache failed"); }
00183 
00184       store.cache(key, pval, vsize, expiryTime);
00185    }
00186 };
00187 
00188 BOOST_FIXTURE_TEST_CASE( test_kyoto_tycoon_client_literal_keys, Fixture )
00189 {
00190    ClientTester< KyotoTycoonClient,
00191                  MockKyotoTycoonConnection<UnitTestAccessPolicy>,
00192                  StringLiteralToPodTypePolicy > tester;
00193    tester.run();
00194 }
00195 
00196 BOOST_FIXTURE_TEST_CASE( test_kyoto_tycoon_client_string_keys, Fixture )
00197 {
00198    ClientTester< KyotoTycoonClient,
00199                  MockKyotoTycoonConnection<UnitTestAccessPolicy>,
00200                  StringLiteralToStringPolicy > tester;
00201    tester.run();
00202 }
00203 
00204 BOOST_AUTO_TEST_SUITE_END()