1 // Copyright 2015 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/remote_commands_invalidator.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/run_loop.h"
9 #include "chrome/browser/invalidation/fake_invalidation_service.h"
10 #include "components/invalidation/impl/invalidator_registrar.h"
11 #include "components/invalidation/impl/mock_ack_handler.h"
12 #include "components/invalidation/public/invalidation.h"
13 #include "components/invalidation/public/invalidation_util.h"
14 #include "components/invalidation/public/invalidator_state.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 namespace em
= enterprise_management
;
20 using ::testing::Mock
;
21 using ::testing::StrictMock
;
25 class MockRemoteCommandInvalidator
: public RemoteCommandsInvalidator
{
27 MockRemoteCommandInvalidator() {}
29 MOCK_METHOD0(OnInitialize
, void());
30 MOCK_METHOD0(OnShutdown
, void());
31 MOCK_METHOD0(OnStart
, void());
32 MOCK_METHOD0(OnStop
, void());
33 MOCK_METHOD0(DoRemoteCommandsFetch
, void());
35 void SetInvalidationObjectID(const invalidation::ObjectId
& object_id
) {
36 em::PolicyData policy_data
;
37 policy_data
.set_command_invalidation_source(object_id
.source());
38 policy_data
.set_command_invalidation_name(object_id
.name());
39 ReloadPolicyData(&policy_data
);
42 void ClearInvalidationObjectID() {
43 const em::PolicyData policy_data
;
44 ReloadPolicyData(&policy_data
);
48 DISALLOW_COPY_AND_ASSIGN(MockRemoteCommandInvalidator
);
51 class RemoteCommandsInvalidatorTest
: public testing::Test
{
53 RemoteCommandsInvalidatorTest()
54 : kTestingObjectId1(123456, "abcdef"),
55 kTestingObjectId2(654321, "defabc") {
58 void EnableInvalidationService() {
59 invalidation_service_
.SetInvalidatorState(syncer::INVALIDATIONS_ENABLED
);
62 void DisableInvalidationService() {
63 invalidation_service_
.SetInvalidatorState(
64 syncer::TRANSIENT_INVALIDATION_ERROR
);
67 syncer::Invalidation
FireInvalidation(
68 const invalidation::ObjectId
& object_id
) {
69 const syncer::Invalidation invalidation
=
70 syncer::Invalidation::InitUnknownVersion(object_id
);
71 invalidation_service_
.EmitInvalidationForTest(invalidation
);
75 bool IsInvalidationSent(const syncer::Invalidation
& invalidation
) {
76 return !invalidation_service_
.GetMockAckHandler()->IsUnsent(invalidation
);
79 bool IsInvalidationAcknowledged(const syncer::Invalidation
& invalidation
) {
80 return invalidation_service_
.GetMockAckHandler()->IsAcknowledged(
84 bool IsInvalidatorRegistered() {
85 return !invalidation_service_
.invalidator_registrar()
86 .GetRegisteredIds(&invalidator_
)
90 void VerifyExpectations() {
91 Mock::VerifyAndClearExpectations(&invalidator_
);
95 // Initialize and start the invalidator.
96 void InitializeAndStart() {
97 EXPECT_CALL(invalidator_
, OnInitialize()).Times(1);
98 invalidator_
.Initialize(&invalidation_service_
);
101 EXPECT_CALL(invalidator_
, OnStart()).Times(1);
102 invalidator_
.Start();
104 VerifyExpectations();
107 // Stop and shutdown the invalidator.
108 void StopAndShutdown() {
109 EXPECT_CALL(invalidator_
, OnStop()).Times(1);
110 EXPECT_CALL(invalidator_
, OnShutdown()).Times(1);
111 invalidator_
.Shutdown();
113 VerifyExpectations();
116 // Fire an invalidation to verify that invalidation is not working.
117 void VerifyInvalidationDisabled(const invalidation::ObjectId
& object_id
) {
118 const syncer::Invalidation invalidation
= FireInvalidation(object_id
);
120 base::RunLoop().RunUntilIdle();
121 EXPECT_FALSE(IsInvalidationSent(invalidation
));
124 // Fire an invalidation to verify that invalidation works.
125 void VerifyInvalidationEnabled(const invalidation::ObjectId
& object_id
) {
126 EXPECT_TRUE(invalidator_
.invalidations_enabled());
128 EXPECT_CALL(invalidator_
, DoRemoteCommandsFetch()).Times(1);
129 const syncer::Invalidation invalidation
= FireInvalidation(object_id
);
131 base::RunLoop().RunUntilIdle();
132 EXPECT_TRUE(IsInvalidationSent(invalidation
));
133 EXPECT_TRUE(IsInvalidationAcknowledged(invalidation
));
134 VerifyExpectations();
137 const invalidation::ObjectId kTestingObjectId1
;
138 const invalidation::ObjectId kTestingObjectId2
;
140 base::MessageLoop loop_
;
142 invalidation::FakeInvalidationService invalidation_service_
;
143 StrictMock
<MockRemoteCommandInvalidator
> invalidator_
;
146 DISALLOW_COPY_AND_ASSIGN(RemoteCommandsInvalidatorTest
);
149 // Verifies that only the fired invalidations will be received.
150 TEST_F(RemoteCommandsInvalidatorTest
, FiredInvalidation
) {
151 InitializeAndStart();
153 // Invalidator won't work at this point.
154 EXPECT_FALSE(invalidator_
.invalidations_enabled());
156 // Load the policy data, it should work now.
157 invalidator_
.SetInvalidationObjectID(kTestingObjectId1
);
158 EXPECT_TRUE(invalidator_
.invalidations_enabled());
160 base::RunLoop().RunUntilIdle();
161 // No invalidation will be received if no invalidation is fired.
162 VerifyExpectations();
164 // Fire an invalidation with different object id, no invalidation will be
166 const syncer::Invalidation invalidation1
=
167 FireInvalidation(kTestingObjectId2
);
169 base::RunLoop().RunUntilIdle();
170 EXPECT_FALSE(IsInvalidationSent(invalidation1
));
171 VerifyExpectations();
173 // Fire the invalidation, it should be acknowledged and trigger a remote
175 EXPECT_CALL(invalidator_
, DoRemoteCommandsFetch()).Times(1);
176 const syncer::Invalidation invalidation2
=
177 FireInvalidation(kTestingObjectId1
);
179 base::RunLoop().RunUntilIdle();
180 EXPECT_TRUE(IsInvalidationSent(invalidation2
));
181 EXPECT_TRUE(IsInvalidationAcknowledged(invalidation2
));
182 VerifyExpectations();
187 // Verifies that no invalidation will be received when invalidator is shutdown.
188 TEST_F(RemoteCommandsInvalidatorTest
, ShutDown
) {
189 EXPECT_FALSE(invalidator_
.invalidations_enabled());
190 FireInvalidation(kTestingObjectId1
);
192 base::RunLoop().RunUntilIdle();
193 EXPECT_FALSE(invalidator_
.invalidations_enabled());
196 // Verifies that no invalidation will be received when invalidator is stopped.
197 TEST_F(RemoteCommandsInvalidatorTest
, Stopped
) {
198 EXPECT_CALL(invalidator_
, OnInitialize()).Times(1);
199 invalidator_
.Initialize(&invalidation_service_
);
200 VerifyExpectations();
202 EXPECT_FALSE(invalidator_
.invalidations_enabled());
203 FireInvalidation(kTestingObjectId2
);
205 base::RunLoop().RunUntilIdle();
206 EXPECT_FALSE(invalidator_
.invalidations_enabled());
208 EXPECT_CALL(invalidator_
, OnShutdown()).Times(1);
209 invalidator_
.Shutdown();
212 // Verifies that stated/stopped state changes work as expected.
213 TEST_F(RemoteCommandsInvalidatorTest
, StartedStateChange
) {
214 InitializeAndStart();
216 // Invalidator requires object id to work.
217 VerifyInvalidationDisabled(kTestingObjectId1
);
218 EXPECT_FALSE(invalidator_
.invalidations_enabled());
219 invalidator_
.SetInvalidationObjectID(kTestingObjectId1
);
220 VerifyInvalidationEnabled(kTestingObjectId1
);
222 // Stop and restart invalidator.
223 EXPECT_CALL(invalidator_
, OnStop()).Times(1);
225 VerifyExpectations();
227 VerifyInvalidationDisabled(kTestingObjectId1
);
228 EXPECT_FALSE(invalidator_
.invalidations_enabled());
230 EXPECT_CALL(invalidator_
, OnStart()).Times(1);
231 invalidator_
.Start();
232 VerifyExpectations();
234 // Invalidator requires object id to work.
235 invalidator_
.SetInvalidationObjectID(kTestingObjectId1
);
236 VerifyInvalidationEnabled(kTestingObjectId1
);
241 // Verifies that registered state changes work as expected.
242 TEST_F(RemoteCommandsInvalidatorTest
, RegistedStateChange
) {
243 InitializeAndStart();
245 invalidator_
.SetInvalidationObjectID(kTestingObjectId1
);
246 VerifyInvalidationEnabled(kTestingObjectId1
);
248 invalidator_
.SetInvalidationObjectID(kTestingObjectId2
);
249 VerifyInvalidationEnabled(kTestingObjectId2
);
250 VerifyInvalidationDisabled(kTestingObjectId1
);
252 invalidator_
.SetInvalidationObjectID(kTestingObjectId1
);
253 VerifyInvalidationEnabled(kTestingObjectId1
);
254 VerifyInvalidationDisabled(kTestingObjectId2
);
256 invalidator_
.ClearInvalidationObjectID();
257 VerifyInvalidationDisabled(kTestingObjectId1
);
258 VerifyInvalidationDisabled(kTestingObjectId2
);
259 EXPECT_FALSE(invalidator_
.invalidations_enabled());
261 invalidator_
.SetInvalidationObjectID(kTestingObjectId2
);
262 VerifyInvalidationEnabled(kTestingObjectId2
);
263 VerifyInvalidationDisabled(kTestingObjectId1
);
268 // Verifies that invalidation service enabled state changes work as expected.
269 TEST_F(RemoteCommandsInvalidatorTest
, InvalidationServiceEnabledStateChanged
) {
270 InitializeAndStart();
272 invalidator_
.SetInvalidationObjectID(kTestingObjectId1
);
273 VerifyInvalidationEnabled(kTestingObjectId1
);
275 DisableInvalidationService();
276 EXPECT_FALSE(invalidator_
.invalidations_enabled());
278 EnableInvalidationService();
279 VerifyInvalidationEnabled(kTestingObjectId1
);
281 EnableInvalidationService();
282 VerifyInvalidationEnabled(kTestingObjectId1
);
284 DisableInvalidationService();
285 EXPECT_FALSE(invalidator_
.invalidations_enabled());
287 DisableInvalidationService();
288 EXPECT_FALSE(invalidator_
.invalidations_enabled());
293 } // namespace policy