OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/component_updater/sw_reporter_installer_win.h" | 5 #include "chrome/browser/component_updater/sw_reporter_installer_win.h" |
6 | 6 |
7 #include <map> | |
7 #include <memory> | 8 #include <memory> |
9 #include <string> | |
10 #include <utility> | |
8 #include <vector> | 11 #include <vector> |
9 | 12 |
10 #include "base/bind.h" | 13 #include "base/bind.h" |
11 #include "base/bind_helpers.h" | 14 #include "base/bind_helpers.h" |
12 #include "base/command_line.h" | 15 #include "base/command_line.h" |
16 #include "base/feature_list.h" | |
13 #include "base/files/file_path.h" | 17 #include "base/files/file_path.h" |
18 #include "base/json/json_reader.h" | |
14 #include "base/macros.h" | 19 #include "base/macros.h" |
20 #include "base/metrics/field_trial.h" | |
21 #include "base/strings/stringprintf.h" | |
22 #include "base/test/histogram_tester.h" | |
23 #include "base/test/scoped_feature_list.h" | |
15 #include "base/values.h" | 24 #include "base/values.h" |
16 #include "base/version.h" | 25 #include "base/version.h" |
17 #include "chrome/browser/safe_browsing/srt_fetcher_win.h" | 26 #include "chrome/browser/safe_browsing/srt_fetcher_win.h" |
27 #include "components/variations/variations_associated_data.h" | |
18 #include "content/public/test/test_browser_thread_bundle.h" | 28 #include "content/public/test/test_browser_thread_bundle.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
20 | 30 |
21 namespace component_updater { | 31 namespace component_updater { |
22 | 32 |
33 namespace { | |
34 | |
35 constexpr char kExperimentGroupName[] = "ExperimentalSwReporterEngine"; | |
36 | |
37 // These MUST match the values for SwReporterExperimentError in histograms.xml. | |
38 enum ExperimentError { | |
csharp
2016/08/25 19:47:28
What about putting this into the header (with a sl
Joe Mason
2016/08/25 22:03:20
Done.
| |
39 EXPERIMENT_ERROR_BAD_TAG = 0, | |
40 EXPERIMENT_ERROR_BAD_PARAMS = 1, | |
41 EXPERIMENT_ERROR_MAX, | |
42 }; | |
43 | |
44 }; // namespace | |
45 | |
23 class SwReporterInstallerTest : public ::testing::Test { | 46 class SwReporterInstallerTest : public ::testing::Test { |
24 public: | 47 public: |
25 SwReporterInstallerTest() | 48 SwReporterInstallerTest() |
26 : traits_(base::Bind(&SwReporterInstallerTest::SwReporterLaunched, | 49 : launched_callback_( |
27 base::Unretained(this))), | 50 base::Bind(&SwReporterInstallerTest::SwReporterLaunched, |
51 base::Unretained(this))), | |
28 default_version_("1.2.3"), | 52 default_version_("1.2.3"), |
29 default_path_(L"C:\\full\\path\\to\\download") {} | 53 default_path_(L"C:\\full\\path\\to\\download") {} |
30 | 54 |
csharp
2016/08/25 19:47:28
nit: Please add a virtual deconstructor
Joe Mason
2016/08/25 22:03:20
Done.
| |
31 protected: | 55 protected: |
32 // Each test fixture inherits from |SwReporterInstallerTest|, and friendship | |
33 // is not transitive so they will not have access to |ComponentReady|. Use | |
34 // this helper function to call it. | |
35 void TestComponentReady(const base::Version& version, | |
36 const base::FilePath& path) { | |
37 traits_.ComponentReady(version, path, | |
38 std::make_unique<base::DictionaryValue>()); | |
39 } | |
40 | |
41 void SwReporterLaunched(const safe_browsing::SwReporterInvocation& invocation, | 56 void SwReporterLaunched(const safe_browsing::SwReporterInvocation& invocation, |
42 const base::Version& version) { | 57 const base::Version& version) { |
43 ASSERT_TRUE(launched_invocations_.empty()); | 58 ASSERT_TRUE(launched_invocations_.empty()); |
44 launched_invocations_.push_back(invocation); | 59 launched_invocations_.push_back(invocation); |
45 launched_version_ = version; | 60 launched_version_ = version; |
46 } | 61 } |
47 | 62 |
48 base::FilePath MakeTestFilePath(const base::FilePath& path) const { | 63 base::FilePath MakeTestFilePath(const base::FilePath& path) const { |
49 return path.Append(L"software_reporter_tool.exe"); | 64 return path.Append(L"software_reporter_tool.exe"); |
50 } | 65 } |
51 | 66 |
67 // Expects that the SwReporter was launched exactly once, with no arguments. | |
68 void ExpectDefaultInvocation() const { | |
69 EXPECT_EQ(default_version_, launched_version_); | |
70 ASSERT_EQ(1U, launched_invocations_.size()); | |
71 | |
72 const safe_browsing::SwReporterInvocation& invocation = | |
73 launched_invocations_[0]; | |
74 EXPECT_EQ(MakeTestFilePath(default_path_), | |
75 invocation.command_line.GetProgram()); | |
76 EXPECT_TRUE(invocation.command_line.GetSwitches().empty()); | |
77 EXPECT_TRUE(invocation.command_line.GetArgs().empty()); | |
78 EXPECT_TRUE(invocation.suffix.empty()); | |
79 EXPECT_FALSE(invocation.is_experimental); | |
80 } | |
81 | |
52 // |ComponentReady| asserts that it is run on the UI thread, so we must | 82 // |ComponentReady| asserts that it is run on the UI thread, so we must |
53 // create test threads before calling it. | 83 // create test threads before calling it. |
54 content::TestBrowserThreadBundle threads_; | 84 content::TestBrowserThreadBundle threads_; |
55 | 85 |
56 // The traits object to test. | 86 // Bound callback to the |SwReporterLaunched| method. |
57 SwReporterInstallerTraits traits_; | 87 SwReporterRunner launched_callback_; |
58 | 88 |
59 // Default parameters for |ComponentReady|. | 89 // Default parameters for |ComponentReady|. |
60 base::Version default_version_; | 90 base::Version default_version_; |
61 base::FilePath default_path_; | 91 base::FilePath default_path_; |
62 | 92 |
63 // Results of running |ComponentReady|. | 93 // Results of running |ComponentReady|. |
64 std::vector<safe_browsing::SwReporterInvocation> launched_invocations_; | 94 std::vector<safe_browsing::SwReporterInvocation> launched_invocations_; |
65 base::Version launched_version_; | 95 base::Version launched_version_; |
66 | 96 |
67 private: | 97 private: |
68 DISALLOW_COPY_AND_ASSIGN(SwReporterInstallerTest); | 98 DISALLOW_COPY_AND_ASSIGN(SwReporterInstallerTest); |
69 }; | 99 }; |
70 | 100 |
101 // This class contains extended setup that is only used for tests of the | |
102 // experimental reporter. | |
103 class ExperimentalSwReporterInstallerTest : public SwReporterInstallerTest { | |
104 public: | |
105 ExperimentalSwReporterInstallerTest() {} | |
106 | |
csharp
2016/08/25 19:47:28
nit: Please add a virtual deconstructor
Joe Mason
2016/08/25 22:03:20
Done.
| |
107 protected: | |
108 void CreateFeatureWithoutTag() { | |
109 std::map<std::string, std::string> params; | |
110 CreateFeatureWithParams(params); | |
111 } | |
112 | |
113 void CreateFeatureWithTag(const std::string& tag) { | |
114 std::map<std::string, std::string> params; | |
115 params["tag"] = tag; | |
116 CreateFeatureWithParams(params); | |
117 } | |
118 | |
119 void CreateFeatureWithParams( | |
csharp
2016/08/25 19:47:28
nit: Worth making this private to ensure users cal
Joe Mason
2016/08/25 22:03:20
There's no reason a unit test couldn't create a cu
| |
120 const std::map<std::string, std::string>& params) { | |
121 // Assign the given variation params to the experiment group until | |
122 // |variations_| goes out of scope when the test exits. This will also | |
123 // create a FieldTrial for this group. | |
124 variations_ = std::make_unique<variations::testing::VariationParamsManager>( | |
125 kExperimentGroupName, params); | |
126 | |
127 // Create a feature list containing only the field trial for this group, | |
128 // and enable it for the length of the test. | |
129 base::FieldTrial* trial = base::FieldTrialList::Find(kExperimentGroupName); | |
130 ASSERT_TRUE(trial); | |
131 auto feature_list = std::make_unique<base::FeatureList>(); | |
132 feature_list->RegisterFieldTrialOverride( | |
133 kExperimentGroupName, base::FeatureList::OVERRIDE_ENABLE_FEATURE, | |
134 trial); | |
135 scoped_feature_list_.InitWithFeatureList(std::move(feature_list)); | |
136 } | |
137 | |
138 // Expects that the SwReporter was launched exactly once, with the given | |
139 // |expected_suffix| and one |expected_additional_argument| on the | |
140 // command-line. (|expected_additional_argument| mainly exists to test that | |
141 // arguments are included at all, so there is no need to test for | |
142 // combinations of multiple arguments and switches in this function.) | |
143 void ExpectExperimentalInvocation( | |
144 const std::string& expected_suffix, | |
145 const base::string16& expected_additional_argument) { | |
146 EXPECT_EQ(default_version_, launched_version_); | |
147 ASSERT_EQ(1U, launched_invocations_.size()); | |
148 | |
149 const safe_browsing::SwReporterInvocation& invocation = | |
150 launched_invocations_[0]; | |
151 EXPECT_EQ(MakeTestFilePath(default_path_), | |
152 invocation.command_line.GetProgram()); | |
153 if (expected_suffix.empty()) { | |
154 EXPECT_TRUE(invocation.command_line.GetSwitches().empty()); | |
155 EXPECT_TRUE(invocation.suffix.empty()); | |
156 } else { | |
157 EXPECT_EQ(1U, invocation.command_line.GetSwitches().size()); | |
158 EXPECT_EQ(expected_suffix, | |
159 invocation.command_line.GetSwitchValueASCII("registry-suffix")); | |
160 EXPECT_EQ(expected_suffix, invocation.suffix); | |
161 } | |
162 if (expected_additional_argument.empty()) { | |
csharp
2016/08/25 19:47:28
nit: Please add a blank line above
Joe Mason
2016/08/25 22:03:20
Done.
| |
163 EXPECT_TRUE(invocation.command_line.GetArgs().empty()); | |
164 } else { | |
165 EXPECT_EQ(1U, invocation.command_line.GetArgs().size()); | |
166 EXPECT_EQ(expected_additional_argument, | |
167 invocation.command_line.GetArgs()[0]); | |
168 } | |
169 EXPECT_TRUE(invocation.is_experimental); | |
170 histograms_.ExpectTotalCount("SoftwareReporter.ExperimentErrors", 0); | |
171 } | |
172 | |
173 std::unique_ptr<variations::testing::VariationParamsManager> variations_; | |
174 base::test::ScopedFeatureList scoped_feature_list_; | |
175 base::HistogramTester histograms_; | |
176 | |
177 private: | |
178 DISALLOW_COPY_AND_ASSIGN(ExperimentalSwReporterInstallerTest); | |
179 }; | |
180 | |
71 TEST_F(SwReporterInstallerTest, Default) { | 181 TEST_F(SwReporterInstallerTest, Default) { |
72 TestComponentReady(default_version_, default_path_); | 182 SwReporterInstallerTraits traits(launched_callback_, false); |
73 | 183 |
74 // The SwReporter should be launched exactly once, with no arguments. | 184 update_client::InstallerAttributes attributes = |
185 traits.GetInstallerAttributes(); | |
186 EXPECT_TRUE(attributes.empty()); | |
187 | |
188 traits.ComponentReady(default_version_, default_path_, | |
189 std::make_unique<base::DictionaryValue>()); | |
190 ExpectDefaultInvocation(); | |
191 } | |
192 | |
193 TEST_F(ExperimentalSwReporterInstallerTest, NoExperimentConfig) { | |
194 // Even if the experiment is supported on this hardware, the user shouldn't | |
195 // be enrolled unless enabled through variations. | |
196 SwReporterInstallerTraits traits(launched_callback_, true); | |
197 | |
198 update_client::InstallerAttributes attributes = | |
199 traits.GetInstallerAttributes(); | |
200 EXPECT_TRUE(attributes.empty()); | |
201 | |
202 traits.ComponentReady(default_version_, default_path_, | |
203 std::make_unique<base::DictionaryValue>()); | |
204 ExpectDefaultInvocation(); | |
205 } | |
206 | |
207 TEST_F(ExperimentalSwReporterInstallerTest, ExperimentUnsupported) { | |
208 // Even if the experiment config is enabled in variations, the user shouldn't | |
209 // be enrolled if the hardware doesn't support it. | |
210 SwReporterInstallerTraits traits(launched_callback_, false); | |
211 CreateFeatureWithTag("experiment_tag"); | |
212 | |
213 update_client::InstallerAttributes attributes = | |
214 traits.GetInstallerAttributes(); | |
215 EXPECT_TRUE(attributes.empty()); | |
216 | |
217 traits.ComponentReady(default_version_, default_path_, | |
218 std::make_unique<base::DictionaryValue>()); | |
219 ExpectDefaultInvocation(); | |
220 } | |
221 | |
222 TEST_F(ExperimentalSwReporterInstallerTest, ExperimentMissingTag) { | |
223 SwReporterInstallerTraits traits(launched_callback_, true); | |
224 CreateFeatureWithoutTag(); | |
225 | |
226 update_client::InstallerAttributes attributes = | |
227 traits.GetInstallerAttributes(); | |
228 EXPECT_EQ(1U, attributes.size()); | |
229 EXPECT_EQ("missing_tag", attributes["tag"]); | |
230 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors", | |
231 EXPERIMENT_ERROR_BAD_TAG, 1); | |
232 } | |
233 | |
234 TEST_F(ExperimentalSwReporterInstallerTest, ExperimentInvalidTag) { | |
235 SwReporterInstallerTraits traits(launched_callback_, true); | |
236 CreateFeatureWithTag("tag with invalid whitespace chars"); | |
237 | |
238 update_client::InstallerAttributes attributes = | |
239 traits.GetInstallerAttributes(); | |
240 EXPECT_EQ(1U, attributes.size()); | |
241 EXPECT_EQ("missing_tag", attributes["tag"]); | |
242 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors", | |
243 EXPERIMENT_ERROR_BAD_TAG, 1); | |
244 } | |
245 | |
246 TEST_F(ExperimentalSwReporterInstallerTest, ExperimentTagTooLong) { | |
247 SwReporterInstallerTraits traits(launched_callback_, true); | |
248 std::string tag_too_long(500, 'x'); | |
249 CreateFeatureWithTag(tag_too_long); | |
250 | |
251 update_client::InstallerAttributes attributes = | |
252 traits.GetInstallerAttributes(); | |
253 EXPECT_EQ(1U, attributes.size()); | |
254 EXPECT_EQ("missing_tag", attributes["tag"]); | |
255 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors", | |
256 EXPERIMENT_ERROR_BAD_TAG, 1); | |
257 } | |
258 | |
259 TEST_F(ExperimentalSwReporterInstallerTest, ExperimentEmptyTag) { | |
260 SwReporterInstallerTraits traits(launched_callback_, true); | |
261 CreateFeatureWithTag(""); | |
262 | |
263 update_client::InstallerAttributes attributes = | |
264 traits.GetInstallerAttributes(); | |
265 EXPECT_EQ(1U, attributes.size()); | |
266 EXPECT_EQ("missing_tag", attributes["tag"]); | |
csharp
2016/08/25 19:47:28
nit: Make a const for "missing_tag" since it is us
Joe Mason
2016/08/25 22:03:20
Done.
| |
267 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors", | |
268 EXPERIMENT_ERROR_BAD_TAG, 1); | |
269 } | |
270 | |
271 TEST_F(ExperimentalSwReporterInstallerTest, SingleInvocation) { | |
272 SwReporterInstallerTraits traits(launched_callback_, true); | |
273 CreateFeatureWithTag("experiment_tag"); | |
csharp
2016/08/25 19:47:28
make a const for experiment_tag too?
Joe Mason
2016/08/25 22:03:20
Done.
| |
274 | |
275 update_client::InstallerAttributes attributes = | |
276 traits.GetInstallerAttributes(); | |
277 EXPECT_EQ(1U, attributes.size()); | |
278 EXPECT_EQ("experiment_tag", attributes["tag"]); | |
279 | |
280 static constexpr char kTestManifest[] = | |
281 "{\"launch_params\": [" | |
282 " {" | |
283 " \"arguments\": [\"--engine=experimental\", \"random argument\"]," | |
284 " \"suffix\": \"Experimental\"" | |
csharp
2016/08/25 19:47:28
nit: what about making the suffix just "suffix", t
Joe Mason
2016/08/25 22:03:20
Done.
| |
285 " }" | |
286 "]}"; | |
287 traits.ComponentReady( | |
288 default_version_, default_path_, | |
289 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest))); | |
290 | |
291 // The SwReporter should be launched once with the given arguments. | |
75 EXPECT_EQ(default_version_, launched_version_); | 292 EXPECT_EQ(default_version_, launched_version_); |
76 ASSERT_EQ(1U, launched_invocations_.size()); | 293 ASSERT_EQ(1U, launched_invocations_.size()); |
77 | 294 |
78 const safe_browsing::SwReporterInvocation& invocation = | 295 const safe_browsing::SwReporterInvocation& invocation = |
79 launched_invocations_[0]; | 296 launched_invocations_[0]; |
80 EXPECT_EQ(MakeTestFilePath(default_path_), | 297 EXPECT_EQ(MakeTestFilePath(default_path_), |
81 invocation.command_line.GetProgram()); | 298 invocation.command_line.GetProgram()); |
82 EXPECT_TRUE(invocation.command_line.GetSwitches().empty()); | 299 EXPECT_EQ(2U, invocation.command_line.GetSwitches().size()); |
83 EXPECT_TRUE(invocation.command_line.GetArgs().empty()); | 300 EXPECT_EQ("experimental", |
301 invocation.command_line.GetSwitchValueASCII("engine")); | |
302 EXPECT_EQ("Experimental", | |
303 invocation.command_line.GetSwitchValueASCII("registry-suffix")); | |
304 ASSERT_EQ(1U, invocation.command_line.GetArgs().size()); | |
305 EXPECT_EQ(L"random argument", invocation.command_line.GetArgs()[0]); | |
306 EXPECT_EQ("Experimental", invocation.suffix); | |
307 EXPECT_TRUE(invocation.is_experimental); | |
308 histograms_.ExpectTotalCount("SoftwareReporter.ExperimentErrors", 0); | |
309 } | |
310 | |
311 TEST_F(ExperimentalSwReporterInstallerTest, MissingSuffix) { | |
312 SwReporterInstallerTraits traits(launched_callback_, true); | |
313 CreateFeatureWithTag("experiment_tag"); | |
314 | |
315 static constexpr char kTestManifest[] = | |
316 "{\"launch_params\": [" | |
317 " {" | |
318 " \"arguments\": [\"random argument\"]" | |
319 " }" | |
320 "]}"; | |
321 traits.ComponentReady( | |
322 default_version_, default_path_, | |
323 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest))); | |
324 | |
325 ExpectExperimentalInvocation("", L"random argument"); | |
326 } | |
327 | |
328 TEST_F(ExperimentalSwReporterInstallerTest, EmptySuffix) { | |
329 SwReporterInstallerTraits traits(launched_callback_, true); | |
330 CreateFeatureWithTag("experiment_tag"); | |
331 | |
332 static constexpr char kTestManifest[] = | |
333 "{\"launch_params\": [" | |
334 " {" | |
335 " \"suffix\": \"\"," | |
336 " \"arguments\": [\"random argument\"]" | |
337 " }" | |
338 "]}"; | |
339 traits.ComponentReady( | |
340 default_version_, default_path_, | |
341 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest))); | |
342 | |
343 ExpectExperimentalInvocation("", L"random argument"); | |
344 } | |
345 | |
346 TEST_F(ExperimentalSwReporterInstallerTest, MissingSuffixAndArgs) { | |
347 SwReporterInstallerTraits traits(launched_callback_, true); | |
348 CreateFeatureWithTag("experiment_tag"); | |
349 | |
350 static constexpr char kTestManifest[] = | |
351 "{\"launch_params\": [" | |
352 " {" | |
353 " }" | |
354 "]}"; | |
355 traits.ComponentReady( | |
356 default_version_, default_path_, | |
357 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest))); | |
358 | |
359 ExpectExperimentalInvocation("", L""); | |
360 } | |
361 | |
362 TEST_F(ExperimentalSwReporterInstallerTest, EmptySuffixAndArgs) { | |
363 SwReporterInstallerTraits traits(launched_callback_, true); | |
364 CreateFeatureWithTag("experiment_tag"); | |
365 | |
366 static constexpr char kTestManifest[] = | |
367 "{\"launch_params\": [" | |
368 " {" | |
369 " \"suffix\": \"\"," | |
370 " \"arguments\": []" | |
371 " }" | |
372 "]}"; | |
373 traits.ComponentReady( | |
374 default_version_, default_path_, | |
375 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest))); | |
376 | |
377 ExpectExperimentalInvocation("", L""); | |
378 } | |
379 | |
380 TEST_F(ExperimentalSwReporterInstallerTest, EmptySuffixAndArgs2) { | |
381 SwReporterInstallerTraits traits(launched_callback_, true); | |
382 CreateFeatureWithTag("experiment_tag"); | |
383 | |
384 static constexpr char kTestManifest[] = | |
385 "{\"launch_params\": [" | |
386 " {" | |
387 " \"suffix\": \"\"," | |
388 " \"arguments\": [\"\"]" | |
389 " }" | |
390 "]}"; | |
391 traits.ComponentReady( | |
392 default_version_, default_path_, | |
393 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest))); | |
394 | |
395 ExpectExperimentalInvocation("", L""); | |
396 } | |
397 | |
398 TEST_F(ExperimentalSwReporterInstallerTest, MissingArguments) { | |
399 SwReporterInstallerTraits traits(launched_callback_, true); | |
400 CreateFeatureWithTag("experiment_tag"); | |
401 | |
402 static constexpr char kTestManifest[] = | |
403 "{\"launch_params\": [" | |
404 " {" | |
405 " \"suffix\": \"Experimental\"" | |
406 " }" | |
407 "]}"; | |
408 traits.ComponentReady( | |
409 default_version_, default_path_, | |
410 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest))); | |
411 | |
412 ExpectExperimentalInvocation("Experimental", L""); | |
413 } | |
414 | |
415 TEST_F(ExperimentalSwReporterInstallerTest, EmptyArguments) { | |
416 SwReporterInstallerTraits traits(launched_callback_, true); | |
417 CreateFeatureWithTag("experiment_tag"); | |
418 | |
419 static constexpr char kTestManifest[] = | |
420 "{\"launch_params\": [" | |
421 " {" | |
422 " \"suffix\": \"Experimental\"," | |
423 " \"arguments\": []" | |
424 " }" | |
425 "]}"; | |
426 traits.ComponentReady( | |
427 default_version_, default_path_, | |
428 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest))); | |
429 | |
430 ExpectExperimentalInvocation("Experimental", L""); | |
431 } | |
432 | |
433 TEST_F(ExperimentalSwReporterInstallerTest, EmptyArguments2) { | |
434 SwReporterInstallerTraits traits(launched_callback_, true); | |
435 CreateFeatureWithTag("experiment_tag"); | |
436 | |
437 static constexpr char kTestManifest[] = | |
438 "{\"launch_params\": [" | |
439 " {" | |
440 " \"suffix\": \"Experimental\"," | |
441 " \"arguments\": [\"\"]" | |
442 " }" | |
443 "]}"; | |
444 traits.ComponentReady( | |
445 default_version_, default_path_, | |
446 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest))); | |
447 | |
448 ExpectExperimentalInvocation("Experimental", L""); | |
449 } | |
450 | |
451 TEST_F(ExperimentalSwReporterInstallerTest, EmptyManifest) { | |
452 SwReporterInstallerTraits traits(launched_callback_, true); | |
453 CreateFeatureWithTag("experiment_tag"); | |
454 | |
455 update_client::InstallerAttributes attributes = | |
456 traits.GetInstallerAttributes(); | |
457 EXPECT_EQ(1U, attributes.size()); | |
458 EXPECT_EQ("experiment_tag", attributes["tag"]); | |
csharp
2016/08/25 19:47:28
The first 5 lines of this function seem to be repe
Joe Mason
2016/08/25 22:03:20
Done.
| |
459 | |
460 static constexpr char kTestManifest[] = "{}"; | |
461 traits.ComponentReady( | |
462 default_version_, default_path_, | |
463 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest))); | |
464 | |
465 // The SwReporter should not be launched, but no error should be logged. | |
466 // (This tests the case where a non-experimental version of the reporter, | |
467 // which does not have "launch_params" in its manifest, is already present.) | |
468 EXPECT_TRUE(launched_invocations_.empty()); | |
469 histograms_.ExpectTotalCount("SoftwareReporter.ExperimentErrors", 0); | |
470 } | |
471 | |
472 TEST_F(ExperimentalSwReporterInstallerTest, EmptyLaunchParams) { | |
473 SwReporterInstallerTraits traits(launched_callback_, true); | |
474 CreateFeatureWithTag("experiment_tag"); | |
475 | |
476 update_client::InstallerAttributes attributes = | |
477 traits.GetInstallerAttributes(); | |
478 EXPECT_EQ(1U, attributes.size()); | |
479 EXPECT_EQ("experiment_tag", attributes["tag"]); | |
480 | |
481 static constexpr char kTestManifest[] = "{\"launch_params\": []}"; | |
csharp
2016/08/25 19:47:28
It seems a bit weird that launch_params =[] is and
Joe Mason
2016/08/25 22:03:20
As we discussed, I'm made the "suffix" and "argume
| |
482 traits.ComponentReady( | |
483 default_version_, default_path_, | |
484 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest))); | |
485 | |
486 // The SwReporter should not be launched, and an error should be logged. | |
487 EXPECT_TRUE(launched_invocations_.empty()); | |
488 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors", | |
489 EXPERIMENT_ERROR_BAD_PARAMS, 1); | |
490 | |
491 static constexpr char kTestManifest2[] = "{\"launch_params\": {}}"; | |
csharp
2016/08/25 19:47:28
Maybe move this into it's own test (if the helper
Joe Mason
2016/08/25 22:03:20
Actually there's no point testing the tag each tim
| |
492 traits.ComponentReady( | |
493 default_version_, default_path_, | |
494 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest2))); | |
495 | |
496 // The SwReporter should not be launched, and an error should be logged. | |
497 EXPECT_TRUE(launched_invocations_.empty()); | |
498 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors", | |
499 EXPERIMENT_ERROR_BAD_PARAMS, 2); | |
500 } | |
501 | |
502 TEST_F(ExperimentalSwReporterInstallerTest, BadSuffix) { | |
503 SwReporterInstallerTraits traits(launched_callback_, true); | |
504 CreateFeatureWithTag("experiment_tag"); | |
505 | |
506 update_client::InstallerAttributes attributes = | |
507 traits.GetInstallerAttributes(); | |
508 EXPECT_EQ(1U, attributes.size()); | |
509 EXPECT_EQ("experiment_tag", attributes["tag"]); | |
510 | |
511 static constexpr char kTestManifest[] = | |
512 "{\"launch_params\": [" | |
513 " {" | |
514 " \"arguments\": [\"--engine=experimental\"]," | |
515 " \"suffix\": \"invalid whitespace characters\"" | |
516 " }" | |
517 "]}"; | |
518 traits.ComponentReady( | |
519 default_version_, default_path_, | |
520 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest))); | |
521 | |
522 // The SwReporter should not be launched, and an error should be logged. | |
523 EXPECT_TRUE(launched_invocations_.empty()); | |
524 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors", | |
525 EXPERIMENT_ERROR_BAD_PARAMS, 1); | |
526 | |
527 static constexpr char kTestManifest2[] = | |
528 "{\"launch_params\": [" | |
529 " {" | |
530 " \"arguments\": [\"--engine=experimental\"]," | |
531 " \"suffix\": \"%s\"" | |
532 " }" | |
533 "]}"; | |
534 std::string suffix_too_long(500, 'x'); | |
535 std::string manifest = | |
536 base::StringPrintf(kTestManifest2, suffix_too_long.c_str()); | |
537 traits.ComponentReady( | |
538 default_version_, default_path_, | |
539 base::DictionaryValue::From(base::JSONReader::Read(manifest))); | |
540 | |
541 // The SwReporter should not be launched, and an error should be logged. | |
542 EXPECT_TRUE(launched_invocations_.empty()); | |
543 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors", | |
544 EXPERIMENT_ERROR_BAD_PARAMS, 2); | |
545 } | |
546 | |
547 TEST_F(ExperimentalSwReporterInstallerTest, BadTypesInManifest) { | |
548 SwReporterInstallerTraits traits(launched_callback_, true); | |
549 CreateFeatureWithTag("experiment_tag"); | |
550 | |
551 update_client::InstallerAttributes attributes = | |
552 traits.GetInstallerAttributes(); | |
553 EXPECT_EQ(1U, attributes.size()); | |
554 EXPECT_EQ("experiment_tag", attributes["tag"]); | |
555 | |
556 // This has a string instead of a list for "arguments". | |
557 static constexpr char kTestManifest[] = | |
558 "{\"launch_params\": [" | |
559 " {" | |
560 " \"arguments\": \"--engine=experimental\"," | |
561 " \"suffix\": \"Experimental\"" | |
562 " }" | |
563 "]}"; | |
564 traits.ComponentReady( | |
565 default_version_, default_path_, | |
566 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest))); | |
567 | |
568 // The SwReporter should not be launched, and an error should be logged. | |
569 EXPECT_TRUE(launched_invocations_.empty()); | |
570 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors", | |
571 EXPERIMENT_ERROR_BAD_PARAMS, 1); | |
572 | |
573 // This has the invocation parameters as direct children of "launch_params", | |
574 // instead of using a list. | |
575 static constexpr char kTestManifest2[] = | |
576 "{\"launch_params\": " | |
577 " {" | |
578 " \"arguments\": [\"--engine=experimental\"]," | |
579 " \"suffix\": \"Experimental\"" | |
580 " }" | |
581 "}"; | |
582 traits.ComponentReady( | |
583 default_version_, default_path_, | |
584 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest2))); | |
585 | |
586 // The SwReporter should not be launched, and an error should be logged. | |
587 EXPECT_TRUE(launched_invocations_.empty()); | |
588 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors", | |
589 EXPERIMENT_ERROR_BAD_PARAMS, 2); | |
590 | |
591 // This has a list for suffix as well as for arguments. | |
592 static constexpr char kTestManifest3[] = | |
593 "{\"launch_params\": [" | |
594 " {" | |
595 " \"arguments\": [\"--engine=experimental\"]," | |
596 " \"suffix\": [\"Experimental\"]" | |
597 " }" | |
598 "]}"; | |
599 traits.ComponentReady( | |
600 default_version_, default_path_, | |
601 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest3))); | |
602 | |
603 // The SwReporter should not be launched, and an error should be logged. | |
604 EXPECT_TRUE(launched_invocations_.empty()); | |
605 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors", | |
606 EXPERIMENT_ERROR_BAD_PARAMS, 3); | |
84 } | 607 } |
85 | 608 |
86 } // namespace component_updater | 609 } // namespace component_updater |
OLD | NEW |