OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "base/bind.h" |
| 6 #include "base/message_loop/message_loop.h" |
| 7 #include "base/run_loop.h" |
| 8 #include "chrome/browser/extensions/extension_install_checker.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 |
| 11 namespace extensions { |
| 12 |
| 13 namespace { |
| 14 |
| 15 const char kDummyRequirementsError[] = "Requirements error"; |
| 16 const char kDummyPolicyError[] = "Cannot install extension"; |
| 17 |
| 18 } // namespace |
| 19 |
| 20 // Stubs most of the checks since we are interested in validating the logic in |
| 21 // the install checker. This class implements a synchronous version of all |
| 22 // checks. |
| 23 class ExtensionInstallCheckerForTest : public ExtensionInstallChecker { |
| 24 public: |
| 25 ExtensionInstallCheckerForTest() |
| 26 : ExtensionInstallChecker(NULL), |
| 27 requirements_check_called_(false), |
| 28 blacklist_check_called_(false), |
| 29 policy_check_called_(false), |
| 30 blacklist_state_(NOT_BLACKLISTED) {} |
| 31 |
| 32 virtual ~ExtensionInstallCheckerForTest() {} |
| 33 |
| 34 void set_requirements_error(const std::string& error) { |
| 35 requirements_error_ = error; |
| 36 } |
| 37 void set_policy_check_error(const std::string& error) { |
| 38 policy_check_error_ = error; |
| 39 } |
| 40 void set_blacklist_state(BlacklistState state) { blacklist_state_ = state; } |
| 41 |
| 42 bool requirements_check_called() const { return requirements_check_called_; } |
| 43 bool blacklist_check_called() const { return blacklist_check_called_; } |
| 44 bool policy_check_called() const { return policy_check_called_; } |
| 45 |
| 46 void MockCheckRequirements() { |
| 47 std::vector<std::string> errors; |
| 48 if (!requirements_error_.empty()) |
| 49 errors.push_back(requirements_error_); |
| 50 OnRequirementsCheckDone(errors); |
| 51 } |
| 52 |
| 53 void MockCheckBlacklistState() { |
| 54 OnBlacklistStateCheckDone(blacklist_state_); |
| 55 } |
| 56 |
| 57 protected: |
| 58 virtual void CheckRequirements() OVERRIDE { |
| 59 requirements_check_called_ = true; |
| 60 MockCheckRequirements(); |
| 61 } |
| 62 |
| 63 virtual void CheckManagementPolicy() OVERRIDE { |
| 64 policy_check_called_ = true; |
| 65 OnManagementPolicyCheckDone(policy_check_error_.empty(), |
| 66 policy_check_error_); |
| 67 } |
| 68 |
| 69 virtual void CheckBlacklistState() OVERRIDE { |
| 70 blacklist_check_called_ = true; |
| 71 MockCheckBlacklistState(); |
| 72 } |
| 73 |
| 74 virtual void ResetResults() OVERRIDE { |
| 75 ExtensionInstallChecker::ResetResults(); |
| 76 |
| 77 requirements_check_called_ = false; |
| 78 blacklist_check_called_ = false; |
| 79 policy_check_called_ = false; |
| 80 } |
| 81 |
| 82 bool requirements_check_called_; |
| 83 bool blacklist_check_called_; |
| 84 bool policy_check_called_; |
| 85 |
| 86 // Dummy errors for testing. |
| 87 std::string requirements_error_; |
| 88 std::string policy_check_error_; |
| 89 BlacklistState blacklist_state_; |
| 90 }; |
| 91 |
| 92 // This class implements asynchronous mocks of the requirements and blacklist |
| 93 // checks. |
| 94 class ExtensionInstallCheckerAsync : public ExtensionInstallCheckerForTest { |
| 95 protected: |
| 96 virtual void CheckRequirements() OVERRIDE { |
| 97 requirements_check_called_ = true; |
| 98 |
| 99 base::MessageLoop::current()->PostTask( |
| 100 FROM_HERE, |
| 101 base::Bind(&ExtensionInstallCheckerForTest::MockCheckRequirements, |
| 102 base::Unretained(this))); |
| 103 } |
| 104 |
| 105 virtual void CheckBlacklistState() OVERRIDE { |
| 106 blacklist_check_called_ = true; |
| 107 |
| 108 base::MessageLoop::current()->PostTask( |
| 109 FROM_HERE, |
| 110 base::Bind(&ExtensionInstallCheckerForTest::MockCheckBlacklistState, |
| 111 base::Unretained(this))); |
| 112 } |
| 113 }; |
| 114 |
| 115 class CheckObserver { |
| 116 public: |
| 117 CheckObserver() : result_(0), call_count_(0) {} |
| 118 |
| 119 int result() const { return result_; } |
| 120 int call_count() const { return call_count_; } |
| 121 |
| 122 void OnChecksComplete(int checks_failed) { |
| 123 result_ = checks_failed; |
| 124 ++call_count_; |
| 125 } |
| 126 |
| 127 void Wait() { |
| 128 if (call_count_) |
| 129 return; |
| 130 |
| 131 base::RunLoop().RunUntilIdle(); |
| 132 } |
| 133 |
| 134 private: |
| 135 int result_; |
| 136 int call_count_; |
| 137 }; |
| 138 |
| 139 class ExtensionInstallCheckerTest : public testing::Test { |
| 140 protected: |
| 141 ExtensionInstallCheckerTest() {} |
| 142 virtual ~ExtensionInstallCheckerTest() {} |
| 143 |
| 144 void SetAllErrors(ExtensionInstallCheckerForTest* checker) { |
| 145 checker->set_blacklist_state(BLACKLISTED_MALWARE); |
| 146 checker->set_policy_check_error(kDummyPolicyError); |
| 147 checker->set_requirements_error(kDummyRequirementsError); |
| 148 } |
| 149 |
| 150 void ValidateExpectedCalls(int call_mask, |
| 151 const ExtensionInstallCheckerForTest& checker) { |
| 152 bool expect_blacklist_checked = |
| 153 (call_mask & ExtensionInstallChecker::CHECK_BLACKLIST) != 0; |
| 154 bool expect_requirements_checked = |
| 155 (call_mask & ExtensionInstallChecker::CHECK_REQUIREMENTS) != 0; |
| 156 bool expect_policy_checked = |
| 157 (call_mask & ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY) != 0; |
| 158 EXPECT_EQ(expect_blacklist_checked, checker.blacklist_check_called()); |
| 159 EXPECT_EQ(expect_policy_checked, checker.policy_check_called()); |
| 160 EXPECT_EQ(expect_requirements_checked, checker.requirements_check_called()); |
| 161 } |
| 162 |
| 163 void ExpectRequirementsPass(const ExtensionInstallCheckerForTest& checker) { |
| 164 EXPECT_TRUE(checker.requirement_errors().empty()); |
| 165 } |
| 166 |
| 167 void ExpectRequirementsError(const ExtensionInstallCheckerForTest& checker) { |
| 168 EXPECT_FALSE(checker.requirement_errors().empty()); |
| 169 EXPECT_EQ(std::string(kDummyRequirementsError), |
| 170 checker.requirement_errors().front()); |
| 171 } |
| 172 |
| 173 void ExpectBlacklistPass(const ExtensionInstallCheckerForTest& checker) { |
| 174 EXPECT_EQ(NOT_BLACKLISTED, checker.blacklist_state()); |
| 175 } |
| 176 |
| 177 void ExpectBlacklistError(const ExtensionInstallCheckerForTest& checker) { |
| 178 EXPECT_EQ(BLACKLISTED_MALWARE, checker.blacklist_state()); |
| 179 } |
| 180 |
| 181 void ExpectPolicyPass(const ExtensionInstallCheckerForTest& checker) { |
| 182 EXPECT_TRUE(checker.policy_allows_load()); |
| 183 EXPECT_TRUE(checker.policy_error().empty()); |
| 184 } |
| 185 |
| 186 void ExpectPolicyError(const ExtensionInstallCheckerForTest& checker) { |
| 187 EXPECT_FALSE(checker.policy_allows_load()); |
| 188 EXPECT_FALSE(checker.policy_error().empty()); |
| 189 EXPECT_EQ(std::string(kDummyPolicyError), checker.policy_error()); |
| 190 } |
| 191 |
| 192 void RunChecker(ExtensionInstallCheckerForTest* checker, |
| 193 bool fail_fast, |
| 194 int checks_to_run, |
| 195 int expected_checks_run, |
| 196 int expected_result) { |
| 197 CheckObserver observer; |
| 198 checker->Start(checks_to_run, |
| 199 fail_fast, |
| 200 base::Bind(&CheckObserver::OnChecksComplete, |
| 201 base::Unretained(&observer))); |
| 202 observer.Wait(); |
| 203 |
| 204 EXPECT_FALSE(checker->is_running()); |
| 205 EXPECT_EQ(expected_result, observer.result()); |
| 206 EXPECT_EQ(1, observer.call_count()); |
| 207 ValidateExpectedCalls(expected_checks_run, *checker); |
| 208 } |
| 209 |
| 210 void DoRunAllChecksPass(ExtensionInstallCheckerForTest* checker) { |
| 211 RunChecker(checker, |
| 212 false, |
| 213 ExtensionInstallChecker::CHECK_ALL, |
| 214 ExtensionInstallChecker::CHECK_ALL, |
| 215 0); |
| 216 |
| 217 ExpectRequirementsPass(*checker); |
| 218 ExpectPolicyPass(*checker); |
| 219 ExpectBlacklistPass(*checker); |
| 220 } |
| 221 |
| 222 void DoRunAllChecksFail(ExtensionInstallCheckerForTest* checker) { |
| 223 SetAllErrors(checker); |
| 224 RunChecker(checker, |
| 225 false, |
| 226 ExtensionInstallChecker::CHECK_ALL, |
| 227 ExtensionInstallChecker::CHECK_ALL, |
| 228 ExtensionInstallChecker::CHECK_ALL); |
| 229 |
| 230 ExpectRequirementsError(*checker); |
| 231 ExpectPolicyError(*checker); |
| 232 ExpectBlacklistError(*checker); |
| 233 } |
| 234 |
| 235 void DoRunSubsetOfChecks(ExtensionInstallCheckerForTest* checker) { |
| 236 // Test check set 1. |
| 237 int tests_to_run = ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY | |
| 238 ExtensionInstallChecker::CHECK_REQUIREMENTS; |
| 239 SetAllErrors(checker); |
| 240 RunChecker(checker, false, tests_to_run, tests_to_run, tests_to_run); |
| 241 |
| 242 ExpectRequirementsError(*checker); |
| 243 ExpectPolicyError(*checker); |
| 244 ExpectBlacklistPass(*checker); |
| 245 |
| 246 // Test check set 2. |
| 247 tests_to_run = ExtensionInstallChecker::CHECK_BLACKLIST | |
| 248 ExtensionInstallChecker::CHECK_REQUIREMENTS; |
| 249 SetAllErrors(checker); |
| 250 RunChecker(checker, false, tests_to_run, tests_to_run, tests_to_run); |
| 251 |
| 252 ExpectRequirementsError(*checker); |
| 253 ExpectPolicyPass(*checker); |
| 254 ExpectBlacklistError(*checker); |
| 255 |
| 256 // Test a single check. |
| 257 tests_to_run = ExtensionInstallChecker::CHECK_BLACKLIST; |
| 258 SetAllErrors(checker); |
| 259 RunChecker(checker, false, tests_to_run, tests_to_run, tests_to_run); |
| 260 |
| 261 ExpectRequirementsPass(*checker); |
| 262 ExpectPolicyPass(*checker); |
| 263 ExpectBlacklistError(*checker); |
| 264 } |
| 265 |
| 266 private: |
| 267 // A message loop is required for the asynchronous tests. |
| 268 base::MessageLoop message_loop; |
| 269 }; |
| 270 |
| 271 // Test the case where all tests pass. |
| 272 TEST_F(ExtensionInstallCheckerTest, AllSucceeded) { |
| 273 ExtensionInstallCheckerForTest sync_checker; |
| 274 DoRunAllChecksPass(&sync_checker); |
| 275 |
| 276 ExtensionInstallCheckerAsync async_checker; |
| 277 DoRunAllChecksPass(&async_checker); |
| 278 } |
| 279 |
| 280 // Test the case where all tests fail. |
| 281 TEST_F(ExtensionInstallCheckerTest, AllFailed) { |
| 282 ExtensionInstallCheckerForTest sync_checker; |
| 283 DoRunAllChecksFail(&sync_checker); |
| 284 |
| 285 ExtensionInstallCheckerAsync async_checker; |
| 286 DoRunAllChecksFail(&async_checker); |
| 287 } |
| 288 |
| 289 // Test running only a subset of tests. |
| 290 TEST_F(ExtensionInstallCheckerTest, RunSubsetOfChecks) { |
| 291 ExtensionInstallCheckerForTest sync_checker; |
| 292 ExtensionInstallCheckerAsync async_checker; |
| 293 DoRunSubsetOfChecks(&sync_checker); |
| 294 DoRunSubsetOfChecks(&async_checker); |
| 295 } |
| 296 |
| 297 // Test fail fast with synchronous callbacks. |
| 298 TEST_F(ExtensionInstallCheckerTest, FailFastSync) { |
| 299 // This test assumes some internal knowledge of the implementation - that |
| 300 // the policy check runs first. |
| 301 ExtensionInstallCheckerForTest checker; |
| 302 SetAllErrors(&checker); |
| 303 RunChecker(&checker, |
| 304 true, |
| 305 ExtensionInstallChecker::CHECK_ALL, |
| 306 ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY, |
| 307 ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY); |
| 308 |
| 309 ExpectRequirementsPass(checker); |
| 310 ExpectPolicyError(checker); |
| 311 ExpectBlacklistPass(checker); |
| 312 |
| 313 // This test assumes some internal knowledge of the implementation - that |
| 314 // the requirements check runs before the blacklist check. |
| 315 SetAllErrors(&checker); |
| 316 RunChecker(&checker, |
| 317 true, |
| 318 ExtensionInstallChecker::CHECK_REQUIREMENTS | |
| 319 ExtensionInstallChecker::CHECK_BLACKLIST, |
| 320 ExtensionInstallChecker::CHECK_REQUIREMENTS, |
| 321 ExtensionInstallChecker::CHECK_REQUIREMENTS); |
| 322 |
| 323 ExpectRequirementsError(checker); |
| 324 ExpectPolicyPass(checker); |
| 325 ExpectBlacklistPass(checker); |
| 326 } |
| 327 |
| 328 // Test fail fast with asynchronous callbacks. |
| 329 TEST_F(ExtensionInstallCheckerTest, FailFastAsync) { |
| 330 // This test assumes some internal knowledge of the implementation - that |
| 331 // the requirements check runs before the blacklist check. |
| 332 // Both checks should be called, but the requirements check callback arrives |
| 333 // first and the blacklist result will be discarded. |
| 334 ExtensionInstallCheckerAsync checker; |
| 335 SetAllErrors(&checker); |
| 336 RunChecker(&checker, |
| 337 true, |
| 338 ExtensionInstallChecker::CHECK_REQUIREMENTS | |
| 339 ExtensionInstallChecker::CHECK_BLACKLIST, |
| 340 ExtensionInstallChecker::CHECK_REQUIREMENTS | |
| 341 ExtensionInstallChecker::CHECK_BLACKLIST, |
| 342 ExtensionInstallChecker::CHECK_REQUIREMENTS); |
| 343 |
| 344 ExpectRequirementsError(checker); |
| 345 ExpectPolicyPass(checker); |
| 346 ExpectBlacklistPass(checker); |
| 347 } |
| 348 |
| 349 } // namespace extensions |
OLD | NEW |