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.
5 #include "components/policy/core/common/async_policy_provider.h"
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"
21 using testing::Return
;
22 using testing::Sequence
;
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()))
34 POLICY_LEVEL_MANDATORY
,
36 base::Value::CreateStringValue(value
),
40 class MockPolicyLoader
: public AsyncPolicyLoader
{
42 explicit MockPolicyLoader(
43 scoped_refptr
<base::SequencedTaskRunner
> task_runner
);
44 virtual ~MockPolicyLoader();
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
;
52 MOCK_METHOD0(MockLoad
, const PolicyBundle
*());
53 MOCK_METHOD0(InitOnBackgroundThread
, void());
54 MOCK_METHOD0(LastModificationTime
, base::Time());
57 DISALLOW_COPY_AND_ASSIGN(MockPolicyLoader
);
60 MockPolicyLoader::MockPolicyLoader(
61 scoped_refptr
<base::SequencedTaskRunner
> task_runner
)
62 : AsyncPolicyLoader(task_runner
) {}
64 MockPolicyLoader::~MockPolicyLoader() {}
66 scoped_ptr
<PolicyBundle
> MockPolicyLoader::Load() {
67 scoped_ptr
<PolicyBundle
> bundle
;
68 const PolicyBundle
* loaded
= MockLoad();
70 bundle
.reset(new PolicyBundle());
71 bundle
->CopyFrom(*loaded
);
78 class AsyncPolicyProviderTest
: public testing::Test
{
80 AsyncPolicyProviderTest();
81 virtual ~AsyncPolicyProviderTest();
83 virtual void SetUp() OVERRIDE
;
84 virtual void TearDown() OVERRIDE
;
86 base::MessageLoop loop_
;
87 SchemaRegistry schema_registry_
;
88 PolicyBundle initial_bundle_
;
89 MockPolicyLoader
* loader_
;
90 scoped_ptr
<AsyncPolicyProvider
> provider_
;
93 DISALLOW_COPY_AND_ASSIGN(AsyncPolicyProviderTest
);
96 AsyncPolicyProviderTest::AsyncPolicyProviderTest() {}
98 AsyncPolicyProviderTest::~AsyncPolicyProviderTest() {}
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_
));
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_
));
114 loop_
.RunUntilIdle();
115 Mock::VerifyAndClearExpectations(loader_
);
117 EXPECT_CALL(*loader_
, LastModificationTime())
118 .WillRepeatedly(Return(base::Time()));
121 void AsyncPolicyProviderTest::TearDown() {
123 provider_
->Shutdown();
126 loop_
.RunUntilIdle();
129 TEST_F(AsyncPolicyProviderTest
, RefreshPolicies
) {
130 PolicyBundle refreshed_bundle
;
131 SetPolicy(&refreshed_bundle
, "policy", "refreshed");
132 EXPECT_CALL(*loader_
, MockLoad()).WillOnce(Return(&refreshed_bundle
));
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
);
144 TEST_F(AsyncPolicyProviderTest
, RefreshPoliciesTwice
) {
145 PolicyBundle refreshed_bundle
;
146 SetPolicy(&refreshed_bundle
, "policy", "refreshed");
147 EXPECT_CALL(*loader_
, MockLoad()).WillRepeatedly(Return(&refreshed_bundle
));
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
);
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
);
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
);
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");
175 Sequence load_sequence
;
177 EXPECT_CALL(*loader_
, MockLoad()).InSequence(load_sequence
)
178 .WillOnce(Return(&reloaded_bundle
));
180 EXPECT_CALL(*loader_
, MockLoad()).InSequence(load_sequence
)
181 .WillOnce(Return(&refreshed_bundle
));
183 MockConfigurationPolicyObserver observer
;
184 provider_
->AddObserver(&observer
);
185 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(0);
187 // A Reload is triggered before RefreshPolicies, and it shouldn't trigger
189 loader_
->Reload(true);
190 Mock::VerifyAndClearExpectations(&observer
);
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
);
197 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(1);
198 loop_
.RunUntilIdle();
199 // The refreshed policies are now provided, and the |reloaded_bundle| was
201 EXPECT_TRUE(provider_
->policies().Equals(refreshed_bundle
));
202 Mock::VerifyAndClearExpectations(&observer
);
203 provider_
->RemoveObserver(&observer
);
206 TEST_F(AsyncPolicyProviderTest
, Shutdown
) {
207 EXPECT_CALL(*loader_
, MockLoad()).WillRepeatedly(Return(&initial_bundle_
));
209 MockConfigurationPolicyObserver observer
;
210 provider_
->AddObserver(&observer
);
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
);
218 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(0);
219 provider_
->Shutdown();
220 loop_
.RunUntilIdle();
221 Mock::VerifyAndClearExpectations(&observer
);
223 provider_
->RemoveObserver(&observer
);
227 } // namespace policy