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/policy_types.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 POLICY_SOURCE_PLATFORM
,
37 new base::StringValue(value
),
41 class MockPolicyLoader
: public AsyncPolicyLoader
{
43 explicit MockPolicyLoader(
44 scoped_refptr
<base::SequencedTaskRunner
> task_runner
);
45 ~MockPolicyLoader() override
;
47 // Load() returns a scoped_ptr<PolicyBundle> but it can't be mocked because
48 // scoped_ptr is moveable but not copyable. This override forwards the
49 // call to MockLoad() which returns a PolicyBundle*, and returns a copy
50 // wrapped in a passed scoped_ptr.
51 scoped_ptr
<PolicyBundle
> Load() override
;
53 MOCK_METHOD0(MockLoad
, const PolicyBundle
*());
54 MOCK_METHOD0(InitOnBackgroundThread
, void());
55 MOCK_METHOD0(LastModificationTime
, base::Time());
58 DISALLOW_COPY_AND_ASSIGN(MockPolicyLoader
);
61 MockPolicyLoader::MockPolicyLoader(
62 scoped_refptr
<base::SequencedTaskRunner
> task_runner
)
63 : AsyncPolicyLoader(task_runner
) {}
65 MockPolicyLoader::~MockPolicyLoader() {}
67 scoped_ptr
<PolicyBundle
> MockPolicyLoader::Load() {
68 scoped_ptr
<PolicyBundle
> bundle
;
69 const PolicyBundle
* loaded
= MockLoad();
71 bundle
.reset(new PolicyBundle());
72 bundle
->CopyFrom(*loaded
);
79 class AsyncPolicyProviderTest
: public testing::Test
{
81 AsyncPolicyProviderTest();
82 ~AsyncPolicyProviderTest() override
;
84 void SetUp() override
;
85 void TearDown() override
;
87 base::MessageLoop loop_
;
88 SchemaRegistry schema_registry_
;
89 PolicyBundle initial_bundle_
;
90 MockPolicyLoader
* loader_
;
91 scoped_ptr
<AsyncPolicyProvider
> provider_
;
94 DISALLOW_COPY_AND_ASSIGN(AsyncPolicyProviderTest
);
97 AsyncPolicyProviderTest::AsyncPolicyProviderTest() {}
99 AsyncPolicyProviderTest::~AsyncPolicyProviderTest() {}
101 void AsyncPolicyProviderTest::SetUp() {
102 SetPolicy(&initial_bundle_
, "policy", "initial");
103 loader_
= new MockPolicyLoader(loop_
.task_runner());
104 EXPECT_CALL(*loader_
, LastModificationTime())
105 .WillRepeatedly(Return(base::Time()));
106 EXPECT_CALL(*loader_
, InitOnBackgroundThread()).Times(1);
107 EXPECT_CALL(*loader_
, MockLoad()).WillOnce(Return(&initial_bundle_
));
109 provider_
.reset(new AsyncPolicyProvider(
110 &schema_registry_
, scoped_ptr
<AsyncPolicyLoader
>(loader_
)));
111 provider_
->Init(&schema_registry_
);
112 // Verify that the initial load is done synchronously:
113 EXPECT_TRUE(provider_
->policies().Equals(initial_bundle_
));
115 loop_
.RunUntilIdle();
116 Mock::VerifyAndClearExpectations(loader_
);
118 EXPECT_CALL(*loader_
, LastModificationTime())
119 .WillRepeatedly(Return(base::Time()));
122 void AsyncPolicyProviderTest::TearDown() {
124 provider_
->Shutdown();
127 loop_
.RunUntilIdle();
130 TEST_F(AsyncPolicyProviderTest
, RefreshPolicies
) {
131 PolicyBundle refreshed_bundle
;
132 SetPolicy(&refreshed_bundle
, "policy", "refreshed");
133 EXPECT_CALL(*loader_
, MockLoad()).WillOnce(Return(&refreshed_bundle
));
135 MockConfigurationPolicyObserver observer
;
136 provider_
->AddObserver(&observer
);
137 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(1);
138 provider_
->RefreshPolicies();
139 loop_
.RunUntilIdle();
140 // The refreshed policies are now provided.
141 EXPECT_TRUE(provider_
->policies().Equals(refreshed_bundle
));
142 provider_
->RemoveObserver(&observer
);
145 TEST_F(AsyncPolicyProviderTest
, RefreshPoliciesTwice
) {
146 PolicyBundle refreshed_bundle
;
147 SetPolicy(&refreshed_bundle
, "policy", "refreshed");
148 EXPECT_CALL(*loader_
, MockLoad()).WillRepeatedly(Return(&refreshed_bundle
));
150 MockConfigurationPolicyObserver observer
;
151 provider_
->AddObserver(&observer
);
152 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(0);
153 provider_
->RefreshPolicies();
154 // Doesn't refresh before going through the background thread.
155 Mock::VerifyAndClearExpectations(&observer
);
157 // Doesn't refresh if another RefreshPolicies request is made.
158 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(0);
159 provider_
->RefreshPolicies();
160 Mock::VerifyAndClearExpectations(&observer
);
162 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(1);
163 loop_
.RunUntilIdle();
164 // The refreshed policies are now provided.
165 EXPECT_TRUE(provider_
->policies().Equals(refreshed_bundle
));
166 Mock::VerifyAndClearExpectations(&observer
);
167 provider_
->RemoveObserver(&observer
);
170 TEST_F(AsyncPolicyProviderTest
, RefreshPoliciesDuringReload
) {
171 PolicyBundle reloaded_bundle
;
172 SetPolicy(&reloaded_bundle
, "policy", "reloaded");
173 PolicyBundle refreshed_bundle
;
174 SetPolicy(&refreshed_bundle
, "policy", "refreshed");
176 Sequence load_sequence
;
178 EXPECT_CALL(*loader_
, MockLoad()).InSequence(load_sequence
)
179 .WillOnce(Return(&reloaded_bundle
));
181 EXPECT_CALL(*loader_
, MockLoad()).InSequence(load_sequence
)
182 .WillOnce(Return(&refreshed_bundle
));
184 MockConfigurationPolicyObserver observer
;
185 provider_
->AddObserver(&observer
);
186 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(0);
188 // A Reload is triggered before RefreshPolicies, and it shouldn't trigger
190 loader_
->Reload(true);
191 Mock::VerifyAndClearExpectations(&observer
);
193 // Doesn't refresh before going through the background thread.
194 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(0);
195 provider_
->RefreshPolicies();
196 Mock::VerifyAndClearExpectations(&observer
);
198 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(1);
199 loop_
.RunUntilIdle();
200 // The refreshed policies are now provided, and the |reloaded_bundle| was
202 EXPECT_TRUE(provider_
->policies().Equals(refreshed_bundle
));
203 Mock::VerifyAndClearExpectations(&observer
);
204 provider_
->RemoveObserver(&observer
);
207 TEST_F(AsyncPolicyProviderTest
, Shutdown
) {
208 EXPECT_CALL(*loader_
, MockLoad()).WillRepeatedly(Return(&initial_bundle_
));
210 MockConfigurationPolicyObserver observer
;
211 provider_
->AddObserver(&observer
);
213 // Though there is a pending Reload, the provider and the loader can be
214 // deleted at any time.
215 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(0);
216 loader_
->Reload(true);
217 Mock::VerifyAndClearExpectations(&observer
);
219 EXPECT_CALL(observer
, OnUpdatePolicy(provider_
.get())).Times(0);
220 provider_
->Shutdown();
221 loop_
.RunUntilIdle();
222 Mock::VerifyAndClearExpectations(&observer
);
224 provider_
->RemoveObserver(&observer
);
228 } // namespace policy