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/sequenced_task_runner.h"
11 #include "base/values.h"
12 #include "components/policy/core/common/async_policy_loader.h"
13 #include "components/policy/core/common/external_data_fetcher.h"
14 #include "components/policy/core/common/mock_configuration_policy_provider.h"
15 #include "components/policy/core/common/schema_registry.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
20 using testing::Return
;
21 using testing::Sequence
;
27 // Helper to write a policy in |bundle| with less code.
28 void SetPolicy(PolicyBundle
* bundle
,
29 const std::string
& name
,
30 const std::string
& value
) {
31 bundle
->Get(PolicyNamespace(POLICY_DOMAIN_CHROME
, std::string()))
33 POLICY_LEVEL_MANDATORY
,
35 new base::StringValue(value
),
39 class MockPolicyLoader
: public AsyncPolicyLoader
{
41 explicit MockPolicyLoader(
42 scoped_refptr
<base::SequencedTaskRunner
> task_runner
);
43 ~MockPolicyLoader() override
;
45 // Load() returns a scoped_ptr<PolicyBundle> but it can't be mocked because
46 // scoped_ptr is moveable but not copyable. This override forwards the
47 // call to MockLoad() which returns a PolicyBundle*, and returns a copy
48 // wrapped in a passed scoped_ptr.
49 scoped_ptr
<PolicyBundle
> Load() override
;
51 MOCK_METHOD0(MockLoad
, const PolicyBundle
*());
52 MOCK_METHOD0(InitOnBackgroundThread
, void());
53 MOCK_METHOD0(LastModificationTime
, base::Time());
56 DISALLOW_COPY_AND_ASSIGN(MockPolicyLoader
);
59 MockPolicyLoader::MockPolicyLoader(
60 scoped_refptr
<base::SequencedTaskRunner
> task_runner
)
61 : AsyncPolicyLoader(task_runner
) {}
63 MockPolicyLoader::~MockPolicyLoader() {}
65 scoped_ptr
<PolicyBundle
> MockPolicyLoader::Load() {
66 scoped_ptr
<PolicyBundle
> bundle
;
67 const PolicyBundle
* loaded
= MockLoad();
69 bundle
.reset(new PolicyBundle());
70 bundle
->CopyFrom(*loaded
);
77 class AsyncPolicyProviderTest
: public testing::Test
{
79 AsyncPolicyProviderTest();
80 ~AsyncPolicyProviderTest() override
;
82 void SetUp() override
;
83 void TearDown() override
;
85 base::MessageLoop loop_
;
86 SchemaRegistry schema_registry_
;
87 PolicyBundle initial_bundle_
;
88 MockPolicyLoader
* loader_
;
89 scoped_ptr
<AsyncPolicyProvider
> provider_
;
92 DISALLOW_COPY_AND_ASSIGN(AsyncPolicyProviderTest
);
95 AsyncPolicyProviderTest::AsyncPolicyProviderTest() {}
97 AsyncPolicyProviderTest::~AsyncPolicyProviderTest() {}
99 void AsyncPolicyProviderTest::SetUp() {
100 SetPolicy(&initial_bundle_
, "policy", "initial");
101 loader_
= new MockPolicyLoader(loop_
.task_runner());
102 EXPECT_CALL(*loader_
, LastModificationTime())
103 .WillRepeatedly(Return(base::Time()));
104 EXPECT_CALL(*loader_
, InitOnBackgroundThread()).Times(1);
105 EXPECT_CALL(*loader_
, MockLoad()).WillOnce(Return(&initial_bundle_
));
107 provider_
.reset(new AsyncPolicyProvider(
108 &schema_registry_
, scoped_ptr
<AsyncPolicyLoader
>(loader_
)));
109 provider_
->Init(&schema_registry_
);
110 // Verify that the initial load is done synchronously:
111 EXPECT_TRUE(provider_
->policies().Equals(initial_bundle_
));
113 loop_
.RunUntilIdle();
114 Mock::VerifyAndClearExpectations(loader_
);
116 EXPECT_CALL(*loader_
, LastModificationTime())
117 .WillRepeatedly(Return(base::Time()));
120 void AsyncPolicyProviderTest::TearDown() {
122 provider_
->Shutdown();
125 loop_
.RunUntilIdle();
128 TEST_F(AsyncPolicyProviderTest
, RefreshPolicies
) {
129 PolicyBundle refreshed_bundle
;
130 SetPolicy(&refreshed_bundle
, "policy", "refreshed");
131 EXPECT_CALL(*loader_
, MockLoad()).WillOnce(Return(&refreshed_bundle
));
133 MockConfigurationPolicyObserver observer
;
134 provider_
->AddObserver(&observer
);
135 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(1);
136 provider_
->RefreshPolicies();
137 loop_
.RunUntilIdle();
138 // The refreshed policies are now provided.
139 EXPECT_TRUE(provider_
->policies().Equals(refreshed_bundle
));
140 provider_
->RemoveObserver(&observer
);
143 TEST_F(AsyncPolicyProviderTest
, RefreshPoliciesTwice
) {
144 PolicyBundle refreshed_bundle
;
145 SetPolicy(&refreshed_bundle
, "policy", "refreshed");
146 EXPECT_CALL(*loader_
, MockLoad()).WillRepeatedly(Return(&refreshed_bundle
));
148 MockConfigurationPolicyObserver observer
;
149 provider_
->AddObserver(&observer
);
150 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(0);
151 provider_
->RefreshPolicies();
152 // Doesn't refresh before going through the background thread.
153 Mock::VerifyAndClearExpectations(&observer
);
155 // Doesn't refresh if another RefreshPolicies request is made.
156 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(0);
157 provider_
->RefreshPolicies();
158 Mock::VerifyAndClearExpectations(&observer
);
160 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(1);
161 loop_
.RunUntilIdle();
162 // The refreshed policies are now provided.
163 EXPECT_TRUE(provider_
->policies().Equals(refreshed_bundle
));
164 Mock::VerifyAndClearExpectations(&observer
);
165 provider_
->RemoveObserver(&observer
);
168 TEST_F(AsyncPolicyProviderTest
, RefreshPoliciesDuringReload
) {
169 PolicyBundle reloaded_bundle
;
170 SetPolicy(&reloaded_bundle
, "policy", "reloaded");
171 PolicyBundle refreshed_bundle
;
172 SetPolicy(&refreshed_bundle
, "policy", "refreshed");
174 Sequence load_sequence
;
176 EXPECT_CALL(*loader_
, MockLoad()).InSequence(load_sequence
)
177 .WillOnce(Return(&reloaded_bundle
));
179 EXPECT_CALL(*loader_
, MockLoad()).InSequence(load_sequence
)
180 .WillOnce(Return(&refreshed_bundle
));
182 MockConfigurationPolicyObserver observer
;
183 provider_
->AddObserver(&observer
);
184 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(0);
186 // A Reload is triggered before RefreshPolicies, and it shouldn't trigger
188 loader_
->Reload(true);
189 Mock::VerifyAndClearExpectations(&observer
);
191 // Doesn't refresh before going through the background thread.
192 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(0);
193 provider_
->RefreshPolicies();
194 Mock::VerifyAndClearExpectations(&observer
);
196 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(1);
197 loop_
.RunUntilIdle();
198 // The refreshed policies are now provided, and the |reloaded_bundle| was
200 EXPECT_TRUE(provider_
->policies().Equals(refreshed_bundle
));
201 Mock::VerifyAndClearExpectations(&observer
);
202 provider_
->RemoveObserver(&observer
);
205 TEST_F(AsyncPolicyProviderTest
, Shutdown
) {
206 EXPECT_CALL(*loader_
, MockLoad()).WillRepeatedly(Return(&initial_bundle_
));
208 MockConfigurationPolicyObserver observer
;
209 provider_
->AddObserver(&observer
);
211 // Though there is a pending Reload, the provider and the loader can be
212 // deleted at any time.
213 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(0);
214 loader_
->Reload(true);
215 Mock::VerifyAndClearExpectations(&observer
);
217 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(0);
218 provider_
->Shutdown();
219 loop_
.RunUntilIdle();
220 Mock::VerifyAndClearExpectations(&observer
);
222 provider_
->RemoveObserver(&observer
);
226 } // namespace policy