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

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: Addressed Fabio's 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 "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 "base/threading/thread_task_runner_handle.h"
21 #include "chrome/browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_proces s_win.h"
22 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h"
23 #include "components/chrome_cleaner/public/constants/constants.h"
24 #include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h"
25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/test/test_browser_thread_bundle.h"
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "testing/multiprocess_func_list.h"
30
31 namespace safe_browsing {
32 namespace {
33
34 using ::chrome_cleaner::mojom::ChromePrompt;
35 using ::chrome_cleaner::mojom::PromptAcceptance;
36 using ::content::BrowserThread;
37 using ::testing::Bool;
38 using ::testing::Combine;
39 using ::testing::Values;
40 using ChromeMetricsStatus = ChromeCleanerRunner::ChromeMetricsStatus;
41 using CleanerLogsStatus = ChromeCleanerRunner::CleanerLogsStatus;
42
43 enum class ReporterEngine {
44 kUnspecified,
45 kOldEngine,
46 kNewEngine,
47 };
48
49 // Simple test fixture that intercepts the launching of the Chrome Cleaner
50 // process. Intended for testing simple things like command line flags that
51 // Chrome sends to the Chrome Cleaner process.
csharp 2017/05/24 20:49:35 Worth mentioning it returns an invalid process and
alito 2017/05/24 22:20:50 Done.
52 //
53 // Parameters:
54 // - metrics_status (ChromeMetricsStatus): whether Chrome metrics reporting is
55 // enabled
56 // - logs_upload_status (CleanerLogsStatus): whether logs upload in the Cleaner
57 // process should be enabled.
58 // - reporter_engine (ReporterEngine): the type of Cleaner engine specified in
59 // the SwReporterInvocation.
60 class ChromeCleanerRunnerSimpleTest
61 : public testing::TestWithParam<
62 std::tuple<ChromeCleanerRunner::ChromeMetricsStatus,
63 ChromeCleanerRunner::CleanerLogsStatus,
64 ReporterEngine>>,
65 public ChromeCleanerRunnerTestDelegate {
66 public:
67 ChromeCleanerRunnerSimpleTest()
68 : command_line_(base::CommandLine::NO_PROGRAM) {}
69
70 void SetUp() override {
71 std::tie(metrics_status_, logs_upload_status_, reporter_engine_) =
72 GetParam();
73
74 SetChromeCleanerRunnerTestDelegateForTesting(this);
75 scoped_feature_list_.InitAndEnableFeature(kInBrowserCleanerUIFeature);
76 }
77
78 void CallRunChromeCleaner() {
79 SwReporterInvocation reporter_invocation;
80 switch (reporter_engine_) {
81 case ReporterEngine::kUnspecified:
82 // No engine switch.
83 break;
84 case ReporterEngine::kOldEngine:
85 reporter_invocation.command_line.AppendSwitchASCII(
86 chrome_cleaner::kEngineSwitch, "1");
87 break;
88 case ReporterEngine::kNewEngine:
89 reporter_invocation.command_line.AppendSwitchASCII(
90 chrome_cleaner::kEngineSwitch, "2");
91 break;
92 }
93
94 ChromeCleanerRunner::RunChromeCleanerAndReplyWithExitCode(
95 base::FilePath(FILE_PATH_LITERAL("cleaner.exe")), reporter_invocation,
96 metrics_status_, logs_upload_status_,
97 base::BindOnce(&ChromeCleanerRunnerSimpleTest::OnPromptUser,
98 base::Unretained(this)),
99 base::BindOnce(&ChromeCleanerRunnerSimpleTest::OnConnectionClosed,
100 base::Unretained(this)),
101 base::BindOnce(&ChromeCleanerRunnerSimpleTest::OnProcessDone,
102 base::Unretained(this)),
103 base::ThreadTaskRunnerHandle::Get());
104 }
105
106 // ChromeCleanerRunnerTestDelegate overrides.
107
108 base::Process LaunchTestProcess(
109 const base::CommandLine& command_line,
110 const base::LaunchOptions& launch_options) override {
111 command_line_ = command_line;
112 // Return an invalid process.
113 return base::Process();
114 }
115
116 base::CommandLine GetTestBaseCommandLine() override {
117 return base::CommandLine(base::CommandLine::NO_PROGRAM);
118 }
119
120 // IPC callbacks.
121
122 void OnPromptUser(std::unique_ptr<std::set<base::FilePath>> files_to_delete,
123 ChromePrompt::PromptUserCallback response) {}
124
125 void OnConnectionClosed() {}
126
127 void OnProcessDone(ChromeCleanerRunner::LaunchStatus launch_status) {
128 on_process_done_called_ = true;
129 launch_status_ = launch_status;
130 run_loop_.QuitWhenIdle();
131 }
132
133 protected:
134 content::TestBrowserThreadBundle test_browser_thread_bundle_;
135 base::test::ScopedFeatureList scoped_feature_list_;
136
137 // Test fixture parameters.
138 ChromeCleanerRunner::ChromeMetricsStatus metrics_status_;
139 ChromeCleanerRunner::CleanerLogsStatus logs_upload_status_;
140 ReporterEngine reporter_engine_;
141
142 // Set by LaunchTestProcess.
143 base::CommandLine command_line_;
144
145 // Variables set by OnProcessDone().
146 bool on_process_done_called_ = false;
147 ChromeCleanerRunner::LaunchStatus launch_status_;
148
149 base::RunLoop run_loop_;
150 };
151
152 TEST_P(ChromeCleanerRunnerSimpleTest, LaunchParams) {
153 CallRunChromeCleaner();
154 run_loop_.Run();
155
156 EXPECT_TRUE(on_process_done_called_);
157
158 EXPECT_EQ(
159 command_line_.GetSwitchValueASCII(chrome_cleaner::kExecutionModeSwitch),
160 base::IntToString(
161 static_cast<int>(chrome_cleaner::ExecutionMode::kScanning)));
csharp 2017/05/24 20:49:35 nit: I wonder if it is worth adding a helper funct
alito 2017/05/24 22:20:50 There is just this instance in this file... so pro
csharp 2017/05/25 14:44:46 For this file yes, but I think there are 3 or 4 ca
alito 2017/05/25 18:39:13 As discussed, this particular enum is cast only on
162
163 // Ensure that the engine flag is always set and that it correctly reflects
164 // the value of the same flag in the SwReporterInvocation() that was passed to
165 // ChromeCleanerRunner::RunChromeCleanerAndReplyWithExitCode(). In the tests,
166 // the engine flag in the SwReporterInvocation is controlled by the value of
167 // |reporter_engine_|.
168 //
169 // If the engine switch is missing in reporter invocation, it should still be
170 // explicitly set to the value "1" for the Cleaner.
171 std::string expected_engine_switch =
172 reporter_engine_ == ReporterEngine::kNewEngine ? "2" : "1";
173 EXPECT_EQ(command_line_.GetSwitchValueASCII(chrome_cleaner::kEngineSwitch),
174 expected_engine_switch);
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 // Enum to be used as parameter for the ChromeCleanerRunnerTest fixture below.
199 enum class UwsFoundState {
200 kNoUwsFound,
201 kUwsFoundRebootRequired,
202 kUwsFoundNoRebootRequired,
203 };
204
205 // Test fixture for testing ChromeCleanerRunner with a mock Chrome Cleaner
206 // process.
207 //
208 // Parameters:
209 //
210 // - uws_found_state (UwsFoundState): Whether the Chrome Cleaner process should
211 // find UwS on the system and if so whether reboot is required.
212 // - crash_point (CrashPoint): a single crash point where the Chrome Cleaner
213 // process will crash. See the MockChromeCleanerProcess documentation for
214 // possible values.
215 // - prompt_acceptance_to_send (PromptAcceptance): the prompt acceptance value
216 // that Chrome should send to the Chrome Cleaner process. Must be DENIED
217 // if |found_uws| is false.
218 class ChromeCleanerRunnerTest
219 : public testing::TestWithParam<
220 std::tuple<UwsFoundState,
221 MockChromeCleanerProcess::CrashPoint,
222 PromptAcceptance>>,
223 public ChromeCleanerRunnerTestDelegate {
224 public:
225 void SetUp() override {
226 UwsFoundState uws_found_state;
227 MockChromeCleanerProcess::CrashPoint crash_point;
228 PromptAcceptance prompt_acceptance_to_send;
229 std::tie(uws_found_state, crash_point, prompt_acceptance_to_send) =
230 GetParam();
231
232 ASSERT_FALSE(uws_found_state == UwsFoundState::kNoUwsFound &&
233 prompt_acceptance_to_send != PromptAcceptance::DENIED);
234
235 cleaner_process_options_.SetDoFindUws(uws_found_state !=
236 UwsFoundState::kNoUwsFound);
237 cleaner_process_options_.set_reboot_required(
238 uws_found_state == UwsFoundState::kUwsFoundRebootRequired);
239 cleaner_process_options_.set_crash_point(crash_point);
240 prompt_acceptance_to_send_ = prompt_acceptance_to_send;
241
242 SetChromeCleanerRunnerTestDelegateForTesting(this);
243 scoped_feature_list_.InitAndEnableFeature(kInBrowserCleanerUIFeature);
244 }
245
246 void CallRunChromeCleaner() {
247 ChromeCleanerRunner::RunChromeCleanerAndReplyWithExitCode(
248 base::FilePath(FILE_PATH_LITERAL("cleaner.exe")),
249 SwReporterInvocation(), ChromeMetricsStatus::kDisabled,
250 CleanerLogsStatus::kUploadDisabled,
251 base::BindOnce(&ChromeCleanerRunnerTest::OnPromptUser,
252 base::Unretained(this)),
253 base::BindOnce(&ChromeCleanerRunnerTest::OnConnectionClosed,
254 base::Unretained(this)),
255 base::BindOnce(&ChromeCleanerRunnerTest::OnProcessDone,
256 base::Unretained(this)),
257 base::ThreadTaskRunnerHandle::Get());
258 }
259
260 // ChromeCleanerRunnerTestDelegate overrides.
261
262 base::Process LaunchTestProcess(
263 const base::CommandLine& command_line,
264 const base::LaunchOptions& launch_options) override {
265 base::SpawnChildResult result = base::SpawnMultiProcessTestChild(
266 "MockChromeCleanerProcessMain", command_line, launch_options);
267
268 EXPECT_TRUE(result.process.IsValid());
269 return std::move(result.process);
270 }
271
272 base::CommandLine GetTestBaseCommandLine() override {
273 base::CommandLine command_line =
274 base::GetMultiProcessTestChildBaseCommandLine();
275 cleaner_process_options_.AddSwitchesToCommandLine(&command_line);
276 return command_line;
277 }
278
279 // IPC callbacks.
280
281 // Will receive the main Mojo message from the Mock Chrome Cleaner process.
282 void OnPromptUser(std::unique_ptr<std::set<base::FilePath>> files_to_delete,
283 ChromePrompt::PromptUserCallback response) {
284 on_prompt_user_called_ = true;
285 received_files_to_delete_ = std::move(files_to_delete);
286 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)
287 ->PostTask(FROM_HERE, base::BindOnce(std::move(response),
288 prompt_acceptance_to_send_));
289 }
290
291 void ContinueTestIfCommunicationDone() {
csharp 2017/05/24 20:49:35 I don't quite understand what this name means. Thi
alito 2017/05/24 22:20:50 It is not really waiting... so I tried, QuitTestRu
292 if (on_process_done_called_ && on_connection_closed_called_)
293 run_loop_.QuitWhenIdle();
294 }
295
296 void OnConnectionClosed() {
297 on_connection_closed_called_ = true;
298 ContinueTestIfCommunicationDone();
299 }
300
301 void OnProcessDone(ChromeCleanerRunner::LaunchStatus launch_status) {
302 on_process_done_called_ = true;
303 launch_status_ = launch_status;
304 ContinueTestIfCommunicationDone();
305 }
306
307 protected:
308 content::TestBrowserThreadBundle test_browser_thread_bundle_;
309 base::test::ScopedFeatureList scoped_feature_list_;
310
311 base::RunLoop run_loop_;
312
313 MockChromeCleanerProcess::Options cleaner_process_options_;
314 PromptAcceptance prompt_acceptance_to_send_ = PromptAcceptance::UNSPECIFIED;
315
316 // Set by OnProcessDone().
317 ChromeCleanerRunner::LaunchStatus launch_status_ = {false, -1};
318 // Set by OnPromptUser().
319 std::unique_ptr<std::set<base::FilePath>> received_files_to_delete_;
320
321 bool on_prompt_user_called_ = false;
322 bool on_connection_closed_called_ = false;
323 bool on_process_done_called_ = false;
324 };
325
326 MULTIPROCESS_TEST_MAIN(MockChromeCleanerProcessMain) {
327 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
328 MockChromeCleanerProcess::Options options;
329 EXPECT_TRUE(MockChromeCleanerProcess::Options::FromCommandLine(*command_line,
330 &options));
331
332 std::string chrome_mojo_pipe_token = command_line->GetSwitchValueASCII(
333 chrome_cleaner::kChromeMojoPipeTokenSwitch);
334 EXPECT_FALSE(chrome_mojo_pipe_token.empty());
335
336 // Since failures in any of the above calls to EXPECT_*() do not actually fail
337 // the test, we need to ensure that we return an exit code to indicate test
338 // failure in such cases.
339 if (::testing::Test::HasFailure())
340 return MockChromeCleanerProcess::kInternalTestFailureExitCode;
341
342 MockChromeCleanerProcess mock_cleaner_process(options,
343 chrome_mojo_pipe_token);
344 return mock_cleaner_process.Run();
345 }
346
347 TEST_P(ChromeCleanerRunnerTest, MockChromeCleanerProcess) {
csharp 2017/05/24 20:49:35 Maybe change MockChromeCleanerProcess so it isn't
alito 2017/05/24 22:20:50 Done.
348 CallRunChromeCleaner();
349 run_loop_.Run();
350
351 EXPECT_TRUE(on_process_done_called_);
352 EXPECT_TRUE(on_connection_closed_called_);
353 EXPECT_EQ(on_prompt_user_called_,
354 (cleaner_process_options_.crash_point() ==
355 MockChromeCleanerProcess::CrashPoint::kNone ||
356 cleaner_process_options_.crash_point() ==
357 MockChromeCleanerProcess::CrashPoint::kAfterResponseReceived));
358
359 if (on_prompt_user_called_ && !cleaner_process_options_.found_uws().empty()) {
360 EXPECT_EQ(*received_files_to_delete_,
361 cleaner_process_options_.files_to_delete());
362 }
363
364 EXPECT_TRUE(launch_status_.process_ok);
365 EXPECT_EQ(launch_status_.exit_code, cleaner_process_options_.ExpectedExitCode(
366 prompt_acceptance_to_send_));
367 }
368
369 INSTANTIATE_TEST_CASE_P(
370 All,
371 ChromeCleanerRunnerTest,
372 Combine(
373 Values(UwsFoundState::kNoUwsFound),
374 Values(MockChromeCleanerProcess::CrashPoint::kNone,
375 MockChromeCleanerProcess::CrashPoint::kOnStartup,
376 MockChromeCleanerProcess::CrashPoint::kAfterConnection,
377 MockChromeCleanerProcess::CrashPoint::kAfterRequestSent,
378 MockChromeCleanerProcess::CrashPoint::kAfterResponseReceived),
379 Values(PromptAcceptance::DENIED)));
380
381 INSTANTIATE_TEST_CASE_P(
382 UwsFound,
383 ChromeCleanerRunnerTest,
384 Combine(
385 Values(UwsFoundState::kUwsFoundRebootRequired,
386 UwsFoundState::kUwsFoundNoRebootRequired),
387 Values(MockChromeCleanerProcess::CrashPoint::kNone,
388 MockChromeCleanerProcess::CrashPoint::kOnStartup,
389 MockChromeCleanerProcess::CrashPoint::kAfterConnection,
390 MockChromeCleanerProcess::CrashPoint::kAfterRequestSent,
391 MockChromeCleanerProcess::CrashPoint::kAfterResponseReceived),
392 Values(PromptAcceptance::DENIED,
393 PromptAcceptance::ACCEPTED_WITH_LOGS,
394 PromptAcceptance::ACCEPTED_WITHOUT_LOGS)));
395
396 } // namespace
397 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698