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.
5 #include "chrome/browser/policy/cloud/cloud_policy_service.h"
8 #include "base/callback.h"
9 #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
10 #include "chrome/browser/policy/cloud/mock_cloud_policy_client.h"
11 #include "chrome/browser/policy/cloud/mock_cloud_policy_store.h"
12 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace em = enterprise_management;
22 class MockCloudPolicyServiceObserver : public CloudPolicyService::Observer {
24 MockCloudPolicyServiceObserver() {}
25 virtual ~MockCloudPolicyServiceObserver() {}
27 MOCK_METHOD1(OnInitializationCompleted, void(CloudPolicyService* service));
29 DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyServiceObserver);
32 class CloudPolicyServiceTest : public testing::Test {
34 CloudPolicyServiceTest()
35 : policy_ns_key_(dm_protocol::kChromeUserPolicyType, std::string()),
36 service_(policy_ns_key_, &client_, &store_) {}
38 MOCK_METHOD1(OnPolicyRefresh, void(bool));
41 PolicyNamespaceKey policy_ns_key_;
42 MockCloudPolicyClient client_;
43 MockCloudPolicyStore store_;
44 CloudPolicyService service_;
47 MATCHER_P(ProtoMatches, proto, "") {
48 return arg.SerializePartialAsString() == proto.SerializePartialAsString();
51 TEST_F(CloudPolicyServiceTest, ManagedByEmptyPolicy) {
52 EXPECT_EQ("", service_.ManagedBy());
55 TEST_F(CloudPolicyServiceTest, ManagedByValidPolicy) {
56 store_.policy_.reset(new em::PolicyData());
57 store_.policy_->set_username("user@example.com");
58 EXPECT_EQ("example.com", service_.ManagedBy());
61 TEST_F(CloudPolicyServiceTest, PolicyUpdateSuccess) {
62 em::PolicyFetchResponse policy;
63 policy.set_policy_data("fake policy");
64 client_.SetPolicy(policy_ns_key_, policy);
65 EXPECT_CALL(store_, Store(ProtoMatches(policy))).Times(1);
66 client_.NotifyPolicyFetched();
68 // After |store_| initializes, credentials and other meta data should be
69 // transferred to |client_|.
70 store_.policy_.reset(new em::PolicyData());
71 store_.policy_->set_request_token("fake token");
72 store_.policy_->set_device_id("fake client id");
73 store_.policy_->set_timestamp(32);
74 store_.policy_->set_valid_serial_number_missing(true);
75 store_.policy_->set_public_key_version(17);
77 SetupRegistration(store_.policy_->request_token(),
78 store_.policy_->device_id())).Times(1);
79 store_.NotifyStoreLoaded();
80 EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMilliseconds(32),
81 client_.last_policy_timestamp_);
82 EXPECT_TRUE(client_.submit_machine_id_);
83 EXPECT_TRUE(client_.public_key_version_valid_);
84 EXPECT_EQ(17, client_.public_key_version_);
87 TEST_F(CloudPolicyServiceTest, PolicyUpdateClientFailure) {
88 client_.SetStatus(DM_STATUS_REQUEST_FAILED);
89 EXPECT_CALL(store_, Store(_)).Times(0);
90 client_.NotifyPolicyFetched();
93 TEST_F(CloudPolicyServiceTest, RefreshPolicySuccess) {
94 testing::InSequence seq;
96 EXPECT_CALL(*this, OnPolicyRefresh(_)).Times(0);
97 client_.SetDMToken("fake token");
99 // Trigger a fetch on the client.
100 EXPECT_CALL(client_, FetchPolicy()).Times(1);
101 service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
102 base::Unretained(this)));
104 // Client responds, push policy to store.
105 em::PolicyFetchResponse policy;
106 policy.set_policy_data("fake policy");
107 client_.SetPolicy(policy_ns_key_, policy);
108 client_.fetched_invalidation_version_ = 12345;
109 EXPECT_CALL(store_, Store(ProtoMatches(policy))).Times(1);
110 EXPECT_EQ(0, store_.invalidation_version());
111 client_.NotifyPolicyFetched();
112 EXPECT_EQ(12345, store_.invalidation_version());
114 // Store reloads policy, callback gets triggered.
115 store_.policy_.reset(new em::PolicyData());
116 store_.policy_->set_request_token("token");
117 store_.policy_->set_device_id("device-id");
118 EXPECT_CALL(*this, OnPolicyRefresh(true)).Times(1);
119 store_.NotifyStoreLoaded();
122 TEST_F(CloudPolicyServiceTest, RefreshPolicyNotRegistered) {
123 // Clear the token so the client is not registered.
124 client_.SetDMToken(std::string());
126 EXPECT_CALL(client_, FetchPolicy()).Times(0);
127 EXPECT_CALL(*this, OnPolicyRefresh(false)).Times(1);
128 service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
129 base::Unretained(this)));
132 TEST_F(CloudPolicyServiceTest, RefreshPolicyClientError) {
133 testing::InSequence seq;
135 EXPECT_CALL(*this, OnPolicyRefresh(_)).Times(0);
136 client_.SetDMToken("fake token");
138 // Trigger a fetch on the client.
139 EXPECT_CALL(client_, FetchPolicy()).Times(1);
140 service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
141 base::Unretained(this)));
143 // Client responds with an error, which should trigger the callback.
144 client_.SetStatus(DM_STATUS_REQUEST_FAILED);
145 EXPECT_CALL(*this, OnPolicyRefresh(false)).Times(1);
146 client_.NotifyClientError();
149 TEST_F(CloudPolicyServiceTest, RefreshPolicyStoreError) {
150 testing::InSequence seq;
152 EXPECT_CALL(*this, OnPolicyRefresh(_)).Times(0);
153 client_.SetDMToken("fake token");
155 // Trigger a fetch on the client.
156 EXPECT_CALL(client_, FetchPolicy()).Times(1);
157 service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
158 base::Unretained(this)));
160 // Client responds, push policy to store.
161 em::PolicyFetchResponse policy;
162 policy.set_policy_data("fake policy");
163 client_.SetPolicy(policy_ns_key_, policy);
164 EXPECT_CALL(store_, Store(ProtoMatches(policy))).Times(1);
165 client_.NotifyPolicyFetched();
167 // Store fails, which should trigger the callback.
168 EXPECT_CALL(*this, OnPolicyRefresh(false)).Times(1);
169 store_.NotifyStoreError();
172 TEST_F(CloudPolicyServiceTest, RefreshPolicyConcurrent) {
173 testing::InSequence seq;
175 EXPECT_CALL(*this, OnPolicyRefresh(_)).Times(0);
176 client_.SetDMToken("fake token");
178 // Trigger a fetch on the client.
179 EXPECT_CALL(client_, FetchPolicy()).Times(1);
180 service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
181 base::Unretained(this)));
183 // Triggering another policy refresh should generate a new fetch request.
184 EXPECT_CALL(client_, FetchPolicy()).Times(1);
185 service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
186 base::Unretained(this)));
188 // Client responds, push policy to store.
189 em::PolicyFetchResponse policy;
190 policy.set_policy_data("fake policy");
191 client_.SetPolicy(policy_ns_key_, policy);
192 EXPECT_CALL(store_, Store(ProtoMatches(policy))).Times(1);
193 client_.NotifyPolicyFetched();
195 // Trigger another policy fetch.
196 EXPECT_CALL(client_, FetchPolicy()).Times(1);
197 service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
198 base::Unretained(this)));
200 // The store finishing the first load should not generate callbacks.
201 EXPECT_CALL(*this, OnPolicyRefresh(_)).Times(0);
202 store_.NotifyStoreLoaded();
204 // Second policy fetch finishes.
205 EXPECT_CALL(store_, Store(ProtoMatches(policy))).Times(1);
206 client_.NotifyPolicyFetched();
208 // Corresponding store operation finishes, all _three_ callbacks fire.
209 EXPECT_CALL(*this, OnPolicyRefresh(true)).Times(3);
210 store_.NotifyStoreLoaded();
213 TEST_F(CloudPolicyServiceTest, StoreAlreadyInitialized) {
214 // Service should start off initialized if the store has already loaded
216 store_.NotifyStoreLoaded();
217 CloudPolicyService service(policy_ns_key_, &client_, &store_);
218 EXPECT_TRUE(service.IsInitializationComplete());
221 TEST_F(CloudPolicyServiceTest, StoreLoadAfterCreation) {
222 // Service should start off un-initialized if the store has not yet loaded
224 EXPECT_FALSE(service_.IsInitializationComplete());
225 MockCloudPolicyServiceObserver observer;
226 service_.AddObserver(&observer);
227 // Service should be marked as initialized and observer should be called back.
228 EXPECT_CALL(observer, OnInitializationCompleted(&service_)).Times(1);
229 store_.NotifyStoreLoaded();
230 EXPECT_TRUE(service_.IsInitializationComplete());
231 testing::Mock::VerifyAndClearExpectations(&observer);
233 // Now, the next time the store is loaded, the observer should not be called
235 EXPECT_CALL(observer, OnInitializationCompleted(&service_)).Times(0);
236 store_.NotifyStoreLoaded();
237 service_.RemoveObserver(&observer);
240 } // namespace policy