EMMA Coverage Report (generated Fri Aug 23 16:39:17 PDT 2013)
[all classes][org.chromium.sync.notifier]

COVERAGE SUMMARY FOR SOURCE FILE [InvalidationServiceTest.java]

nameclass, %method, %block, %line, %
InvalidationServiceTest.java100% (2/2)100% (31/31)100% (1612/1612)100% (275/275)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class InvalidationServiceTest100% (1/1)100% (29/29)100% (1593/1593)100% (273/273)
<static initializer> 100% (1/1)100% (16/16)100% (1/1)
InvalidationServiceTest (): void 100% (1/1)100% (4/4)100% (2/2)
access$000 (InvalidationServiceTest): List 100% (1/1)100% (3/3)100% (1/1)
assertSingleAcknowledgement (byte []): void 100% (1/1)100% (18/18)100% (3/3)
doTestInvalidate (boolean): void 100% (1/1)100% (83/83)100% (13/13)
isAndroidListenerStartIntent (Intent): boolean 100% (1/1)100% (15/15)100% (2/2)
isAndroidListenerStopIntent (Intent): boolean 100% (1/1)100% (12/12)100% (2/2)
setUp (): void 100% (1/1)100% (18/18)100% (5/5)
tearDown (): void 100% (1/1)100% (19/19)100% (6/6)
testClientStopsWhenShouldNotBeRunning (): void 100% (1/1)100% (56/56)100% (12/12)
testComputeRegistrationOps (): void 100% (1/1)100% (159/159)100% (19/19)
testDeferredRegistrationsIssued (): void 100% (1/1)100% (116/116)100% (21/21)
testInformError (): void 100% (1/1)100% (77/77)100% (13/13)
testInformRegistrationFailure (): void 100% (1/1)100% (129/129)100% (17/17)
testInformRegistrationStatus (): void 100% (1/1)100% (126/126)100% (17/17)
testInvalidateAll (): void 100% (1/1)100% (32/32)100% (7/7)
testInvalidateUnknownVersion (): void 100% (1/1)100% (46/46)100% (10/10)
testInvalidateWithPayload (): void 100% (1/1)100% (4/4)100% (2/2)
testInvalidateWithoutPayload (): void 100% (1/1)100% (4/4)100% (2/2)
testReadWriteState (): void 100% (1/1)100% (33/33)100% (5/5)
testReady (): void 100% (1/1)100% (73/73)100% (11/11)
testRegistrationIntent (): void 100% (1/1)100% (137/137)100% (24/24)
testRegistrationIntentNoProxyTabsAlreadyWithClientId (): void 100% (1/1)100% (99/99)100% (19/19)
testRegistrationIntentNoProxyTabsUsingReady (): void 100% (1/1)100% (84/84)100% (16/16)
testRegistrationIntentWhenClientShouldNotBeRunning (): void 100% (1/1)100% (52/52)100% (11/11)
testRegistrationRetries (): void 100% (1/1)100% (1/1)100% (1/1)
testReissueRegistrations (): void 100% (1/1)100% (75/75)100% (10/10)
testShouldClientBeRunning (): void 100% (1/1)100% (45/45)100% (9/9)
testStartAndStopClient (): void 100% (1/1)100% (57/57)100% (12/12)
     
class InvalidationServiceTest$1100% (1/1)100% (2/2)100% (19/19)100% (3/3)
InvalidationServiceTest$1 (InvalidationServiceTest, Context): void 100% (1/1)100% (7/7)100% (1/1)
startService (Intent): ComponentName 100% (1/1)100% (12/12)100% (2/2)

1// Copyright (c) 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.
4 
5package org.chromium.sync.notifier;
6 
7import android.accounts.Account;
8import android.content.ComponentName;
9import android.content.Intent;
10import android.os.Bundle;
11import android.test.ServiceTestCase;
12import android.test.suitebuilder.annotation.SmallTest;
13 
14import com.google.ipc.invalidation.external.client.InvalidationListener.RegistrationState;
15import com.google.ipc.invalidation.external.client.contrib.AndroidListener;
16import com.google.ipc.invalidation.external.client.types.ErrorInfo;
17import com.google.ipc.invalidation.external.client.types.Invalidation;
18import com.google.ipc.invalidation.external.client.types.ObjectId;
19 
20import org.chromium.base.CollectionUtil;
21import org.chromium.base.test.util.AdvancedMockContext;
22import org.chromium.base.test.util.Feature;
23import org.chromium.sync.internal_api.pub.base.ModelType;
24import org.chromium.sync.notifier.InvalidationController.IntentProtocol;
25import org.chromium.sync.notifier.InvalidationPreferences.EditContext;
26import org.chromium.sync.signin.AccountManagerHelper;
27 
28import java.util.ArrayList;
29import java.util.Arrays;
30import java.util.EnumSet;
31import java.util.HashSet;
32import java.util.List;
33import java.util.Set;
34 
35/**
36 * Tests for the {@link InvalidationService}.
37 *
38 * @author dsmyers@google.com (Daniel Myers)
39 */
40public class InvalidationServiceTest extends ServiceTestCase<TestableInvalidationService> {
41    /** Id used when creating clients. */
42    private static final byte[] CLIENT_ID = new byte[]{0, 4, 7};
43 
44    /** Intents provided to {@link #startService}. */
45    private List<Intent> mStartServiceIntents;
46 
47    public InvalidationServiceTest() {
48        super(TestableInvalidationService.class);
49    }
50 
51    @Override
52    public void setUp() throws Exception {
53        super.setUp();
54        mStartServiceIntents = new ArrayList<Intent>();
55        setContext(new AdvancedMockContext(getContext()) {
56            @Override
57            public ComponentName startService(Intent intent) {
58                mStartServiceIntents.add(intent);
59                return new ComponentName(this, InvalidationServiceTest.class);
60            }
61        });
62        setupService();
63    }
64 
65    @Override
66    public void tearDown() throws Exception {
67        if (InvalidationService.getIsClientStartedForTest()) {
68            Intent stopIntent = new Intent().putExtra(IntentProtocol.EXTRA_STOP, true);
69            getService().onHandleIntent(stopIntent);
70        }
71        assertFalse(InvalidationService.getIsClientStartedForTest());
72        super.tearDown();
73    }
74 
75    @SmallTest
76    @Feature({"Sync"})
77    public void testComputeRegistrationOps() {
78        /*
79         * Test plan: compute the set of registration operations resulting from various combinations
80         * of existing and desired registrations. Verifying that they are correct.
81         */
82        Set<ObjectId> regAccumulator = new HashSet<ObjectId>();
83        Set<ObjectId> unregAccumulator = new HashSet<ObjectId>();
84 
85        // Empty existing and desired registrations should yield empty operation sets.
86        InvalidationService.computeRegistrationOps(
87                ModelType.modelTypesToObjectIds(
88                        CollectionUtil.newHashSet(ModelType.BOOKMARK, ModelType.SESSION)),
89                ModelType.modelTypesToObjectIds(
90                        CollectionUtil.newHashSet(ModelType.BOOKMARK, ModelType.SESSION)),
91                regAccumulator, unregAccumulator);
92        assertEquals(0, regAccumulator.size());
93        assertEquals(0, unregAccumulator.size());
94 
95        // Equal existing and desired registrations should yield empty operation sets.
96        InvalidationService.computeRegistrationOps(new HashSet<ObjectId>(),
97                new HashSet<ObjectId>(), regAccumulator, unregAccumulator);
98        assertEquals(0, regAccumulator.size());
99        assertEquals(0, unregAccumulator.size());
100 
101        // Empty existing and non-empty desired registrations should yield desired registrations
102        // as the registration operations to do and no unregistrations.
103        Set<ObjectId> desiredTypes =
104                CollectionUtil.newHashSet(
105                        ModelType.BOOKMARK.toObjectId(), ModelType.SESSION.toObjectId());
106        InvalidationService.computeRegistrationOps(
107                new HashSet<ObjectId>(),
108                desiredTypes,
109                regAccumulator, unregAccumulator);
110        assertEquals(
111                CollectionUtil.newHashSet(
112                        ModelType.BOOKMARK.toObjectId(), ModelType.SESSION.toObjectId()),
113                new HashSet<ObjectId>(regAccumulator));
114        assertEquals(0, unregAccumulator.size());
115        regAccumulator.clear();
116 
117        // Unequal existing and desired registrations should yield both registrations and
118        // unregistrations. We should unregister TYPED_URL and register BOOKMARK, keeping SESSION.
119        InvalidationService.computeRegistrationOps(
120                CollectionUtil.newHashSet(
121                        ModelType.SESSION.toObjectId(), ModelType.TYPED_URL.toObjectId()),
122                CollectionUtil.newHashSet(
123                        ModelType.BOOKMARK.toObjectId(), ModelType.SESSION.toObjectId()),
124                regAccumulator, unregAccumulator);
125        assertEquals(CollectionUtil.newHashSet(ModelType.BOOKMARK.toObjectId()), regAccumulator);
126        assertEquals(CollectionUtil.newHashSet(ModelType.TYPED_URL.toObjectId()),
127                unregAccumulator);
128        regAccumulator.clear();
129        unregAccumulator.clear();
130    }
131 
132    @SmallTest
133    @Feature({"Sync"})
134    public void testReady() {
135       /**
136        * Test plan: call ready. Verify that the service sets the client id correctly and reissues
137        * pending registrations.
138        */
139 
140        // Persist some registrations.
141        InvalidationPreferences invPrefs = new InvalidationPreferences(getContext());
142        EditContext editContext = invPrefs.edit();
143        invPrefs.setSyncTypes(editContext, CollectionUtil.newArrayList("BOOKMARK", "SESSION"));
144        assertTrue(invPrefs.commit(editContext));
145 
146        // Issue ready.
147        getService().ready(CLIENT_ID);
148        assertTrue(Arrays.equals(CLIENT_ID, InvalidationService.getClientIdForTest()));
149        byte[] otherCid = "otherCid".getBytes();
150        getService().ready(otherCid);
151        assertTrue(Arrays.equals(otherCid, InvalidationService.getClientIdForTest()));
152 
153        // Verify registrations issued.
154        assertEquals(CollectionUtil.newHashSet(
155                ModelType.BOOKMARK.toObjectId(), ModelType.SESSION.toObjectId()),
156                new HashSet<ObjectId>(getService().mRegistrations.get(0)));
157    }
158 
159    @SmallTest
160    @Feature({"Sync"})
161    public void testReissueRegistrations() {
162        /*
163         * Test plan: call the reissueRegistrations method of the listener with both empty and
164         * non-empty sets of desired registrations stored in preferences. Verify that no register
165         * intent is set in the first case and that the appropriate register intent is sent in
166         * the second.
167         */
168 
169        // No persisted registrations.
170        getService().reissueRegistrations(CLIENT_ID);
171        assertTrue(getService().mRegistrations.isEmpty());
172 
173        // Persist some registrations.
174        InvalidationPreferences invPrefs = new InvalidationPreferences(getContext());
175        EditContext editContext = invPrefs.edit();
176        invPrefs.setSyncTypes(editContext, CollectionUtil.newArrayList("BOOKMARK", "SESSION"));
177        assertTrue(invPrefs.commit(editContext));
178 
179        // Reissue registrations and verify that the appropriate registrations are issued.
180        getService().reissueRegistrations(CLIENT_ID);
181        assertEquals(1, getService().mRegistrations.size());
182        assertEquals(CollectionUtil.newHashSet(
183                ModelType.BOOKMARK.toObjectId(), ModelType.SESSION.toObjectId()),
184                new HashSet<ObjectId>(getService().mRegistrations.get(0)));
185    }
186 
187    @SmallTest
188    @Feature({"Sync"})
189    public void testInformRegistrationStatus() {
190        /*
191         * Test plan: call inform registration status under a variety of circumstances and verify
192         * that the appropriate (un)register calls are issued.
193         *
194         * 1. Registration of desired object. No calls issued.
195         * 2. Unregistration of undesired object. No calls issued.
196         * 3. Registration of undesired object. Unregistration issued.
197         * 4. Unregistration of desired object. Registration issued.
198         */
199        // Initial test setup: persist a single registration into preferences.
200        InvalidationPreferences invPrefs = new InvalidationPreferences(getContext());
201        EditContext editContext = invPrefs.edit();
202        invPrefs.setSyncTypes(editContext, CollectionUtil.newArrayList("SESSION"));
203        assertTrue(invPrefs.commit(editContext));
204 
205        // Cases 1 and 2: calls matching desired state cause no actions.
206        getService().informRegistrationStatus(CLIENT_ID, ModelType.SESSION.toObjectId(),
207                RegistrationState.REGISTERED);
208        getService().informRegistrationStatus(CLIENT_ID, ModelType.BOOKMARK.toObjectId(),
209                RegistrationState.UNREGISTERED);
210        assertTrue(getService().mRegistrations.isEmpty());
211        assertTrue(getService().mUnregistrations.isEmpty());
212 
213        // Case 3: registration of undesired object triggers an unregistration.
214        getService().informRegistrationStatus(CLIENT_ID, ModelType.BOOKMARK.toObjectId(),
215                RegistrationState.REGISTERED);
216        assertEquals(1, getService().mUnregistrations.size());
217        assertEquals(0, getService().mRegistrations.size());
218        assertEquals(CollectionUtil.newArrayList(ModelType.BOOKMARK.toObjectId()),
219                getService().mUnregistrations.get(0));
220 
221        // Case 4: unregistration of a desired object triggers a registration.
222        getService().informRegistrationStatus(CLIENT_ID, ModelType.SESSION.toObjectId(),
223                RegistrationState.UNREGISTERED);
224        assertEquals(1, getService().mUnregistrations.size());
225        assertEquals(1, getService().mRegistrations.size());
226        assertEquals(CollectionUtil.newArrayList(ModelType.SESSION.toObjectId()),
227                getService().mRegistrations.get(0));
228    }
229 
230    @SmallTest
231    @Feature({"Sync"})
232    public void testInformRegistrationFailure() {
233        /*
234         * Test plan: call inform registration failure under a variety of circumstances and verify
235         * that the appropriate (un)register calls are issued.
236         *
237         * 1. Transient registration failure for an object that should be registered. Register
238         *    should be called.
239         * 2. Permanent registration failure for an object that should be registered. No calls.
240         * 3. Transient registration failure for an object that should not be registered. Unregister
241         *    should be called.
242         * 4. Permanent registration failure for an object should not be registered. No calls.
243         */
244 
245        // Initial test setup: persist a single registration into preferences.
246        InvalidationPreferences invPrefs = new InvalidationPreferences(getContext());
247        EditContext editContext = invPrefs.edit();
248        invPrefs.setSyncTypes(editContext, CollectionUtil.newArrayList("SESSION"));
249        assertTrue(invPrefs.commit(editContext));
250 
251        // Cases 2 and 4: permanent registration failures never cause calls to be made.
252        getService().informRegistrationFailure(CLIENT_ID, ModelType.SESSION.toObjectId(), false,
253                "");
254        getService().informRegistrationFailure(CLIENT_ID, ModelType.BOOKMARK.toObjectId(), false,
255                "");
256        assertTrue(getService().mRegistrations.isEmpty());
257        assertTrue(getService().mUnregistrations.isEmpty());
258 
259        // Case 1: transient failure of a desired registration results in re-registration.
260        getService().informRegistrationFailure(CLIENT_ID, ModelType.SESSION.toObjectId(), true, "");
261        assertEquals(1, getService().mRegistrations.size());
262        assertTrue(getService().mUnregistrations.isEmpty());
263        assertEquals(CollectionUtil.newArrayList(ModelType.SESSION.toObjectId()),
264                getService().mRegistrations.get(0));
265 
266        // Case 3: transient failure of an undesired registration results in unregistration.
267        getService().informRegistrationFailure(CLIENT_ID, ModelType.BOOKMARK.toObjectId(), true,
268                "");
269        assertEquals(1, getService().mRegistrations.size());
270        assertEquals(1, getService().mUnregistrations.size());
271        assertEquals(CollectionUtil.newArrayList(ModelType.BOOKMARK.toObjectId()),
272                getService().mUnregistrations.get(0));
273    }
274 
275    @SmallTest
276    @Feature({"Sync"})
277    public void testInformError() {
278        /*
279         * Test plan: call informError with both permanent and transient errors. Verify that
280         * the transient error causes no action to be taken and that the permanent error causes
281         * the client to be stopped.
282         */
283 
284        // Client needs to be started for the permament error to trigger and stop.
285        getService().setShouldRunStates(true, true);
286        getService().onCreate();
287        getService().onHandleIntent(new Intent());
288        getService().mStartedServices.clear();  // Discard start intent.
289 
290        // Transient error.
291        getService().informError(ErrorInfo.newInstance(0, true, "transient", null));
292        assertTrue(getService().mStartedServices.isEmpty());
293 
294        // Permanent error.
295        getService().informError(ErrorInfo.newInstance(0, false, "permanent", null));
296        assertEquals(1, getService().mStartedServices.size());
297        Intent sentIntent = getService().mStartedServices.get(0);
298        Intent stopIntent = AndroidListener.createStopIntent(getContext());
299        assertTrue(stopIntent.filterEquals(sentIntent));
300        assertEquals(stopIntent.getExtras().keySet(), sentIntent.getExtras().keySet());
301    }
302 
303    @SmallTest
304    @Feature({"Sync"})
305    public void testReadWriteState() {
306        /*
307         * Test plan: read, write, and read the internal notification client persistent state.
308         * Verify appropriate return values.
309         */
310        assertNull(getService().readState());
311        byte[] writtenState = new byte[]{7,4,0};
312        getService().writeState(writtenState);
313        assertTrue(Arrays.equals(writtenState, getService().readState()));
314    }
315 
316    @SmallTest
317    @Feature({"Sync"})
318    public void testInvalidateWithPayload() {
319        doTestInvalidate(true);
320    }
321 
322    @SmallTest
323    @Feature({"Sync"})
324    public void testInvalidateWithoutPayload() {
325        doTestInvalidate(false);
326    }
327 
328    private void doTestInvalidate(boolean hasPayload) {
329        /*
330         * Test plan: call invalidate() with an invalidation that may or may not have a payload.
331         * Verify the produced bundle has the correct fields.
332         */
333        // Call invalidate.
334        int version = 4747;
335        ObjectId objectId = ModelType.BOOKMARK.toObjectId();
336        final String payload = "testInvalidate-" + hasPayload;
337        Invalidation invalidation = hasPayload ?
338                Invalidation.newInstance(objectId, version, payload.getBytes()) :
339                Invalidation.newInstance(objectId, version);
340        byte[] ackHandle = ("testInvalidate-" + hasPayload).getBytes();
341        getService().invalidate(invalidation, ackHandle);
342 
343        // Validate bundle.
344        assertEquals(1, getService().mRequestedSyncs.size());
345        Bundle syncBundle = getService().mRequestedSyncs.get(0);
346        assertEquals("BOOKMARK", syncBundle.getString("objectId"));
347        assertEquals(version, syncBundle.getLong("version"));
348        assertEquals(hasPayload ? payload : "", syncBundle.getString("payload"));
349 
350        // Ensure acknowledged.
351        assertSingleAcknowledgement(ackHandle);
352    }
353 
354    @SmallTest
355    @Feature({"Sync"})
356    public void testInvalidateUnknownVersion() {
357        /*
358         * Test plan: call invalidateUnknownVersion(). Verify the produced bundle has the correct
359         * fields.
360         */
361        ObjectId objectId = ModelType.BOOKMARK.toObjectId();
362        byte[] ackHandle = "testInvalidateUV".getBytes();
363        getService().invalidateUnknownVersion(objectId, ackHandle);
364 
365        // Validate bundle.
366        assertEquals(1, getService().mRequestedSyncs.size());
367        Bundle syncBundle = getService().mRequestedSyncs.get(0);
368        assertEquals("BOOKMARK", syncBundle.getString("objectId"));
369        assertEquals(0, syncBundle.getLong("version"));
370        assertEquals("", syncBundle.getString("payload"));
371 
372        // Ensure acknowledged.
373        assertSingleAcknowledgement(ackHandle);
374    }
375 
376    @SmallTest
377    @Feature({"Sync"})
378    public void testInvalidateAll() {
379        /*
380         * Test plan: call invalidateAll(). Verify the produced bundle has the correct fields.
381         */
382        byte[] ackHandle = "testInvalidateAll".getBytes();
383        getService().invalidateAll(ackHandle);
384 
385        // Validate bundle.
386        assertEquals(1, getService().mRequestedSyncs.size());
387        Bundle syncBundle = getService().mRequestedSyncs.get(0);
388        assertEquals(0, syncBundle.keySet().size());
389 
390        // Ensure acknowledged.
391        assertSingleAcknowledgement(ackHandle);
392    }
393 
394    /** Asserts that the service received a single acknowledgement with handle {@code ackHandle}. */
395    private void assertSingleAcknowledgement(byte[] ackHandle) {
396        assertEquals(1, getService().mAcknowledgements.size());
397        assertTrue(Arrays.equals(ackHandle, getService().mAcknowledgements.get(0)));
398    }
399 
400    @SmallTest
401    @Feature({"Sync"})
402    public void testShouldClientBeRunning() {
403        /*
404         * Test plan: call shouldClientBeRunning with various combinations of
405         * in-foreground/sync-enabled. Verify appropriate return values.
406         */
407        getService().setShouldRunStates(false, false);
408        assertFalse(getService().shouldClientBeRunning());
409 
410        getService().setShouldRunStates(false, true);
411        assertFalse(getService().shouldClientBeRunning());
412 
413        getService().setShouldRunStates(true, false);
414        assertFalse(getService().shouldClientBeRunning());
415 
416        // Should only be running if both in the foreground and sync is enabled.
417        getService().setShouldRunStates(true, true);
418        assertTrue(getService().shouldClientBeRunning());
419    }
420 
421    @SmallTest
422    @Feature({"Sync"})
423    public void testStartAndStopClient() {
424        /*
425         * Test plan: with Chrome configured so that the client should run, send it an empty
426         * intent. Even though no owning account is known, the client should still start. Send
427         * it a stop intent and verify that it stops.
428         */
429 
430        // Note: we are manipulating the service object directly, rather than through startService,
431        // because otherwise we would need to handle the asynchronous execution model of the
432        // underlying IntentService.
433        getService().setShouldRunStates(true, true);
434        getService().onCreate();
435 
436        Intent startIntent = new Intent();
437        getService().onHandleIntent(startIntent);
438        assertTrue(InvalidationService.getIsClientStartedForTest());
439 
440        Intent stopIntent = new Intent().putExtra(IntentProtocol.EXTRA_STOP, true);
441        getService().onHandleIntent(stopIntent);
442        assertFalse(InvalidationService.getIsClientStartedForTest());
443 
444        // The issued intents should have been an AndroidListener start intent followed by an
445        // AndroidListener stop intent.
446        assertEquals(2, mStartServiceIntents.size());
447        assertTrue(isAndroidListenerStartIntent(mStartServiceIntents.get(0)));
448        assertTrue(isAndroidListenerStopIntent(mStartServiceIntents.get(1)));
449    }
450 
451    @SmallTest
452    @Feature({"Sync"})
453    public void testClientStopsWhenShouldNotBeRunning() {
454        /*
455         * Test plan: start the client. Then, change the configuration so that Chrome should not
456         * be running. Send an intent to the service and verify that it stops.
457         */
458        getService().setShouldRunStates(true, true);
459        getService().onCreate();
460 
461        // Start the service.
462        Intent startIntent = new Intent();
463        getService().onHandleIntent(startIntent);
464        assertTrue(InvalidationService.getIsClientStartedForTest());
465 
466        // Change configuration.
467        getService().setShouldRunStates(false, false);
468 
469        // Send an Intent and verify that the service stops.
470        getService().onHandleIntent(startIntent);
471        assertFalse(InvalidationService.getIsClientStartedForTest());
472 
473        // The issued intents should have been an AndroidListener start intent followed by an
474        // AndroidListener stop intent.
475        assertEquals(2, mStartServiceIntents.size());
476        assertTrue(isAndroidListenerStartIntent(mStartServiceIntents.get(0)));
477        assertTrue(isAndroidListenerStopIntent(mStartServiceIntents.get(1)));
478    }
479 
480    @SmallTest
481    @Feature({"Sync"})
482    public void testRegistrationIntent() {
483        /*
484         * Test plan: send a registration-change intent. Verify that it starts the client and
485         * sets both the account and registrations in shared preferences.
486         */
487        getService().setShouldRunStates(true, true);
488        getService().onCreate();
489 
490        // Send register Intent.
491        Set<ModelType> desiredRegistrations = CollectionUtil.newHashSet(
492                ModelType.BOOKMARK, ModelType.SESSION);
493        Account account = AccountManagerHelper.createAccountFromName("test@example.com");
494        Intent registrationIntent = IntentProtocol.createRegisterIntent(account, false,
495                desiredRegistrations);
496        getService().onHandleIntent(registrationIntent);
497 
498        // Verify client started and state written.
499        assertTrue(InvalidationService.getIsClientStartedForTest());
500        InvalidationPreferences invPrefs = new InvalidationPreferences(getContext());
501        assertEquals(account, invPrefs.getSavedSyncedAccount());
502        assertEquals(ModelType.modelTypesToSyncTypes(desiredRegistrations),
503                invPrefs.getSavedSyncedTypes());
504        assertEquals(1, mStartServiceIntents.size());
505        assertTrue(isAndroidListenerStartIntent(mStartServiceIntents.get(0)));
506 
507        // Send another registration-change intent, this type with all-types set to true, and
508        // verify that the on-disk state is updated and that no addition Intents are issued.
509        getService().onHandleIntent(IntentProtocol.createRegisterIntent(account, true, null));
510        assertEquals(account, invPrefs.getSavedSyncedAccount());
511        assertEquals(CollectionUtil.newHashSet(ModelType.ALL_TYPES_TYPE),
512                invPrefs.getSavedSyncedTypes());
513        assertEquals(1, mStartServiceIntents.size());
514 
515        // Finally, send one more registration-change intent, this time with a different account,
516        // and verify that it both updates the account, stops thye existing client, and
517        // starts a new client.
518        Account account2 = AccountManagerHelper.createAccountFromName("test2@example.com");
519        getService().onHandleIntent(IntentProtocol.createRegisterIntent(account2, true, null));
520        assertEquals(account2, invPrefs.getSavedSyncedAccount());
521        assertEquals(3, mStartServiceIntents.size());
522        assertTrue(isAndroidListenerStartIntent(mStartServiceIntents.get(0)));
523        assertTrue(isAndroidListenerStopIntent(mStartServiceIntents.get(1)));
524        assertTrue(isAndroidListenerStartIntent(mStartServiceIntents.get(2)));
525    }
526 
527    @SmallTest
528    @Feature({"Sync"})
529    public void testRegistrationIntentNoProxyTabsUsingReady() {
530        getService().setShouldRunStates(true, true);
531        getService().onCreate();
532 
533        // Send register Intent.
534        Account account = AccountManagerHelper.createAccountFromName("test@example.com");
535        Intent registrationIntent = IntentProtocol.createRegisterIntent(account, true, null);
536        getService().onHandleIntent(registrationIntent);
537 
538        // Verify client started and state written.
539        assertTrue(InvalidationService.getIsClientStartedForTest());
540        InvalidationPreferences invPrefs = new InvalidationPreferences(getContext());
541        assertEquals(account, invPrefs.getSavedSyncedAccount());
542        assertEquals(CollectionUtil.newHashSet(ModelType.ALL_TYPES_TYPE),
543                invPrefs.getSavedSyncedTypes());
544        assertEquals(1, mStartServiceIntents.size());
545        assertTrue(isAndroidListenerStartIntent(mStartServiceIntents.get(0)));
546 
547        // Set client to be ready. This triggers registrations.
548        getService().ready(CLIENT_ID);
549        assertTrue(Arrays.equals(CLIENT_ID, InvalidationService.getClientIdForTest()));
550 
551        // Ensure registrations are correct.
552        Set<ObjectId> expectedTypes =
553                ModelType.modelTypesToObjectIds(EnumSet.allOf(ModelType.class));
554        assertEquals(expectedTypes, new HashSet<ObjectId>(getService().mRegistrations.get(0)));
555    }
556 
557    @SmallTest
558    @Feature({"Sync"})
559    public void testRegistrationIntentNoProxyTabsAlreadyWithClientId() {
560        getService().setShouldRunStates(true, true);
561        getService().onCreate();
562 
563        // Send register Intent with no desired types.
564        Account account = AccountManagerHelper.createAccountFromName("test@example.com");
565        Intent registrationIntent =
566                IntentProtocol.createRegisterIntent(account, false, new HashSet<ModelType>());
567        getService().onHandleIntent(registrationIntent);
568 
569        // Verify client started and state written.
570        assertTrue(InvalidationService.getIsClientStartedForTest());
571        InvalidationPreferences invPrefs = new InvalidationPreferences(getContext());
572        assertEquals(account, invPrefs.getSavedSyncedAccount());
573        assertEquals(new HashSet<String>(), invPrefs.getSavedSyncedTypes());
574        assertEquals(1, mStartServiceIntents.size());
575        assertTrue(isAndroidListenerStartIntent(mStartServiceIntents.get(0)));
576 
577        // Make sure client is ready.
578        getService().ready(CLIENT_ID);
579        assertTrue(Arrays.equals(CLIENT_ID, InvalidationService.getClientIdForTest()));
580 
581        // Choose to register for all types in an already ready client.
582        registrationIntent = IntentProtocol.createRegisterIntent(account, true, null);
583        getService().onHandleIntent(registrationIntent);
584 
585        // Ensure registrations are correct.
586        assertEquals(1, getService().mRegistrations.size());
587        Set<ObjectId> expectedTypes =
588                ModelType.modelTypesToObjectIds(EnumSet.allOf(ModelType.class));
589        assertEquals(expectedTypes, new HashSet<ObjectId>(getService().mRegistrations.get(0)));
590    }
591 
592    @SmallTest
593    @Feature({"Sync"})
594    public void testRegistrationIntentWhenClientShouldNotBeRunning() {
595        /*
596         * Test plan: send a registration change event when the client should not be running.
597         * Verify that the service updates the on-disk state but does not start the client.
598         */
599        getService().onCreate();
600 
601        // Send register Intent.
602        Account account = AccountManagerHelper.createAccountFromName("test@example.com");
603        Set<ModelType> desiredRegistrations = CollectionUtil.newHashSet(
604                ModelType.BOOKMARK, ModelType.SESSION);
605        Intent registrationIntent = IntentProtocol.createRegisterIntent(account, false,
606                desiredRegistrations);
607        getService().onHandleIntent(registrationIntent);
608 
609        // Verify state written but client not started.
610        assertFalse(InvalidationService.getIsClientStartedForTest());
611        InvalidationPreferences invPrefs = new InvalidationPreferences(getContext());
612        assertEquals(account, invPrefs.getSavedSyncedAccount());
613        assertEquals(ModelType.modelTypesToSyncTypes(desiredRegistrations),
614                invPrefs.getSavedSyncedTypes());
615        assertEquals(0, mStartServiceIntents.size());
616    }
617 
618    @SmallTest
619    @Feature({"Sync"})
620    public void testDeferredRegistrationsIssued() {
621        /*
622         * Test plan: send a registration-change intent. Verify that the client issues a start
623         * intent but makes no registration calls. Issue a reissueRegistrations call and verify
624         * that the client does issue the appropriate registrations.
625         */
626        getService().setShouldRunStates(true, true);
627        getService().onCreate();
628 
629        // Send register Intent. Verify client started but no registrations issued.
630        Account account = AccountManagerHelper.createAccountFromName("test@example.com");
631        Set<ModelType> desiredRegistrations = CollectionUtil.newHashSet(
632                ModelType.BOOKMARK, ModelType.SESSION);
633        Set<ObjectId> desiredObjectIds = ModelType.modelTypesToObjectIds(desiredRegistrations);
634 
635        Intent registrationIntent = IntentProtocol.createRegisterIntent(account, false,
636                desiredRegistrations);
637        getService().onHandleIntent(registrationIntent);
638        assertTrue(InvalidationService.getIsClientStartedForTest());
639        assertEquals(1, mStartServiceIntents.size());
640        assertTrue(isAndroidListenerStartIntent(mStartServiceIntents.get(0)));
641        InvalidationPreferences invPrefs = new InvalidationPreferences(getContext());
642        assertEquals(ModelType.modelTypesToSyncTypes(desiredRegistrations),
643                invPrefs.getSavedSyncedTypes());
644        assertEquals(desiredObjectIds, getService().readRegistrationsFromPrefs());
645 
646        // Issue reissueRegistrations; verify registration intent issues.
647        getService().reissueRegistrations(CLIENT_ID);
648        assertEquals(2, mStartServiceIntents.size());
649        Intent expectedRegisterIntent = AndroidListener.createRegisterIntent(
650                getContext(),
651                CLIENT_ID,
652                desiredObjectIds);
653        Intent actualRegisterIntent = mStartServiceIntents.get(1);
654        assertTrue(expectedRegisterIntent.filterEquals(actualRegisterIntent));
655        assertEquals(expectedRegisterIntent.getExtras().keySet(),
656                actualRegisterIntent.getExtras().keySet());
657        assertEquals(
658                desiredObjectIds,
659                new HashSet<ObjectId>(getService().mRegistrations.get(0)));
660    }
661 
662    @SmallTest
663    @Feature({"Sync"})
664    public void testRegistrationRetries() {
665        /*
666         * Test plan: validate that the alarm receiver used by the AndroidListener underlying
667         * InvalidationService is correctly configured in the manifest and retries registrations
668         * with exponential backoff. May need to be implemented as a downstream Chrome for Android
669         * test.
670         */
671        // TODO(dsmyers): implement.
672        // Bug: https://code.google.com/p/chromium/issues/detail?id=172398
673    }
674 
675    /** Returns whether {@code intent} is an {@link AndroidListener} start intent. */
676    private boolean isAndroidListenerStartIntent(Intent intent) {
677        Intent startIntent = AndroidListener.createStartIntent(getContext(),
678                InvalidationService.CLIENT_TYPE, "unused".getBytes());
679        return intent.getExtras().keySet().equals(startIntent.getExtras().keySet());
680    }
681 
682    /** Returns whether {@code intent} is an {@link AndroidListener} stop intent. */
683    private boolean isAndroidListenerStopIntent(Intent intent) {
684        Intent stopIntent = AndroidListener.createStopIntent(getContext());
685        return intent.getExtras().keySet().equals(stopIntent.getExtras().keySet());
686    }
687}

[all classes][org.chromium.sync.notifier]
EMMA 2.0.5312 (C) Vladimir Roubtsov