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

Side by Side Diff: chrome/browser/component_updater/sw_reporter_installer_win_unittest.cc

Issue 2278013002: Add support for the ExperimentalSwReporterEngine field trial. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 3 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
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 {
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
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 // Expect 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
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(
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 std::unique_ptr<variations::testing::VariationParamsManager> variations_;
139 base::test::ScopedFeatureList scoped_feature_list_;
140 base::HistogramTester histograms_;
141
142 private:
143 DISALLOW_COPY_AND_ASSIGN(ExperimentalSwReporterInstallerTest);
144 };
145
71 TEST_F(SwReporterInstallerTest, Default) { 146 TEST_F(SwReporterInstallerTest, Default) {
72 TestComponentReady(default_version_, default_path_); 147 SwReporterInstallerTraits traits(launched_callback_, false);
73 148
74 // The SwReporter should be launched exactly once, with no arguments. 149 update_client::InstallerAttributes attributes =
150 traits.GetInstallerAttributes();
151 EXPECT_TRUE(attributes.empty());
152
153 traits.ComponentReady(default_version_, default_path_,
154 std::make_unique<base::DictionaryValue>());
155 ExpectDefaultInvocation();
156 }
157
158 TEST_F(ExperimentalSwReporterInstallerTest, NoExperimentConfig) {
159 // Even if the experiment is supported on this hardware, the user shouldn't
160 // be enrolled unless enabled through variations.
161 SwReporterInstallerTraits traits(launched_callback_, true);
162
163 update_client::InstallerAttributes attributes =
164 traits.GetInstallerAttributes();
165 EXPECT_TRUE(attributes.empty());
166
167 traits.ComponentReady(default_version_, default_path_,
168 std::make_unique<base::DictionaryValue>());
169 ExpectDefaultInvocation();
170 }
171
172 TEST_F(ExperimentalSwReporterInstallerTest, ExperimentUnsupported) {
173 // Even if the experiment config is enabled in variations, the user shouldn't
174 // be enrolled if the hardware doesn't support it.
175 SwReporterInstallerTraits traits(launched_callback_, false);
176 CreateFeatureWithTag("experiment_tag");
177
178 update_client::InstallerAttributes attributes =
179 traits.GetInstallerAttributes();
180 EXPECT_TRUE(attributes.empty());
181
182 traits.ComponentReady(default_version_, default_path_,
183 std::make_unique<base::DictionaryValue>());
184 ExpectDefaultInvocation();
185 }
186
187 TEST_F(ExperimentalSwReporterInstallerTest, ExperimentMissingTag) {
188 SwReporterInstallerTraits traits(launched_callback_, true);
189 CreateFeatureWithoutTag();
190
191 update_client::InstallerAttributes attributes =
192 traits.GetInstallerAttributes();
193 EXPECT_EQ(1U, attributes.size());
194 EXPECT_EQ("missing_tag", attributes["tag"]);
195 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors",
196 EXPERIMENT_ERROR_BAD_TAG, 1);
197 }
198
199 TEST_F(ExperimentalSwReporterInstallerTest, ExperimentInvalidTag) {
200 SwReporterInstallerTraits traits(launched_callback_, true);
201 CreateFeatureWithTag("tag with invalid whitespace chars");
202
203 update_client::InstallerAttributes attributes =
204 traits.GetInstallerAttributes();
205 EXPECT_EQ(1U, attributes.size());
206 EXPECT_EQ("missing_tag", attributes["tag"]);
207 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors",
208 EXPERIMENT_ERROR_BAD_TAG, 1);
209 }
210
211 TEST_F(ExperimentalSwReporterInstallerTest, ExperimentTagTooLong) {
212 SwReporterInstallerTraits traits(launched_callback_, true);
213 std::string tag_too_long(500, 'x');
214 CreateFeatureWithTag(tag_too_long);
215
216 update_client::InstallerAttributes attributes =
217 traits.GetInstallerAttributes();
218 EXPECT_EQ(1U, attributes.size());
219 EXPECT_EQ("missing_tag", attributes["tag"]);
220 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors",
221 EXPERIMENT_ERROR_BAD_TAG, 1);
222 }
223
224 TEST_F(ExperimentalSwReporterInstallerTest, ExperimentEmptyTag) {
225 SwReporterInstallerTraits traits(launched_callback_, true);
226 CreateFeatureWithTag("");
227
228 update_client::InstallerAttributes attributes =
229 traits.GetInstallerAttributes();
230 EXPECT_EQ(1U, attributes.size());
231 EXPECT_EQ("missing_tag", attributes["tag"]);
232 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors",
233 EXPERIMENT_ERROR_BAD_TAG, 1);
234 }
235
236 TEST_F(ExperimentalSwReporterInstallerTest, SingleInvocation) {
237 SwReporterInstallerTraits traits(launched_callback_, true);
238 CreateFeatureWithTag("experiment_tag");
239
240 update_client::InstallerAttributes attributes =
241 traits.GetInstallerAttributes();
242 EXPECT_EQ(1U, attributes.size());
243 EXPECT_EQ("experiment_tag", attributes["tag"]);
244
245 static constexpr char kTestManifest[] =
246 "{\"launch_params\": ["
247 " {"
248 " \"arguments\": [\"--engine=experimental\", \"random argument\"],"
249 " \"suffix\": \"Experimental\""
250 " }"
251 "]}";
252 traits.ComponentReady(
253 default_version_, default_path_,
254 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest)));
255
256 // The SwReporter should be launched once with the given arguments.
75 EXPECT_EQ(default_version_, launched_version_); 257 EXPECT_EQ(default_version_, launched_version_);
76 ASSERT_EQ(1U, launched_invocations_.size()); 258 ASSERT_EQ(1U, launched_invocations_.size());
77 259
260 const safe_browsing::SwReporterInvocation& invocation =
261 launched_invocations_[0];
262 EXPECT_EQ(MakeTestFilePath(default_path_),
263 invocation.command_line.GetProgram());
264 EXPECT_EQ(2U, invocation.command_line.GetSwitches().size());
265 EXPECT_EQ("experimental",
266 invocation.command_line.GetSwitchValueASCII("engine"));
267 EXPECT_EQ("Experimental",
268 invocation.command_line.GetSwitchValueASCII("registry-suffix"));
269 ASSERT_EQ(1U, invocation.command_line.GetArgs().size());
270 EXPECT_EQ(L"random argument", invocation.command_line.GetArgs()[0]);
271 EXPECT_EQ("Experimental", invocation.suffix);
272 EXPECT_TRUE(invocation.is_experimental);
273 histograms_.ExpectTotalCount("SoftwareReporter.ExperimentErrors", 0);
274 }
275
276 TEST_F(ExperimentalSwReporterInstallerTest, MissingSuffix) {
277 SwReporterInstallerTraits traits(launched_callback_, true);
278 CreateFeatureWithTag("experiment_tag");
279
280 update_client::InstallerAttributes attributes =
281 traits.GetInstallerAttributes();
282 EXPECT_EQ(1U, attributes.size());
283 EXPECT_EQ("experiment_tag", attributes["tag"]);
284
285 static constexpr char kTestManifest[] =
286 "{\"launch_params\": ["
287 " {"
288 " \"arguments\": [\"--engine=experimental\"]"
289 " }"
290 "]}";
291 traits.ComponentReady(
292 default_version_, default_path_,
293 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest)));
294
295 // The SwReporter should not be launched, and an error should be logged.
296 EXPECT_TRUE(launched_invocations_.empty());
297 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors",
298 EXPERIMENT_ERROR_BAD_PARAMS, 1);
299
300 static constexpr char kTestManifest2[] =
301 "{\"launch_params\": ["
302 " {"
303 " \"suffix\": \"\","
304 " \"arguments\": [\"--engine=experimental\"]"
305 " }"
306 "]}";
307 traits.ComponentReady(
308 default_version_, default_path_,
309 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest2)));
310
311 // The SwReporter should not be launched, and an error should be logged.
312 EXPECT_TRUE(launched_invocations_.empty());
313 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors",
314 EXPERIMENT_ERROR_BAD_PARAMS, 2);
315 }
316
317 TEST_F(ExperimentalSwReporterInstallerTest, MissingArguments) {
318 SwReporterInstallerTraits traits(launched_callback_, true);
319 CreateFeatureWithTag("experiment_tag");
320
321 update_client::InstallerAttributes attributes =
322 traits.GetInstallerAttributes();
323 EXPECT_EQ(1U, attributes.size());
324 EXPECT_EQ("experiment_tag", attributes["tag"]);
325
326 static constexpr char kTestManifest[] =
327 "{\"launch_params\": ["
328 " {"
329 " \"suffix\": \"Experimental\""
330 " }"
331 "]}";
332 traits.ComponentReady(
333 default_version_, default_path_,
334 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest)));
335
336 // The SwReporter should be launched once with no arguments except the
337 // suffix.
338 EXPECT_EQ(default_version_, launched_version_);
339 ASSERT_EQ(1U, launched_invocations_.size());
340
341 const safe_browsing::SwReporterInvocation& invocation =
342 launched_invocations_[0];
343 EXPECT_EQ(MakeTestFilePath(default_path_),
344 invocation.command_line.GetProgram());
345 EXPECT_EQ(1U, invocation.command_line.GetSwitches().size());
346 EXPECT_EQ("Experimental",
347 invocation.command_line.GetSwitchValueASCII("registry-suffix"));
348 EXPECT_TRUE(invocation.command_line.GetArgs().empty());
349 EXPECT_EQ("Experimental", invocation.suffix);
350 EXPECT_TRUE(invocation.is_experimental);
351 histograms_.ExpectTotalCount("SoftwareReporter.ExperimentErrors", 0);
352 }
353
354 TEST_F(ExperimentalSwReporterInstallerTest, EmptyManifest) {
355 SwReporterInstallerTraits traits(launched_callback_, true);
356 CreateFeatureWithTag("experiment_tag");
357
358 update_client::InstallerAttributes attributes =
359 traits.GetInstallerAttributes();
360 EXPECT_EQ(1U, attributes.size());
361 EXPECT_EQ("experiment_tag", attributes["tag"]);
362
363 static constexpr char kTestManifest[] = "{}";
364 traits.ComponentReady(
365 default_version_, default_path_,
366 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest)));
367
368 // The SwReporter should not be launched, but no error should be logged.
369 // (This tests the case where a non-experimental version of the reporter,
370 // which does not have "launch_params" in its manifest, is already present.)
371 EXPECT_TRUE(launched_invocations_.empty());
372 histograms_.ExpectTotalCount("SoftwareReporter.ExperimentErrors", 0);
373 }
374
375 TEST_F(ExperimentalSwReporterInstallerTest, EmptyLaunchParams) {
376 SwReporterInstallerTraits traits(launched_callback_, true);
377 CreateFeatureWithTag("experiment_tag");
378
379 update_client::InstallerAttributes attributes =
380 traits.GetInstallerAttributes();
381 EXPECT_EQ(1U, attributes.size());
382 EXPECT_EQ("experiment_tag", attributes["tag"]);
383
384 static constexpr char kTestManifest[] = "{\"launch_params\": []}";
385
386 traits.ComponentReady(
387 default_version_, default_path_,
388 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest)));
389
390 // The SwReporter should be launched once with no arguments and no suffix.
391 EXPECT_EQ(default_version_, launched_version_);
392 ASSERT_EQ(1U, launched_invocations_.size());
393
78 const safe_browsing::SwReporterInvocation& invocation = 394 const safe_browsing::SwReporterInvocation& invocation =
79 launched_invocations_[0]; 395 launched_invocations_[0];
80 EXPECT_EQ(MakeTestFilePath(default_path_), 396 EXPECT_EQ(MakeTestFilePath(default_path_),
81 invocation.command_line.GetProgram()); 397 invocation.command_line.GetProgram());
82 EXPECT_TRUE(invocation.command_line.GetSwitches().empty()); 398 EXPECT_TRUE(invocation.command_line.GetSwitches().empty());
83 EXPECT_TRUE(invocation.command_line.GetArgs().empty()); 399 EXPECT_TRUE(invocation.command_line.GetArgs().empty());
400 EXPECT_TRUE(invocation.suffix.empty());
401 EXPECT_TRUE(invocation.is_experimental);
402 histograms_.ExpectTotalCount("SoftwareReporter.ExperimentErrors", 0);
403 }
404
405 TEST_F(ExperimentalSwReporterInstallerTest, BadSuffix) {
406 SwReporterInstallerTraits traits(launched_callback_, true);
407 CreateFeatureWithTag("experiment_tag");
408
409 update_client::InstallerAttributes attributes =
410 traits.GetInstallerAttributes();
411 EXPECT_EQ(1U, attributes.size());
412 EXPECT_EQ("experiment_tag", attributes["tag"]);
413
414 static constexpr char kTestManifest[] =
415 "{\"launch_params\": ["
416 " {"
417 " \"arguments\": [\"--engine=experimental\"],"
418 " \"suffix\": \"invalid whitespace characters\""
419 " }"
420 "]}";
421 traits.ComponentReady(
422 default_version_, default_path_,
423 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest)));
424
425 // The SwReporter should not be launched, and an error should be logged.
426 EXPECT_TRUE(launched_invocations_.empty());
427 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors",
428 EXPERIMENT_ERROR_BAD_PARAMS, 1);
429
430 static constexpr char kTestManifest2[] =
431 "{\"launch_params\": ["
432 " {"
433 " \"arguments\": [\"--engine=experimental\"],"
434 " \"suffix\": \"%s\""
435 " }"
436 "]}";
437 std::string suffix_too_long(500, 'x');
438 std::string manifest =
439 base::StringPrintf(kTestManifest2, suffix_too_long.c_str());
440 traits.ComponentReady(
441 default_version_, default_path_,
442 base::DictionaryValue::From(base::JSONReader::Read(manifest)));
443
444 // The SwReporter should not be launched, and an error should be logged.
445 EXPECT_TRUE(launched_invocations_.empty());
446 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors",
447 EXPERIMENT_ERROR_BAD_PARAMS, 2);
448 }
449
450 TEST_F(ExperimentalSwReporterInstallerTest, BadTypesInManifest) {
451 SwReporterInstallerTraits traits(launched_callback_, true);
452 CreateFeatureWithTag("experiment_tag");
453
454 update_client::InstallerAttributes attributes =
455 traits.GetInstallerAttributes();
456 EXPECT_EQ(1U, attributes.size());
457 EXPECT_EQ("experiment_tag", attributes["tag"]);
458
459 // This has a string instead of a list for "arguments".
460 static constexpr char kTestManifest[] =
461 "{\"launch_params\": ["
462 " {"
463 " \"arguments\": \"--engine=experimental\","
464 " \"suffix\": \"Experimental\""
465 " }"
466 "]}";
467 traits.ComponentReady(
468 default_version_, default_path_,
469 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest)));
470
471 // The SwReporter should not be launched, and an error should be logged.
472 EXPECT_TRUE(launched_invocations_.empty());
473 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors",
474 EXPERIMENT_ERROR_BAD_PARAMS, 1);
475
476 // This has the invocation parameters as direct children of "launch_params",
477 // instead of using a list.
478 static constexpr char kTestManifest2[] =
479 "{\"launch_params\": "
480 " {"
481 " \"arguments\": [\"--engine=experimental\"],"
482 " \"suffix\": \"Experimental\""
483 " }"
484 "}";
485 traits.ComponentReady(
486 default_version_, default_path_,
487 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest2)));
488
489 // The SwReporter should not be launched, and an error should be logged.
490 EXPECT_TRUE(launched_invocations_.empty());
491 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors",
492 EXPERIMENT_ERROR_BAD_PARAMS, 2);
493
494 // This has a list for suffix as well as for arguments.
495 static constexpr char kTestManifest3[] =
496 "{\"launch_params\": ["
497 " {"
498 " \"arguments\": [\"--engine=experimental\"],"
499 " \"suffix\": [\"Experimental\"]"
500 " }"
501 "]}";
502 traits.ComponentReady(
503 default_version_, default_path_,
504 base::DictionaryValue::From(base::JSONReader::Read(kTestManifest3)));
505
506 // The SwReporter should not be launched, and an error should be logged.
507 EXPECT_TRUE(launched_invocations_.empty());
508 histograms_.ExpectUniqueSample("SoftwareReporter.ExperimentErrors",
509 EXPERIMENT_ERROR_BAD_PARAMS, 3);
84 } 510 }
85 511
86 } // namespace component_updater 512 } // namespace component_updater
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698