Page Speed Optimization Libraries  1.6.29.3
net/instaweb/util/cache_test_base.h
Go to the documentation of this file.
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines