SyncStorageEngineTest.java revision 8ef2204c8f5f9744a2ff7abdbbf2d26a5ea02837
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 assertTrue(engine.getPendingOperationCount() == 1); 124 List<SyncStorageEngine.PendingOperation> pops = engine.getPendingOperations(); 125 SyncStorageEngine.PendingOperation popRetrieved = pops.get(0); 126 assertEquals(sop.target.account, popRetrieved.target.account); 127 assertEquals(sop.target.provider, popRetrieved.target.provider); 128 assertEquals(sop.target.service, popRetrieved.target.service); 129 assertEquals(sop.target.userId, popRetrieved.target.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 364 byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 365 + "<accounts version=\"2\" >\n" 366 + "<authority id=\"0\" user=\"0\" package=\"" + syncService1.getPackageName() + "\"" 367 + " class=\"" + syncService1.getClassName() + "\" syncable=\"true\">" 368 + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>" 369 + "\n</authority>" 370 + "</accounts>").getBytes(); 371 372 File syncDir = getSyncDir(); 373 syncDir.mkdirs(); 374 AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 375 FileOutputStream fos = accountInfoFile.startWrite(); 376 fos.write(accountsFileData); 377 accountInfoFile.finishWrite(fos); 378 379 engine.clearAndReadState(); 380 381 SyncStorageEngine.AuthorityInfo aInfo = engine.getAuthority(0); 382 assertNotNull(aInfo); 383 384 // Test service component read 385 List<PeriodicSync> syncs = engine.getPeriodicSyncs( 386 new SyncStorageEngine.EndPoint(syncService1, 0)); 387 assertEquals(1, syncs.size()); 388 assertEquals(true, engine.getIsTargetServiceActive(syncService1, 0)); 389 } 390 391 @SmallTest 392 public void testComponentSettings() throws Exception { 393 EndPoint target1 = new EndPoint(syncService1, 0); 394 engine.updateOrAddPeriodicSync(target1, dayPoll, dayFuzz, Bundle.EMPTY); 395 396 engine.setIsTargetServiceActive(target1.service, 0, true); 397 boolean active = engine.getIsTargetServiceActive(target1.service, 0); 398 assert(active); 399 400 engine.setIsTargetServiceActive(target1.service, 1, false); 401 active = engine.getIsTargetServiceActive(target1.service, 1); 402 assert(!active); 403 } 404 405 @MediumTest 406 /** 407 * V2 introduces flex time as well as service components. 408 * @throws Exception 409 */ 410 public void testAuthorityParsingV2() throws Exception { 411 final Account account = new Account("account1", "type1"); 412 final String authority1 = "auth1"; 413 final String authority2 = "auth2"; 414 final String authority3 = "auth3"; 415 416 EndPoint target1 = new EndPoint(account, authority1, 0); 417 EndPoint target2 = new EndPoint(account, authority2, 0); 418 EndPoint target3 = new EndPoint(account, authority3, 0); 419 EndPoint target4 = new EndPoint(account, authority3, 1); 420 421 PeriodicSync sync1 = new PeriodicSync(account, authority1, Bundle.EMPTY, dayPoll, dayFuzz); 422 PeriodicSync sync2 = new PeriodicSync(account, authority2, Bundle.EMPTY, dayPoll, dayFuzz); 423 PeriodicSync sync3 = new PeriodicSync(account, authority3, Bundle.EMPTY, dayPoll, dayFuzz); 424 PeriodicSync sync1s = new PeriodicSync(account, authority1, Bundle.EMPTY, thousandSecs, 425 thousandSecsFuzz); 426 PeriodicSync sync2s = new PeriodicSync(account, authority2, Bundle.EMPTY, thousandSecs, 427 thousandSecsFuzz); 428 PeriodicSync sync3s = new PeriodicSync(account, authority3, Bundle.EMPTY, thousandSecs, 429 thousandSecsFuzz); 430 431 byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 432 + "<accounts version=\"2\" >\n" 433 + "<authority id=\"0\" user=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" >" 434 + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>" 435 + "\n</authority>" 436 + "<authority id=\"1\" user=\"0\" account=\"account1\" type=\"type1\" authority=\"auth2\" >" 437 + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>" 438 + "\n</authority>" 439 // No user defaults to user 0 - all users. 440 + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\" >" 441 + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>" 442 + "\n</authority>" 443 + "<authority id=\"3\" user=\"1\" account=\"account1\" type=\"type1\" authority=\"auth3\" >" 444 + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>" 445 + "\n</authority>" 446 + "</accounts>").getBytes(); 447 448 File syncDir = getSyncDir(); 449 syncDir.mkdirs(); 450 AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 451 FileOutputStream fos = accountInfoFile.startWrite(); 452 fos.write(accountsFileData); 453 accountInfoFile.finishWrite(fos); 454 455 engine.clearAndReadState(); 456 457 List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1); 458 assertEquals("Got incorrect # of syncs", 1, syncs.size()); 459 assertEquals(sync1, syncs.get(0)); 460 461 syncs = engine.getPeriodicSyncs(target2); 462 assertEquals(1, syncs.size()); 463 assertEquals(sync2, syncs.get(0)); 464 465 syncs = engine.getPeriodicSyncs(target3); 466 assertEquals(1, syncs.size()); 467 assertEquals(sync3, syncs.get(0)); 468 469 syncs = engine.getPeriodicSyncs(target4); 470 471 assertEquals(1, syncs.size()); 472 assertEquals(sync3, syncs.get(0)); 473 474 // Test empty periodic data. 475 accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 476 + "<accounts version=\"2\">\n" 477 + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n" 478 + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\" />\n" 479 + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\" />\n" 480 + "</accounts>\n").getBytes(); 481 482 accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 483 fos = accountInfoFile.startWrite(); 484 fos.write(accountsFileData); 485 accountInfoFile.finishWrite(fos); 486 487 engine.clearAndReadState(); 488 489 syncs = engine.getPeriodicSyncs(target1); 490 assertEquals(0, syncs.size()); 491 492 syncs = engine.getPeriodicSyncs(target2); 493 assertEquals(0, syncs.size()); 494 495 syncs = engine.getPeriodicSyncs(target3); 496 assertEquals(0, syncs.size()); 497 498 accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 499 + "<accounts version=\"2\">\n" 500 + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\">\n" 501 + "<periodicSync period=\"1000\" />\n" 502 + "</authority>" 503 + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\">\n" 504 + "<periodicSync period=\"1000\" />\n" 505 + "</authority>" 506 + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\">\n" 507 + "<periodicSync period=\"1000\" />\n" 508 + "</authority>" 509 + "</accounts>\n").getBytes(); 510 511 accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 512 fos = accountInfoFile.startWrite(); 513 fos.write(accountsFileData); 514 accountInfoFile.finishWrite(fos); 515 516 engine.clearAndReadState(); 517 518 syncs = engine.getPeriodicSyncs(target1); 519 assertEquals(1, syncs.size()); 520 assertEquals(sync1s, syncs.get(0)); 521 522 syncs = engine.getPeriodicSyncs(target2); 523 assertEquals(1, syncs.size()); 524 assertEquals(sync2s, syncs.get(0)); 525 526 syncs = engine.getPeriodicSyncs(target3); 527 assertEquals(1, syncs.size()); 528 assertEquals(sync3s, syncs.get(0)); 529 } 530 531 @MediumTest 532 public void testAuthorityParsing() throws Exception { 533 final Account account = new Account("account1", "type1"); 534 final String authority1 = "auth1"; 535 final String authority2 = "auth2"; 536 final String authority3 = "auth3"; 537 final Bundle extras = new Bundle(); 538 539 EndPoint target1 = new EndPoint(account, authority1, 0); 540 EndPoint target2 = new EndPoint(account, authority2, 0); 541 EndPoint target3 = new EndPoint(account, authority3, 0); 542 EndPoint target4 = new EndPoint(account, authority3, 1); 543 544 PeriodicSync sync1 = new PeriodicSync(account, authority1, extras, (long) (60 * 60 * 24)); 545 PeriodicSync sync2 = new PeriodicSync(account, authority2, extras, (long) (60 * 60 * 24)); 546 PeriodicSync sync3 = new PeriodicSync(account, authority3, extras, (long) (60 * 60 * 24)); 547 PeriodicSync sync1s = new PeriodicSync(account, authority1, extras, 1000); 548 PeriodicSync sync2s = new PeriodicSync(account, authority2, extras, 1000); 549 PeriodicSync sync3s = new PeriodicSync(account, authority3, extras, 1000); 550 551 MockContentResolver mockResolver = new MockContentResolver(); 552 553 final TestContext testContext = new TestContext(mockResolver, getContext()); 554 555 byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 556 + "<accounts>\n" 557 + "<authority id=\"0\" user=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n" 558 + "<authority id=\"1\" user=\"0\" account=\"account1\" type=\"type1\" authority=\"auth2\" />\n" 559 + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\" />\n" 560 + "<authority id=\"3\" user=\"1\" account=\"account1\" type=\"type1\" authority=\"auth3\" />\n" 561 + "</accounts>\n").getBytes(); 562 563 File syncDir = getSyncDir(); 564 syncDir.mkdirs(); 565 AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 566 FileOutputStream fos = accountInfoFile.startWrite(); 567 fos.write(accountsFileData); 568 accountInfoFile.finishWrite(fos); 569 570 SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext); 571 572 List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1); 573 assertEquals(1, syncs.size()); 574 assertEquals("expected sync1: " + sync1.toString() + " == sync 2" + syncs.get(0).toString(), sync1, syncs.get(0)); 575 576 syncs = engine.getPeriodicSyncs(target2); 577 assertEquals(1, syncs.size()); 578 assertEquals(sync2, syncs.get(0)); 579 580 syncs = engine.getPeriodicSyncs(target3); 581 assertEquals(1, syncs.size()); 582 assertEquals(sync3, syncs.get(0)); 583 syncs = engine.getPeriodicSyncs(target4); 584 585 586 assertEquals(1, syncs.size()); 587 assertEquals(sync3, syncs.get(0)); 588 589 accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 590 + "<accounts version=\"2\">\n" 591 + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n" 592 + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\" />\n" 593 + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\" />\n" 594 + "</accounts>\n").getBytes(); 595 596 accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 597 fos = accountInfoFile.startWrite(); 598 fos.write(accountsFileData); 599 accountInfoFile.finishWrite(fos); 600 601 engine.clearAndReadState(); 602 603 syncs = engine.getPeriodicSyncs(target1); 604 assertEquals(0, syncs.size()); 605 606 syncs = engine.getPeriodicSyncs(target2); 607 assertEquals(0, syncs.size()); 608 609 syncs = engine.getPeriodicSyncs(target3); 610 assertEquals(0, syncs.size()); 611 612 accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 613 + "<accounts version=\"2\">\n" 614 + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\">\n" 615 + "<periodicSync period=\"1000\" />\n" 616 + "</authority>" 617 + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\">\n" 618 + "<periodicSync period=\"1000\" />\n" 619 + "</authority>" 620 + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\">\n" 621 + "<periodicSync period=\"1000\" />\n" 622 + "</authority>" 623 + "</accounts>\n").getBytes(); 624 625 accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 626 fos = accountInfoFile.startWrite(); 627 fos.write(accountsFileData); 628 accountInfoFile.finishWrite(fos); 629 630 engine.clearAndReadState(); 631 632 syncs = engine.getPeriodicSyncs(target1); 633 assertEquals(1, syncs.size()); 634 assertEquals(sync1s, syncs.get(0)); 635 636 syncs = engine.getPeriodicSyncs(target2); 637 assertEquals(1, syncs.size()); 638 assertEquals(sync2s, syncs.get(0)); 639 640 syncs = engine.getPeriodicSyncs(target3); 641 assertEquals(1, syncs.size()); 642 assertEquals(sync3s, syncs.get(0)); 643 } 644 645 @MediumTest 646 public void testListenForTicklesParsing() throws Exception { 647 byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 648 + "<accounts>\n" 649 + "<listenForTickles user=\"0\" enabled=\"false\" />" 650 + "<listenForTickles user=\"1\" enabled=\"true\" />" 651 + "<authority id=\"0\" user=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n" 652 + "<authority id=\"1\" user=\"1\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n" 653 + "</accounts>\n").getBytes(); 654 655 MockContentResolver mockResolver = new MockContentResolver(); 656 final TestContext testContext = new TestContext(mockResolver, getContext()); 657 658 File syncDir = getSyncDir(); 659 syncDir.mkdirs(); 660 AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 661 FileOutputStream fos = accountInfoFile.startWrite(); 662 fos.write(accountsFileData); 663 accountInfoFile.finishWrite(fos); 664 665 SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext); 666 667 assertEquals(false, engine.getMasterSyncAutomatically(0)); 668 assertEquals(true, engine.getMasterSyncAutomatically(1)); 669 assertEquals(true, engine.getMasterSyncAutomatically(2)); 670 671 } 672 673 @MediumTest 674 public void testAuthorityRenaming() throws Exception { 675 final Account account1 = new Account("acc1", "type1"); 676 final Account account2 = new Account("acc2", "type2"); 677 final String authorityContacts = "contacts"; 678 final String authorityCalendar = "calendar"; 679 final String authorityOther = "other"; 680 final String authorityContactsNew = "com.android.contacts"; 681 final String authorityCalendarNew = "com.android.calendar"; 682 683 MockContentResolver mockResolver = new MockContentResolver(); 684 685 final TestContext testContext = new TestContext(mockResolver, getContext()); 686 687 byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 688 + "<accounts>\n" 689 + "<authority id=\"0\" account=\"acc1\" type=\"type1\" authority=\"contacts\" />\n" 690 + "<authority id=\"1\" account=\"acc1\" type=\"type1\" authority=\"calendar\" />\n" 691 + "<authority id=\"2\" account=\"acc1\" type=\"type1\" authority=\"other\" />\n" 692 + "<authority id=\"3\" account=\"acc2\" type=\"type2\" authority=\"contacts\" />\n" 693 + "<authority id=\"4\" account=\"acc2\" type=\"type2\" authority=\"calendar\" />\n" 694 + "<authority id=\"5\" account=\"acc2\" type=\"type2\" authority=\"other\" />\n" 695 + "<authority id=\"6\" account=\"acc2\" type=\"type2\" enabled=\"false\"" 696 + " authority=\"com.android.calendar\" />\n" 697 + "<authority id=\"7\" account=\"acc2\" type=\"type2\" enabled=\"false\"" 698 + " authority=\"com.android.contacts\" />\n" 699 + "</accounts>\n").getBytes(); 700 701 File syncDir = new File(new File(testContext.getFilesDir(), "system"), "sync"); 702 syncDir.mkdirs(); 703 AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 704 FileOutputStream fos = accountInfoFile.startWrite(); 705 fos.write(accountsFileData); 706 accountInfoFile.finishWrite(fos); 707 708 SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext); 709 710 assertEquals(false, engine.getSyncAutomatically(account1, 0, authorityContacts)); 711 assertEquals(false, engine.getSyncAutomatically(account1, 0, authorityCalendar)); 712 assertEquals(true, engine.getSyncAutomatically(account1, 0, authorityOther)); 713 assertEquals(true, engine.getSyncAutomatically(account1, 0, authorityContactsNew)); 714 assertEquals(true, engine.getSyncAutomatically(account1, 0, authorityCalendarNew)); 715 716 assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityContacts)); 717 assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityCalendar)); 718 assertEquals(true, engine.getSyncAutomatically(account2, 0, authorityOther)); 719 assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityContactsNew)); 720 assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityCalendarNew)); 721 } 722 723 @SmallTest 724 public void testSyncableMigration() throws Exception { 725 final Account account = new Account("acc", "type"); 726 727 MockContentResolver mockResolver = new MockContentResolver(); 728 729 final TestContext testContext = new TestContext(mockResolver, getContext()); 730 731 byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 732 + "<accounts>\n" 733 + "<authority id=\"0\" account=\"acc\" authority=\"other1\" />\n" 734 + "<authority id=\"1\" account=\"acc\" type=\"type\" authority=\"other2\" />\n" 735 + "<authority id=\"2\" account=\"acc\" type=\"type\" syncable=\"false\"" 736 + " authority=\"other3\" />\n" 737 + "<authority id=\"3\" account=\"acc\" type=\"type\" syncable=\"true\"" 738 + " authority=\"other4\" />\n" 739 + "</accounts>\n").getBytes(); 740 741 File syncDir = new File(new File(testContext.getFilesDir(), "system"), "sync"); 742 syncDir.mkdirs(); 743 AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); 744 FileOutputStream fos = accountInfoFile.startWrite(); 745 fos.write(accountsFileData); 746 accountInfoFile.finishWrite(fos); 747 748 SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext); 749 750 assertEquals(-1, engine.getIsSyncable(account, 0, "other1")); 751 assertEquals(1, engine.getIsSyncable(account, 0, "other2")); 752 assertEquals(0, engine.getIsSyncable(account, 0, "other3")); 753 assertEquals(1, engine.getIsSyncable(account, 0, "other4")); 754 } 755} 756 757class TestContext extends ContextWrapper { 758 759 ContentResolver mResolver; 760 761 private final Context mRealContext; 762 763 public TestContext(ContentResolver resolver, Context realContext) { 764 super(new RenamingDelegatingContext(new MockContext(), realContext, "test.")); 765 mRealContext = realContext; 766 mResolver = resolver; 767 } 768 769 @Override 770 public Resources getResources() { 771 return mRealContext.getResources(); 772 } 773 774 @Override 775 public File getFilesDir() { 776 return mRealContext.getFilesDir(); 777 } 778 779 @Override 780 public void enforceCallingOrSelfPermission(String permission, String message) { 781 } 782 783 @Override 784 public void sendBroadcast(Intent intent) { 785 } 786 787 @Override 788 public ContentResolver getContentResolver() { 789 return mResolver; 790 } 791} 792