SyncStorageEngineTest.java revision c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffc
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.content;
18
19import com.android.internal.os.AtomicFile;
20
21import android.test.AndroidTestCase;
22import android.test.RenamingDelegatingContext;
23import android.test.suitebuilder.annotation.SmallTest;
24import android.test.mock.MockContext;
25import android.test.mock.MockContentResolver;
26import android.accounts.Account;
27import android.os.Bundle;
28
29import java.util.List;
30import java.io.File;
31import java.io.FileOutputStream;
32
33public class SyncStorageEngineTest extends AndroidTestCase {
34
35    /**
36     * Test that we handle the case of a history row being old enough to purge before the
37     * correcponding sync is finished. This can happen if the clock changes while we are syncing.
38     *
39     */
40    @SmallTest
41    public void testPurgeActiveSync() throws Exception {
42        final Account account = new Account("a@example.com", "example.type");
43        final String authority = "testprovider";
44
45        MockContentResolver mockResolver = new MockContentResolver();
46
47        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
48                new TestContext(mockResolver, getContext()));
49
50        long time0 = 1000;
51        long historyId = engine.insertStartSyncEvent(
52                account, authority, time0, SyncStorageEngine.SOURCE_LOCAL);
53        long time1 = time0 + SyncStorageEngine.MILLIS_IN_4WEEKS * 2;
54        engine.stopSyncEvent(historyId, new Bundle(), time1 - time0, "yay", 0, 0);
55    }
56
57    /**
58     * Test that we can create, remove and retrieve periodic syncs
59     */
60    @SmallTest
61    public void testPeriodics() throws Exception {
62        final Account account1 = new Account("a@example.com", "example.type");
63        final Account account2 = new Account("b@example.com", "example.type.2");
64        final String authority = "testprovider";
65        final Bundle extras1 = new Bundle();
66        extras1.putString("a", "1");
67        final Bundle extras2 = new Bundle();
68        extras2.putString("a", "2");
69        final int period1 = 200;
70        final int period2 = 1000;
71
72        PeriodicSync sync1 = new PeriodicSync(account1, authority, extras1, period1);
73        PeriodicSync sync2 = new PeriodicSync(account1, authority, extras2, period1);
74        PeriodicSync sync3 = new PeriodicSync(account1, authority, extras2, period2);
75        PeriodicSync sync4 = new PeriodicSync(account2, authority, extras2, period2);
76
77        MockContentResolver mockResolver = new MockContentResolver();
78
79        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
80                new TestContext(mockResolver, getContext()));
81
82        removePeriodicSyncs(engine, account1, authority);
83        removePeriodicSyncs(engine, account2, authority);
84
85        // this should add two distinct periodic syncs for account1 and one for account2
86        engine.addPeriodicSync(sync1.account, sync1.authority, sync1.extras, sync1.period);
87        engine.addPeriodicSync(sync2.account, sync2.authority, sync2.extras, sync2.period);
88        engine.addPeriodicSync(sync3.account, sync3.authority, sync3.extras, sync3.period);
89        engine.addPeriodicSync(sync4.account, sync4.authority, sync4.extras, sync4.period);
90
91        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account1, authority);
92
93        assertEquals(2, syncs.size());
94
95        assertEquals(sync1, syncs.get(0));
96        assertEquals(sync3, syncs.get(1));
97
98        engine.removePeriodicSync(sync1.account, sync1.authority, sync1.extras);
99
100        syncs = engine.getPeriodicSyncs(account1, authority);
101        assertEquals(1, syncs.size());
102        assertEquals(sync3, syncs.get(0));
103
104        syncs = engine.getPeriodicSyncs(account2, authority);
105        assertEquals(1, syncs.size());
106        assertEquals(sync4, syncs.get(0));
107    }
108
109    private void removePeriodicSyncs(SyncStorageEngine engine, Account account, String authority) {
110        engine.setIsSyncable(account, authority, engine.getIsSyncable(account, authority));
111        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account, authority);
112        for (PeriodicSync sync : syncs) {
113            engine.removePeriodicSync(sync.account, sync.authority, sync.extras);
114        }
115    }
116
117    @SmallTest
118    public void testAuthorityPersistence() throws Exception {
119        final Account account1 = new Account("a@example.com", "example.type");
120        final Account account2 = new Account("b@example.com", "example.type.2");
121        final String authority1 = "testprovider1";
122        final String authority2 = "testprovider2";
123        final Bundle extras1 = new Bundle();
124        extras1.putString("a", "1");
125        final Bundle extras2 = new Bundle();
126        extras2.putString("a", "2");
127        extras2.putLong("b", 2);
128        extras2.putInt("c", 1);
129        extras2.putBoolean("d", true);
130        extras2.putDouble("e", 1.2);
131        extras2.putFloat("f", 4.5f);
132        extras2.putParcelable("g", account1);
133        final int period1 = 200;
134        final int period2 = 1000;
135
136        PeriodicSync sync1 = new PeriodicSync(account1, authority1, extras1, period1);
137        PeriodicSync sync2 = new PeriodicSync(account1, authority1, extras2, period1);
138        PeriodicSync sync3 = new PeriodicSync(account1, authority2, extras1, period1);
139        PeriodicSync sync4 = new PeriodicSync(account1, authority2, extras2, period2);
140        PeriodicSync sync5 = new PeriodicSync(account2, authority1, extras1, period1);
141
142        MockContentResolver mockResolver = new MockContentResolver();
143
144        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
145                new TestContext(mockResolver, getContext()));
146
147        removePeriodicSyncs(engine, account1, authority1);
148        removePeriodicSyncs(engine, account2, authority1);
149        removePeriodicSyncs(engine, account1, authority2);
150        removePeriodicSyncs(engine, account2, authority2);
151
152        engine.setMasterSyncAutomatically(false);
153
154        engine.setIsSyncable(account1, authority1, 1);
155        engine.setSyncAutomatically(account1, authority1, true);
156
157        engine.setIsSyncable(account2, authority1, 1);
158        engine.setSyncAutomatically(account2, authority1, true);
159
160        engine.setIsSyncable(account1, authority2, 1);
161        engine.setSyncAutomatically(account1, authority2, false);
162
163        engine.setIsSyncable(account2, authority2, 0);
164        engine.setSyncAutomatically(account2, authority2, true);
165
166        engine.addPeriodicSync(sync1.account, sync1.authority, sync1.extras, sync1.period);
167        engine.addPeriodicSync(sync2.account, sync2.authority, sync2.extras, sync2.period);
168        engine.addPeriodicSync(sync3.account, sync3.authority, sync3.extras, sync3.period);
169        engine.addPeriodicSync(sync4.account, sync4.authority, sync4.extras, sync4.period);
170        engine.addPeriodicSync(sync5.account, sync5.authority, sync5.extras, sync5.period);
171
172        engine.writeAllState();
173        engine.clearAndReadState();
174
175        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account1, authority1);
176        assertEquals(2, syncs.size());
177        assertEquals(sync1, syncs.get(0));
178        assertEquals(sync2, syncs.get(1));
179
180        syncs = engine.getPeriodicSyncs(account1, authority2);
181        assertEquals(2, syncs.size());
182        assertEquals(sync3, syncs.get(0));
183        assertEquals(sync4, syncs.get(1));
184
185        syncs = engine.getPeriodicSyncs(account2, authority1);
186        assertEquals(1, syncs.size());
187        assertEquals(sync5, syncs.get(0));
188
189        assertEquals(true, engine.getSyncAutomatically(account1, authority1));
190        assertEquals(true, engine.getSyncAutomatically(account2, authority1));
191        assertEquals(false, engine.getSyncAutomatically(account1, authority2));
192        assertEquals(true, engine.getSyncAutomatically(account2, authority2));
193
194        assertEquals(1, engine.getIsSyncable(account1, authority1));
195        assertEquals(1, engine.getIsSyncable(account2, authority1));
196        assertEquals(1, engine.getIsSyncable(account1, authority2));
197        assertEquals(0, engine.getIsSyncable(account2, authority2));
198    }
199
200    @SmallTest
201    public void testAuthorityParsing() throws Exception {
202        final Account account = new Account("account1", "type1");
203        final String authority1 = "auth1";
204        final String authority2 = "auth2";
205        final String authority3 = "auth3";
206        final Bundle extras = new Bundle();
207        PeriodicSync sync1 = new PeriodicSync(account, authority1, extras, (long) (60 * 60 * 24));
208        PeriodicSync sync2 = new PeriodicSync(account, authority2, extras, (long) (60 * 60 * 24));
209        PeriodicSync sync3 = new PeriodicSync(account, authority3, extras, (long) (60 * 60 * 24));
210        PeriodicSync sync1s = new PeriodicSync(account, authority1, extras, 1000);
211        PeriodicSync sync2s = new PeriodicSync(account, authority2, extras, 1000);
212        PeriodicSync sync3s = new PeriodicSync(account, authority3, extras, 1000);
213
214        MockContentResolver mockResolver = new MockContentResolver();
215
216        final TestContext testContext = new TestContext(mockResolver, getContext());
217        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);
218
219        byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
220                + "<accounts>\n"
221                + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n"
222                + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\" />\n"
223                + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\" />\n"
224                + "</accounts>\n").getBytes();
225
226        File syncDir = new File(new File(testContext.getFilesDir(), "system"), "sync");
227        syncDir.mkdirs();
228        AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
229        FileOutputStream fos = accountInfoFile.startWrite();
230        fos.write(accountsFileData);
231        accountInfoFile.finishWrite(fos);
232
233        engine.clearAndReadState();
234
235        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account, authority1);
236        assertEquals(1, syncs.size());
237        assertEquals(sync1, syncs.get(0));
238
239        syncs = engine.getPeriodicSyncs(account, authority2);
240        assertEquals(1, syncs.size());
241        assertEquals(sync2, syncs.get(0));
242
243        syncs = engine.getPeriodicSyncs(account, authority3);
244        assertEquals(1, syncs.size());
245        assertEquals(sync3, syncs.get(0));
246
247        accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
248                + "<accounts version=\"1\">\n"
249                + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n"
250                + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\" />\n"
251                + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\" />\n"
252                + "</accounts>\n").getBytes();
253
254        accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
255        fos = accountInfoFile.startWrite();
256        fos.write(accountsFileData);
257        accountInfoFile.finishWrite(fos);
258
259        engine.clearAndReadState();
260
261        syncs = engine.getPeriodicSyncs(account, authority1);
262        assertEquals(0, syncs.size());
263
264        syncs = engine.getPeriodicSyncs(account, authority2);
265        assertEquals(0, syncs.size());
266
267        syncs = engine.getPeriodicSyncs(account, authority3);
268        assertEquals(0, syncs.size());
269
270        accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
271                + "<accounts version=\"1\">\n"
272                + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\">\n"
273                + "<periodicSync period=\"1000\" />\n"
274                + "</authority>"
275                + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\">\n"
276                + "<periodicSync period=\"1000\" />\n"
277                + "</authority>"
278                + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\">\n"
279                + "<periodicSync period=\"1000\" />\n"
280                + "</authority>"
281                + "</accounts>\n").getBytes();
282
283        accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
284        fos = accountInfoFile.startWrite();
285        fos.write(accountsFileData);
286        accountInfoFile.finishWrite(fos);
287
288        engine.clearAndReadState();
289
290        syncs = engine.getPeriodicSyncs(account, authority1);
291        assertEquals(1, syncs.size());
292        assertEquals(sync1s, syncs.get(0));
293
294        syncs = engine.getPeriodicSyncs(account, authority2);
295        assertEquals(1, syncs.size());
296        assertEquals(sync2s, syncs.get(0));
297
298        syncs = engine.getPeriodicSyncs(account, authority3);
299        assertEquals(1, syncs.size());
300        assertEquals(sync3s, syncs.get(0));
301    }
302}
303
304class TestContext extends ContextWrapper {
305
306    ContentResolver mResolver;
307
308    private final Context mRealContext;
309
310    public TestContext(ContentResolver resolver, Context realContext) {
311        super(new RenamingDelegatingContext(new MockContext(), realContext, "test."));
312        mRealContext = realContext;
313        mResolver = resolver;
314    }
315
316    @Override
317    public File getFilesDir() {
318        return mRealContext.getFilesDir();
319    }
320
321    @Override
322    public void enforceCallingOrSelfPermission(String permission, String message) {
323    }
324
325    @Override
326    public void sendBroadcast(Intent intent) {
327    }
328
329    @Override
330    public ContentResolver getContentResolver() {
331        return mResolver;
332    }
333}
334