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

Side by Side Diff: chrome/browser/media/router/discovery/dial/device_description_service_unittest.cc

Issue 2701633002: [Media Router] Add DialMediaSinkService and DeviceDescriptionService (Closed)
Patch Set: merge with master Created 3 years, 8 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 "chrome/browser/media/router/discovery/dial/device_description_service. h"
6
7 #include "base/strings/stringprintf.h"
8 #include "base/test/mock_callback.h"
9 #include "chrome/browser/media/router/discovery/dial/device_description_fetcher. h"
10 #include "chrome/browser/media/router/discovery/dial/dial_device_data.h"
11 #include "chrome/browser/media/router/discovery/dial/parsed_dial_device_descript ion.h"
12 #include "chrome/browser/media/router/discovery/dial/safe_dial_device_descriptio n_parser.h"
13 #include "chrome/test/base/testing_profile.h"
14 #include "content/public/test/test_browser_thread_bundle.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 using ::testing::_;
19 using ::testing::Return;
20 using ::testing::SaveArg;
21
22 namespace media_router {
23
24 class TestSafeDialDeviceDescriptionParser
25 : public SafeDialDeviceDescriptionParser {
26 public:
27 void Start(const std::string& xml_text,
imcheng 2017/04/25 01:40:12 Do you intend to mock out this method?
zhaobin 2017/04/26 18:50:04 Done.
28 const DeviceDescriptionCallback& callback) override {}
29 };
30
31 class TestDeviceDescriptionService : public DeviceDescriptionService {
32 public:
33 TestDeviceDescriptionService(
34 const DeviceDescriptionParseSuccessCallback& success_cb,
35 const DeviceDescriptionParseErrorCallback& error_cb)
36 : DeviceDescriptionService(success_cb, error_cb) {}
37
38 MOCK_METHOD0(CreateSafeParser, SafeDialDeviceDescriptionParser*());
39 };
40
41 class DeviceDescriptionServiceTest : public ::testing::Test {
42 public:
43 DeviceDescriptionServiceTest()
44 : device_description_service_(mock_success_cb_.Get(),
45 mock_error_cb_.Get()),
46 fetcher_map_(
47 device_description_service_.device_description_fetcher_map_),
48 description_map_(device_description_service_.description_map_),
49 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
50
51 TestDeviceDescriptionService* device_description_service() {
52 return &device_description_service_;
53 }
54
55 // Create Test Data
mark a. foltz 2017/04/25 21:06:26 These static methods to create test data could go
zhaobin 2017/04/26 18:50:04 Done.
56 static DialDeviceData CreateDialDeviceData(int num) {
57 DialDeviceData device_data(
58 base::StringPrintf("Device id %d", num),
59 GURL(base::StringPrintf("http://192.168.1.%d/dd.xml", num)),
60 base::Time::Now());
61 device_data.set_label(base::StringPrintf("Device label %d", num));
62 return device_data;
63 }
64
65 static DialDeviceDescriptionData CreateDialDeviceDescriptionData(int num) {
66 return DialDeviceDescriptionData(
67 "", GURL(base::StringPrintf("http://192.168.1.%d/apps", num)));
68 }
69
70 static chrome::mojom::DialDeviceDescriptionPtr CreateDialDeviceDescriptionPtr(
71 int num) {
72 chrome::mojom::DialDeviceDescriptionPtr description_ptr =
73 chrome::mojom::DialDeviceDescription::New();
74 description_ptr->friendly_name =
75 base::StringPrintf("Friendly name %d", num);
76 description_ptr->model_name = base::StringPrintf("Model name %d", num);
77 description_ptr->unique_id = base::StringPrintf("Unique ID %d", num);
78 return description_ptr;
79 }
80
81 static ParsedDialDeviceDescription CreateParsedDialDeviceDescription(
82 int num) {
83 ParsedDialDeviceDescription description_data;
84 description_data.app_url =
85 GURL(base::StringPrintf("http://192.168.1.%d/apps", num));
86 description_data.friendly_name =
87 base::StringPrintf("Friendly name %d", num);
88 description_data.model_name = base::StringPrintf("Model name %d", num);
89 description_data.unique_id = base::StringPrintf("Unique ID %d", num);
90 return description_data;
91 }
92
93 void AddToCache(const std::string& device_label,
94 const ParsedDialDeviceDescription& description_data,
95 bool expired) {
96 DeviceDescriptionService::CacheEntry cache_entry;
97 cache_entry.expire_time = base::Time::Now();
98 if (!expired)
99 cache_entry.expire_time += base::TimeDelta::FromHours(12);
100 cache_entry.description_data = description_data;
101 description_map_[device_label] = cache_entry;
102 }
103
104 void OnDeviceDescriptionFetchComplete(int num) {
105 if (!device_description_service_.parser_) {
106 device_description_service_.parser_ =
107 base::MakeUnique<TestSafeDialDeviceDescriptionParser>();
108 }
109
110 auto device_data = CreateDialDeviceData(num);
111 auto description_response_data = CreateDialDeviceDescriptionData(num);
112 auto parsed_description_data = CreateParsedDialDeviceDescription(num);
113
114 EXPECT_CALL(mock_success_cb_, Run(device_data, parsed_description_data));
115
116 device_description_service_.OnDeviceDescriptionFetchComplete(
117 device_data, description_response_data);
118 device_description_service_.OnParsedDeviceDescription(
119 device_data, description_response_data.app_url,
120 CreateDialDeviceDescriptionPtr(num));
121 }
122
123 void TestOnParsedDeviceDescription(
124 chrome::mojom::DialDeviceDescriptionPtr description_ptr,
125 const std::string& error_message) {
126 GURL app_url("http://192.168.1.1/apps");
127 auto device_data = CreateDialDeviceData(1);
128 auto description_data = CreateParsedDialDeviceDescription(1);
129
130 if (!error_message.empty()) {
131 EXPECT_CALL(mock_error_cb_, Run(device_data, error_message));
132 } else {
133 EXPECT_CALL(mock_success_cb_, Run(device_data, description_data));
134 }
135 device_description_service()->OnParsedDeviceDescription(
136 device_data, app_url, std::move(description_ptr));
137 }
138
139 protected:
140 base::MockCallback<
141 DeviceDescriptionService::DeviceDescriptionParseSuccessCallback>
142 mock_success_cb_;
143 base::MockCallback<
144 DeviceDescriptionService::DeviceDescriptionParseErrorCallback>
145 mock_error_cb_;
146
147 TestDeviceDescriptionService device_description_service_;
148 std::map<std::string, std::unique_ptr<DeviceDescriptionFetcher>>&
149 fetcher_map_;
150 std::map<std::string, DeviceDescriptionService::CacheEntry>& description_map_;
151
152 const content::TestBrowserThreadBundle thread_bundle_;
153 TestingProfile profile_;
154 };
155
156 TEST_F(DeviceDescriptionServiceTest, TestGetDeviceDescriptionFromCache) {
157 auto device_data = CreateDialDeviceData(1);
158 auto description_data = CreateParsedDialDeviceDescription(1);
159 EXPECT_CALL(mock_success_cb_, Run(device_data, description_data));
160
161 AddToCache(device_data.label(), description_data, false /* expired */);
162
163 std::vector<DialDeviceData> devices = {device_data};
164 device_description_service()->GetDeviceDescriptions(devices, nullptr);
165 }
166
167 TEST_F(DeviceDescriptionServiceTest, TestGetDeviceDescriptionFetchURL) {
168 DialDeviceData device_data = CreateDialDeviceData(1);
169 std::vector<DialDeviceData> devices = {device_data};
170
171 // Create Fetcher
172 EXPECT_TRUE(fetcher_map_.empty());
173 device_description_service()->GetDeviceDescriptions(
174 devices, profile_.GetRequestContext());
175 EXPECT_EQ(size_t(1), fetcher_map_.size());
176
177 // Remove fetcher and create safe parser
178 OnDeviceDescriptionFetchComplete(1);
179 }
180
181 TEST_F(DeviceDescriptionServiceTest, TestGetDeviceDescriptionFetchURLError) {
182 DialDeviceData device_data = CreateDialDeviceData(1);
183 std::vector<DialDeviceData> devices;
184 devices.push_back(device_data);
185
186 // Create Fetcher
187 EXPECT_TRUE(fetcher_map_.empty());
188 device_description_service()->GetDeviceDescriptions(
189 devices, profile_.GetRequestContext());
190 EXPECT_EQ(size_t(1), fetcher_map_.size());
191
192 EXPECT_CALL(mock_error_cb_, Run(device_data, ""));
193
194 device_description_service()->OnDeviceDescriptionFetchError(device_data, "");
195 EXPECT_TRUE(fetcher_map_.empty());
196 }
197
198 TEST_F(DeviceDescriptionServiceTest,
199 TestGetDeviceDescriptionRemoveOutDatedFetchers) {
200 DialDeviceData device_data_1 = CreateDialDeviceData(1);
201 DialDeviceData device_data_2 = CreateDialDeviceData(2);
202 DialDeviceData device_data_3 = CreateDialDeviceData(3);
203
204 std::vector<DialDeviceData> devices;
205 devices.push_back(device_data_1);
206 devices.push_back(device_data_2);
207
208 // insert fetchers
209 device_description_service()->GetDeviceDescriptions(
210 devices, profile_.GetRequestContext());
211
212 // Keep fetchers no exist in current device list and remove fetchers with
213 // different description url.
214 GURL new_url_2 = GURL("http://example.com");
215 device_data_2.set_device_description_url(new_url_2);
216
217 devices.clear();
218 devices.push_back(device_data_2);
219 devices.push_back(device_data_3);
220 device_description_service()->GetDeviceDescriptions(
221 devices, profile_.GetRequestContext());
222
223 EXPECT_EQ(size_t(3), fetcher_map_.size());
224
225 auto* description_fetcher = fetcher_map_[device_data_2.label()].get();
226 EXPECT_EQ(new_url_2, description_fetcher->device_description_url());
227
228 EXPECT_CALL(mock_error_cb_, Run(_, _)).Times(3);
229 device_description_service()->OnDeviceDescriptionFetchError(device_data_1,
230 "");
231 device_description_service()->OnDeviceDescriptionFetchError(device_data_2,
mark a. foltz 2017/04/25 21:06:26 Is this asserting that the original fetcher for |d
zhaobin 2017/04/26 18:50:04 No, |device_data_2| will fail quietly without any
232 "");
233 device_description_service()->OnDeviceDescriptionFetchError(device_data_3,
234 "");
235 }
236
237 TEST_F(DeviceDescriptionServiceTest, TestCleanUpCacheEntries) {
238 DialDeviceData device_data_1 = CreateDialDeviceData(1);
239 DialDeviceData device_data_2 = CreateDialDeviceData(2);
240 DialDeviceData device_data_3 = CreateDialDeviceData(3);
241
242 AddToCache(device_data_1.label(), ParsedDialDeviceDescription(),
243 true /* expired */);
244 AddToCache(device_data_2.label(), ParsedDialDeviceDescription(),
245 true /* expired */);
246 AddToCache(device_data_3.label(), ParsedDialDeviceDescription(),
247 false /* expired */);
248
249 device_description_service_.CleanUpCacheEntries();
250 EXPECT_EQ(size_t(1), description_map_.size());
mark a. foltz 2017/04/25 21:06:26 Nit: Check that device 3 specifically is not remov
zhaobin 2017/04/26 18:50:04 Done.
251
252 AddToCache(device_data_3.label(), ParsedDialDeviceDescription(),
253 true /* expired*/);
254 device_description_service_.CleanUpCacheEntries();
255 EXPECT_TRUE(description_map_.empty());
256 }
257
258 TEST_F(DeviceDescriptionServiceTest, TestOnParsedDeviceDescription) {
259 GURL app_url("http://192.168.1.1/apps");
260 DialDeviceData device_data = CreateDialDeviceData(1);
261
262 // null_ptr
263 std::string error_message = "Failed to parse device description xml";
264 TestOnParsedDeviceDescription(nullptr, error_message);
265
266 // Empty field
267 error_message = "Failed to process fetch result";
268 TestOnParsedDeviceDescription(chrome::mojom::DialDeviceDescription::New(),
269 error_message);
270
271 // Valid device description ptr and put in cache
272 auto description_ptr = CreateDialDeviceDescriptionPtr(1);
273 TestOnParsedDeviceDescription(std::move(description_ptr), "");
274 EXPECT_EQ(size_t(1), description_map_.size());
275
276 // Valid device description ptr and skip cache.
277 size_t cache_num = 256;
278 for (size_t i = 0; i < cache_num; i++) {
279 AddToCache(std::to_string(i), ParsedDialDeviceDescription(),
280 false /* expired */);
281 }
282
283 EXPECT_EQ(size_t(cache_num + 1), description_map_.size());
284 description_ptr = CreateDialDeviceDescriptionPtr(1);
285 TestOnParsedDeviceDescription(std::move(description_ptr), "");
286 EXPECT_EQ(size_t(cache_num + 1), description_map_.size());
287 }
288
289 TEST_F(DeviceDescriptionServiceTest, TestSafeParserProperlyCreated) {
290 DialDeviceData device_data_1 = CreateDialDeviceData(1);
291 DialDeviceData device_data_2 = CreateDialDeviceData(2);
292 DialDeviceData device_data_3 = CreateDialDeviceData(3);
293
294 std::vector<DialDeviceData> devices = {device_data_1, device_data_2,
295 device_data_3};
296
297 // insert fetchers
298 device_description_service()->GetDeviceDescriptions(
299 devices, profile_.GetRequestContext());
300
301 EXPECT_FALSE(device_description_service()->parser_);
302 OnDeviceDescriptionFetchComplete(1);
303
304 EXPECT_TRUE(device_description_service()->parser_);
305 OnDeviceDescriptionFetchComplete(2);
306 OnDeviceDescriptionFetchComplete(3);
307
308 EXPECT_FALSE(device_description_service()->parser_);
309 }
310
311 } // namespace media_router
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698