Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "components/feature_engagement_tracker/internal/persistent_store.h" | |
| 6 | |
| 7 #include <map> | |
| 8 | |
| 9 #include "base/files/file_path.h" | |
| 10 #include "base/memory/ptr_util.h" | |
| 11 #include "base/optional.h" | |
| 12 #include "components/feature_engagement_tracker/internal/proto/event.pb.h" | |
| 13 #include "components/feature_engagement_tracker/internal/test/event_util.h" | |
| 14 #include "components/leveldb_proto/proto_database.h" | |
| 15 #include "components/leveldb_proto/testing/fake_db.h" | |
| 16 #include "testing/gtest/include/gtest/gtest.h" | |
| 17 | |
| 18 namespace feature_engagement_tracker { | |
| 19 | |
| 20 namespace { | |
| 21 | |
| 22 void VerifyEventsInListAndMap(const std::map<std::string, Event>& map, | |
| 23 const std::vector<Event>& list) { | |
| 24 ASSERT_EQ(map.size(), list.size()); | |
| 25 | |
| 26 for (const auto& event : list) { | |
| 27 const auto& it = map.find(event.name()); | |
| 28 ASSERT_NE(map.end(), it); | |
| 29 test::VerifyEventsEqual(&event, &it->second); | |
| 30 } | |
| 31 } | |
| 32 | |
| 33 class PersistentStoreTest : public ::testing::Test { | |
| 34 public: | |
| 35 PersistentStoreTest() | |
| 36 : db_(nullptr), | |
| 37 storage_dir_(FILE_PATH_LITERAL("/persistent/store/lalala")) { | |
| 38 load_callback_ = | |
| 39 base::Bind(&PersistentStoreTest::LoadCallback, base::Unretained(this)); | |
| 40 } | |
| 41 | |
| 42 void TearDown() override { | |
| 43 db_events_.clear(); | |
| 44 db_ = nullptr; | |
| 45 store_.reset(); | |
| 46 } | |
| 47 | |
| 48 protected: | |
| 49 void SetUpDb() { | |
|
nyquist
2017/05/11 17:08:03
Nit: I think we're allowed to use all-caps for thi
David Trainor- moved to gerrit
2017/05/11 19:30:28
Done.
| |
| 50 DCHECK(!db_); | |
| 51 DCHECK(!store_); | |
| 52 | |
| 53 db_ = new leveldb_proto::test::FakeDB<Event>(&db_events_); | |
|
nyquist
2017/05/11 17:08:03
Nit: I know we discussed offline... Could you see
David Trainor- moved to gerrit
2017/05/11 19:30:28
Done.
| |
| 54 store_.reset(new PersistentStore( | |
| 55 storage_dir_, | |
| 56 base::WrapUnique<leveldb_proto::ProtoDatabase<Event>>(db_))); | |
| 57 } | |
| 58 | |
| 59 void LoadCallback(bool success, std::unique_ptr<std::vector<Event>> events) { | |
| 60 load_successful_ = success; | |
| 61 load_results_ = std::move(events); | |
| 62 } | |
| 63 | |
| 64 // Callback results. | |
| 65 base::Optional<bool> load_successful_; | |
|
nyquist
2017/05/11 17:08:03
Ooooh... I like so much!
David Trainor- moved to gerrit
2017/05/11 19:30:28
Acknowledged.
| |
| 66 std::unique_ptr<std::vector<Event>> load_results_; | |
| 67 | |
| 68 Store::OnLoadedCallback load_callback_; | |
| 69 std::map<std::string, Event> db_events_; | |
| 70 leveldb_proto::test::FakeDB<Event>* db_; | |
| 71 std::unique_ptr<Store> store_; | |
| 72 | |
| 73 // Constant test data. | |
| 74 base::FilePath storage_dir_; | |
| 75 }; | |
| 76 | |
| 77 } // namespace | |
| 78 | |
| 79 TEST_F(PersistentStoreTest, StorageDirectory) { | |
| 80 SetUpDb(); | |
| 81 store_->Load(load_callback_); | |
| 82 EXPECT_EQ(storage_dir_, db_->GetDirectory()); | |
| 83 } | |
| 84 | |
| 85 TEST_F(PersistentStoreTest, SuccessfulInitAndLoadEmptyStore) { | |
| 86 SetUpDb(); | |
| 87 | |
| 88 store_->Load(load_callback_); | |
| 89 | |
| 90 // The initialize should not trigger a response to the callback. | |
| 91 db_->InitCallback(true); | |
| 92 EXPECT_FALSE(load_successful_.has_value()); | |
| 93 | |
| 94 // The load should trigger a response to the callback. | |
| 95 db_->LoadCallback(true); | |
| 96 EXPECT_TRUE(load_successful_.value()); | |
| 97 | |
| 98 // Validate that we have no entries. | |
| 99 EXPECT_NE(nullptr, load_results_); | |
| 100 EXPECT_TRUE(load_results_->empty()); | |
| 101 } | |
| 102 | |
| 103 TEST_F(PersistentStoreTest, SuccessfulInitAndLoadWithEvents) { | |
| 104 // Populate fake Event entries. | |
| 105 Event event1; | |
| 106 event1.set_name("event1"); | |
| 107 test::SetEventCountForDay(&event1, 1, 1); | |
| 108 | |
| 109 Event event2; | |
| 110 event2.set_name("event2"); | |
| 111 test::SetEventCountForDay(&event2, 1, 3); | |
| 112 test::SetEventCountForDay(&event2, 2, 5); | |
| 113 | |
| 114 db_events_.insert(std::pair<std::string, Event>(event1.name(), event1)); | |
| 115 db_events_.insert(std::pair<std::string, Event>(event2.name(), event2)); | |
| 116 | |
| 117 SetUpDb(); | |
| 118 | |
| 119 // The initialize should not trigger a response to the callback. | |
| 120 store_->Load(load_callback_); | |
| 121 db_->InitCallback(true); | |
| 122 EXPECT_FALSE(load_successful_.has_value()); | |
| 123 | |
| 124 // The load should trigger a response to the callback. | |
| 125 db_->LoadCallback(true); | |
| 126 EXPECT_TRUE(load_successful_.value()); | |
| 127 EXPECT_NE(nullptr, load_results_); | |
| 128 | |
| 129 // Validate that we have the two events that we expect. | |
| 130 VerifyEventsInListAndMap(db_events_, *load_results_); | |
| 131 } | |
| 132 | |
| 133 TEST_F(PersistentStoreTest, SuccessfulInitBadLoad) { | |
| 134 SetUpDb(); | |
| 135 | |
| 136 store_->Load(load_callback_); | |
| 137 | |
| 138 // The initialize should not trigger a response to the callback. | |
| 139 db_->InitCallback(true); | |
| 140 EXPECT_FALSE(load_successful_.has_value()); | |
| 141 | |
| 142 // The load will fail and should trigger the callback. | |
| 143 db_->LoadCallback(false); | |
| 144 EXPECT_FALSE(load_successful_.value()); | |
| 145 EXPECT_FALSE(store_->IsReady()); | |
| 146 } | |
| 147 | |
| 148 TEST_F(PersistentStoreTest, BadInit) { | |
| 149 SetUpDb(); | |
| 150 | |
| 151 store_->Load(load_callback_); | |
| 152 | |
| 153 // The initialize will fail and should trigger the callback. | |
| 154 db_->InitCallback(false); | |
| 155 EXPECT_FALSE(load_successful_.value()); | |
| 156 EXPECT_FALSE(store_->IsReady()); | |
| 157 } | |
| 158 | |
| 159 TEST_F(PersistentStoreTest, IsReady) { | |
| 160 SetUpDb(); | |
| 161 EXPECT_FALSE(store_->IsReady()); | |
| 162 | |
| 163 store_->Load(load_callback_); | |
| 164 EXPECT_FALSE(store_->IsReady()); | |
| 165 | |
| 166 db_->InitCallback(true); | |
| 167 EXPECT_FALSE(store_->IsReady()); | |
| 168 | |
| 169 db_->LoadCallback(true); | |
| 170 EXPECT_TRUE(store_->IsReady()); | |
| 171 } | |
| 172 | |
| 173 TEST_F(PersistentStoreTest, WriteEvent) { | |
| 174 SetUpDb(); | |
| 175 | |
| 176 store_->Load(load_callback_); | |
| 177 db_->InitCallback(true); | |
| 178 db_->LoadCallback(true); | |
| 179 | |
| 180 Event event; | |
| 181 event.set_name("event"); | |
| 182 test::SetEventCountForDay(&event, 1, 2); | |
| 183 | |
| 184 store_->WriteEvent(event); | |
| 185 db_->UpdateCallback(true); | |
| 186 | |
| 187 EXPECT_EQ(1U, db_events_.size()); | |
| 188 | |
| 189 const auto& it = db_events_.find("event"); | |
| 190 EXPECT_NE(db_events_.end(), it); | |
| 191 test::VerifyEventsEqual(&event, &it->second); | |
| 192 } | |
| 193 | |
| 194 } // namespace feature_engagement_tracker | |
| OLD | NEW |