1 // Copyright 2014 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.
6 #include "base/location.h"
7 #include "base/run_loop.h"
8 #include "base/single_thread_task_runner.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "chrome/browser/extensions/extension_install_checker.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 namespace extensions
{
17 const BlacklistState kBlacklistStateError
= BLACKLISTED_MALWARE
;
18 const char kDummyRequirementsError
[] = "Requirements error";
19 const char kDummyPolicyError
[] = "Cannot install extension";
21 const char kDummyPolicyError2
[] = "Another policy error";
22 const char kDummyRequirementsError2
[] = "Another requirements error";
23 const BlacklistState kBlacklistState2
= BLACKLISTED_SECURITY_VULNERABILITY
;
27 // Stubs most of the checks since we are interested in validating the logic in
28 // the install checker. This class implements a synchronous version of all
30 class ExtensionInstallCheckerForTest
: public ExtensionInstallChecker
{
32 ExtensionInstallCheckerForTest()
33 : ExtensionInstallChecker(NULL
),
34 requirements_check_called_(false),
35 blacklist_check_called_(false),
36 policy_check_called_(false),
37 blacklist_state_(NOT_BLACKLISTED
) {}
39 ~ExtensionInstallCheckerForTest() override
{}
41 void set_requirements_error(const std::string
& error
) {
42 requirements_error_
= error
;
44 void set_policy_check_error(const std::string
& error
) {
45 policy_check_error_
= error
;
47 void set_blacklist_state(BlacklistState state
) { blacklist_state_
= state
; }
49 bool requirements_check_called() const { return requirements_check_called_
; }
50 bool blacklist_check_called() const { return blacklist_check_called_
; }
51 bool policy_check_called() const { return policy_check_called_
; }
53 void MockCheckRequirements(int sequence_number
) {
54 std::vector
<std::string
> errors
;
55 if (!requirements_error_
.empty())
56 errors
.push_back(requirements_error_
);
57 OnRequirementsCheckDone(sequence_number
, errors
);
60 void MockCheckBlacklistState(int sequence_number
) {
61 OnBlacklistStateCheckDone(sequence_number
, blacklist_state_
);
65 void CheckRequirements() override
{
66 requirements_check_called_
= true;
67 MockCheckRequirements(current_sequence_number());
70 void CheckManagementPolicy() override
{
71 policy_check_called_
= true;
72 OnManagementPolicyCheckDone(policy_check_error_
.empty(),
76 void CheckBlacklistState() override
{
77 blacklist_check_called_
= true;
78 MockCheckBlacklistState(current_sequence_number());
81 void ResetResults() override
{
82 ExtensionInstallChecker::ResetResults();
84 requirements_check_called_
= false;
85 blacklist_check_called_
= false;
86 policy_check_called_
= false;
89 bool requirements_check_called_
;
90 bool blacklist_check_called_
;
91 bool policy_check_called_
;
93 // Dummy errors for testing.
94 std::string requirements_error_
;
95 std::string policy_check_error_
;
96 BlacklistState blacklist_state_
;
99 // This class implements asynchronous mocks of the requirements and blacklist
101 class ExtensionInstallCheckerAsync
: public ExtensionInstallCheckerForTest
{
103 void CheckRequirements() override
{
104 requirements_check_called_
= true;
106 base::ThreadTaskRunnerHandle::Get()->PostTask(
108 base::Bind(&ExtensionInstallCheckerForTest::MockCheckRequirements
,
109 base::Unretained(this), current_sequence_number()));
112 void CheckBlacklistState() override
{
113 blacklist_check_called_
= true;
115 base::ThreadTaskRunnerHandle::Get()->PostTask(
117 base::Bind(&ExtensionInstallCheckerForTest::MockCheckBlacklistState
,
118 base::Unretained(this), current_sequence_number()));
122 class CheckObserver
{
124 CheckObserver() : result_(0), call_count_(0) {}
126 int result() const { return result_
; }
127 int call_count() const { return call_count_
; }
129 void OnChecksComplete(int checks_failed
) {
130 result_
= checks_failed
;
138 base::RunLoop().RunUntilIdle();
146 class ExtensionInstallCheckerTest
: public testing::Test
{
148 ExtensionInstallCheckerTest() {}
149 ~ExtensionInstallCheckerTest() override
{}
151 void RunSecondInvocation(ExtensionInstallCheckerForTest
* checker
,
153 EXPECT_GT(checks_failed
, 0);
154 EXPECT_FALSE(checker
->is_running());
155 ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL
, *checker
);
157 // Set up different return values.
158 checker
->set_blacklist_state(kBlacklistState2
);
159 checker
->set_policy_check_error(kDummyPolicyError2
);
160 checker
->set_requirements_error(kDummyRequirementsError2
);
162 // Run the install checker again and ensure the second set of return values
165 ExtensionInstallChecker::CHECK_ALL
,
166 false /* fail fast */,
167 base::Bind(&ExtensionInstallCheckerTest::ValidateSecondInvocation
,
168 base::Unretained(this),
172 void ValidateSecondInvocation(ExtensionInstallCheckerForTest
* checker
,
174 EXPECT_FALSE(checker
->is_running());
175 EXPECT_EQ(ExtensionInstallChecker::CHECK_REQUIREMENTS
|
176 ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY
,
178 ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL
, *checker
);
180 EXPECT_EQ(kBlacklistState2
, checker
->blacklist_state());
181 ExpectPolicyError(kDummyPolicyError2
, *checker
);
182 ExpectRequirementsError(kDummyRequirementsError2
, *checker
);
186 void SetAllErrors(ExtensionInstallCheckerForTest
* checker
) {
187 checker
->set_blacklist_state(kBlacklistStateError
);
188 checker
->set_policy_check_error(kDummyPolicyError
);
189 checker
->set_requirements_error(kDummyRequirementsError
);
192 void ValidateExpectedCalls(int call_mask
,
193 const ExtensionInstallCheckerForTest
& checker
) {
194 bool expect_blacklist_checked
=
195 (call_mask
& ExtensionInstallChecker::CHECK_BLACKLIST
) != 0;
196 bool expect_requirements_checked
=
197 (call_mask
& ExtensionInstallChecker::CHECK_REQUIREMENTS
) != 0;
198 bool expect_policy_checked
=
199 (call_mask
& ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY
) != 0;
200 EXPECT_EQ(expect_blacklist_checked
, checker
.blacklist_check_called());
201 EXPECT_EQ(expect_policy_checked
, checker
.policy_check_called());
202 EXPECT_EQ(expect_requirements_checked
, checker
.requirements_check_called());
205 void ExpectRequirementsPass(const ExtensionInstallCheckerForTest
& checker
) {
206 EXPECT_TRUE(checker
.requirement_errors().empty());
209 void ExpectRequirementsError(const char* expected_error
,
210 const ExtensionInstallCheckerForTest
& checker
) {
211 EXPECT_FALSE(checker
.requirement_errors().empty());
212 EXPECT_EQ(std::string(expected_error
),
213 checker
.requirement_errors().front());
216 void ExpectRequirementsError(const ExtensionInstallCheckerForTest
& checker
) {
217 ExpectRequirementsError(kDummyRequirementsError
, checker
);
220 void ExpectBlacklistPass(const ExtensionInstallCheckerForTest
& checker
) {
221 EXPECT_EQ(NOT_BLACKLISTED
, checker
.blacklist_state());
224 void ExpectBlacklistError(const ExtensionInstallCheckerForTest
& checker
) {
225 EXPECT_EQ(kBlacklistStateError
, checker
.blacklist_state());
228 void ExpectPolicyPass(const ExtensionInstallCheckerForTest
& checker
) {
229 EXPECT_TRUE(checker
.policy_allows_load());
230 EXPECT_TRUE(checker
.policy_error().empty());
233 void ExpectPolicyError(const char* expected_error
,
234 const ExtensionInstallCheckerForTest
& checker
) {
235 EXPECT_FALSE(checker
.policy_allows_load());
236 EXPECT_FALSE(checker
.policy_error().empty());
237 EXPECT_EQ(std::string(expected_error
), checker
.policy_error());
240 void ExpectPolicyError(const ExtensionInstallCheckerForTest
& checker
) {
241 ExpectPolicyError(kDummyPolicyError
, checker
);
244 void RunChecker(ExtensionInstallCheckerForTest
* checker
,
247 int expected_checks_run
,
248 int expected_result
) {
249 CheckObserver observer
;
250 checker
->Start(checks_to_run
,
252 base::Bind(&CheckObserver::OnChecksComplete
,
253 base::Unretained(&observer
)));
256 EXPECT_FALSE(checker
->is_running());
257 EXPECT_EQ(expected_result
, observer
.result());
258 EXPECT_EQ(1, observer
.call_count());
259 ValidateExpectedCalls(expected_checks_run
, *checker
);
262 void DoRunAllChecksPass(ExtensionInstallCheckerForTest
* checker
) {
264 false /* fail fast */,
265 ExtensionInstallChecker::CHECK_ALL
,
266 ExtensionInstallChecker::CHECK_ALL
,
269 ExpectRequirementsPass(*checker
);
270 ExpectPolicyPass(*checker
);
271 ExpectBlacklistPass(*checker
);
274 void DoRunAllChecksFail(ExtensionInstallCheckerForTest
* checker
) {
275 SetAllErrors(checker
);
277 false /* fail fast */,
278 ExtensionInstallChecker::CHECK_ALL
,
279 ExtensionInstallChecker::CHECK_ALL
,
280 ExtensionInstallChecker::CHECK_ALL
);
282 ExpectRequirementsError(*checker
);
283 ExpectPolicyError(*checker
);
284 ExpectBlacklistError(*checker
);
287 void DoRunSubsetOfChecks(ExtensionInstallCheckerForTest
* checker
) {
289 int tests_to_run
= ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY
|
290 ExtensionInstallChecker::CHECK_REQUIREMENTS
;
291 SetAllErrors(checker
);
292 RunChecker(checker
, false, tests_to_run
, tests_to_run
, tests_to_run
);
294 ExpectRequirementsError(*checker
);
295 ExpectPolicyError(*checker
);
296 ExpectBlacklistPass(*checker
);
299 tests_to_run
= ExtensionInstallChecker::CHECK_BLACKLIST
|
300 ExtensionInstallChecker::CHECK_REQUIREMENTS
;
301 SetAllErrors(checker
);
302 RunChecker(checker
, false, tests_to_run
, tests_to_run
, tests_to_run
);
304 ExpectRequirementsError(*checker
);
305 ExpectPolicyPass(*checker
);
306 ExpectBlacklistError(*checker
);
308 // Test a single check.
309 tests_to_run
= ExtensionInstallChecker::CHECK_BLACKLIST
;
310 SetAllErrors(checker
);
311 RunChecker(checker
, false, tests_to_run
, tests_to_run
, tests_to_run
);
313 ExpectRequirementsPass(*checker
);
314 ExpectPolicyPass(*checker
);
315 ExpectBlacklistError(*checker
);
319 // A message loop is required for the asynchronous tests.
320 base::MessageLoop message_loop
;
323 class ExtensionInstallCheckerMultipleInvocationTest
324 : public ExtensionInstallCheckerTest
{
326 ExtensionInstallCheckerMultipleInvocationTest() : callback_count_(0) {}
327 ~ExtensionInstallCheckerMultipleInvocationTest() override
{}
329 void RunSecondInvocation(ExtensionInstallCheckerForTest
* checker
,
331 ASSERT_EQ(0, callback_count_
);
333 EXPECT_FALSE(checker
->is_running());
334 EXPECT_GT(checks_failed
, 0);
335 ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL
, *checker
);
337 // Set up different return values.
338 checker
->set_blacklist_state(kBlacklistState2
);
339 checker
->set_policy_check_error(kDummyPolicyError2
);
340 checker
->set_requirements_error(kDummyRequirementsError2
);
342 // Run the install checker again and ensure the second set of return values
344 checker
->Start(ExtensionInstallChecker::CHECK_ALL
,
345 false /* fail fast */,
346 base::Bind(&ExtensionInstallCheckerMultipleInvocationTest::
347 ValidateSecondInvocation
,
348 base::Unretained(this),
352 void ValidateSecondInvocation(ExtensionInstallCheckerForTest
* checker
,
354 ASSERT_EQ(1, callback_count_
);
355 EXPECT_FALSE(checker
->is_running());
356 EXPECT_EQ(ExtensionInstallChecker::CHECK_REQUIREMENTS
|
357 ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY
,
359 ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL
, *checker
);
361 EXPECT_EQ(kBlacklistState2
, checker
->blacklist_state());
362 ExpectPolicyError(kDummyPolicyError2
, *checker
);
363 ExpectRequirementsError(kDummyRequirementsError2
, *checker
);
370 // Test the case where all tests pass.
371 TEST_F(ExtensionInstallCheckerTest
, AllSucceeded
) {
372 ExtensionInstallCheckerForTest sync_checker
;
373 DoRunAllChecksPass(&sync_checker
);
375 ExtensionInstallCheckerAsync async_checker
;
376 DoRunAllChecksPass(&async_checker
);
379 // Test the case where all tests fail.
380 TEST_F(ExtensionInstallCheckerTest
, AllFailed
) {
381 ExtensionInstallCheckerForTest sync_checker
;
382 DoRunAllChecksFail(&sync_checker
);
384 ExtensionInstallCheckerAsync async_checker
;
385 DoRunAllChecksFail(&async_checker
);
388 // Test running only a subset of tests.
389 TEST_F(ExtensionInstallCheckerTest
, RunSubsetOfChecks
) {
390 ExtensionInstallCheckerForTest sync_checker
;
391 ExtensionInstallCheckerAsync async_checker
;
392 DoRunSubsetOfChecks(&sync_checker
);
393 DoRunSubsetOfChecks(&async_checker
);
396 // Test fail fast with synchronous callbacks.
397 TEST_F(ExtensionInstallCheckerTest
, FailFastSync
) {
398 // This test assumes some internal knowledge of the implementation - that
399 // the policy check runs first.
400 ExtensionInstallCheckerForTest checker
;
401 SetAllErrors(&checker
);
403 true /* fail fast */,
404 ExtensionInstallChecker::CHECK_ALL
,
405 ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY
,
406 ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY
);
408 ExpectRequirementsPass(checker
);
409 ExpectPolicyError(checker
);
410 ExpectBlacklistPass(checker
);
412 // This test assumes some internal knowledge of the implementation - that
413 // the requirements check runs before the blacklist check.
414 SetAllErrors(&checker
);
416 true /* fail fast */,
417 ExtensionInstallChecker::CHECK_REQUIREMENTS
|
418 ExtensionInstallChecker::CHECK_BLACKLIST
,
419 ExtensionInstallChecker::CHECK_REQUIREMENTS
,
420 ExtensionInstallChecker::CHECK_REQUIREMENTS
);
422 ExpectRequirementsError(checker
);
423 ExpectPolicyPass(checker
);
424 ExpectBlacklistPass(checker
);
427 // Test fail fast with asynchronous callbacks.
428 TEST_F(ExtensionInstallCheckerTest
, FailFastAsync
) {
429 // This test assumes some internal knowledge of the implementation - that
430 // the requirements check runs before the blacklist check. Both checks should
431 // be called, but the requirements check callback arrives first and the
432 // blacklist result will be discarded.
433 ExtensionInstallCheckerAsync checker
;
434 SetAllErrors(&checker
);
436 // The policy check is synchronous and needs to pass for the other tests to
438 checker
.set_policy_check_error(std::string());
441 true /* fail fast */,
442 ExtensionInstallChecker::CHECK_ALL
,
443 ExtensionInstallChecker::CHECK_ALL
,
444 ExtensionInstallChecker::CHECK_REQUIREMENTS
);
446 ExpectRequirementsError(checker
);
447 ExpectPolicyPass(checker
);
448 ExpectBlacklistPass(checker
);
451 // Test multiple invocations of the install checker. Wait for all checks to
453 TEST_F(ExtensionInstallCheckerMultipleInvocationTest
, CompleteAll
) {
454 ExtensionInstallCheckerAsync checker
;
455 SetAllErrors(&checker
);
457 // Start the second check as soon as the callback of the first run is invoked.
459 ExtensionInstallChecker::CHECK_ALL
,
460 false /* fail fast */,
462 &ExtensionInstallCheckerMultipleInvocationTest::RunSecondInvocation
,
463 base::Unretained(this),
465 base::RunLoop().RunUntilIdle();
468 // Test multiple invocations of the install checker and fail fast.
469 TEST_F(ExtensionInstallCheckerMultipleInvocationTest
, FailFast
) {
470 ExtensionInstallCheckerAsync checker
;
471 SetAllErrors(&checker
);
473 // The policy check is synchronous and needs to pass for the other tests to
475 checker
.set_policy_check_error(std::string());
477 // Start the second check as soon as the callback of the first run is invoked.
479 ExtensionInstallChecker::CHECK_ALL
,
480 true /* fail fast */,
482 &ExtensionInstallCheckerMultipleInvocationTest::RunSecondInvocation
,
483 base::Unretained(this),
485 base::RunLoop().RunUntilIdle();
488 } // namespace extensions