SyncStorageEngineTest.java revision 56dbf8f23677d28615e61ef2fbb0e738cca02528
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 com.android.server.content; 18 19import android.accounts.Account; 20import android.content.ComponentName; 21import android.content.ContentResolver; 22import android.content.Context; 23import android.content.ContextWrapper; 24import android.content.Intent; 25import android.content.PeriodicSync; 26import android.content.res.Resources; 27import android.os.Bundle; 28import android.test.AndroidTestCase; 29import android.test.RenamingDelegatingContext; 30import android.test.mock.MockContentResolver; 31import android.test.mock.MockContext; 32import android.test.suitebuilder.annotation.LargeTest; 33import android.test.suitebuilder.annotation.MediumTest; 34import android.test.suitebuilder.annotation.SmallTest; 35 36import com.android.server.content.SyncStorageEngine.EndPoint; 37 38import com.android.internal.os.AtomicFile; 39 40import java.io.File; 41import java.io.FileOutputStream; 42import java.util.List; 43 44import com.android.server.content.SyncStorageEngine.EndPoint; 45 46public class SyncStorageEngineTest extends AndroidTestCase { 47 48 protected Account account1; 49 protected ComponentName syncService1; 50 protected String authority1 = "testprovider"; 51 protected Bundle defaultBundle; 52 protected final int DEFAULT_USER = 0; 53 54 /* Some default poll frequencies. */ 55 final long dayPoll = (60 * 60 * 24); 56 final long dayFuzz = 60; 57 final long thousandSecs = 1000; 58 final long thousandSecsFuzz = 100; 59 60 MockContentResolver mockResolver; 61 SyncStorageEngine engine; 62 63 private File getSyncDir() { 64 return new File(new File(getContext().getFilesDir(), "system"), "sync"); 65 } 66 67 @Override 68 public void setUp() { 69 account1 = new Account("a@example.com", "example.type"); 70 syncService1 = new ComponentName("com.example", "SyncService"); 71 // Default bundle. 72 defaultBundle = new Bundle(); 73 defaultBundle.putInt("int_key", 0); 74 defaultBundle.putString("string_key", "hello"); 75 // Set up storage engine. 76 mockResolver = new MockContentResolver(); 77 engine = SyncStorageEngine.newTestInstance( 78 new TestContext(mockResolver, getContext())); 79 } 80 81 /** 82 * Test that we handle the case of a history row being old enough to purge before the 83 * corresponding sync is finished. This can happen if the clock changes while we are syncing. 84 * 85 */ 86 // TODO: this test causes AidlTest to fail. Omit for now 87 // @SmallTest 88 public void testPurgeActiveSync() throws Exception { 89 final Account account = new Account("a@example.com", "example.type"); 90 final String authority = "testprovider"; 91 92 MockContentResolver mockResolver = new MockContentResolver(); 93 94 SyncStorageEngine engine = SyncStorageEngine.newTestInstance( 95 new TestContext(mockResolver, getContext())); 96 long time0 = 1000; 97 SyncOperation op = new SyncOperation(account, 0, 98 SyncOperation.REASON_PERIODIC, 99 SyncStorageEngine.SOURCE_LOCAL, 100 authority, 101 null, time0, 0 /* flex*/, 0, 0, true); 102 long historyId = engine.insertStartSyncEvent(op, time0); 103 long time1 = time0 + SyncStorageEngine.MILLIS_IN_4WEEKS * 2; 104 engine.stopSyncEvent(historyId, time1 - time0, "yay", 0, 0); 105 } 106 107 /** 108 * Test persistence of pending operations. 109 */ 110 @MediumTest 111 public void testPending() throws Exception { 112 SyncOperation sop = new SyncOperation(account1, 113 DEFAULT_USER, 114 SyncOperation.REASON_PERIODIC, 115 SyncStorageEngine.SOURCE_LOCAL, authority1, null, 116 0 /* runtime */, 0 /* flex */, 0 /* backoff */, 0 /* delayuntil */, 117 true /* expedited */); 118 engine.insertIntoPending(sop); 119 120 // Force engine to read from disk. 121 engine.clearAndReadState(); 122 123 assert(engine.getPendingOperationCount() == 1); 124 List<SyncStorageEngine.PendingOperation> pops = engine.getPendingOperations(); 125 SyncStorageEngine.PendingOperation popRetrieved = pops.get(0); 126 assertEquals(sop.target.account, popRetrieved.authority.account); 127 assertEquals(sop.target.provider, popRetrieved.authority.provider); 128 assertEquals(sop.target.service, popRetrieved.authority.service); 129 assertEquals(sop.target.userId, popRetrieved.authority.userId); 130 assertEquals(sop.reason, popRetrieved.reason); 131 assertEquals(sop.syncSource, popRetrieved.syncSource); 132 assertEquals(sop.expedited, popRetrieved.expedited); 133 assert(android.content.PeriodicSync.syncExtrasEquals(sop.extras, popRetrieved.extras)); 134 } 135 136 /** 137 * Test that we can create, remove and retrieve periodic syncs. Backwards compatibility - 138 * periodic syncs with no flex time are no longer used. 139 */ 140 @MediumTest 141 public void testPeriodics() throws Exception { 142 final Account account1 = new Account("a@example.com", "example.type"); 143 final Account account2 = new Account("b@example.com", "example.type.2"); 144 final String authority = "testprovider"; 145 final Bundle extras1 = new Bundle(); 146 extras1.putString("a", "1"); 147 final Bundle extras2 = new Bundle(); 148 extras2.putString("a", "2"); 149 final int period1 = 200; 150 final int period2 = 1000; 151 152 PeriodicSync sync1 = new PeriodicSync(account1, authority, extras1, period1); 153 EndPoint end1 = new EndPoint(account1, authority, 0); 154 155 PeriodicSync sync2 = new PeriodicSync(account1, authority, extras2, period1); 156 PeriodicSync sync3 = new PeriodicSync(account1, authority, extras2, period2); 157 PeriodicSync sync4 = new PeriodicSync(account2, authority, extras2, period2); 158 159 160 161 removePeriodicSyncs(engine, account1, 0, authority); 162 removePeriodicSyncs(engine, account2, 0, authority); 163 removePeriodicSyncs(engine, account1, 1, authority); 164 165 // this should add two distinct periodic syncs for account1 and one for account2 166 engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 0), period1, 0, extras1); 167 engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 0), period1, 0, extras2); 168 engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 0), period2, 0, extras2); 169 engine.updateOrAddPeriodicSync(new EndPoint(account2, authority, 0), period2, 0, extras2); 170 // add a second user 171 engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 1), period1, 0, extras2); 172 173 List<PeriodicSync> syncs = engine.getPeriodicSyncs(new EndPoint(account1, authority, 0)); 174 175 assertEquals(2, syncs.size()); 176 177 assertEquals(sync1, syncs.get(0)); 178 assertEquals(sync3, syncs.get(1)); 179 180 engine.removePeriodicSync(new EndPoint(account1, authority, 0), extras1); 181 182 syncs = engine.getPeriodicSyncs(new EndPoint(account1, authority, 0)); 183 assertEquals(1, syncs.size()); 184 assertEquals(sync3, syncs.get(0)); 185 186 syncs = engine.getPeriodicSyncs(new EndPoint(account2, authority, 0)); 187 assertEquals(1, syncs.size()); 188 assertEquals(sync4, syncs.get(0)); 189 190 syncs = engine.getPeriodicSyncs(new EndPoint(sync2.account, sync2.authority, 1)); 191 assertEquals(1, syncs.size()); 192 assertEquals(sync2, syncs.get(0)); 193 } 194 195 /** 196 * Test that we can create, remove and retrieve periodic syncs with a provided flex time. 197 */ 198 @MediumTest 199 public void testPeriodicsV2() throws Exception { 200 final Account account1 = new Account("a@example.com", "example.type"); 201 final Account account2 = new Account("b@example.com", "example.type.2"); 202 final String authority = "testprovider"; 203 final Bundle extras1 = new Bundle(); 204 extras1.putString("a", "1"); 205 final Bundle extras2 = new Bundle(); 206 extras2.putString("a", "2"); 207 final int period1 = 200; 208 final int period2 = 1000; 209 final int flex1 = 10; 210 final int flex2 = 100; 211 EndPoint point1 = new EndPoint(account1, authority, 0); 212 EndPoint point2 = new EndPoint(account2, authority, 0); 213 EndPoint point1User2 = new EndPoint(account1, authority, 1); 214 215 PeriodicSync sync1 = new PeriodicSync(account1, authority, extras1, period1, flex1); 216 PeriodicSync sync2 = new PeriodicSync(account1, authority, extras2, period1, flex1); 217 PeriodicSync sync3 = new PeriodicSync(account1, authority, extras2, period2, flex2); 218 PeriodicSync sync4 = new PeriodicSync(account2, authority, extras2, period2, flex2); 219 220 EndPoint target1 = new EndPoint(account1, authority, 0); 221 EndPoint target2 = new EndPoint(account2, authority, 0); 222 EndPoint target1UserB = new EndPoint(account1, authority, 1); 223 224 MockContentResolver mockResolver = new MockContentResolver(); 225 226 SyncStorageEngine engine = SyncStorageEngine.newTestInstance( 227 new TestContext(mockResolver, getContext())); 228 229 removePeriodicSyncs(engine, account1, 0, authority); 230 removePeriodicSyncs(engine, account2, 0, authority); 231 removePeriodicSyncs(engine, account1, 1, authority); 232 233 // This should add two distinct periodic syncs for account1 and one for account2 234 engine.updateOrAddPeriodicSync(target1, period1, flex1, extras1); 235 engine.updateOrAddPeriodicSync(target1, period1, flex1, extras2); 236 // Edit existing sync and update the period and flex. 237 engine.updateOrAddPeriodicSync(target1, period2, flex2, extras2); 238 engine.updateOrAddPeriodicSync(target2, period2, flex2, extras2); 239 // add a target for a second user. 240 engine.updateOrAddPeriodicSync(target1UserB, period1, flex1, extras2); 241 242 List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1); 243 244 assertEquals(2, syncs.size()); 245 246 assertEquals(sync1, syncs.get(0)); 247 assertEquals(sync3, syncs.get(1)); 248 249 engine.removePeriodicSync(target1, extras1); 250 251 syncs = engine.getPeriodicSyncs(target1); 252 assertEquals(1, syncs.size()); 253 assertEquals(sync3, syncs.get(0)); 254 255 syncs = engine.getPeriodicSyncs(target2); 256 assertEquals(1, syncs.size()); 257 assertEquals(sync4, syncs.get(0)); 258 259 syncs = engine.getPeriodicSyncs(target1UserB); 260 assertEquals(1, syncs.size()); 261 assertEquals(sync2, syncs.get(0)); 262 } 263 264 private void removePeriodicSyncs(SyncStorageEngine engine, Account account, int userId, String authority) { 265 EndPoint target = new EndPoint(account, authority, userId); 266 engine.setIsSyncable(account, userId, authority, engine.getIsSyncable(account, userId, authority)); 267 List<PeriodicSync> syncs = engine.getPeriodicSyncs(target); 268 for (PeriodicSync sync : syncs) { 269 engine.removePeriodicSync(target, sync.extras); 270 } 271 } 272 273 @LargeTest 274 public void testAuthorityPersistence() throws Exception { 275 final Account account1 = new Account("a@example.com", "example.type"); 276 final Account account2 = new Account("b@example.com", "example.type.2"); 277 final String authority1 = "testprovider1"; 278 final String authority2 = "testprovider2"; 279 final Bundle extras1 = new Bundle(); 280 extras1.putString("a", "1"); 281 final Bundle extras2 = new Bundle(); 282 extras2.putString("a", "2"); 283 extras2.putLong("b", 2); 284 extras2.putInt("c", 1); 285 extras2.putBoolean("d", true); 286 extras2.putDouble("e", 1.2); 287 extras2.putFloat("f", 4.5f); 288 extras2.putParcelable("g", account1); 289 final int period1 = 200; 290 final int period2 = 1000; 291 final int flex1 = 10; 292 final int flex2 = 100; 293 294 EndPoint point1 = new EndPoint(account1, authority1, 0); 295 EndPoint point2 = new EndPoint(account1, authority2, 0); 296 EndPoint point3 = new EndPoint(account2, authority1, 0); 297 298 PeriodicSync sync1 = new PeriodicSync(account1, authority1, extras1, period1, flex1); 299 PeriodicSync sync2 = new PeriodicSync(account1, authority1, extras2, period1, flex1); 300 PeriodicSync sync3 = new PeriodicSync(account1, authority2, extras1, period1, flex1); 301 PeriodicSync sync4 = new PeriodicSync(account1, authority2, extras2, period2, flex2); 302 PeriodicSync sync5 = new PeriodicSync(account2, authority1, extras1, period1, flex1); 303 304 EndPoint target1 = new EndPoint(account1, authority1, 0); 305 EndPoint target2 = new EndPoint(account1, authority2, 0); 306 EndPoint target3 = new EndPoint(account2, authority1, 0); 307 308 removePeriodicSyncs(engine, account1, 0, authority1); 309 removePeriodicSyncs(engine, account2, 0, authority1); 310 removePeriodicSyncs(engine, account1, 0, authority2); 311 removePeriodicSyncs(engine, account2, 0, authority2); 312 313 engine.setMasterSyncAutomatically(false, 0); 314 315 engine.setIsSyncable(account1, 0, authority1, 1); 316 engine.setSyncAutomatically(account1, 0, authority1, true); 317 318 engine.setIsSyncable(account2, 0, authority1, 1); 319 engine.setSyncAutomatically(account2, 0, authority1, true); 320 321 engine.setIsSyncable(account1, 0, authority2, 1); 322 engine.setSyncAutomatically(account1, 0, authority2, false); 323 324 engine.setIsSyncable(account2, 0, authority2, 0); 325 engine.setSyncAutomatically(account2, 0, authority2, true); 326 327 engine.updateOrAddPeriodicSync(target1, period1, flex1, extras1); 328 engine.updateOrAddPeriodicSync(target1, period1, flex1, extras2); 329 engine.updateOrAddPeriodicSync(target2, period1, flex1, extras1); 330 engine.updateOrAddPeriodicSync(target2, period2, flex2, extras2); 331 engine.updateOrAddPeriodicSync(target3, period1, flex1, extras1); 332 333 engine.writeAllState(); 334 engine.clearAndReadState(); 335 336 List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1); 337 assertEquals(2, syncs.size()); 338 assertEquals(sync1, syncs.get(0)); 339 assertEquals(sync2, syncs.get(1)); 340 341 syncs = engine.getPeriodicSyncs(target2); 342 assertEquals(2, syncs.size()); 343 assertEquals(sync3, syncs.get(0)); 344 assertEquals(sync4, syncs.get(1)); 345 346 syncs = engine.getPeriodicSyncs(target3); 347 assertEquals(1, syncs.size()); 348 assertEquals(sync5, syncs.get(0)); 349 350 assertEquals(true, engine.getSyncAutomatically(account1, 0, authority1)); 351 assertEquals(true, engine.getSyncAutomatically(account2, 0, authority1)); 352 assertEquals(false, engine.getSyncAutomatically(account1, 0, authority2)); 353 assertEquals(true, engine.getSyncAutomatically(account2, 0, authority2)); 354 355 assertEquals(1, engine.getIsSyncable(account1, 0, authority1)); 356 assertEquals(1, engine.getIsSyncable(account2, 0, authority1)); 357 assertEquals(1, engine.getIsSyncable(account1, 0, authority2)); 358 assertEquals(0, engine.getIsSyncable(account2, 0, authority2)); 359 } 360 361 @SmallTest 362 public void testComponentParsing() throws Exception { 363 // Sync Service component. 364 PeriodicSync sync1 = new PeriodicSync(syncService1, Bundle.EMPTY, dayPoll, dayFuzz); 365 366 byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 367 + "<accounts version=\"2\" >\n" 368 + "<authority id=\"0\" user=\"0\" package=\"" + syncService1.getPackageName() + "\"" 369 + " class=\"" + syncService1.getClassName() + "\" syncable=\"true\">" 370 + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>" 371 + "\n</authority>" 372 + "</accounts>").getBytes(); 373 374 File syncDir = getSyncDir(); 375 syncDir.mkdirs(); 376 AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 377 FileOutputStream fos = accountInfoFile.startWrite(); 378 fos.write(accountsFileData); 379 accountInfoFile.finishWrite(fos); 380 381 engine.clearAndReadState(); 382 383 // Test service component read 384 List<PeriodicSync> syncs = engine.getPeriodicSyncs( 385 new SyncStorageEngine.EndPoint(syncService1, 0)); 386 assertEquals(1, syncs.size()); 387 assertEquals(1, engine.getIsTargetServiceActive(syncService1, 0)); 388 } 389 390 @MediumTest 391 /** 392 * V2 introduces flex time as well as service components. 393 * @throws Exception 394 */ 395 public void testAuthorityParsingV2() throws Exception { 396 final Account account = new Account("account1", "type1"); 397 final String authority1 = "auth1"; 398 final String authority2 = "auth2"; 399 final String authority3 = "auth3"; 400 401 EndPoint target1 = new EndPoint(account, authority1, 0); 402 EndPoint target2 = new EndPoint(account, authority2, 0); 403 EndPoint target3 = new EndPoint(account, authority3, 0); 404 EndPoint target4 = new EndPoint(account, authority3, 1); 405 406 PeriodicSync sync1 = new PeriodicSync(account, authority1, Bundle.EMPTY, dayPoll, dayFuzz); 407 PeriodicSync sync2 = new PeriodicSync(account, authority2, Bundle.EMPTY, dayPoll, dayFuzz); 408 PeriodicSync sync3 = new PeriodicSync(account, authority3, Bundle.EMPTY, dayPoll, dayFuzz); 409 PeriodicSync sync1s = new PeriodicSync(account, authority1, Bundle.EMPTY, thousandSecs, 410 thousandSecsFuzz); 411 PeriodicSync sync2s = new PeriodicSync(account, authority2, Bundle.EMPTY, thousandSecs, 412 thousandSecsFuzz); 413 PeriodicSync sync3s = new PeriodicSync(account, authority3, Bundle.EMPTY, thousandSecs, 414 thousandSecsFuzz); 415 416 byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 417 + "<accounts version=\"2\" >\n" 418 + "<authority id=\"0\" user=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" >" 419 + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>" 420 + "\n</authority>" 421 + "<authority id=\"1\" user=\"0\" account=\"account1\" type=\"type1\" authority=\"auth2\" >" 422 + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>" 423 + "\n</authority>" 424 // No user defaults to user 0 - all users. 425 + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\" >" 426 + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>" 427 + "\n</authority>" 428 + "<authority id=\"3\" user=\"1\" account=\"account1\" type=\"type1\" authority=\"auth3\" >" 429 + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>" 430 + "\n</authority>" 431 + "</accounts>").getBytes(); 432 433 File syncDir = getSyncDir(); 434 syncDir.mkdirs(); 435 AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 436 FileOutputStream fos = accountInfoFile.startWrite(); 437 fos.write(accountsFileData); 438 accountInfoFile.finishWrite(fos); 439 440 engine.clearAndReadState(); 441 442 List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1); 443 assertEquals("Got incorrect # of syncs", 1, syncs.size()); 444 assertEquals(sync1, syncs.get(0)); 445 446 syncs = engine.getPeriodicSyncs(target2); 447 assertEquals(1, syncs.size()); 448 assertEquals(sync2, syncs.get(0)); 449 450 syncs = engine.getPeriodicSyncs(target3); 451 assertEquals(1, syncs.size()); 452 assertEquals(sync3, syncs.get(0)); 453 454 syncs = engine.getPeriodicSyncs(target4); 455 456 assertEquals(1, syncs.size()); 457 assertEquals(sync3, syncs.get(0)); 458 459 // Test empty periodic data. 460 accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 461 + "<accounts version=\"2\">\n" 462 + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n" 463 + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\" />\n" 464 + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\" />\n" 465 + "</accounts>\n").getBytes(); 466 467 accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 468 fos = accountInfoFile.startWrite(); 469 fos.write(accountsFileData); 470 accountInfoFile.finishWrite(fos); 471 472 engine.clearAndReadState(); 473 474 syncs = engine.getPeriodicSyncs(target1); 475 assertEquals(0, syncs.size()); 476 477 syncs = engine.getPeriodicSyncs(target2); 478 assertEquals(0, syncs.size()); 479 480 syncs = engine.getPeriodicSyncs(target3); 481 assertEquals(0, syncs.size()); 482 483 accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 484 + "<accounts version=\"2\">\n" 485 + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\">\n" 486 + "<periodicSync period=\"1000\" />\n" 487 + "</authority>" 488 + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\">\n" 489 + "<periodicSync period=\"1000\" />\n" 490 + "</authority>" 491 + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\">\n" 492 + "<periodicSync period=\"1000\" />\n" 493 + "</authority>" 494 + "</accounts>\n").getBytes(); 495 496 accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 497 fos = accountInfoFile.startWrite(); 498 fos.write(accountsFileData); 499 accountInfoFile.finishWrite(fos); 500 501 engine.clearAndReadState(); 502 503 syncs = engine.getPeriodicSyncs(target1); 504 assertEquals(1, syncs.size()); 505 assertEquals(sync1s, syncs.get(0)); 506 507 syncs = engine.getPeriodicSyncs(target2); 508 assertEquals(1, syncs.size()); 509 assertEquals(sync2s, syncs.get(0)); 510 511 syncs = engine.getPeriodicSyncs(target3); 512 assertEquals(1, syncs.size()); 513 assertEquals(sync3s, syncs.get(0)); 514 } 515 516 @MediumTest 517 public void testAuthorityParsing() throws Exception { 518 final Account account = new Account("account1", "type1"); 519 final String authority1 = "auth1"; 520 final String authority2 = "auth2"; 521 final String authority3 = "auth3"; 522 final Bundle extras = new Bundle(); 523 524 EndPoint target1 = new EndPoint(account, authority1, 0); 525 EndPoint target2 = new EndPoint(account, authority2, 0); 526 EndPoint target3 = new EndPoint(account, authority3, 0); 527 EndPoint target4 = new EndPoint(account, authority3, 1); 528 529 PeriodicSync sync1 = new PeriodicSync(account, authority1, extras, (long) (60 * 60 * 24)); 530 PeriodicSync sync2 = new PeriodicSync(account, authority2, extras, (long) (60 * 60 * 24)); 531 PeriodicSync sync3 = new PeriodicSync(account, authority3, extras, (long) (60 * 60 * 24)); 532 PeriodicSync sync1s = new PeriodicSync(account, authority1, extras, 1000); 533 PeriodicSync sync2s = new PeriodicSync(account, authority2, extras, 1000); 534 PeriodicSync sync3s = new PeriodicSync(account, authority3, extras, 1000); 535 536 MockContentResolver mockResolver = new MockContentResolver(); 537 538 final TestContext testContext = new TestContext(mockResolver, getContext()); 539 540 byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 541 + "<accounts>\n" 542 + "<authority id=\"0\" user=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n" 543 + "<authority id=\"1\" user=\"0\" account=\"account1\" type=\"type1\" authority=\"auth2\" />\n" 544 + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\" />\n" 545 + "<authority id=\"3\" user=\"1\" account=\"account1\" type=\"type1\" authority=\"auth3\" />\n" 546 + "</accounts>\n").getBytes(); 547 548 File syncDir = getSyncDir(); 549 syncDir.mkdirs(); 550 AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 551 FileOutputStream fos = accountInfoFile.startWrite(); 552 fos.write(accountsFileData); 553 accountInfoFile.finishWrite(fos); 554 555 SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext); 556 557 List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1); 558 assertEquals(1, syncs.size()); 559 assertEquals("expected sync1: " + sync1.toString() + " == sync 2" + syncs.get(0).toString(), sync1, syncs.get(0)); 560 561 syncs = engine.getPeriodicSyncs(target2); 562 assertEquals(1, syncs.size()); 563 assertEquals(sync2, syncs.get(0)); 564 565 syncs = engine.getPeriodicSyncs(target3); 566 assertEquals(1, syncs.size()); 567 assertEquals(sync3, syncs.get(0)); 568 syncs = engine.getPeriodicSyncs(target4); 569 570 571 assertEquals(1, syncs.size()); 572 assertEquals(sync3, syncs.get(0)); 573 574 accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 575 + "<accounts version=\"2\">\n" 576 + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n" 577 + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\" />\n" 578 + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\" />\n" 579 + "</accounts>\n").getBytes(); 580 581 accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 582 fos = accountInfoFile.startWrite(); 583 fos.write(accountsFileData); 584 accountInfoFile.finishWrite(fos); 585 586 engine.clearAndReadState(); 587 588 syncs = engine.getPeriodicSyncs(target1); 589 assertEquals(0, syncs.size()); 590 591 syncs = engine.getPeriodicSyncs(target2); 592 assertEquals(0, syncs.size()); 593 594 syncs = engine.getPeriodicSyncs(target3); 595 assertEquals(0, syncs.size()); 596 597 accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 598 + "<accounts version=\"2\">\n" 599 + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\">\n" 600 + "<periodicSync period=\"1000\" />\n" 601 + "</authority>" 602 + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\">\n" 603 + "<periodicSync period=\"1000\" />\n" 604 + "</authority>" 605 + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\">\n" 606 + "<periodicSync period=\"1000\" />\n" 607 + "</authority>" 608 + "</accounts>\n").getBytes(); 609 610 accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 611 fos = accountInfoFile.startWrite(); 612 fos.write(accountsFileData); 613 accountInfoFile.finishWrite(fos); 614 615 engine.clearAndReadState(); 616 617 syncs = engine.getPeriodicSyncs(target1); 618 assertEquals(1, syncs.size()); 619 assertEquals(sync1s, syncs.get(0)); 620 621 syncs = engine.getPeriodicSyncs(target2); 622 assertEquals(1, syncs.size()); 623 assertEquals(sync2s, syncs.get(0)); 624 625 syncs = engine.getPeriodicSyncs(target3); 626 assertEquals(1, syncs.size()); 627 assertEquals(sync3s, syncs.get(0)); 628 } 629 630 @MediumTest 631 public void testListenForTicklesParsing() throws Exception { 632 byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 633 + "<accounts>\n" 634 + "<listenForTickles user=\"0\" enabled=\"false\" />" 635 + "<listenForTickles user=\"1\" enabled=\"true\" />" 636 + "<authority id=\"0\" user=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n" 637 + "<authority id=\"1\" user=\"1\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n" 638 + "</accounts>\n").getBytes(); 639 640 MockContentResolver mockResolver = new MockContentResolver(); 641 final TestContext testContext = new TestContext(mockResolver, getContext()); 642 643 File syncDir = getSyncDir(); 644 syncDir.mkdirs(); 645 AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 646 FileOutputStream fos = accountInfoFile.startWrite(); 647 fos.write(accountsFileData); 648 accountInfoFile.finishWrite(fos); 649 650 SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext); 651 652 assertEquals(false, engine.getMasterSyncAutomatically(0)); 653 assertEquals(true, engine.getMasterSyncAutomatically(1)); 654 assertEquals(true, engine.getMasterSyncAutomatically(2)); 655 656 } 657 658 @MediumTest 659 public void testAuthorityRenaming() throws Exception { 660 final Account account1 = new Account("acc1", "type1"); 661 final Account account2 = new Account("acc2", "type2"); 662 final String authorityContacts = "contacts"; 663 final String authorityCalendar = "calendar"; 664 final String authorityOther = "other"; 665 final String authorityContactsNew = "com.android.contacts"; 666 final String authorityCalendarNew = "com.android.calendar"; 667 668 MockContentResolver mockResolver = new MockContentResolver(); 669 670 final TestContext testContext = new TestContext(mockResolver, getContext()); 671 672 byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 673 + "<accounts>\n" 674 + "<authority id=\"0\" account=\"acc1\" type=\"type1\" authority=\"contacts\" />\n" 675 + "<authority id=\"1\" account=\"acc1\" type=\"type1\" authority=\"calendar\" />\n" 676 + "<authority id=\"2\" account=\"acc1\" type=\"type1\" authority=\"other\" />\n" 677 + "<authority id=\"3\" account=\"acc2\" type=\"type2\" authority=\"contacts\" />\n" 678 + "<authority id=\"4\" account=\"acc2\" type=\"type2\" authority=\"calendar\" />\n" 679 + "<authority id=\"5\" account=\"acc2\" type=\"type2\" authority=\"other\" />\n" 680 + "<authority id=\"6\" account=\"acc2\" type=\"type2\" enabled=\"false\"" 681 + " authority=\"com.android.calendar\" />\n" 682 + "<authority id=\"7\" account=\"acc2\" type=\"type2\" enabled=\"false\"" 683 + " authority=\"com.android.contacts\" />\n" 684 + "</accounts>\n").getBytes(); 685 686 File syncDir = new File(new File(testContext.getFilesDir(), "system"), "sync"); 687 syncDir.mkdirs(); 688 AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 689 FileOutputStream fos = accountInfoFile.startWrite(); 690 fos.write(accountsFileData); 691 accountInfoFile.finishWrite(fos); 692 693 SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext); 694 695 assertEquals(false, engine.getSyncAutomatically(account1, 0, authorityContacts)); 696 assertEquals(false, engine.getSyncAutomatically(account1, 0, authorityCalendar)); 697 assertEquals(true, engine.getSyncAutomatically(account1, 0, authorityOther)); 698 assertEquals(true, engine.getSyncAutomatically(account1, 0, authorityContactsNew)); 699 assertEquals(true, engine.getSyncAutomatically(account1, 0, authorityCalendarNew)); 700 701 assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityContacts)); 702 assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityCalendar)); 703 assertEquals(true, engine.getSyncAutomatically(account2, 0, authorityOther)); 704 assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityContactsNew)); 705 assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityCalendarNew)); 706 } 707 708 @SmallTest 709 public void testSyncableMigration() throws Exception { 710 final Account account = new Account("acc", "type"); 711 712 MockContentResolver mockResolver = new MockContentResolver(); 713 714 final TestContext testContext = new TestContext(mockResolver, getContext()); 715 716 byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 717 + "<accounts>\n" 718 + "<authority id=\"0\" account=\"acc\" authority=\"other1\" />\n" 719 + "<authority id=\"1\" account=\"acc\" type=\"type\" authority=\"other2\" />\n" 720 + "<authority id=\"2\" account=\"acc\" type=\"type\" syncable=\"false\"" 721 + " authority=\"other3\" />\n" 722 + "<authority id=\"3\" account=\"acc\" type=\"type\" syncable=\"true\"" 723 + " authority=\"other4\" />\n" 724 + "</accounts>\n").getBytes(); 725 726 File syncDir = new File(new File(testContext.getFilesDir(), "system"), "sync"); 727 syncDir.mkdirs(); 728 AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 729 FileOutputStream fos = accountInfoFile.startWrite(); 730 fos.write(accountsFileData); 731 accountInfoFile.finishWrite(fos); 732 733 SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext); 734 735 assertEquals(-1, engine.getIsSyncable(account, 0, "other1")); 736 assertEquals(1, engine.getIsSyncable(account, 0, "other2")); 737 assertEquals(0, engine.getIsSyncable(account, 0, "other3")); 738 assertEquals(1, engine.getIsSyncable(account, 0, "other4")); 739 } 740} 741 742class TestContext extends ContextWrapper { 743 744 ContentResolver mResolver; 745 746 private final Context mRealContext; 747 748 public TestContext(ContentResolver resolver, Context realContext) { 749 super(new RenamingDelegatingContext(new MockContext(), realContext, "test.")); 750 mRealContext = realContext; 751 mResolver = resolver; 752 } 753 754 @Override 755 public Resources getResources() { 756 return mRealContext.getResources(); 757 } 758 759 @Override 760 public File getFilesDir() { 761 return mRealContext.getFilesDir(); 762 } 763 764 @Override 765 public void enforceCallingOrSelfPermission(String permission, String message) { 766 } 767 768 @Override 769 public void sendBroadcast(Intent intent) { 770 } 771 772 @Override 773 public ContentResolver getContentResolver() { 774 return mResolver; 775 } 776} 777