Home | History | Annotate | Download | only in test
      1 // Copyright (C) 2013 Google Inc.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 // http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include "retriever.h"
     16 
     17 #include <libaddressinput/callback.h>
     18 #include <libaddressinput/null_storage.h>
     19 #include <libaddressinput/storage.h>
     20 #include <libaddressinput/util/basictypes.h>
     21 #include <libaddressinput/util/scoped_ptr.h>
     22 
     23 #include <cstddef>
     24 #include <string>
     25 
     26 #include <gtest/gtest.h>
     27 
     28 #include "mock_source.h"
     29 #include "testdata_source.h"
     30 
     31 #define CHECKSUM "dd63dafcbd4d5b28badfcaf86fb6fcdb"
     32 #define DATA "{'foo': 'bar'}"
     33 #define OLD_TIMESTAMP "0"
     34 
     35 namespace {
     36 
     37 using i18n::addressinput::BuildCallback;
     38 using i18n::addressinput::MockSource;
     39 using i18n::addressinput::NullStorage;
     40 using i18n::addressinput::Retriever;
     41 using i18n::addressinput::scoped_ptr;
     42 using i18n::addressinput::Storage;
     43 using i18n::addressinput::TestdataSource;
     44 
     45 const char kKey[] = "data/CA/AB--fr";
     46 
     47 // Empty data that the source can return.
     48 const char kEmptyData[] = "{}";
     49 
     50 // The value of the data that the stale storage returns.
     51 const char kStaleData[] = DATA;
     52 
     53 // The actual data that the stale storage returns.
     54 const char kStaleWrappedData[] = "timestamp=" OLD_TIMESTAMP "\n"
     55                                  "checksum=" CHECKSUM "\n"
     56                                  DATA;
     57 
     58 // Tests for Retriever object.
     59 class RetrieverTest : public testing::Test {
     60  protected:
     61   RetrieverTest()
     62       : retriever_(new TestdataSource(false), new NullStorage),
     63         success_(false),
     64         key_(),
     65         data_(),
     66         data_ready_(BuildCallback(this, &RetrieverTest::OnDataReady)) {}
     67 
     68   Retriever retriever_;
     69   bool success_;
     70   std::string key_;
     71   std::string data_;
     72   const scoped_ptr<const Retriever::Callback> data_ready_;
     73 
     74  private:
     75   void OnDataReady(bool success,
     76                    const std::string& key,
     77                    const std::string& data) {
     78     success_ = success;
     79     key_ = key;
     80     data_ = data;
     81   }
     82 
     83   DISALLOW_COPY_AND_ASSIGN(RetrieverTest);
     84 };
     85 
     86 TEST_F(RetrieverTest, RetrieveData) {
     87   retriever_.Retrieve(kKey, *data_ready_);
     88 
     89   EXPECT_TRUE(success_);
     90   EXPECT_EQ(kKey, key_);
     91   EXPECT_FALSE(data_.empty());
     92   EXPECT_NE(kEmptyData, data_);
     93 }
     94 
     95 TEST_F(RetrieverTest, ReadDataFromStorage) {
     96   retriever_.Retrieve(kKey, *data_ready_);
     97   retriever_.Retrieve(kKey, *data_ready_);
     98 
     99   EXPECT_TRUE(success_);
    100   EXPECT_EQ(kKey, key_);
    101   EXPECT_FALSE(data_.empty());
    102   EXPECT_NE(kEmptyData, data_);
    103 }
    104 
    105 TEST_F(RetrieverTest, MissingKeyReturnsEmptyData) {
    106   static const char kMissingKey[] = "junk";
    107 
    108   retriever_.Retrieve(kMissingKey, *data_ready_);
    109 
    110   EXPECT_TRUE(success_);
    111   EXPECT_EQ(kMissingKey, key_);
    112   EXPECT_EQ(kEmptyData, data_);
    113 }
    114 
    115 TEST_F(RetrieverTest, FaultySource) {
    116   // An empty MockSource will fail for any request.
    117   Retriever bad_retriever(new MockSource, new NullStorage);
    118 
    119   bad_retriever.Retrieve(kKey, *data_ready_);
    120 
    121   EXPECT_FALSE(success_);
    122   EXPECT_EQ(kKey, key_);
    123   EXPECT_TRUE(data_.empty());
    124 }
    125 
    126 // The storage that always returns stale data.
    127 class StaleStorage : public Storage {
    128  public:
    129   StaleStorage() : data_updated_(false) {}
    130   virtual ~StaleStorage() {}
    131 
    132   // Storage implementation.
    133   virtual void Get(const std::string& key, const Callback& data_ready) const {
    134     data_ready(true, key, new std::string(kStaleWrappedData));
    135   }
    136 
    137   virtual void Put(const std::string& key, std::string* value) {
    138     ASSERT_TRUE(value != NULL);
    139     data_updated_ = true;
    140     delete value;
    141   }
    142 
    143   bool data_updated_;
    144 
    145  private:
    146   DISALLOW_COPY_AND_ASSIGN(StaleStorage);
    147 };
    148 
    149 TEST_F(RetrieverTest, UseStaleDataWhenSourceFails) {
    150   // Owned by |resilient_retriver|.
    151   StaleStorage* stale_storage = new StaleStorage;
    152   // An empty MockSource will fail for any request.
    153   Retriever resilient_retriever(new MockSource, stale_storage);
    154 
    155   resilient_retriever.Retrieve(kKey, *data_ready_);
    156 
    157   EXPECT_TRUE(success_);
    158   EXPECT_EQ(kKey, key_);
    159   EXPECT_EQ(kStaleData, data_);
    160   EXPECT_FALSE(stale_storage->data_updated_);
    161 }
    162 
    163 TEST_F(RetrieverTest, DoNotUseStaleDataWhenSourceSucceeds) {
    164   // Owned by |resilient_retriver|.
    165   StaleStorage* stale_storage = new StaleStorage;
    166   Retriever resilient_retriever(new TestdataSource(false), stale_storage);
    167 
    168   resilient_retriever.Retrieve(kKey, *data_ready_);
    169 
    170   EXPECT_TRUE(success_);
    171   EXPECT_EQ(kKey, key_);
    172   EXPECT_FALSE(data_.empty());
    173   EXPECT_NE(kEmptyData, data_);
    174   EXPECT_NE(kStaleData, data_);
    175   EXPECT_TRUE(stale_storage->data_updated_);
    176 }
    177 
    178 }  // namespace
    179