OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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/extensions/extension_install_checker.h" | |
6 | |
5 #include "base/bind.h" | 7 #include "base/bind.h" |
6 #include "base/location.h" | 8 #include "base/location.h" |
9 #include "base/memory/ptr_util.h" | |
7 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
8 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" |
12 #include "base/strings/utf_string_conversions.h" | |
9 #include "base/threading/thread_task_runner_handle.h" | 13 #include "base/threading/thread_task_runner_handle.h" |
10 #include "chrome/browser/extensions/extension_install_checker.h" | 14 #include "extensions/browser/preload_check_test_util.h" |
11 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
12 | 16 |
13 namespace extensions { | 17 namespace extensions { |
14 | 18 |
15 namespace { | 19 namespace { |
16 | 20 |
17 const BlacklistState kBlacklistStateError = BLACKLISTED_MALWARE; | 21 const PreloadCheck::Error kBlacklistError = PreloadCheck::BLACKLISTED_ID; |
18 const char kDummyRequirementsError[] = "Requirements error"; | 22 const char kDummyRequirementsError[] = "Requirements error"; |
19 const char kDummyPolicyError[] = "Cannot install extension"; | 23 const char kDummyPolicyError[] = "Cannot install extension"; |
20 | 24 |
21 } // namespace | 25 } // namespace |
22 | 26 |
23 // Stubs most of the checks since we are interested in validating the logic in | 27 // Stubs most of the checks since we are interested in validating the logic in |
24 // the install checker. This class implements a synchronous version of all | 28 // the install checker. This class implements a synchronous version of all |
25 // checks. | 29 // checks. |
26 class ExtensionInstallCheckerForTest : public ExtensionInstallChecker { | 30 class ExtensionInstallCheckerForTest : public ExtensionInstallChecker { |
27 public: | 31 public: |
28 ExtensionInstallCheckerForTest(int enabled_checks, bool fail_fast) | 32 ExtensionInstallCheckerForTest(int enabled_checks, bool fail_fast) |
29 : ExtensionInstallChecker(nullptr, nullptr, enabled_checks, fail_fast), | 33 : ExtensionInstallChecker(nullptr, nullptr, enabled_checks, fail_fast), |
30 requirements_check_called_(false), | 34 requirements_check_called_(false), |
31 blacklist_check_called_(false), | 35 blacklist_check_called_(false), |
32 policy_check_called_(false), | 36 policy_check_called_(false) {} |
33 blacklist_state_(NOT_BLACKLISTED) {} | |
34 | 37 |
35 ~ExtensionInstallCheckerForTest() override {} | 38 ~ExtensionInstallCheckerForTest() override {} |
36 | 39 |
37 void set_requirements_error(const std::string& error) { | 40 void set_requirements_error(const std::string& error) { |
38 requirements_error_ = error; | 41 requirements_error_ = error; |
39 } | 42 } |
40 void set_policy_check_error(const std::string& error) { | |
41 policy_check_error_ = error; | |
42 } | |
43 void set_blacklist_state(BlacklistState state) { blacklist_state_ = state; } | |
44 | 43 |
45 bool requirements_check_called() const { return requirements_check_called_; } | 44 bool requirements_check_called() const { return requirements_check_called_; } |
46 bool blacklist_check_called() const { return blacklist_check_called_; } | 45 bool blacklist_check_called() const { return blacklist_check_called_; } |
47 bool policy_check_called() const { return policy_check_called_; } | 46 bool policy_check_called() const { return policy_check_called_; } |
48 | 47 |
48 virtual bool is_async() { return false; } | |
49 | |
49 void MockCheckRequirements() { | 50 void MockCheckRequirements() { |
50 if (!is_running()) | 51 if (!is_running()) |
51 return; | 52 return; |
52 std::vector<std::string> errors; | 53 std::vector<std::string> errors; |
53 if (!requirements_error_.empty()) | 54 if (!requirements_error_.empty()) |
54 errors.push_back(requirements_error_); | 55 errors.push_back(requirements_error_); |
55 OnRequirementsCheckDone(errors); | 56 OnRequirementsCheckDone(errors); |
56 } | 57 } |
57 | 58 |
58 void MockCheckBlacklistState() { | |
59 if (!is_running()) | |
60 return; | |
61 OnBlacklistStateCheckDone(blacklist_state_); | |
62 } | |
63 | |
64 protected: | 59 protected: |
65 void CheckRequirements() override { | 60 void CheckRequirements() override { |
66 requirements_check_called_ = true; | 61 requirements_check_called_ = true; |
67 MockCheckRequirements(); | 62 if (is_async()) { |
63 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
64 FROM_HERE, | |
65 base::Bind(&ExtensionInstallCheckerForTest::MockCheckRequirements, | |
66 base::Unretained(this))); | |
67 } else { | |
68 MockCheckRequirements(); | |
69 } | |
68 } | 70 } |
69 | 71 |
70 void CheckManagementPolicy() override { | 72 void CheckManagementPolicy() override { |
71 policy_check_called_ = true; | 73 policy_check_called_ = true; |
Devlin
2017/03/22 15:08:46
(Mostly just thinking out loud) I'm a little dubio
michaelpg
2017/03/24 02:34:16
Makes sense; these primarily existed for mocking w
| |
72 OnManagementPolicyCheckDone(policy_check_error_.empty(), | 74 ExtensionInstallChecker::CheckManagementPolicy(); |
73 policy_check_error_); | |
74 } | 75 } |
75 | 76 |
76 void CheckBlacklistState() override { | 77 void CheckBlacklistState() override { |
77 blacklist_check_called_ = true; | 78 blacklist_check_called_ = true; |
78 MockCheckBlacklistState(); | 79 ExtensionInstallChecker::CheckBlacklistState(); |
79 } | 80 } |
80 | 81 |
81 bool requirements_check_called_; | 82 bool requirements_check_called_; |
82 bool blacklist_check_called_; | 83 bool blacklist_check_called_; |
83 bool policy_check_called_; | 84 bool policy_check_called_; |
84 | 85 |
85 // Dummy errors for testing. | 86 // Dummy error for testing. |
86 std::string requirements_error_; | 87 std::string requirements_error_; |
87 std::string policy_check_error_; | |
88 BlacklistState blacklist_state_; | |
89 }; | 88 }; |
90 | 89 |
91 // This class implements asynchronous mocks of the requirements and blacklist | 90 // This class implements asynchronous mocks of the requirements and blacklist |
92 // checks. | 91 // checks. |
93 class ExtensionInstallCheckerAsync : public ExtensionInstallCheckerForTest { | 92 class ExtensionInstallCheckerAsync : public ExtensionInstallCheckerForTest { |
Devlin
2017/03/22 15:08:46
Given how small this class is, I'd just expose a s
michaelpg
2017/03/24 02:34:16
Reasonable.
| |
94 public: | 93 public: |
95 ExtensionInstallCheckerAsync(int enabled_checks, bool fail_fast) | 94 ExtensionInstallCheckerAsync(int enabled_checks, bool fail_fast) |
96 : ExtensionInstallCheckerForTest(enabled_checks, fail_fast) {} | 95 : ExtensionInstallCheckerForTest(enabled_checks, fail_fast) {} |
96 ~ExtensionInstallCheckerAsync() override {} | |
97 | 97 |
98 protected: | 98 protected: |
99 void CheckRequirements() override { | 99 bool is_async() override { return true; } |
100 requirements_check_called_ = true; | |
101 | |
102 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
103 FROM_HERE, | |
104 base::Bind(&ExtensionInstallCheckerForTest::MockCheckRequirements, | |
105 base::Unretained(this))); | |
106 } | |
107 | |
108 void CheckBlacklistState() override { | |
109 blacklist_check_called_ = true; | |
110 | |
111 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
112 FROM_HERE, | |
113 base::Bind(&ExtensionInstallCheckerForTest::MockCheckBlacklistState, | |
114 base::Unretained(this))); | |
115 } | |
116 }; | 100 }; |
117 | 101 |
118 class CheckObserver { | 102 class CheckObserver { |
119 public: | 103 public: |
120 CheckObserver() : result_(0), call_count_(0) {} | 104 CheckObserver() : result_(0), call_count_(0) {} |
121 | 105 |
122 int result() const { return result_; } | 106 int result() const { return result_; } |
123 int call_count() const { return call_count_; } | 107 int call_count() const { return call_count_; } |
124 | 108 |
125 void OnChecksComplete(int checks_failed) { | 109 void OnChecksComplete(int checks_failed) { |
(...skipping 11 matching lines...) Expand all Loading... | |
137 private: | 121 private: |
138 int result_; | 122 int result_; |
139 int call_count_; | 123 int call_count_; |
140 }; | 124 }; |
141 | 125 |
142 class ExtensionInstallCheckerTest : public testing::Test { | 126 class ExtensionInstallCheckerTest : public testing::Test { |
143 public: | 127 public: |
144 ExtensionInstallCheckerTest() {} | 128 ExtensionInstallCheckerTest() {} |
145 ~ExtensionInstallCheckerTest() override {} | 129 ~ExtensionInstallCheckerTest() override {} |
146 | 130 |
131 void SetBlacklistError(ExtensionInstallCheckerForTest* checker, | |
132 PreloadCheck::Error error) { | |
133 std::unique_ptr<PreloadCheckStub> blacklist_check = | |
134 base::MakeUnique<PreloadCheckStub>(checker->is_async()); | |
135 if (error != PreloadCheck::NONE) | |
136 blacklist_check->AddError(error); | |
137 checker->SetBlacklistCheckForTesting(std::move(blacklist_check)); | |
138 } | |
139 | |
140 void SetPolicyError(ExtensionInstallCheckerForTest* checker, | |
141 PreloadCheck::Error error, | |
142 std::string message) { | |
143 // The policy check always runs synchronously. | |
144 std::unique_ptr<PreloadCheckStub> policy_check = | |
145 base::MakeUnique<PreloadCheckStub>(); | |
146 if (error != PreloadCheck::NONE) { | |
147 policy_check->AddError(error); | |
148 policy_check->set_error_message(base::UTF8ToUTF16(message)); | |
149 } | |
150 checker->SetPolicyCheckForTesting(std::move(policy_check)); | |
151 } | |
152 | |
147 protected: | 153 protected: |
154 void SetAllPass(ExtensionInstallCheckerForTest* checker) { | |
155 SetBlacklistError(checker, PreloadCheck::NONE); | |
156 SetPolicyError(checker, PreloadCheck::NONE, ""); | |
157 checker->set_requirements_error(""); | |
158 } | |
159 | |
148 void SetAllErrors(ExtensionInstallCheckerForTest* checker) { | 160 void SetAllErrors(ExtensionInstallCheckerForTest* checker) { |
149 checker->set_blacklist_state(kBlacklistStateError); | 161 SetBlacklistError(checker, kBlacklistError); |
150 checker->set_policy_check_error(kDummyPolicyError); | 162 SetPolicyError(checker, PreloadCheck::DISALLOWED_BY_POLICY, |
163 kDummyPolicyError); | |
151 checker->set_requirements_error(kDummyRequirementsError); | 164 checker->set_requirements_error(kDummyRequirementsError); |
152 } | 165 } |
153 | 166 |
154 void ValidateExpectedCalls(int call_mask, | 167 void ValidateExpectedCalls(int call_mask, |
155 const ExtensionInstallCheckerForTest& checker) { | 168 const ExtensionInstallCheckerForTest& checker) { |
156 bool expect_blacklist_checked = | 169 bool expect_blacklist_checked = |
157 (call_mask & ExtensionInstallChecker::CHECK_BLACKLIST) != 0; | 170 (call_mask & ExtensionInstallChecker::CHECK_BLACKLIST) != 0; |
158 bool expect_requirements_checked = | 171 bool expect_requirements_checked = |
159 (call_mask & ExtensionInstallChecker::CHECK_REQUIREMENTS) != 0; | 172 (call_mask & ExtensionInstallChecker::CHECK_REQUIREMENTS) != 0; |
160 bool expect_policy_checked = | 173 bool expect_policy_checked = |
(...skipping 12 matching lines...) Expand all Loading... | |
173 EXPECT_FALSE(checker.requirement_errors().empty()); | 186 EXPECT_FALSE(checker.requirement_errors().empty()); |
174 EXPECT_EQ(std::string(expected_error), | 187 EXPECT_EQ(std::string(expected_error), |
175 checker.requirement_errors().front()); | 188 checker.requirement_errors().front()); |
176 } | 189 } |
177 | 190 |
178 void ExpectRequirementsError(const ExtensionInstallCheckerForTest& checker) { | 191 void ExpectRequirementsError(const ExtensionInstallCheckerForTest& checker) { |
179 ExpectRequirementsError(kDummyRequirementsError, checker); | 192 ExpectRequirementsError(kDummyRequirementsError, checker); |
180 } | 193 } |
181 | 194 |
182 void ExpectBlacklistPass(const ExtensionInstallCheckerForTest& checker) { | 195 void ExpectBlacklistPass(const ExtensionInstallCheckerForTest& checker) { |
183 EXPECT_EQ(NOT_BLACKLISTED, checker.blacklist_state()); | 196 EXPECT_EQ(PreloadCheck::NONE, checker.blacklist_error()); |
184 } | 197 } |
185 | 198 |
186 void ExpectBlacklistError(const ExtensionInstallCheckerForTest& checker) { | 199 void ExpectBlacklistError(const ExtensionInstallCheckerForTest& checker) { |
187 EXPECT_EQ(kBlacklistStateError, checker.blacklist_state()); | 200 EXPECT_EQ(kBlacklistError, checker.blacklist_error()); |
188 } | 201 } |
189 | 202 |
190 void ExpectPolicyPass(const ExtensionInstallCheckerForTest& checker) { | 203 void ExpectPolicyPass(const ExtensionInstallCheckerForTest& checker) { |
191 EXPECT_TRUE(checker.policy_allows_load()); | |
192 EXPECT_TRUE(checker.policy_error().empty()); | 204 EXPECT_TRUE(checker.policy_error().empty()); |
193 } | 205 } |
194 | 206 |
195 void ExpectPolicyError(const char* expected_error, | 207 void ExpectPolicyError(const char* expected_error, |
196 const ExtensionInstallCheckerForTest& checker) { | 208 const ExtensionInstallCheckerForTest& checker) { |
197 EXPECT_FALSE(checker.policy_allows_load()); | |
198 EXPECT_FALSE(checker.policy_error().empty()); | 209 EXPECT_FALSE(checker.policy_error().empty()); |
199 EXPECT_EQ(std::string(expected_error), checker.policy_error()); | 210 EXPECT_EQ(std::string(expected_error), checker.policy_error()); |
200 } | 211 } |
201 | 212 |
202 void ExpectPolicyError(const ExtensionInstallCheckerForTest& checker) { | 213 void ExpectPolicyError(const ExtensionInstallCheckerForTest& checker) { |
203 ExpectPolicyError(kDummyPolicyError, checker); | 214 ExpectPolicyError(kDummyPolicyError, checker); |
204 } | 215 } |
205 | 216 |
206 void RunChecker(ExtensionInstallCheckerForTest* checker, | 217 void RunChecker(ExtensionInstallCheckerForTest* checker, |
207 int expected_checks_run, | 218 int expected_checks_run, |
208 int expected_result) { | 219 int expected_result) { |
209 CheckObserver observer; | 220 CheckObserver observer; |
210 checker->Start(base::Bind(&CheckObserver::OnChecksComplete, | 221 checker->Start(base::Bind(&CheckObserver::OnChecksComplete, |
211 base::Unretained(&observer))); | 222 base::Unretained(&observer))); |
212 observer.Wait(); | 223 observer.Wait(); |
213 | 224 |
214 EXPECT_FALSE(checker->is_running()); | 225 EXPECT_FALSE(checker->is_running()); |
215 EXPECT_EQ(expected_result, observer.result()); | 226 EXPECT_EQ(expected_result, observer.result()); |
216 EXPECT_EQ(1, observer.call_count()); | 227 EXPECT_EQ(1, observer.call_count()); |
217 ValidateExpectedCalls(expected_checks_run, *checker); | 228 ValidateExpectedCalls(expected_checks_run, *checker); |
218 } | 229 } |
219 | 230 |
220 void DoRunAllChecksPass(ExtensionInstallCheckerForTest* checker) { | 231 void DoRunAllChecksPass(ExtensionInstallCheckerForTest* checker) { |
232 SetAllPass(checker); | |
221 RunChecker(checker, | 233 RunChecker(checker, |
222 ExtensionInstallChecker::CHECK_ALL, | 234 ExtensionInstallChecker::CHECK_ALL, |
223 0); | 235 0); |
224 | 236 |
225 ExpectRequirementsPass(*checker); | 237 ExpectRequirementsPass(*checker); |
226 ExpectPolicyPass(*checker); | 238 ExpectPolicyPass(*checker); |
227 ExpectBlacklistPass(*checker); | 239 ExpectBlacklistPass(*checker); |
228 } | 240 } |
229 | 241 |
230 void DoRunAllChecksFail(ExtensionInstallCheckerForTest* checker) { | 242 void DoRunAllChecksFail(ExtensionInstallCheckerForTest* checker) { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
336 } | 348 } |
337 | 349 |
338 // Test fail fast with asynchronous callbacks. | 350 // Test fail fast with asynchronous callbacks. |
339 TEST_F(ExtensionInstallCheckerTest, FailFastAsync) { | 351 TEST_F(ExtensionInstallCheckerTest, FailFastAsync) { |
340 // This test assumes some internal knowledge of the implementation - that | 352 // This test assumes some internal knowledge of the implementation - that |
341 // the requirements check runs before the blacklist check. Both checks should | 353 // the requirements check runs before the blacklist check. Both checks should |
342 // be called, but the requirements check callback arrives first and the | 354 // be called, but the requirements check callback arrives first and the |
343 // blacklist result will be discarded. | 355 // blacklist result will be discarded. |
344 ExtensionInstallCheckerAsync checker(ExtensionInstallChecker::CHECK_ALL, | 356 ExtensionInstallCheckerAsync checker(ExtensionInstallChecker::CHECK_ALL, |
345 /*fail_fast=*/true); | 357 /*fail_fast=*/true); |
346 | |
347 SetAllErrors(&checker); | 358 SetAllErrors(&checker); |
348 | 359 |
349 // The policy check is synchronous and needs to pass for the other tests to | 360 // The policy check is synchronous and needs to pass for the other tests to |
350 // run. | 361 // run. |
351 checker.set_policy_check_error(std::string()); | 362 SetPolicyError(&checker, PreloadCheck::NONE, ""); |
352 | 363 |
353 RunChecker(&checker, | 364 RunChecker(&checker, |
354 ExtensionInstallChecker::CHECK_ALL, | 365 ExtensionInstallChecker::CHECK_ALL, |
355 ExtensionInstallChecker::CHECK_REQUIREMENTS); | 366 ExtensionInstallChecker::CHECK_REQUIREMENTS); |
356 | 367 |
357 ExpectRequirementsError(checker); | 368 ExpectRequirementsError(checker); |
358 ExpectPolicyPass(checker); | 369 ExpectPolicyPass(checker); |
359 ExpectBlacklistPass(checker); | 370 ExpectBlacklistPass(checker); |
360 } | 371 } |
361 | 372 |
362 } // namespace extensions | 373 } // namespace extensions |
OLD | NEW |