• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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 "components/policy/core/common/async_policy_provider.h"
6 
7 #include "base/callback.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/sequenced_task_runner.h"
12 #include "base/values.h"
13 #include "components/policy/core/common/async_policy_loader.h"
14 #include "components/policy/core/common/external_data_fetcher.h"
15 #include "components/policy/core/common/mock_configuration_policy_provider.h"
16 #include "components/policy/core/common/schema_registry.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 
20 using testing::Mock;
21 using testing::Return;
22 using testing::Sequence;
23 
24 namespace policy {
25 
26 namespace {
27 
28 // Helper to write a policy in |bundle| with less code.
SetPolicy(PolicyBundle * bundle,const std::string & name,const std::string & value)29 void SetPolicy(PolicyBundle* bundle,
30                const std::string& name,
31                const std::string& value) {
32   bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
33       .Set(name,
34            POLICY_LEVEL_MANDATORY,
35            POLICY_SCOPE_USER,
36            base::Value::CreateStringValue(value),
37            NULL);
38 }
39 
40 class MockPolicyLoader : public AsyncPolicyLoader {
41  public:
42   explicit MockPolicyLoader(
43       scoped_refptr<base::SequencedTaskRunner> task_runner);
44   virtual ~MockPolicyLoader();
45 
46   // Load() returns a scoped_ptr<PolicyBundle> but it can't be mocked because
47   // scoped_ptr is moveable but not copyable. This override forwards the
48   // call to MockLoad() which returns a PolicyBundle*, and returns a copy
49   // wrapped in a passed scoped_ptr.
50   virtual scoped_ptr<PolicyBundle> Load() OVERRIDE;
51 
52   MOCK_METHOD0(MockLoad, const PolicyBundle*());
53   MOCK_METHOD0(InitOnBackgroundThread, void());
54   MOCK_METHOD0(LastModificationTime, base::Time());
55 
56  private:
57   DISALLOW_COPY_AND_ASSIGN(MockPolicyLoader);
58 };
59 
MockPolicyLoader(scoped_refptr<base::SequencedTaskRunner> task_runner)60 MockPolicyLoader::MockPolicyLoader(
61     scoped_refptr<base::SequencedTaskRunner> task_runner)
62     : AsyncPolicyLoader(task_runner) {}
63 
~MockPolicyLoader()64 MockPolicyLoader::~MockPolicyLoader() {}
65 
Load()66 scoped_ptr<PolicyBundle> MockPolicyLoader::Load() {
67   scoped_ptr<PolicyBundle> bundle;
68   const PolicyBundle* loaded = MockLoad();
69   if (loaded) {
70     bundle.reset(new PolicyBundle());
71     bundle->CopyFrom(*loaded);
72   }
73   return bundle.Pass();
74 }
75 
76 }  // namespace
77 
78 class AsyncPolicyProviderTest : public testing::Test {
79  protected:
80   AsyncPolicyProviderTest();
81   virtual ~AsyncPolicyProviderTest();
82 
83   virtual void SetUp() OVERRIDE;
84   virtual void TearDown() OVERRIDE;
85 
86   base::MessageLoop loop_;
87   SchemaRegistry schema_registry_;
88   PolicyBundle initial_bundle_;
89   MockPolicyLoader* loader_;
90   scoped_ptr<AsyncPolicyProvider> provider_;
91 
92  private:
93   DISALLOW_COPY_AND_ASSIGN(AsyncPolicyProviderTest);
94 };
95 
AsyncPolicyProviderTest()96 AsyncPolicyProviderTest::AsyncPolicyProviderTest() {}
97 
~AsyncPolicyProviderTest()98 AsyncPolicyProviderTest::~AsyncPolicyProviderTest() {}
99 
SetUp()100 void AsyncPolicyProviderTest::SetUp() {
101   SetPolicy(&initial_bundle_, "policy", "initial");
102   loader_ = new MockPolicyLoader(loop_.message_loop_proxy());
103   EXPECT_CALL(*loader_, LastModificationTime())
104       .WillRepeatedly(Return(base::Time()));
105   EXPECT_CALL(*loader_, InitOnBackgroundThread()).Times(1);
106   EXPECT_CALL(*loader_, MockLoad()).WillOnce(Return(&initial_bundle_));
107 
108   provider_.reset(new AsyncPolicyProvider(
109       &schema_registry_, scoped_ptr<AsyncPolicyLoader>(loader_)));
110   provider_->Init(&schema_registry_);
111   // Verify that the initial load is done synchronously:
112   EXPECT_TRUE(provider_->policies().Equals(initial_bundle_));
113 
114   loop_.RunUntilIdle();
115   Mock::VerifyAndClearExpectations(loader_);
116 
117   EXPECT_CALL(*loader_, LastModificationTime())
118       .WillRepeatedly(Return(base::Time()));
119 }
120 
TearDown()121 void AsyncPolicyProviderTest::TearDown() {
122   if (provider_) {
123     provider_->Shutdown();
124     provider_.reset();
125   }
126   loop_.RunUntilIdle();
127 }
128 
TEST_F(AsyncPolicyProviderTest,RefreshPolicies)129 TEST_F(AsyncPolicyProviderTest, RefreshPolicies) {
130   PolicyBundle refreshed_bundle;
131   SetPolicy(&refreshed_bundle, "policy", "refreshed");
132   EXPECT_CALL(*loader_, MockLoad()).WillOnce(Return(&refreshed_bundle));
133 
134   MockConfigurationPolicyObserver observer;
135   provider_->AddObserver(&observer);
136   EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1);
137   provider_->RefreshPolicies();
138   loop_.RunUntilIdle();
139   // The refreshed policies are now provided.
140   EXPECT_TRUE(provider_->policies().Equals(refreshed_bundle));
141   provider_->RemoveObserver(&observer);
142 }
143 
TEST_F(AsyncPolicyProviderTest,RefreshPoliciesTwice)144 TEST_F(AsyncPolicyProviderTest, RefreshPoliciesTwice) {
145   PolicyBundle refreshed_bundle;
146   SetPolicy(&refreshed_bundle, "policy", "refreshed");
147   EXPECT_CALL(*loader_, MockLoad()).WillRepeatedly(Return(&refreshed_bundle));
148 
149   MockConfigurationPolicyObserver observer;
150   provider_->AddObserver(&observer);
151   EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0);
152   provider_->RefreshPolicies();
153   // Doesn't refresh before going through the background thread.
154   Mock::VerifyAndClearExpectations(&observer);
155 
156   // Doesn't refresh if another RefreshPolicies request is made.
157   EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0);
158   provider_->RefreshPolicies();
159   Mock::VerifyAndClearExpectations(&observer);
160 
161   EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1);
162   loop_.RunUntilIdle();
163   // The refreshed policies are now provided.
164   EXPECT_TRUE(provider_->policies().Equals(refreshed_bundle));
165   Mock::VerifyAndClearExpectations(&observer);
166   provider_->RemoveObserver(&observer);
167 }
168 
TEST_F(AsyncPolicyProviderTest,RefreshPoliciesDuringReload)169 TEST_F(AsyncPolicyProviderTest, RefreshPoliciesDuringReload) {
170   PolicyBundle reloaded_bundle;
171   SetPolicy(&reloaded_bundle, "policy", "reloaded");
172   PolicyBundle refreshed_bundle;
173   SetPolicy(&refreshed_bundle, "policy", "refreshed");
174 
175   Sequence load_sequence;
176   // Reload.
177   EXPECT_CALL(*loader_, MockLoad()).InSequence(load_sequence)
178                                    .WillOnce(Return(&reloaded_bundle));
179   // RefreshPolicies.
180   EXPECT_CALL(*loader_, MockLoad()).InSequence(load_sequence)
181                                    .WillOnce(Return(&refreshed_bundle));
182 
183   MockConfigurationPolicyObserver observer;
184   provider_->AddObserver(&observer);
185   EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0);
186 
187   // A Reload is triggered before RefreshPolicies, and it shouldn't trigger
188   // notifications.
189   loader_->Reload(true);
190   Mock::VerifyAndClearExpectations(&observer);
191 
192   // Doesn't refresh before going through the background thread.
193   EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0);
194   provider_->RefreshPolicies();
195   Mock::VerifyAndClearExpectations(&observer);
196 
197   EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1);
198   loop_.RunUntilIdle();
199   // The refreshed policies are now provided, and the |reloaded_bundle| was
200   // dropped.
201   EXPECT_TRUE(provider_->policies().Equals(refreshed_bundle));
202   Mock::VerifyAndClearExpectations(&observer);
203   provider_->RemoveObserver(&observer);
204 }
205 
TEST_F(AsyncPolicyProviderTest,Shutdown)206 TEST_F(AsyncPolicyProviderTest, Shutdown) {
207   EXPECT_CALL(*loader_, MockLoad()).WillRepeatedly(Return(&initial_bundle_));
208 
209   MockConfigurationPolicyObserver observer;
210   provider_->AddObserver(&observer);
211 
212   // Though there is a pending Reload, the provider and the loader can be
213   // deleted at any time.
214   EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0);
215   loader_->Reload(true);
216   Mock::VerifyAndClearExpectations(&observer);
217 
218   EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0);
219   provider_->Shutdown();
220   loop_.RunUntilIdle();
221   Mock::VerifyAndClearExpectations(&observer);
222 
223   provider_->RemoveObserver(&observer);
224   provider_.reset();
225 }
226 
227 }  // namespace policy
228