From: cchengleo Date: Mon, 8 Sep 2014 14:37:56 +0000 (-0400) Subject: test-shared-cache: X-Git-Tag: v0.88~137^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d34c21ce4836de173c996f04be6953415ed9dc5e;p=ceph.git test-shared-cache: Initial draft for the unit test of "common/shared_cache.hpp". Signed-off-by: Cheng Cheng Loic Dachary --- diff --git a/src/common/shared_cache.hpp b/src/common/shared_cache.hpp index f5f53f90aec..38098d923c6 100644 --- a/src/common/shared_cache.hpp +++ b/src/common/shared_cache.hpp @@ -31,7 +31,9 @@ class SharedLRU { size_t max_size; Cond cond; unsigned size; - +public: + int waiting; +private: map >::iterator > contents; list > lru; @@ -86,7 +88,8 @@ class SharedLRU { public: SharedLRU(CephContext *cct = NULL, size_t max_size = 20) - : cct(cct), lock("SharedLRU::lock"), max_size(max_size), size(0) {} + : cct(cct), lock("SharedLRU::lock"), max_size(max_size), + size(0), waiting(0) {} ~SharedLRU() { contents.clear(); @@ -145,6 +148,7 @@ public: list to_release; { Mutex::Locker l(lock); + ++waiting; bool retry = false; do { retry = false; @@ -162,6 +166,7 @@ public: if (retry) cond.Wait(lock); } while (retry); + --waiting; } return val; } @@ -171,6 +176,7 @@ public: list to_release; { Mutex::Locker l(lock); + ++waiting; bool retry = false; do { retry = false; @@ -186,6 +192,7 @@ public: if (retry) cond.Wait(lock); } while (retry); + --waiting; } return val; } @@ -223,6 +230,8 @@ public: } return val; } + + friend class SharedLRUTest; }; #endif diff --git a/src/test/Makefile.am b/src/test/Makefile.am index ba994921594..88718e6559e 100644 --- a/src/test/Makefile.am +++ b/src/test/Makefile.am @@ -293,6 +293,11 @@ unittest_sharedptr_registry_CXXFLAGS = $(UNITTEST_CXXFLAGS) unittest_sharedptr_registry_LDADD = $(UNITTEST_LDADD) $(CEPH_GLOBAL) check_PROGRAMS += unittest_sharedptr_registry +unittest_shared_cache_SOURCES = test/common/test_shared_cache.cc +unittest_shared_cache_CXXFLAGS = $(UNITTEST_CXXFLAGS) +unittest_shared_cache_LDADD = $(UNITTEST_LDADD) $(CEPH_GLOBAL) +check_PROGRAMS += unittest_shared_cache + unittest_sloppy_crc_map_SOURCES = test/common/test_sloppy_crc_map.cc unittest_sloppy_crc_map_CXXFLAGS = $(UNITTEST_CXXFLAGS) unittest_sloppy_crc_map_LDADD = $(UNITTEST_LDADD) $(CEPH_GLOBAL) diff --git a/src/test/common/test_shared_cache.cc b/src/test/common/test_shared_cache.cc new file mode 100644 index 00000000000..7cd372f8f04 --- /dev/null +++ b/src/test/common/test_shared_cache.cc @@ -0,0 +1,159 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2013 Cloudwatt + * + * Author: Loic Dachary + * Cheng Cheng + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library Public License for more details. + * + */ + + #include + #include + #include "common/Thread.h" + #include "common/shared_cache.hpp" + #include "common/ceph_argparse.h" + #include "global/global_init.h" + #include + +class SharedLRUTest : public SharedLRU { +public: + Mutex &get_lock() { return lock; } +}; + +class SharedLRU_all : public ::testing::Test { +public: + + class Thread_wait : public Thread { + public: + SharedLRUTest &cache; + unsigned int key; + int value; + shared_ptr ptr; + enum in_method_t { LOOKUP, LOWER_BOUND } in_method; + + Thread_wait(SharedLRUTest& _cache, unsigned int _key, + int _value, in_method_t _in_method) : + cache(_cache), + key(_key), + value(_value), + in_method(_in_method) { } + + virtual void * entry() { + switch (in_method) { + case LOWER_BOUND: + ptr = cache.lower_bound(key); + break; + case LOOKUP: + ptr = shared_ptr(new int); + *ptr = value; + ptr = cache.lookup(key); + break; + } + return NULL; + } + }; + + static const useconds_t DELAY_MAX = 20 * 1000 * 1000; + static useconds_t delay; + + bool wait_for(SharedLRUTest &cache, int waitting) { + do { + // + // the delay variable is supposed to be initialized to zero. It would be fine + // to usleep(0) but we take this opportunity to test the loop. It will try + // again and therefore show that the logic ( increasing the delay ) actually + // works. + // + if (delay > 0) + usleep(delay); + { + Mutex::Locker l(cache.get_lock()); + if (cache.waiting == waitting) + break; + } + if (delay > 0) { + cout << "delay " << delay << "us, is not long enough, try again\n"; + } + } while ((delay = delay * 2 + 1) < DELAY_MAX); + return delay < DELAY_MAX; + } +}; + +useconds_t SharedLRU_all::delay = 0; + +TEST_F(SharedLRU_all, add) { + SharedLRUTest cache; + unsigned int key = 1; + int value1 = 2; + int value2 = 3; + bool existed = false; + { + shared_ptr ptr = cache.add(key, new int(value1), &existed); + ASSERT_EQ(value1, *ptr); + ASSERT_FALSE(existed); + } + { + shared_ptr ptr = cache.add(key, new int(value2), &existed); + ASSERT_EQ(value1, *ptr); + ASSERT_TRUE(existed); + } +} + +TEST_F(SharedLRU_all, lookup) { + SharedLRUTest cache; + unsigned int key = 1; + int value = 2; + { + shared_ptr ptr = cache.add(key, new int(value)); + ASSERT_TRUE(cache.lookup(key)); + ASSERT_EQ(value, *cache.lookup(key)); + } +} + +TEST_F(SharedLRU_all, clear) { + SharedLRUTest cache; + unsigned int key = 1; + int value = 2; + { + ceph::shared_ptr ptr = cache.add(key, new int(value)); + ASSERT_EQ(value, *cache.lookup(key)); + } + ASSERT_TRUE(cache.lookup(key)); + cache.clear(key); + ASSERT_FALSE(cache.lookup(key)); + + { + ceph::shared_ptr ptr = cache.add(key, new int(value)); + } + ASSERT_TRUE(cache.lookup(key)); + cache.clear(key); + ASSERT_FALSE(cache.lookup(key)); +} + +int main(int argc, char **argv) { + vector args; + argv_to_vec(argc, (const char **)argv, args); + + global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0); + common_init_finish(g_ceph_context); + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +// Local Variables: +// compile-command: "cd ../.. ; make unittest_shared_cache && ./unittest_shared_cache # --gtest_filter=*.* --log-to-stderr=true" +// End: