Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(314)

Side by Side Diff: chrome/browser/policy/async_policy_provider_unittest.cc

Issue 10448118: Add the AsyncPolicyProvider and AsyncPolicyLoader (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix unittest Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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/file_util.h"
8 #include "base/message_loop.h"
9 #include "base/scoped_temp_dir.h"
10 #include "base/values.h"
11 #include "chrome/browser/policy/async_policy_loader.h"
12 #include "chrome/browser/policy/configuration_policy_provider.h"
Mattias Nissler (ping if slow) 2012/06/04 08:48:26 already included in async_policy_provider.h and no
Joao da Silva 2012/06/04 14:05:06 Done.
13 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/test/test_browser_thread.h"
16 #include "policy/policy_constants.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 using testing::InvokeWithoutArgs;
21 using testing::Mock;
22 using testing::Return;
23 using testing::ReturnNull;
24 using testing::Sequence;
25
26 namespace policy {
27
28 namespace {
29
30 class MockPolicyLoader : public AsyncPolicyLoader {
31 public:
32 MockPolicyLoader();
33 virtual ~MockPolicyLoader();
34
35 // Load() returns a scoped_ptr<PolicyBundle> but it can't be mocked because
36 // scoped_ptr is moveable but not copyable. This override forwards the
37 // call to MockLoad() which returns a PolicyBundle*, and returns a copy
38 // wrapped in a passed scoped_ptr.
39 virtual scoped_ptr<PolicyBundle> Load() OVERRIDE;
40
41 MOCK_METHOD0(MockLoad, const PolicyBundle*());
42 MOCK_METHOD0(InitOnFile, void());
43 MOCK_METHOD0(LastModificationTime, base::Time());
44
45 private:
46 DISALLOW_COPY_AND_ASSIGN(MockPolicyLoader);
47 };
48
49 MockPolicyLoader::MockPolicyLoader() {}
50
51 MockPolicyLoader::~MockPolicyLoader() {}
52
53 scoped_ptr<PolicyBundle> MockPolicyLoader::Load() {
54 scoped_ptr<PolicyBundle> bundle;
55 const PolicyBundle* loaded = MockLoad();
56 if (loaded) {
57 bundle.reset(new PolicyBundle());
58 bundle->CopyFrom(*loaded);
59 }
60 return bundle.Pass();
61 }
62
63 } // namespace
64
65 class AsyncPolicyProviderTest : public testing::Test {
66 public:
Mattias Nissler (ping if slow) 2012/06/04 08:48:26 you can use protected here if you like to.
Joao da Silva 2012/06/04 14:05:06 Done.
67 AsyncPolicyProviderTest();
68 virtual ~AsyncPolicyProviderTest();
69
70 virtual void SetUp() OVERRIDE;
71 virtual void TearDown() OVERRIDE;
72
73 protected:
74 PolicyBundle initial_bundle_;
75 MockPolicyLoader* loader_;
76 scoped_ptr<AsyncPolicyProvider> provider_;
77
78 // IO loop needed by the FilePathWatcher.
79 MessageLoopForIO loop_;
80
81 private:
82 content::TestBrowserThread ui_thread_;
83 content::TestBrowserThread file_thread_;
84
85 DISALLOW_COPY_AND_ASSIGN(AsyncPolicyProviderTest);
86 };
87
88 AsyncPolicyProviderTest::AsyncPolicyProviderTest()
89 : ui_thread_(content::BrowserThread::UI, &loop_),
90 file_thread_(content::BrowserThread::FILE, &loop_) {}
91
92 AsyncPolicyProviderTest::~AsyncPolicyProviderTest() {}
93
94 void AsyncPolicyProviderTest::SetUp() {
95 initial_bundle_.Get(POLICY_DOMAIN_CHROME, "")
96 .Set("policy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
97 base::Value::CreateStringValue("initial"));
98 loader_ = new MockPolicyLoader();
99 EXPECT_CALL(*loader_, LastModificationTime())
100 .WillRepeatedly(Return(base::Time()));
101 EXPECT_CALL(*loader_, InitOnFile()).Times(1);
102 EXPECT_CALL(*loader_, MockLoad()).WillOnce(Return(&initial_bundle_));
103
104 provider_.reset(
105 new AsyncPolicyProvider(GetChromePolicyDefinitionList(), loader_));
106 // Verify that the initial load is done synchronously:
107 EXPECT_TRUE(provider_->policies().Equals(initial_bundle_));
108
109 loop_.RunAllPending();
110 Mock::VerifyAndClearExpectations(loader_);
111
112 EXPECT_CALL(*loader_, LastModificationTime())
113 .WillRepeatedly(Return(base::Time()));
Mattias Nissler (ping if slow) 2012/06/04 08:48:26 you declared this expectation in line 99 already.
Joao da Silva 2012/06/04 14:05:06 It is cleared in line 110.
114 }
115
116 void AsyncPolicyProviderTest::TearDown() {
117 // Tests that set file watchers may receive notifications during TearDown,
118 // and the |loop_| might have a Reload task already pending (before deletion
119 // of the |provider_| triggers deletion of the |loader_|. Make sure the
120 // loader isn't loading locals at this stage.
121 if (provider_.get())
122 EXPECT_CALL(*loader_, MockLoad()).WillRepeatedly(ReturnNull());
123
124 provider_.reset();
125 loop_.RunAllPending();
126 }
127
128 TEST_F(AsyncPolicyProviderTest, RefreshPolicies) {
129 PolicyBundle refreshed_bundle;
130 refreshed_bundle.Get(POLICY_DOMAIN_CHROME, "")
131 .Set("policy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
132 base::Value::CreateStringValue("refreshed"));
133 EXPECT_CALL(*loader_, MockLoad()).WillOnce(Return(&refreshed_bundle));
134
135 MockConfigurationPolicyObserver observer;
136 ConfigurationPolicyObserverRegistrar registrar;
137 registrar.Init(provider_.get(), &observer);
138 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1);
139 provider_->RefreshPolicies();
140 loop_.RunAllPending();
141 // The refreshed policies are now provided.
142 EXPECT_TRUE(provider_->policies().Equals(refreshed_bundle));
143 }
144
145 TEST_F(AsyncPolicyProviderTest, RefreshPoliciesTwice) {
146 PolicyBundle refreshed_bundle;
147 refreshed_bundle.Get(POLICY_DOMAIN_CHROME, "")
148 .Set("policy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
149 base::Value::CreateBooleanValue(true));
150 EXPECT_CALL(*loader_, MockLoad()).WillRepeatedly(Return(&refreshed_bundle));
151
152 MockConfigurationPolicyObserver observer;
153 ConfigurationPolicyObserverRegistrar registrar;
154 registrar.Init(provider_.get(), &observer);
155 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0);
156 provider_->RefreshPolicies();
157 // Doesn't refresh before going through FILE.
Mattias Nissler (ping if slow) 2012/06/04 08:48:26 thread
Joao da Silva 2012/06/04 14:05:06 Done.
158 Mock::VerifyAndClearExpectations(&observer);
159
160 // Doesn't refresh if another RefreshPolicies request is made.
161 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0);
162 provider_->RefreshPolicies();
163 Mock::VerifyAndClearExpectations(&observer);
164
165 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1);
166 loop_.RunAllPending();
167 // The refreshed policies are now provided.
168 EXPECT_TRUE(provider_->policies().Equals(refreshed_bundle));
169 Mock::VerifyAndClearExpectations(&observer);
170 }
171
172 TEST_F(AsyncPolicyProviderTest, RefreshPoliciesDuringReload) {
173 PolicyBundle reloaded_bundle;
174 reloaded_bundle.Get(POLICY_DOMAIN_CHROME, "")
175 .Set("policy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
176 base::Value::CreateStringValue("reloaded"));
177 PolicyBundle refreshed_bundle;
178 refreshed_bundle.Get(POLICY_DOMAIN_CHROME, "")
179 .Set("policy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
180 base::Value::CreateStringValue("refreshed"));
181
182 Sequence load_sequence;
183 // Reload.
184 EXPECT_CALL(*loader_, MockLoad()).InSequence(load_sequence)
185 .WillRepeatedly(Return(&reloaded_bundle));
186 // RefreshPolicies.
187 EXPECT_CALL(*loader_, MockLoad()).InSequence(load_sequence)
188 .WillRepeatedly(Return(&refreshed_bundle));
Mattias Nissler (ping if slow) 2012/06/04 08:48:26 Configuring both of these as repeatedly seems ambi
Joao da Silva 2012/06/04 14:05:06 Yes, done.
189
190 MockConfigurationPolicyObserver observer;
191 ConfigurationPolicyObserverRegistrar registrar;
192 registrar.Init(provider_.get(), &observer);
193 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0);
194
195 // A Reload is triggered before RefreshPolicies, and it shouldn't trigger
196 // notifications.
197 loader_->Reload(true);
198 Mock::VerifyAndClearExpectations(&observer);
199
200 // Doesn't refresh before going through FILE.
201 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0);
202 provider_->RefreshPolicies();
203 Mock::VerifyAndClearExpectations(&observer);
204
205 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1);
206 loop_.RunAllPending();
207 // The refreshed policies are now provided, and the |reloaded_bundle| was
208 // dropped.
209 EXPECT_TRUE(provider_->policies().Equals(refreshed_bundle));
210 Mock::VerifyAndClearExpectations(&observer);
211 }
212
213 TEST_F(AsyncPolicyProviderTest, FileUpdated) {
214 PolicyBundle updated_bundle;
215 updated_bundle.Get(POLICY_DOMAIN_CHROME, "")
216 .Set("policy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
217 base::Value::CreateStringValue("updated"));
Mattias Nissler (ping if slow) 2012/06/04 08:48:26 It seems like a helper to initialize a policy bund
Joao da Silva 2012/06/04 14:05:06 Done.
218 EXPECT_CALL(*loader_, MockLoad()).WillRepeatedly(Return(&updated_bundle));
219
220 MockConfigurationPolicyObserver observer;
221 ConfigurationPolicyObserverRegistrar registrar;
222 registrar.Init(provider_.get(), &observer);
223
224 // Watch a temporary file.
225 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0);
226 ScopedTempDir tmp_dir;
227 ASSERT_TRUE(tmp_dir.CreateUniqueTempDir());
228 FilePath path(tmp_dir.path().AppendASCII("policy.json"));
229 loader_->WatchPath(path);
230 loop_.RunAllPending();
231 Mock::VerifyAndClearExpectations(&observer);
232 EXPECT_TRUE(provider_->policies().Equals(initial_bundle_));
233
234 // Update the file and trigger an update.
235 // OnUpdatePolicy() is expected multiple times instead of once because the
236 // FilePathWatcher generates more than one notification on some platforms.
237 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get()))
238 .WillRepeatedly(InvokeWithoutArgs(&loop_, &MessageLoop::Quit));
Mattias Nissler (ping if slow) 2012/06/04 08:48:26 Doing actual file watches in tests is very much di
Joao da Silva 2012/06/04 14:05:06 Removed this tests, after the offline discussion.
239 std::string content("{ \"ShowHomeButton\": true }");
240 ASSERT_EQ((int) content.size(),
Mattias Nissler (ping if slow) 2012/06/04 08:48:26 use C++-style casts (also below).
Joao da Silva 2012/06/04 14:05:06 Obsolete
241 file_util::WriteFile(path, content.c_str(), content.size()));
242 loop_.Run();
243 EXPECT_TRUE(provider_->policies().Equals(updated_bundle));
244 }
245
246 TEST_F(AsyncPolicyProviderTest, DirectoryUpdated) {
247 PolicyBundle updated_bundle;
248 updated_bundle.Get(POLICY_DOMAIN_CHROME, "")
249 .Set("policy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
250 base::Value::CreateStringValue("updated"));
251 EXPECT_CALL(*loader_, MockLoad()).WillRepeatedly(Return(&updated_bundle));
252
253 MockConfigurationPolicyObserver observer;
254 ConfigurationPolicyObserverRegistrar registrar;
255 registrar.Init(provider_.get(), &observer);
256
257 // Watch a temporary directory.
258 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0);
259 ScopedTempDir tmp_dir;
260 ASSERT_TRUE(tmp_dir.CreateUniqueTempDir());
261 FilePath path(tmp_dir.path().AppendASCII("policy.json"));
262 // Initial content.
263 std::string content("{ \"ShowHomeButton\": false }");
264 ASSERT_EQ((int) content.size(),
265 file_util::WriteFile(path, content.c_str(), content.size()));
266 // Watch the directory.
267 loader_->WatchPath(tmp_dir.path());
268 loop_.RunAllPending();
269 Mock::VerifyAndClearExpectations(&observer);
270 EXPECT_TRUE(provider_->policies().Equals(initial_bundle_));
271
272 // Update the file and trigger an update.
273 // OnUpdatePolicy() is expected multiple times instead of once because the
274 // FilePathWatcher generates more than one notification on some platforms.
275 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get()))
276 .WillRepeatedly(InvokeWithoutArgs(&loop_, &MessageLoop::Quit));
277 content = "{ \"ShowHomeButton\": true }";
278 #if defined(OS_MACOSX)
279 // FilePathWatcher on the mac only notices directory changes, and not file
Mattias Nissler (ping if slow) 2012/06/04 08:48:26 s/mac/Mac/ according to our more picky Mac fanboys
Joao da Silva 2012/06/04 14:05:06 iObsolete
280 // changes; create a new file on that platform instead.
281 // See the documentation of FilePathWatcher for the details.
282 path = FilePath(tmp_dir.path().AppendASCII("policy2.json"));
283 #endif
284 ASSERT_EQ((int) content.size(),
285 file_util::WriteFile(path, content.c_str(), content.size()));
286
287 loop_.Run();
288 EXPECT_TRUE(provider_->policies().Equals(updated_bundle));
289 }
290
291 TEST_F(AsyncPolicyProviderTest, Shutdown) {
292 EXPECT_CALL(*loader_, MockLoad()).WillRepeatedly(Return(&initial_bundle_));
293
294 MockConfigurationPolicyObserver observer;
295 ConfigurationPolicyObserverRegistrar registrar;
296 registrar.Init(provider_.get(), &observer);
297
298 // Though there is a pending Reload, the provider and the loader can be
299 // deleted at any time.
300 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0);
301 loader_->Reload(true);
302 Mock::VerifyAndClearExpectations(&observer);
303
304 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0);
305 EXPECT_CALL(observer, OnProviderGoingAway(provider_.get()));
306 provider_.reset();
307 loop_.RunAllPending();
308 Mock::VerifyAndClearExpectations(&observer);
309 }
310
311 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698