OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 "chrome/browser/policy/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 "chrome/browser/policy/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. | |
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 | |
60 MockPolicyLoader::MockPolicyLoader( | |
61 scoped_refptr<base::SequencedTaskRunner> task_runner) | |
62 : AsyncPolicyLoader(task_runner) {} | |
63 | |
64 MockPolicyLoader::~MockPolicyLoader() {} | |
65 | |
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 | |
96 AsyncPolicyProviderTest::AsyncPolicyProviderTest() {} | |
97 | |
98 AsyncPolicyProviderTest::~AsyncPolicyProviderTest() {} | |
99 | |
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 | |
121 void AsyncPolicyProviderTest::TearDown() { | |
122 if (provider_) { | |
123 provider_->Shutdown(); | |
124 provider_.reset(); | |
125 } | |
126 loop_.RunUntilIdle(); | |
127 } | |
128 | |
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 | |
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 | |
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 | |
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 | |
OLD | NEW |