Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(273)

Side by Side Diff: chromeos/components/tether/host_scan_cache_unittest.cc

Issue 2852693004: [CrOS Tether] Create HostScanCache, which caches scan results and inserts them into the network sta… (Closed)
Patch Set: hansberry@ comments. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 "chromeos/components/tether/host_scan_cache.h"
6
7 #include <memory>
8 #include <unordered_map>
9 #include <vector>
10
11 #include "base/callback.h"
12 #include "base/memory/ptr_util.h"
13 #include "base/test/scoped_task_environment.h"
14 #include "base/timer/mock_timer.h"
15 #include "chromeos/components/tether/device_id_tether_network_guid_map.h"
16 #include "chromeos/components/tether/fake_active_host.h"
17 #include "chromeos/components/tether/fake_host_scan_cache.h"
18 #include "chromeos/components/tether/mock_tether_host_response_recorder.h"
19 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "chromeos/network/network_state.h"
21 #include "chromeos/network/network_state_handler.h"
22 #include "chromeos/network/network_state_test.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25
26 using testing::NiceMock;
27 using testing::Invoke;
28
29 namespace chromeos {
30
31 namespace tether {
32
33 namespace {
34
35 const char kTetherGuid0[] = "kTetherGuid0";
36 const char kTetherGuid1[] = "kTetherGuid1";
37 const char kTetherGuid2[] = "kTetherGuid2";
38 const char kTetherGuid3[] = "kTetherGuid3";
39
40 const char kTetherDeviceName0[] = "kDeviceName1";
41 const char kTetherDeviceName1[] = "kDeviceName2";
42 const char kTetherDeviceName2[] = "kDeviceName3";
43 const char kTetherDeviceName3[] = "kDeviceName4";
44
45 const char kTetherCarrier0[] = "kTetherCarrier0";
46 const char kTetherCarrier1[] = "kTetherCarrier1";
47 const char kTetherCarrier2[] = "kTetherCarrier2";
48 const char kTetherCarrier3[] = "kTetherCarrier3";
49
50 const int kTetherBatteryPercentage0 = 20;
51 const int kTetherBatteryPercentage1 = 40;
52 const int kTetherBatteryPercentage2 = 60;
53 const int kTetherBatteryPercentage3 = 80;
54
55 const int kTetherSignalStrength0 = 25;
56 const int kTetherSignalStrength1 = 50;
57 const int kTetherSignalStrength2 = 75;
58 const int kTetherSignalStrength3 = 100;
59
60 // MockTimer which invokes a callback in its destructor.
61 class ExtendedMockTimer : public base::MockTimer {
62 public:
63 explicit ExtendedMockTimer(const base::Closure& destructor_callback)
64 : base::MockTimer(true /* retain_user_task */, false /* is_repeating */),
65 destructor_callback_(destructor_callback) {}
66
67 ~ExtendedMockTimer() override { destructor_callback_.Run(); }
68
69 private:
70 base::Closure destructor_callback_;
71 };
72
73 } // namespace
74
75 class HostScanCacheTest : public NetworkStateTest {
76 protected:
77 class MockTimerFactory : public HostScanCache::TimerFactory {
78 public:
79 MockTimerFactory() {}
80 ~MockTimerFactory() {}
81
82 std::unordered_map<std::string, ExtendedMockTimer*>&
83 tether_network_guid_to_timer_map() {
84 return tether_network_guid_to_timer_map_;
85 }
86
87 // HostScanCache::TimerFactory:
88 std::unique_ptr<base::Timer> CreateOneShotTimer(
89 const std::string& tether_network_guid) override {
90 ExtendedMockTimer* mock_timer = new ExtendedMockTimer(
91 base::Bind(&MockTimerFactory::OnActiveTimerDestructor,
92 base::Unretained(this), tether_network_guid));
93 tether_network_guid_to_timer_map_[tether_network_guid] = mock_timer;
94 return base::WrapUnique(mock_timer);
95 }
96
97 private:
98 void OnActiveTimerDestructor(const std::string& tether_network_guid) {
99 tether_network_guid_to_timer_map_.erase(
100 tether_network_guid_to_timer_map_.find(tether_network_guid));
101 }
102
103 std::unordered_map<std::string, ExtendedMockTimer*>
104 tether_network_guid_to_timer_map_;
105 };
106
107 HostScanCacheTest() {}
108
109 void SetUp() override {
110 DBusThreadManager::Initialize();
111 NetworkStateTest::SetUp();
112 network_state_handler()->SetTetherTechnologyState(
113 NetworkStateHandler::TECHNOLOGY_ENABLED);
114
115 mock_timer_factory_ = new MockTimerFactory();
116 fake_active_host_ = base::MakeUnique<FakeActiveHost>();
117 mock_tether_host_response_recorder_ =
118 base::MakeUnique<NiceMock<MockTetherHostResponseRecorder>>();
119 device_id_tether_network_guid_map_ =
120 base::MakeUnique<DeviceIdTetherNetworkGuidMap>();
121
122 ON_CALL(*mock_tether_host_response_recorder_,
123 GetPreviouslyConnectedHostIds())
124 .WillByDefault(
125 Invoke(this, &HostScanCacheTest::GetPreviouslyConnectedHostIds));
126
127 host_scan_cache_ = base::WrapUnique(new HostScanCache(
128 base::WrapUnique(mock_timer_factory_), network_state_handler(),
129 fake_active_host_.get(), mock_tether_host_response_recorder_.get(),
130 device_id_tether_network_guid_map_.get()));
131
132 // To track what is expected to be contained in the cache, maintain a
133 // FakeHostScanCache in memory and update it alongside |host_scan_cache_|.
134 // Use a std::vector to track which device IDs correspond to devices whose
135 // Tether networks' HasConnectedToHost fields are expected to be set.
136 expected_cache_ = base::MakeUnique<FakeHostScanCache>();
137 has_connected_to_host_device_ids_.clear();
138 }
139
140 void TearDown() override {
141 ShutdownNetworkState();
142 NetworkStateTest::TearDown();
143 DBusThreadManager::Shutdown();
144 }
145
146 void FireTimer(const std::string& tether_network_guid) {
147 ExtendedMockTimer* timer =
148 mock_timer_factory_
149 ->tether_network_guid_to_timer_map()[tether_network_guid];
150 ASSERT_TRUE(timer);
151 timer->Fire();
152
153 // If the device whose correlated timer has fired is not the active host, it
154 // is expected to be removed from the cache.
155 EXPECT_EQ(fake_active_host_->GetTetherNetworkGuid(),
156 expected_cache_->active_host_tether_network_guid());
157 if (fake_active_host_->GetTetherNetworkGuid() != tether_network_guid) {
158 expected_cache_->RemoveHostScanResult(tether_network_guid);
159 }
160 }
161
162 std::vector<std::string> GetPreviouslyConnectedHostIds() const {
163 return has_connected_to_host_device_ids_;
164 }
165
166 void SetActiveHost(const std::string& tether_network_guid) {
167 fake_active_host_->SetActiveHostConnected(
168 device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid(
169 tether_network_guid),
170 tether_network_guid, "wifiNetworkGuid");
171 expected_cache_->set_active_host_tether_network_guid(tether_network_guid);
172 }
173
174 void SetHasConnectedToHost(const std::string& tether_network_guid) {
175 has_connected_to_host_device_ids_.push_back(
176 device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid(
177 tether_network_guid));
178 mock_tether_host_response_recorder_
179 ->NotifyPreviouslyConnectedHostIdsChanged();
180 }
181
182 // Sets host scan results in the cache for the device at index |index|. Index
183 // can be from 0 to 3 and corresponds to the index of the constants declared
184 // at the top of this test file.
185 void SetCacheScanResultForDeviceIndex(int32_t index) {
186 // There are 4 sets of test constants.
187 ASSERT_TRUE(index >= 0 && index <= 3);
188
189 std::string tether_network_guid;
190 std::string device_name;
191 std::string carrier;
192 int battery_percentage;
193 int signal_strength;
194
195 switch (index) {
196 case 0:
197 tether_network_guid = kTetherGuid0;
198 device_name = kTetherDeviceName0;
199 carrier = kTetherCarrier0;
200 battery_percentage = kTetherBatteryPercentage0;
201 signal_strength = kTetherSignalStrength0;
202 break;
203 case 1:
204 tether_network_guid = kTetherGuid1;
205 device_name = kTetherDeviceName1;
206 carrier = kTetherCarrier1;
207 battery_percentage = kTetherBatteryPercentage1;
208 signal_strength = kTetherSignalStrength1;
209 break;
210 case 2:
211 tether_network_guid = kTetherGuid2;
212 device_name = kTetherDeviceName2;
213 carrier = kTetherCarrier2;
214 battery_percentage = kTetherBatteryPercentage2;
215 signal_strength = kTetherSignalStrength2;
216 break;
217 case 3:
218 tether_network_guid = kTetherGuid3;
219 device_name = kTetherDeviceName3;
220 carrier = kTetherCarrier3;
221 battery_percentage = kTetherBatteryPercentage3;
222 signal_strength = kTetherSignalStrength3;
223 break;
224 default:
225 NOTREACHED();
226 // Set values for |battery_percentage| and |signal_strength| here to
227 // prevent a compiler warning which says that they may be unset at this
228 // point.
229 battery_percentage = 0;
230 signal_strength = 0;
231 break;
232 }
233
234 SetHostScanResult(tether_network_guid, device_name, carrier,
235 battery_percentage, signal_strength);
236 }
237
238 void SetHostScanResult(const std::string& tether_network_guid,
239 const std::string& device_name,
240 const std::string& carrier,
241 int battery_percentage,
242 int signal_strength) {
243 host_scan_cache_->SetHostScanResult(tether_network_guid, device_name,
244 carrier, battery_percentage,
245 signal_strength);
246 expected_cache_->SetHostScanResult(tether_network_guid, device_name,
247 carrier, battery_percentage,
248 signal_strength);
249 }
250
251 void RemoveHostScanResult(const std::string& tether_network_guid) {
252 host_scan_cache_->RemoveHostScanResult(tether_network_guid);
253 expected_cache_->RemoveHostScanResult(tether_network_guid);
254 }
255
256 void ClearCacheExceptForActiveHost() {
257 host_scan_cache_->ClearCacheExceptForActiveHost();
258 expected_cache_->ClearCacheExceptForActiveHost();
259 }
260
261 bool HasConnectedToHost(const std::string& tether_network_guid) {
262 auto it =
263 std::find(has_connected_to_host_device_ids_.begin(),
264 has_connected_to_host_device_ids_.end(), tether_network_guid);
265 return it != has_connected_to_host_device_ids_.end();
266 }
267
268 // Verifies that the information present in |expected_cache_| and
269 // |has_connected_to_host_device_ids_| mirrors what |host_scan_cache_| has set
270 // in NetworkStateHandler.
271 void VerifyCacheMatchesNetworkStack() {
272 for (auto& it : expected_cache_->cache()) {
273 const std::string tether_network_guid = it.first;
274 const FakeHostScanCache::CacheEntry cache_entry = it.second;
275
276 // Ensure that each entry in |expected_cache_| matches the
277 // corresponding entry in NetworkStateHandler.
278 const NetworkState* tether_network_state =
279 network_state_handler()->GetNetworkStateFromGuid(tether_network_guid);
280 ASSERT_TRUE(tether_network_state);
281 EXPECT_EQ(cache_entry.device_name, tether_network_state->name());
282 EXPECT_EQ(cache_entry.carrier, tether_network_state->carrier());
283 EXPECT_EQ(cache_entry.battery_percentage,
284 tether_network_state->battery_percentage());
285 EXPECT_EQ(cache_entry.signal_strength,
286 tether_network_state->signal_strength());
287 EXPECT_EQ(HasConnectedToHost(tether_network_guid),
288 tether_network_state->tether_has_connected_to_host());
289
290 // Ensure that each entry has an actively-running Timer.
291 auto timer_map_it =
292 mock_timer_factory_->tether_network_guid_to_timer_map().begin();
293 EXPECT_NE(timer_map_it,
294 mock_timer_factory_->tether_network_guid_to_timer_map().end());
295 EXPECT_TRUE(timer_map_it->second->IsRunning());
296 }
297 }
298
299 const base::test::ScopedTaskEnvironment scoped_task_environment_;
300
301 MockTimerFactory* mock_timer_factory_;
302 std::unique_ptr<FakeActiveHost> fake_active_host_;
303 std::unique_ptr<NiceMock<MockTetherHostResponseRecorder>>
304 mock_tether_host_response_recorder_;
305 // TODO(hansberry): Use a fake for this when a real mapping scheme is created.
306 std::unique_ptr<DeviceIdTetherNetworkGuidMap>
307 device_id_tether_network_guid_map_;
308
309 std::vector<std::string> has_connected_to_host_device_ids_;
310 std::unique_ptr<FakeHostScanCache> expected_cache_;
311
312 std::unique_ptr<HostScanCache> host_scan_cache_;
313
314 private:
315 DISALLOW_COPY_AND_ASSIGN(HostScanCacheTest);
316 };
317
318 TEST_F(HostScanCacheTest, TestSetScanResultsAndLetThemExpire) {
319 SetCacheScanResultForDeviceIndex(0);
320 EXPECT_EQ(1u, expected_cache_->size());
321 VerifyCacheMatchesNetworkStack();
322
323 SetCacheScanResultForDeviceIndex(1);
324 EXPECT_EQ(2u, expected_cache_->size());
325 VerifyCacheMatchesNetworkStack();
326
327 SetCacheScanResultForDeviceIndex(2);
328 EXPECT_EQ(3u, expected_cache_->size());
329 VerifyCacheMatchesNetworkStack();
330
331 SetCacheScanResultForDeviceIndex(3);
332 EXPECT_EQ(4u, expected_cache_->size());
333 VerifyCacheMatchesNetworkStack();
334
335 FireTimer(kTetherGuid0);
336 EXPECT_EQ(3u, expected_cache_->size());
337 VerifyCacheMatchesNetworkStack();
338
339 FireTimer(kTetherGuid1);
340 EXPECT_EQ(2u, expected_cache_->size());
341 VerifyCacheMatchesNetworkStack();
342
343 FireTimer(kTetherGuid2);
344 EXPECT_EQ(1u, expected_cache_->size());
345 VerifyCacheMatchesNetworkStack();
346
347 FireTimer(kTetherGuid3);
348 EXPECT_TRUE(expected_cache_->empty());
349 VerifyCacheMatchesNetworkStack();
350 }
351
352 TEST_F(HostScanCacheTest, TestSetScanResultThenUpdateAndRemove) {
353 SetCacheScanResultForDeviceIndex(0);
354 EXPECT_EQ(1u, expected_cache_->size());
355 VerifyCacheMatchesNetworkStack();
356
357 // Change the fields for tether network with GUID |kTetherGuid0| to the
358 // fields corresponding to |kTetherGuid1|.
359 SetHostScanResult(kTetherGuid0, kTetherDeviceName0, kTetherCarrier1,
360 kTetherBatteryPercentage1, kTetherSignalStrength1);
361 EXPECT_EQ(1u, expected_cache_->size());
362 VerifyCacheMatchesNetworkStack();
363
364 // Now, remove that result.
365 RemoveHostScanResult(kTetherGuid0);
366 EXPECT_TRUE(expected_cache_->empty());
367 VerifyCacheMatchesNetworkStack();
368 }
369
370 TEST_F(HostScanCacheTest, TestSetScanResult_SetActiveHost_ThenClear) {
371 SetCacheScanResultForDeviceIndex(0);
372 EXPECT_EQ(1u, expected_cache_->size());
373 VerifyCacheMatchesNetworkStack();
374
375 SetCacheScanResultForDeviceIndex(1);
376 EXPECT_EQ(2u, expected_cache_->size());
377 VerifyCacheMatchesNetworkStack();
378
379 SetCacheScanResultForDeviceIndex(2);
380 EXPECT_EQ(3u, expected_cache_->size());
381 VerifyCacheMatchesNetworkStack();
382
383 // Now, set the active host to be the device 0.
384 SetActiveHost(kTetherGuid0);
385
386 // Clear the cache except for the active host.
387 ClearCacheExceptForActiveHost();
388 EXPECT_EQ(1u, expected_cache_->size());
389 VerifyCacheMatchesNetworkStack();
390
391 // Attempt to remove the active host. This operation should fail since
392 // removing the active host from the cache is not allowed.
393 RemoveHostScanResult(kTetherGuid0);
394 EXPECT_EQ(1u, expected_cache_->size());
395 VerifyCacheMatchesNetworkStack();
396
397 // Fire the timer for the active host. Likewise, this should not result in the
398 // cache entry being removed.
399 FireTimer(kTetherGuid0);
400 EXPECT_EQ(1u, expected_cache_->size());
401 VerifyCacheMatchesNetworkStack();
402
403 // Now, unset the active host.
404 SetActiveHost("");
405
406 // Removing the device should now succeed.
407 RemoveHostScanResult(kTetherGuid0);
408 EXPECT_TRUE(expected_cache_->empty());
409 VerifyCacheMatchesNetworkStack();
410 }
411
412 TEST_F(HostScanCacheTest, TestHasConnectedToHost) {
413 // Before the test starts, set device 0 as having already connected.
414 SetHasConnectedToHost(kTetherGuid0);
415
416 SetCacheScanResultForDeviceIndex(0);
417 EXPECT_EQ(1u, expected_cache_->size());
418 VerifyCacheMatchesNetworkStack();
419
420 SetCacheScanResultForDeviceIndex(1);
421 EXPECT_EQ(2u, expected_cache_->size());
422 VerifyCacheMatchesNetworkStack();
423
424 // Simulate a connection to device 1.
425 SetActiveHost(kTetherGuid1);
426 SetHasConnectedToHost(kTetherGuid1);
427 VerifyCacheMatchesNetworkStack();
428 }
429
430 } // namespace tether
431
432 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698