Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / extension_install_checker_unittest.cc
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 BlacklistState kBlacklistStateError = BLACKLISTED_MALWARE;
16 const char kDummyRequirementsError[] = "Requirements error";
17 const char kDummyPolicyError[] = "Cannot install extension";
18
19 const char kDummyPolicyError2[] = "Another policy error";
20 const char kDummyRequirementsError2[] = "Another requirements error";
21 const BlacklistState kBlacklistState2 = BLACKLISTED_SECURITY_VULNERABILITY;
22
23 }  // namespace
24
25 // Stubs most of the checks since we are interested in validating the logic in
26 // the install checker. This class implements a synchronous version of all
27 // checks.
28 class ExtensionInstallCheckerForTest : public ExtensionInstallChecker {
29  public:
30   ExtensionInstallCheckerForTest()
31       : ExtensionInstallChecker(NULL),
32         requirements_check_called_(false),
33         blacklist_check_called_(false),
34         policy_check_called_(false),
35         blacklist_state_(NOT_BLACKLISTED) {}
36
37   virtual ~ExtensionInstallCheckerForTest() {}
38
39   void set_requirements_error(const std::string& error) {
40     requirements_error_ = error;
41   }
42   void set_policy_check_error(const std::string& error) {
43     policy_check_error_ = error;
44   }
45   void set_blacklist_state(BlacklistState state) { blacklist_state_ = state; }
46
47   bool requirements_check_called() const { return requirements_check_called_; }
48   bool blacklist_check_called() const { return blacklist_check_called_; }
49   bool policy_check_called() const { return policy_check_called_; }
50
51   void MockCheckRequirements(int sequence_number) {
52     std::vector<std::string> errors;
53     if (!requirements_error_.empty())
54       errors.push_back(requirements_error_);
55     OnRequirementsCheckDone(sequence_number, errors);
56   }
57
58   void MockCheckBlacklistState(int sequence_number) {
59     OnBlacklistStateCheckDone(sequence_number, blacklist_state_);
60   }
61
62  protected:
63   virtual void CheckRequirements() OVERRIDE {
64     requirements_check_called_ = true;
65     MockCheckRequirements(current_sequence_number());
66   }
67
68   virtual void CheckManagementPolicy() OVERRIDE {
69     policy_check_called_ = true;
70     OnManagementPolicyCheckDone(policy_check_error_.empty(),
71                                 policy_check_error_);
72   }
73
74   virtual void CheckBlacklistState() OVERRIDE {
75     blacklist_check_called_ = true;
76     MockCheckBlacklistState(current_sequence_number());
77   }
78
79   virtual void ResetResults() OVERRIDE {
80     ExtensionInstallChecker::ResetResults();
81
82     requirements_check_called_ = false;
83     blacklist_check_called_ = false;
84     policy_check_called_ = false;
85   }
86
87   bool requirements_check_called_;
88   bool blacklist_check_called_;
89   bool policy_check_called_;
90
91   // Dummy errors for testing.
92   std::string requirements_error_;
93   std::string policy_check_error_;
94   BlacklistState blacklist_state_;
95 };
96
97 // This class implements asynchronous mocks of the requirements and blacklist
98 // checks.
99 class ExtensionInstallCheckerAsync : public ExtensionInstallCheckerForTest {
100  protected:
101   virtual void CheckRequirements() OVERRIDE {
102     requirements_check_called_ = true;
103
104     base::MessageLoop::current()->PostTask(
105         FROM_HERE,
106         base::Bind(&ExtensionInstallCheckerForTest::MockCheckRequirements,
107                    base::Unretained(this),
108                    current_sequence_number()));
109   }
110
111   virtual void CheckBlacklistState() OVERRIDE {
112     blacklist_check_called_ = true;
113
114     base::MessageLoop::current()->PostTask(
115         FROM_HERE,
116         base::Bind(&ExtensionInstallCheckerForTest::MockCheckBlacklistState,
117                    base::Unretained(this),
118                    current_sequence_number()));
119   }
120 };
121
122 class CheckObserver {
123  public:
124   CheckObserver() : result_(0), call_count_(0) {}
125
126   int result() const { return result_; }
127   int call_count() const { return call_count_; }
128
129   void OnChecksComplete(int checks_failed) {
130     result_ = checks_failed;
131     ++call_count_;
132   }
133
134   void Wait() {
135     if (call_count_)
136       return;
137
138     base::RunLoop().RunUntilIdle();
139   }
140
141  private:
142   int result_;
143   int call_count_;
144 };
145
146 class ExtensionInstallCheckerTest : public testing::Test {
147  public:
148   ExtensionInstallCheckerTest() {}
149   virtual ~ExtensionInstallCheckerTest() {}
150
151   void RunSecondInvocation(ExtensionInstallCheckerForTest* checker,
152                            int checks_failed) {
153     EXPECT_GT(checks_failed, 0);
154     EXPECT_FALSE(checker->is_running());
155     ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL, *checker);
156
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);
161
162     // Run the install checker again and ensure the second set of return values
163     // is received.
164     checker->Start(
165         ExtensionInstallChecker::CHECK_ALL,
166         false /* fail fast */,
167         base::Bind(&ExtensionInstallCheckerTest::ValidateSecondInvocation,
168                    base::Unretained(this),
169                    checker));
170   }
171
172   void ValidateSecondInvocation(ExtensionInstallCheckerForTest* checker,
173                                 int checks_failed) {
174     EXPECT_FALSE(checker->is_running());
175     EXPECT_EQ(ExtensionInstallChecker::CHECK_REQUIREMENTS |
176                   ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY,
177               checks_failed);
178     ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL, *checker);
179
180     EXPECT_EQ(kBlacklistState2, checker->blacklist_state());
181     ExpectPolicyError(kDummyPolicyError2, *checker);
182     ExpectRequirementsError(kDummyRequirementsError2, *checker);
183   }
184
185  protected:
186   void SetAllErrors(ExtensionInstallCheckerForTest* checker) {
187     checker->set_blacklist_state(kBlacklistStateError);
188     checker->set_policy_check_error(kDummyPolicyError);
189     checker->set_requirements_error(kDummyRequirementsError);
190   }
191
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());
203   }
204
205   void ExpectRequirementsPass(const ExtensionInstallCheckerForTest& checker) {
206     EXPECT_TRUE(checker.requirement_errors().empty());
207   }
208
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());
214   }
215
216   void ExpectRequirementsError(const ExtensionInstallCheckerForTest& checker) {
217     ExpectRequirementsError(kDummyRequirementsError, checker);
218   }
219
220   void ExpectBlacklistPass(const ExtensionInstallCheckerForTest& checker) {
221     EXPECT_EQ(NOT_BLACKLISTED, checker.blacklist_state());
222   }
223
224   void ExpectBlacklistError(const ExtensionInstallCheckerForTest& checker) {
225     EXPECT_EQ(kBlacklistStateError, checker.blacklist_state());
226   }
227
228   void ExpectPolicyPass(const ExtensionInstallCheckerForTest& checker) {
229     EXPECT_TRUE(checker.policy_allows_load());
230     EXPECT_TRUE(checker.policy_error().empty());
231   }
232
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());
238   }
239
240   void ExpectPolicyError(const ExtensionInstallCheckerForTest& checker) {
241     ExpectPolicyError(kDummyPolicyError, checker);
242   }
243
244   void RunChecker(ExtensionInstallCheckerForTest* checker,
245                   bool fail_fast,
246                   int checks_to_run,
247                   int expected_checks_run,
248                   int expected_result) {
249     CheckObserver observer;
250     checker->Start(checks_to_run,
251                    fail_fast,
252                    base::Bind(&CheckObserver::OnChecksComplete,
253                               base::Unretained(&observer)));
254     observer.Wait();
255
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);
260   }
261
262   void DoRunAllChecksPass(ExtensionInstallCheckerForTest* checker) {
263     RunChecker(checker,
264                false /* fail fast */,
265                ExtensionInstallChecker::CHECK_ALL,
266                ExtensionInstallChecker::CHECK_ALL,
267                0);
268
269     ExpectRequirementsPass(*checker);
270     ExpectPolicyPass(*checker);
271     ExpectBlacklistPass(*checker);
272   }
273
274   void DoRunAllChecksFail(ExtensionInstallCheckerForTest* checker) {
275     SetAllErrors(checker);
276     RunChecker(checker,
277                false /* fail fast */,
278                ExtensionInstallChecker::CHECK_ALL,
279                ExtensionInstallChecker::CHECK_ALL,
280                ExtensionInstallChecker::CHECK_ALL);
281
282     ExpectRequirementsError(*checker);
283     ExpectPolicyError(*checker);
284     ExpectBlacklistError(*checker);
285   }
286
287   void DoRunSubsetOfChecks(ExtensionInstallCheckerForTest* checker) {
288     // Test check set 1.
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);
293
294     ExpectRequirementsError(*checker);
295     ExpectPolicyError(*checker);
296     ExpectBlacklistPass(*checker);
297
298     // Test check set 2.
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);
303
304     ExpectRequirementsError(*checker);
305     ExpectPolicyPass(*checker);
306     ExpectBlacklistError(*checker);
307
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);
312
313     ExpectRequirementsPass(*checker);
314     ExpectPolicyPass(*checker);
315     ExpectBlacklistError(*checker);
316   }
317
318  private:
319   // A message loop is required for the asynchronous tests.
320   base::MessageLoop message_loop;
321 };
322
323 class ExtensionInstallCheckerMultipleInvocationTest
324     : public ExtensionInstallCheckerTest {
325  public:
326   ExtensionInstallCheckerMultipleInvocationTest() : callback_count_(0) {}
327   virtual ~ExtensionInstallCheckerMultipleInvocationTest() {}
328
329   void RunSecondInvocation(ExtensionInstallCheckerForTest* checker,
330                            int checks_failed) {
331     ASSERT_EQ(0, callback_count_);
332     ++callback_count_;
333     EXPECT_FALSE(checker->is_running());
334     EXPECT_GT(checks_failed, 0);
335     ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL, *checker);
336
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);
341
342     // Run the install checker again and ensure the second set of return values
343     // is received.
344     checker->Start(ExtensionInstallChecker::CHECK_ALL,
345                    false /* fail fast */,
346                    base::Bind(&ExtensionInstallCheckerMultipleInvocationTest::
347                                   ValidateSecondInvocation,
348                               base::Unretained(this),
349                               checker));
350   }
351
352   void ValidateSecondInvocation(ExtensionInstallCheckerForTest* checker,
353                                 int checks_failed) {
354     ASSERT_EQ(1, callback_count_);
355     EXPECT_FALSE(checker->is_running());
356     EXPECT_EQ(ExtensionInstallChecker::CHECK_REQUIREMENTS |
357                   ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY,
358               checks_failed);
359     ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL, *checker);
360
361     EXPECT_EQ(kBlacklistState2, checker->blacklist_state());
362     ExpectPolicyError(kDummyPolicyError2, *checker);
363     ExpectRequirementsError(kDummyRequirementsError2, *checker);
364   }
365
366  private:
367   int callback_count_;
368 };
369
370 // Test the case where all tests pass.
371 TEST_F(ExtensionInstallCheckerTest, AllSucceeded) {
372   ExtensionInstallCheckerForTest sync_checker;
373   DoRunAllChecksPass(&sync_checker);
374
375   ExtensionInstallCheckerAsync async_checker;
376   DoRunAllChecksPass(&async_checker);
377 }
378
379 // Test the case where all tests fail.
380 TEST_F(ExtensionInstallCheckerTest, AllFailed) {
381   ExtensionInstallCheckerForTest sync_checker;
382   DoRunAllChecksFail(&sync_checker);
383
384   ExtensionInstallCheckerAsync async_checker;
385   DoRunAllChecksFail(&async_checker);
386 }
387
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);
394 }
395
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);
402   RunChecker(&checker,
403              true /* fail fast */,
404              ExtensionInstallChecker::CHECK_ALL,
405              ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY,
406              ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY);
407
408   ExpectRequirementsPass(checker);
409   ExpectPolicyError(checker);
410   ExpectBlacklistPass(checker);
411
412   // This test assumes some internal knowledge of the implementation - that
413   // the requirements check runs before the blacklist check.
414   SetAllErrors(&checker);
415   RunChecker(&checker,
416              true /* fail fast */,
417              ExtensionInstallChecker::CHECK_REQUIREMENTS |
418                  ExtensionInstallChecker::CHECK_BLACKLIST,
419              ExtensionInstallChecker::CHECK_REQUIREMENTS,
420              ExtensionInstallChecker::CHECK_REQUIREMENTS);
421
422   ExpectRequirementsError(checker);
423   ExpectPolicyPass(checker);
424   ExpectBlacklistPass(checker);
425 }
426
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);
435
436   // The policy check is synchronous and needs to pass for the other tests to
437   // run.
438   checker.set_policy_check_error(std::string());
439
440   RunChecker(&checker,
441              true /* fail fast */,
442              ExtensionInstallChecker::CHECK_ALL,
443              ExtensionInstallChecker::CHECK_ALL,
444              ExtensionInstallChecker::CHECK_REQUIREMENTS);
445
446   ExpectRequirementsError(checker);
447   ExpectPolicyPass(checker);
448   ExpectBlacklistPass(checker);
449 }
450
451 // Test multiple invocations of the install checker. Wait for all checks to
452 // complete.
453 TEST_F(ExtensionInstallCheckerMultipleInvocationTest, CompleteAll) {
454   ExtensionInstallCheckerAsync checker;
455   SetAllErrors(&checker);
456
457   // Start the second check as soon as the callback of the first run is invoked.
458   checker.Start(
459       ExtensionInstallChecker::CHECK_ALL,
460       false /* fail fast */,
461       base::Bind(
462           &ExtensionInstallCheckerMultipleInvocationTest::RunSecondInvocation,
463           base::Unretained(this),
464           &checker));
465   base::RunLoop().RunUntilIdle();
466 }
467
468 // Test multiple invocations of the install checker and fail fast.
469 TEST_F(ExtensionInstallCheckerMultipleInvocationTest, FailFast) {
470   ExtensionInstallCheckerAsync checker;
471   SetAllErrors(&checker);
472
473   // The policy check is synchronous and needs to pass for the other tests to
474   // run.
475   checker.set_policy_check_error(std::string());
476
477   // Start the second check as soon as the callback of the first run is invoked.
478   checker.Start(
479       ExtensionInstallChecker::CHECK_ALL,
480       true /* fail fast */,
481       base::Bind(
482           &ExtensionInstallCheckerMultipleInvocationTest::RunSecondInvocation,
483           base::Unretained(this),
484           &checker));
485   base::RunLoop().RunUntilIdle();
486 }
487
488 }  // namespace extensions