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

Side by Side Diff: chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win_unittest.cc

Issue 2890023005: Chrome Cleaner UI: reporter no longer uses mojo. (Closed)
Patch Set: Rebase 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 "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win. h"
6
7 #include <tuple>
8 #include <utility>
9 #include <vector>
10
11 #include "base/logging.h"
12 #include "base/process/launch.h"
13 #include "base/process/process.h"
14 #include "base/run_loop.h"
15 #include "base/single_thread_task_runner.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/test/multiprocess_test.h"
18 #include "base/test/scoped_feature_list.h"
19 #include "base/threading/thread.h"
20 #include "chrome/browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_proces s_win.h"
21 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h"
22 #include "components/chrome_cleaner/public/constants/constants.h"
23 #include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "content/public/test/test_browser_thread_bundle.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "testing/multiprocess_func_list.h"
29
30 namespace safe_browsing {
31 namespace {
32
33 using ::chrome_cleaner::mojom::ChromePrompt;
34 using ::chrome_cleaner::mojom::PromptAcceptance;
35 using ::content::BrowserThread;
36 using ::testing::Bool;
37 using ::testing::Combine;
38 using ::testing::Values;
39 using ChromeMetricsStatus = ChromeCleanerRunner::ChromeMetricsStatus;
40 using CleanerLogsStatus = ChromeCleanerRunner::CleanerLogsStatus;
41
42 enum class ReporterEngine {
43 kUnspecified,
44 kOldEngine,
45 kNewEngine,
46 };
47
48 std::string ReporterEngineToString(ReporterEngine reporter_engine) {
49 switch (reporter_engine) {
50 case ReporterEngine::kUnspecified: // Fallthrough.
51 case ReporterEngine::kOldEngine:
52 return "1";
53 case ReporterEngine::kNewEngine:
54 return "2";
55 }
56 NOTREACHED();
57 return std::string();
58 }
59
60 // Simple test fixture that intercepts the launching of the Chrome Cleaner
61 // process. Intended for testing simple things like command line flags that
62 // Chrome sends to the Chrome Cleaner process.
63 //
64 // Parameters:
65 // - metrics_status (ChromeMetricsStatus): whether Chrome metrics reporting is
66 // enabled
67 // - logs_upload_status (CleanerLogsStatus): whether logs upload in the Cleaner
68 // process should be enabled.
69 // - reporter_engine (ReporterEngine): the type of Cleaner engine specified in
70 // the SwReporterInvocation.
71 class ChromeCleanerRunnerSimpleTest
72 : public testing::TestWithParam<
73 std::tuple<ChromeCleanerRunner::ChromeMetricsStatus,
74 ChromeCleanerRunner::CleanerLogsStatus,
75 ReporterEngine>>,
76 public ChromeCleanerRunnerTestDelegate {
77 public:
78 ChromeCleanerRunnerSimpleTest()
79 : command_line_(base::CommandLine::NO_PROGRAM) {}
80
81 void SetUp() override {
82 std::tie(metrics_status_, logs_upload_status_, reporter_engine_) =
83 GetParam();
84
85 SetChromeCleanerRunnerTestDelegateForTesting(this);
86 scoped_feature_list_.InitAndEnableFeature(kInBrowserCleanerUIFeature);
87 }
88
89 void CallRunChromeCleaner() {
90 SwReporterInvocation reporter_invocation;
91 switch (reporter_engine_) {
92 case ReporterEngine::kUnspecified:
93 // No engine switch.
94 break;
95 case ReporterEngine::kOldEngine:
96 reporter_invocation.command_line.AppendSwitchASCII(
97 chrome_cleaner::kEngineSwitch, "1");
98 break;
99 case ReporterEngine::kNewEngine:
100 reporter_invocation.command_line.AppendSwitchASCII(
101 chrome_cleaner::kEngineSwitch, "2");
102 break;
103 }
104
105 ChromeCleanerRunner::RunChromeCleanerAndReplyWithExitCode(
106 base::FilePath(FILE_PATH_LITERAL("cleaner.exe")), reporter_invocation,
107 metrics_status_, logs_upload_status_,
108 base::BindOnce(&ChromeCleanerRunnerSimpleTest::OnPromptUser,
109 base::Unretained(this)),
110 base::BindOnce(&ChromeCleanerRunnerSimpleTest::OnConnectionClosed,
111 base::Unretained(this)),
112 base::BindOnce(&ChromeCleanerRunnerSimpleTest::OnProcessDone,
113 base::Unretained(this)));
114 }
115
116 // ChromeCleanerRunnerTestDelegate overrides.
117
118 base::Process LaunchTestProcess(
119 const base::CommandLine& command_line,
120 const base::LaunchOptions& launch_options) override {
121 command_line_ = command_line;
122 // Return an invalid process.
123 return base::Process();
124 }
125
126 base::CommandLine GetTestBaseCommandLine() override {
127 return base::CommandLine(base::CommandLine::NO_PROGRAM);
128 }
129
130 // IPC callbacks.
131
132 void OnPromptUser(std::unique_ptr<std::set<base::FilePath>> files_to_delete,
133 ChromePrompt::PromptUserCallback response) {}
134
135 void OnConnectionClosed() {}
136
137 void OnProcessDone(ChromeCleanerRunner::LaunchStatus launch_status) {
138 on_process_done_called_ = true;
139 launch_status_ = launch_status;
140 run_loop_.QuitWhenIdle();
141 }
142
143 protected:
144 content::TestBrowserThreadBundle test_browser_thread_bundle_;
145 base::test::ScopedFeatureList scoped_feature_list_;
146
147 // Test fixture parameters.
148 ChromeCleanerRunner::ChromeMetricsStatus metrics_status_;
149 ChromeCleanerRunner::CleanerLogsStatus logs_upload_status_;
150 ReporterEngine reporter_engine_;
151
152 // Set by LaunchTestProcess.
153 base::CommandLine command_line_;
154
155 // Variables set by OnProcessDone().
156 bool on_process_done_called_ = false;
157 ChromeCleanerRunner::LaunchStatus launch_status_;
158
159 base::RunLoop run_loop_;
160 };
161
162 TEST_P(ChromeCleanerRunnerSimpleTest, InterceptLaunchParams) {
Joe Mason 2017/05/23 15:39:36 Nit: I would just name this test "LaunchParams". N
alito 2017/05/23 18:58:57 Done.
163 CallRunChromeCleaner();
164 run_loop_.Run();
165
166 EXPECT_TRUE(on_process_done_called_);
167
168 EXPECT_EQ(
169 command_line_.GetSwitchValueASCII(chrome_cleaner::kExecutionModeSwitch),
170 base::IntToString(
171 static_cast<int>(chrome_cleaner::ExecutionMode::kScanning)));
172
173 EXPECT_EQ(command_line_.GetSwitchValueASCII(chrome_cleaner::kEngineSwitch),
174 ReporterEngineToString(reporter_engine_));
Joe Mason 2017/05/23 15:39:36 It took me a while to realize this wasn't a useles
alito 2017/05/23 18:58:57 Done.
175
176 EXPECT_EQ(metrics_status_ == ChromeMetricsStatus::kEnabled,
177 command_line_.HasSwitch(chrome_cleaner::kUmaUserSwitch));
178 EXPECT_EQ(
179 metrics_status_ == ChromeMetricsStatus::kEnabled,
180 command_line_.HasSwitch(chrome_cleaner::kEnableCrashReportingSwitch));
181
182 EXPECT_EQ(
183 logs_upload_status_ == CleanerLogsStatus::kUploadEnabled,
184 command_line_.HasSwitch(chrome_cleaner::kEnableCleanerLoggingSwitch));
185 }
186
187 INSTANTIATE_TEST_CASE_P(
188 All,
189 ChromeCleanerRunnerSimpleTest,
190 Combine(Values(ChromeCleanerRunner::ChromeMetricsStatus::kEnabled,
191 ChromeCleanerRunner::ChromeMetricsStatus::kDisabled),
192 Values(ChromeCleanerRunner::CleanerLogsStatus::kUploadEnabled,
193 ChromeCleanerRunner::CleanerLogsStatus::kUploadDisabled),
194 Values(ReporterEngine::kUnspecified,
195 ReporterEngine::kOldEngine,
196 ReporterEngine::kNewEngine)));
197
198 // Test fixture for testing ChromeCleanerRunner with a mock Chrome Cleaner
199 // process.
200 //
201 // Parameters:
202 //
203 // - found_uws (bool): Whether the Chrome Cleaner process should find UwS on the
204 // system.
205 // - reboot_required (bool) : Whether the Chrome Cleaner process should exit
206 // with an exit code indicating that that a reboot is required. Must not
207 // be set to true when the |found_uws| parameter is false.
208 // - crash_point (CrashPoint): a single crash point where the Chrome Cleaner
209 // process will crash. See the MockChromeCleanerProcess documentation for
210 // possible values.
211 // - prompt_acceptance_to_send (PromptAcceptance): the prompt acceptance value
212 // that Chrome should send to the Chrome Cleaner process. Must be DENIED
213 // if |found_uws| is false.
214 class ChromeCleanerRunnerTest
215 : public testing::TestWithParam<
216 std::tuple<bool,
217 bool,
218 MockChromeCleanerProcess::CrashPoint,
219 PromptAcceptance>>,
220 public ChromeCleanerRunnerTestDelegate {
221 public:
222 void SetUp() override {
223 bool found_uws;
224 bool reboot_required;
225 MockChromeCleanerProcess::CrashPoint crash_point;
226 PromptAcceptance prompt_acceptance_to_send;
227 std::tie(found_uws, reboot_required, crash_point,
228 prompt_acceptance_to_send) = GetParam();
229
230 ASSERT_FALSE(!found_uws && reboot_required);
231 ASSERT_TRUE(found_uws ||
232 prompt_acceptance_to_send == PromptAcceptance::DENIED);
233
234 cleaner_process_options_.SetDoFindUws(found_uws);
235 cleaner_process_options_.set_reboot_required(reboot_required);
236 cleaner_process_options_.set_crash_point(crash_point);
237 prompt_acceptance_to_send_ = prompt_acceptance_to_send;
238
239 SetChromeCleanerRunnerTestDelegateForTesting(this);
240 scoped_feature_list_.InitAndEnableFeature(kInBrowserCleanerUIFeature);
241 }
242
243 void CallRunChromeCleaner() {
244 ChromeCleanerRunner::RunChromeCleanerAndReplyWithExitCode(
245 base::FilePath(FILE_PATH_LITERAL("cleaner.exe")),
246 SwReporterInvocation(), ChromeMetricsStatus::kDisabled,
247 CleanerLogsStatus::kUploadDisabled,
248 base::BindOnce(&ChromeCleanerRunnerTest::OnPromptUser,
249 base::Unretained(this)),
250 base::BindOnce(&ChromeCleanerRunnerTest::OnConnectionClosed,
251 base::Unretained(this)),
252 base::BindOnce(&ChromeCleanerRunnerTest::OnProcessDone,
253 base::Unretained(this)));
254 }
255
256 // ChromeCleanerRunnerTestDelegate overrides.
257
258 base::Process LaunchTestProcess(
259 const base::CommandLine& command_line,
260 const base::LaunchOptions& launch_options) override {
261 base::SpawnChildResult result = base::SpawnMultiProcessTestChild(
262 "MockChromeCleanerProcessMain", command_line, launch_options);
263
264 EXPECT_TRUE(result.process.IsValid());
265 return std::move(result.process);
266 }
267
268 base::CommandLine GetTestBaseCommandLine() override {
269 base::CommandLine command_line =
270 base::GetMultiProcessTestChildBaseCommandLine();
271 cleaner_process_options_.AddSwitchesToCommandLine(&command_line);
272 return command_line;
273 }
274
275 // IPC callbacks.
276
277 // Will receive the main Mojo message from the Mock Chrome Cleaner process.
278 void OnPromptUser(std::unique_ptr<std::set<base::FilePath>> files_to_delete,
279 ChromePrompt::PromptUserCallback response) {
280 on_prompt_user_called_ = true;
281 received_files_to_delete_ = std::move(files_to_delete);
282 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)
283 ->PostTask(FROM_HERE, base::BindOnce(std::move(response),
284 prompt_acceptance_to_send_));
285 }
286
287 void ContinueTestIfCommunicationDone() {
288 if (on_process_done_called_ && on_connection_closed_called_)
289 run_loop_.QuitWhenIdle();
290 }
291
292 void OnConnectionClosed() {
293 on_connection_closed_called_ = true;
294 ContinueTestIfCommunicationDone();
295 }
296
297 void OnProcessDone(ChromeCleanerRunner::LaunchStatus launch_status) {
298 on_process_done_called_ = true;
299 launch_status_ = launch_status;
300 ContinueTestIfCommunicationDone();
301 }
302
303 protected:
304 content::TestBrowserThreadBundle test_browser_thread_bundle_;
305 base::test::ScopedFeatureList scoped_feature_list_;
306
307 base::RunLoop run_loop_;
308
309 MockChromeCleanerProcess::Options cleaner_process_options_;
310 PromptAcceptance prompt_acceptance_to_send_ = PromptAcceptance::UNSPECIFIED;
311
312 // Set by OnProcessDone().
313 ChromeCleanerRunner::LaunchStatus launch_status_ = {false, -1};
314 // Set by OnPromptUser().
315 std::unique_ptr<std::set<base::FilePath>> received_files_to_delete_;
316
317 bool on_prompt_user_called_ = false;
318 bool on_connection_closed_called_ = false;
319 bool on_process_done_called_ = false;
320 };
321
322 MULTIPROCESS_TEST_MAIN(MockChromeCleanerProcessMain) {
323 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
324 MockChromeCleanerProcess::Options options;
325 EXPECT_TRUE(MockChromeCleanerProcess::Options::FromCommandLine(*command_line,
326 &options));
327
328 std::string chrome_mojo_pipe_token = command_line->GetSwitchValueASCII(
329 chrome_cleaner::kChromeMojoPipeTokenSwitch);
330 EXPECT_FALSE(chrome_mojo_pipe_token.empty());
331
332 if (::testing::Test::HasFailure())
Joe Mason 2017/05/23 15:39:36 When can this happen?
alito 2017/05/23 18:58:57 Added a comment explaining this here as well.
333 return MockChromeCleanerProcess::kInternalTestFailureExitCode;
334
335 MockChromeCleanerProcess mock_cleaner_process(options,
336 chrome_mojo_pipe_token);
337 return mock_cleaner_process.Run();
338 }
339
340 TEST_P(ChromeCleanerRunnerTest, MockChromeCleanerProcess) {
341 CallRunChromeCleaner();
342 run_loop_.Run();
343
344 EXPECT_TRUE(on_process_done_called_);
345 EXPECT_TRUE(on_connection_closed_called_);
346 EXPECT_EQ(on_prompt_user_called_,
347 (cleaner_process_options_.crash_point() ==
348 MockChromeCleanerProcess::CrashPoint::kNone ||
349 cleaner_process_options_.crash_point() ==
350 MockChromeCleanerProcess::CrashPoint::kAfterResponseReceived));
351
352 if (on_prompt_user_called_ && !cleaner_process_options_.found_uws().empty()) {
353 EXPECT_EQ(*received_files_to_delete_,
354 cleaner_process_options_.files_to_delete());
355 }
356
357 EXPECT_TRUE(launch_status_.process_ok);
358 EXPECT_EQ(launch_status_.exit_code, cleaner_process_options_.ExpectedExitCode(
359 prompt_acceptance_to_send_));
360 }
361
362 INSTANTIATE_TEST_CASE_P(
363 NoUwsFound,
364 ChromeCleanerRunnerTest,
365 Combine(
366 Values(false),
Joe Mason 2017/05/23 15:39:36 It would be easier to read if this were an enum in
alito 2017/05/23 18:58:57 Done.
367 Values(false),
368 Values(MockChromeCleanerProcess::CrashPoint::kNone,
369 MockChromeCleanerProcess::CrashPoint::kOnStartup,
370 MockChromeCleanerProcess::CrashPoint::kAfterConnection,
371 MockChromeCleanerProcess::CrashPoint::kAfterRequestSent,
372 MockChromeCleanerProcess::CrashPoint::kAfterResponseReceived),
373 Values(PromptAcceptance::DENIED)));
374
375 INSTANTIATE_TEST_CASE_P(
376 UwsFound,
377 ChromeCleanerRunnerTest,
378 Combine(
379 Values(true),
380 Bool(),
381 Values(MockChromeCleanerProcess::CrashPoint::kNone,
382 MockChromeCleanerProcess::CrashPoint::kOnStartup,
383 MockChromeCleanerProcess::CrashPoint::kAfterConnection,
384 MockChromeCleanerProcess::CrashPoint::kAfterRequestSent,
385 MockChromeCleanerProcess::CrashPoint::kAfterResponseReceived),
386 Values(PromptAcceptance::DENIED,
387 PromptAcceptance::ACCEPTED_WITH_LOGS,
388 PromptAcceptance::ACCEPTED_WITHOUT_LOGS)));
389
390 } // namespace
391 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698