Page Speed Optimization Libraries
1.2.24.1
|
00001 /* 00002 * Copyright 2010 Google Inc. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http:///www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00018 00020 00021 #ifndef NET_INSTAWEB_UTIL_CACHE_TEST_BASE_H_ 00022 #define NET_INSTAWEB_UTIL_CACHE_TEST_BASE_H_ 00023 00024 #include <vector> 00025 00026 #include "net/instaweb/util/public/abstract_mutex.h" 00027 #include "net/instaweb/util/public/cache_interface.h" 00028 #include "net/instaweb/util/public/basictypes.h" 00029 #include "net/instaweb/util/public/gtest.h" 00030 #include "net/instaweb/util/public/null_mutex.h" 00031 #include "net/instaweb/util/public/scoped_ptr.h" 00032 #include "net/instaweb/util/public/shared_string.h" 00033 #include "net/instaweb/util/public/stl_util.h" 00034 #include "net/instaweb/util/public/string.h" 00035 #include "net/instaweb/util/public/string_util.h" 00036 00037 namespace net_instaweb { 00038 00039 class CacheTestBase : public testing::Test { 00040 public: 00044 class Callback : public CacheInterface::SynchronousCallback { 00045 public: 00046 explicit Callback(CacheTestBase* test) : test_(test) { Reset(); } 00047 Callback() : test_(NULL) { Reset(); } 00048 virtual ~Callback() {} 00049 Callback* Reset() { 00050 SynchronousCallback::Reset(); 00051 validate_called_ = false; 00052 noop_wait_called_ = false; 00053 value_of_called_when_wait_was_invoked_ = false; 00054 invalid_value_ = NULL; 00055 return this; 00056 } 00057 00058 virtual bool ValidateCandidate(const GoogleString& key, 00059 CacheInterface::KeyState state) { 00060 validate_called_ = true; 00061 if ((invalid_value_ != NULL) && (value_str() == invalid_value_)) { 00062 return false; 00063 } 00064 return true; 00065 } 00066 00067 virtual void Done(CacheInterface::KeyState state) { 00068 SynchronousCallback::Done(state); 00069 EXPECT_TRUE(validate_called_); 00070 if (test_ != NULL) { 00071 test_->GetDone(); 00072 } 00073 } 00074 00078 virtual void Wait() { 00079 noop_wait_called_ = true; 00080 value_of_called_when_wait_was_invoked_ = called(); 00081 } 00082 00083 void set_invalid_value(const char* v) { invalid_value_ = v; } 00084 StringPiece value_str() { return value()->Value(); } 00085 00086 bool validate_called_; 00087 bool noop_wait_called_; 00088 bool value_of_called_when_wait_was_invoked_; 00089 00090 private: 00091 CacheTestBase* test_; 00092 const char* invalid_value_; 00093 00094 DISALLOW_COPY_AND_ASSIGN(Callback); 00095 }; 00096 00097 protected: 00098 CacheTestBase() 00099 : invalid_value_(NULL), 00100 mutex_(new NullMutex), 00101 outstanding_fetches_(0) { 00102 } 00103 ~CacheTestBase() { 00104 STLDeleteElements(&callbacks_); 00105 } 00106 00109 virtual Callback* NewCallback() { return new Callback(this); } 00110 virtual CacheInterface* Cache() = 0; 00111 00114 virtual void PostOpCleanup() {} 00115 00118 void CheckGet(const GoogleString& key, const GoogleString& expected_value) { 00119 CheckGet(Cache(), key, expected_value); 00120 } 00121 00123 void CheckGet(CacheInterface* cache, const GoogleString& key, 00124 const GoogleString& expected_value) { 00125 Callback* callback = InitiateGet(cache, key); 00126 WaitAndCheck(callback, expected_value); 00127 } 00128 00130 void CheckPut(const GoogleString& key, const GoogleString& value) { 00131 CheckPut(Cache(), key, value); 00132 } 00133 00134 void CheckPut(CacheInterface* cache, const GoogleString& key, 00135 const GoogleString& value) { 00136 SharedString put_buffer(value); 00137 cache->Put(key, &put_buffer); 00138 PostOpCleanup(); 00139 } 00140 00141 void CheckDelete(const GoogleString& key) { 00142 Cache()->Delete(key); 00143 PostOpCleanup(); 00144 } 00145 00147 void CheckNotFound(const char* key) { 00148 CheckNotFound(Cache(), key); 00149 } 00150 00151 void CheckNotFound(CacheInterface* cache, const char* key) { 00152 Callback* callback = InitiateGet(cache, key); 00153 WaitAndCheckNotFound(callback); 00154 } 00155 00158 Callback* AddCallback() { 00159 Callback* callback = NewCallback(); 00160 callback->set_invalid_value(invalid_value_); 00161 callbacks_.push_back(callback); 00162 return callback; 00163 } 00164 00165 void WaitAndCheck(Callback* callback, const GoogleString& expected_value) { 00172 callback->Wait(); 00173 if (callback->noop_wait_called_) { 00174 EXPECT_TRUE(callback->value_of_called_when_wait_was_invoked_); 00179 } 00180 ASSERT_TRUE(callback->called()); 00181 EXPECT_STREQ(expected_value, callback->value_str()); 00182 EXPECT_EQ(CacheInterface::kAvailable, callback->state()); 00183 PostOpCleanup(); 00184 } 00185 00186 void WaitAndCheckNotFound(Callback* callback) { 00187 callback->Wait(); 00188 ASSERT_TRUE(callback->called()); 00189 EXPECT_EQ(CacheInterface::kNotFound, callback->state()); 00190 PostOpCleanup(); 00191 } 00192 00193 void IssueMultiGet(Callback* c0, const GoogleString& key0, 00194 Callback* c1, const GoogleString& key1, 00195 Callback* c2, const GoogleString& key2) { 00196 CacheInterface::MultiGetRequest* request = 00197 new CacheInterface::MultiGetRequest; 00198 request->push_back(CacheInterface::KeyCallback(key0, c0)); 00199 request->push_back(CacheInterface::KeyCallback(key1, c1)); 00200 request->push_back(CacheInterface::KeyCallback(key2, c2)); 00201 Cache()->MultiGet(request); 00202 } 00203 00204 void TestMultiGet() { 00205 PopulateCache(2); 00206 Callback* n0 = AddCallback(); 00207 Callback* not_found = AddCallback(); 00208 Callback* n1 = AddCallback(); 00209 IssueMultiGet(n0, "n0", not_found, "not_found", n1, "n1"); 00210 WaitAndCheck(n0, "v0"); 00211 WaitAndCheckNotFound(not_found); 00212 WaitAndCheck(n1, "v1"); 00213 } 00214 00217 void PopulateCache(int num) { 00218 for (int i = 0; i < num; ++i) { 00219 CheckPut(StringPrintf("n%d", i), StringPrintf("v%d", i)); 00220 } 00221 } 00222 00223 void set_invalid_value(const char* v) { invalid_value_ = v; } 00224 00227 Callback* InitiateGet(const GoogleString& key) { 00228 return InitiateGet(Cache(), key); 00229 } 00230 00231 Callback* InitiateGet(CacheInterface* cache, const GoogleString& key) { 00232 { 00233 ScopedMutex lock(mutex_.get()); 00234 ++outstanding_fetches_; 00235 } 00236 Callback* callback = AddCallback(); 00237 cache->Get(key, callback); 00238 return callback; 00239 } 00240 00242 void set_mutex(AbstractMutex* mutex) { mutex_.reset(mutex); } 00243 00246 int outstanding_fetches() { 00247 ScopedMutex lock(mutex_.get()); 00248 return outstanding_fetches_; 00249 } 00250 00251 private: 00257 void GetDone() { 00258 ScopedMutex lock(mutex_.get()); 00259 --outstanding_fetches_; 00260 } 00261 00262 const char* invalid_value_; 00263 std::vector<Callback*> callbacks_; 00264 scoped_ptr<AbstractMutex> mutex_; 00265 int outstanding_fetches_; 00266 }; 00267 00268 } 00269 00270 #endif ///< NET_INSTAWEB_UTIL_CACHE_TEST_BASE_H_