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 |