MemCacheClient

MemCacheClientTest.cpp

00001 
00005 #ifdef WIN32
00006 # include <winsock2.h>
00007 # pragma comment(lib, "ws2_32.lib")
00008 #endif
00009 
00010 #include <memory>
00011 #include <stdexcept>
00012 #include <stdio.h>
00013 
00014 #include "MemCacheClient.h"
00015 
00016 #define STR(x)      #x
00017 #define VERIFY(x)   if (!(x)) throw std::runtime_error(STR(x));
00018 
00019 #ifdef WIN32
00020 # define MilliSleep(x)  Sleep(x)
00021 #else
00022 # define MilliSleep(x)  usleep((x) * 1000)
00023 #endif
00024 
00025 static int TestServerParsing()
00026 {
00027     // ensure that adding servers correctly parses the name
00028     try {
00029         std::auto_ptr<MemCacheClient> pClient(new MemCacheClient);
00030 
00031         VERIFY(!pClient->AddServer("foo"));
00032         VERIFY(!pClient->AddServer("localhost"));
00033         VERIFY(!pClient->AddServer("12.12.12.12.12"));
00034         VERIFY(!pClient->AddServer("www.microsoft.com"));
00035         VERIFY(!pClient->AddServer(""));
00036         VERIFY(!pClient->AddServer(NULL));
00037         VERIFY(!pClient->AddServer("255.255.255.255:12345"));
00038 
00039         VERIFY(pClient->AddServer("127.0.0.1"));
00040         VERIFY(pClient->AddServer("127.0.0.1"));
00041         VERIFY(pClient->AddServer("127.0.0.1:11212"));
00042         VERIFY(pClient->AddServer("127.0.0.1:11212"));
00043         VERIFY(pClient->AddServer("1.2.3.4:12345"));
00044 
00045         printf("PASSED: TestServerParsing\n");
00046         return 0;
00047     }
00048     catch (const std::exception & e) {
00049         printf("FAILED: TestServerParsing: %s\n", e.what());
00050         return 1;
00051     }
00052 }
00053 
00054 static int TestAdd(MemCacheClient * pClient)
00055 {
00056     MemCacheClient::MemRequest oItem;
00057     try {
00058         VERIFY(pClient->FlushAll() > 0);
00059 
00060         oItem.mKey = "TestAdd";
00061         oItem.mData.WriteBytes("TestAdd", sizeof("TestAdd"));
00062 
00063         VERIFY(pClient->Add(oItem) == 1);
00064         VERIFY(oItem.mResult == MCERR_OK);
00065 
00066         VERIFY(pClient->Add(oItem) == 1);
00067         VERIFY(oItem.mResult == MCERR_NOTSTORED);
00068 
00069         printf("PASSED: TestAdd\n");
00070         return 0;
00071     }
00072     catch (const std::exception & e) {
00073         printf("FAILED: TestAdd: %s\n", e.what());
00074         return 1;
00075     }
00076 }
00077 
00078 static int TestSet(MemCacheClient * pClient)
00079 {
00080     MemCacheClient::MemRequest oItem;
00081     try {
00082         VERIFY(pClient->FlushAll() > 0);
00083 
00084         oItem.mKey = "TestSet";
00085         oItem.mData.WriteBytes("TestSet", sizeof("TestSet"));
00086 
00087         VERIFY(pClient->Set(oItem) == 1);
00088         VERIFY(oItem.mResult == MCERR_OK);
00089 
00090         VERIFY(pClient->Set(oItem) == 1);
00091         VERIFY(oItem.mResult == MCERR_OK);
00092 
00093         printf("PASSED: TestSet\n");
00094         return 0;
00095     }
00096     catch (const std::exception & e) {
00097         printf("FAILED: TestSet: %s\n", e.what());
00098         return 1;
00099     }
00100 }
00101 
00102 static int TestReplace(MemCacheClient * pClient)
00103 {
00104     MemCacheClient::MemRequest oItem;
00105     try {
00106         VERIFY(pClient->FlushAll() > 0);
00107 
00108         oItem.mKey = "TestReplace";
00109         oItem.mData.WriteBytes("TestReplace", sizeof("TestReplace"));
00110 
00111         VERIFY(pClient->Replace(oItem) == 1);
00112         VERIFY(oItem.mResult == MCERR_NOTSTORED);
00113 
00114         VERIFY(pClient->Set(oItem) == 1);
00115         VERIFY(oItem.mResult == MCERR_OK);
00116 
00117         VERIFY(pClient->Replace(oItem) == 1);
00118         VERIFY(oItem.mResult == MCERR_OK);
00119 
00120         printf("PASSED: TestReplace\n");
00121         return 0;
00122     }
00123     catch (const std::exception & e) {
00124         printf("FAILED: TestReplace: %s\n", e.what());
00125         return 1;
00126     }
00127 }
00128 
00129 static int TestDel(MemCacheClient * pClient)
00130 {
00131     MemCacheClient::MemRequest oItem;
00132     try {
00133         VERIFY(pClient->FlushAll() > 0);
00134 
00135         oItem.mKey = "TestDel";
00136         oItem.mData.WriteBytes("TestDel", sizeof("TestDel"));
00137 
00138         VERIFY(pClient->Add(oItem) == 1);
00139         VERIFY(oItem.mResult == MCERR_OK);
00140 
00141         VERIFY(pClient->Del(oItem) == 1);
00142         VERIFY(oItem.mResult == MCERR_OK);
00143 
00144         VERIFY(pClient->Add(oItem) == 1);
00145         VERIFY(oItem.mResult == MCERR_OK);
00146 
00147         printf("PASSED: TestDel\n");
00148         return 0;
00149     }
00150     catch (const std::exception & e) {
00151         printf("FAILED: TestDel: %s\n", e.what());
00152         return 1;
00153     }
00154 }
00155 
00156 static int TestIncrement(MemCacheClient * pClient)
00157 {
00158     MemCacheClient::MemRequest oItem;
00159     MemCacheClient::uint64_t nValue = 999;
00160     try {
00161         VERIFY(pClient->FlushAll() > 0);
00162 
00163         VERIFY(pClient->Increment("TestIncrement", &nValue, 1, true) == MCERR_NOTFOUND);
00164         VERIFY(nValue == 999);
00165 
00166         oItem.mKey = "TestIncrement";
00167         oItem.mData.WriteBytes("999", 3);
00168         VERIFY(pClient->Add(oItem) == 1);
00169         VERIFY(oItem.mResult == MCERR_OK);
00170 
00171         VERIFY(pClient->Increment("TestIncrement", &nValue, 1, true) == MCERR_OK);
00172         VERIFY(nValue == 1000);
00173 
00174         VERIFY(pClient->Increment("TestIncrement", &nValue, 100, true) == MCERR_OK);
00175         VERIFY(nValue == 1100);
00176 
00177         VERIFY(pClient->Increment("TestIncrement", &nValue, 50, false) == MCERR_NOREPLY);
00178         VERIFY(nValue == 1100); // not updated as a_bWantReply is false
00179 
00180         VERIFY(pClient->Increment("TestIncrement", &nValue, 25, true) == MCERR_OK);
00181         VERIFY(nValue == 1175); 
00182 
00183         VERIFY(pClient->Increment("TestIncrement", NULL, 10, true) == MCERR_OK);
00184         VERIFY(nValue == 1175); // not updated
00185 
00186         VERIFY(pClient->Increment("TestIncrement", &nValue, 5, true) == MCERR_OK);
00187         VERIFY(nValue == 1190);
00188 
00189         printf("PASSED: TestIncrement\n");
00190         return 0;
00191     }
00192     catch (const std::exception & e) {
00193         printf("FAILED: TestIncrement: %s\n", e.what());
00194         return 1;
00195     }
00196 }
00197 
00198 static int TestDecrement(MemCacheClient * pClient)
00199 {
00200     MemCacheClient::MemRequest oItem;
00201     MemCacheClient::uint64_t nValue = 999;
00202     try {
00203         VERIFY(pClient->FlushAll() > 0);
00204 
00205         VERIFY(pClient->Decrement("TestDecrement", &nValue, 1, true) == MCERR_NOTFOUND);
00206         VERIFY(nValue == 999);
00207 
00208         oItem.mKey = "TestDecrement";
00209         oItem.mData.WriteBytes("999", 3);
00210         VERIFY(pClient->Add(oItem) == 1);
00211         VERIFY(oItem.mResult == MCERR_OK);
00212 
00213         VERIFY(pClient->Decrement("TestDecrement", &nValue, 1, true) == MCERR_OK);
00214         VERIFY(nValue == 998);
00215 
00216         VERIFY(pClient->Decrement("TestDecrement", &nValue, 100, true) == MCERR_OK);
00217         VERIFY(nValue == 898);
00218 
00219         VERIFY(pClient->Decrement("TestDecrement", &nValue, 50, false) == MCERR_NOREPLY);
00220         VERIFY(nValue == 898); // not updated as a_bWantReply is false
00221 
00222         VERIFY(pClient->Decrement("TestDecrement", &nValue, 25, true) == MCERR_OK);
00223         VERIFY(nValue == 823); 
00224 
00225         VERIFY(pClient->Decrement("TestDecrement", NULL, 10, true) == MCERR_OK);
00226         VERIFY(nValue == 823); // not updated
00227 
00228         VERIFY(pClient->Decrement("TestDecrement", &nValue, 5, true) == MCERR_OK);
00229         VERIFY(nValue == 808);
00230 
00231         VERIFY(pClient->Decrement("TestDecrement", &nValue, 900, true) == MCERR_OK);
00232         VERIFY(nValue == 0);
00233 
00234         printf("PASSED: TestDecrement\n");
00235         return 0;
00236     }
00237     catch (const std::exception & e) {
00238         printf("FAILED: TestDecrement: %s\n", e.what());
00239         return 1;
00240     }
00241 }
00242 
00243 static int TestDelTimeout(MemCacheClient * pClient)
00244 {
00245     MemCacheClient::MemRequest oItem;
00246     try {
00247         VERIFY(pClient->FlushAll() > 0);
00248 
00249         oItem.mKey = "TestDelTimeout";
00250         oItem.mData.WriteBytes("TestDelTimeout", sizeof("TestDelTimeout"));
00251 
00252         VERIFY(pClient->Add(oItem) == 1);
00253         VERIFY(oItem.mResult == MCERR_OK);
00254 
00255         u_long nStart = xplatform::GetCurrentTickCount();
00256 
00257         oItem.mExpiry = 5; // 5 seconds from now
00258         VERIFY(pClient->Del(oItem) == 1);
00259         VERIFY(oItem.mResult == MCERR_OK);
00260         
00261         oItem.mExpiry = 0;
00262         VERIFY(pClient->Add(oItem) == 1);
00263         VERIFY(oItem.mResult == MCERR_NOTSTORED);
00264 
00265         while (oItem.mResult == MCERR_NOTSTORED) {
00266             MilliSleep(100);
00267             VERIFY(pClient->Add(oItem) == 1);
00268         }
00269 
00270         u_long nFinish = xplatform::GetCurrentTickCount();
00271 
00272         VERIFY(oItem.mResult == MCERR_OK);
00273 
00274         u_long nPeriod = nFinish - nStart;
00275         VERIFY(nPeriod >= 4000); // took 5 seconds (+-20%)
00276 
00277         printf("PASSED: TestDelTimeout\n");
00278         return 0;
00279     }
00280     catch (const std::exception & e) {
00281         printf("FAILED: TestDelTimeout: %s\n", e.what());
00282         return 1;
00283     }
00284 }
00285 
00286 int main(int argc, char ** argv)
00287 {
00288 #ifdef WIN32
00289     WSADATA wsaData;
00290     int rc = WSAStartup(MAKEWORD(2,0), &wsaData);
00291     if (rc != 0) {
00292         printf("Failed to start winsock\n");
00293         return 1;
00294     }
00295 #endif
00296 
00297     MemCacheClient * pClient = new MemCacheClient;
00298     for (int n = 1; n < argc; ++n) {
00299         if (!pClient->AddServer(argv[n])) {
00300             printf("Failed to add server: %s\n", argv[n]);
00301         }
00302     }
00303     if (argc < 2) {
00304         printf("No servers supplied on command line. Using localhost.\n\n");
00305         pClient->AddServer("127.0.0.1:11211");
00306     }
00307 
00308     std::vector<MemCacheClient::string_t> rgServers;
00309     pClient->GetServers(rgServers);
00310     for (size_t n = 0; n < rgServers.size(); ++n) {
00311         printf("Using server: %s\n", rgServers[n].data());
00312     }
00313     printf("\n");
00314 
00315     int nFails = 0;
00316     
00317     nFails += TestServerParsing();
00318     nFails += TestAdd(pClient);
00319     nFails += TestSet(pClient);
00320     nFails += TestReplace(pClient);
00321     nFails += TestDel(pClient);
00322     nFails += TestIncrement(pClient);
00323     nFails += TestDecrement(pClient);
00324     nFails += TestDelTimeout(pClient);
00325 
00326     delete pClient;
00327 
00328     printf("\n");
00329     if (nFails == 0) {
00330         printf("All tests passed.\n");
00331     }
00332     else {
00333         printf("%d tests failed\n", nFails);
00334         nFails = 1;
00335     }
00336 
00337 #ifdef WIN32
00338     WSACleanup();
00339 #endif
00340     return nFails;
00341 }