@Test public void testGenerateNewMetaGlobalNonePersisted() throws Exception { final MockGlobalSessionCallback callback = new MockGlobalSessionCallback(); final GlobalSession session = MockPrefsGlobalSession.getSession( TEST_USERNAME, TEST_PASSWORD, new KeyBundle(TEST_USERNAME, TEST_SYNC_KEY), callback, null, null); // Verify we fill in all of our known engines when none are persisted. session.config.enabledEngineNames = null; MetaGlobal mg = session.generateNewMetaGlobal(); assertEquals(Long.valueOf(GlobalSession.STORAGE_VERSION), mg.getStorageVersion()); assertEquals( VersionConstants.BOOKMARKS_ENGINE_VERSION, mg.getEngines().getObject("bookmarks").getIntegerSafely("version").intValue()); assertEquals( VersionConstants.CLIENTS_ENGINE_VERSION, mg.getEngines().getObject("clients").getIntegerSafely("version").intValue()); List<String> namesList = new ArrayList<String>(mg.getEnabledEngineNames()); Collections.sort(namesList); String[] names = namesList.toArray(new String[namesList.size()]); String[] expected = new String[] {"bookmarks", "clients", "forms", "history", "passwords", "tabs"}; assertArrayEquals(expected, names); }
@Test public void testUploadUpdatedMetaGlobal() throws Exception { // Set up session with meta/global. final MockGlobalSessionCallback callback = new MockGlobalSessionCallback(); final GlobalSession session = MockPrefsGlobalSession.getSession( TEST_USERNAME, TEST_PASSWORD, new KeyBundle(TEST_USERNAME, TEST_SYNC_KEY), callback, null, null); session.config.metaGlobal = session.generateNewMetaGlobal(); session.enginesToUpdate.clear(); // Set enabledEngines in meta/global, including a "new engine." String[] origEngines = new String[] {"bookmarks", "clients", "forms", "history", "tabs", "new-engine"}; ExtendedJSONObject origEnginesJSONObject = new ExtendedJSONObject(); for (String engineName : origEngines) { EngineSettings mockEngineSettings = new EngineSettings(Utils.generateGuid(), Integer.valueOf(0)); origEnginesJSONObject.put(engineName, mockEngineSettings); } session.config.metaGlobal.setEngines(origEnginesJSONObject); // Engines to remove. String[] toRemove = new String[] {"bookmarks", "tabs"}; for (String name : toRemove) { session.removeEngineFromMetaGlobal(name); } // Engines to add. String[] toAdd = new String[] {"passwords"}; for (String name : toAdd) { String syncId = Utils.generateGuid(); session.recordForMetaGlobalUpdate(name, new EngineSettings(syncId, Integer.valueOf(1))); } // Update engines. session.uploadUpdatedMetaGlobal(); // Check resulting enabledEngines. Set<String> expected = new HashSet<String>(); for (String name : origEngines) { expected.add(name); } for (String name : toRemove) { expected.remove(name); } for (String name : toAdd) { expected.add(name); } assertEquals(expected, session.config.metaGlobal.getEnabledEngineNames()); }
/** * Clean the server, aborting the current sync. * * <p> * * <ol> * <li>Wipe the server storage. * <li>Reset all stages and purge cached state: (meta/global and crypto/keys records). * <li>Upload fresh meta/global record. * <li>Upload fresh crypto/keys record. * <li>Restart the sync entirely in order to re-download meta/global and crypto/keys record. * </ol> * * @param session the current session. * @param freshStartDelegate delegate to notify on fresh start or failure. */ protected static void freshStart( final GlobalSession session, final FreshStartDelegate freshStartDelegate) { Logger.debug(LOG_TAG, "Fresh starting."); final MetaGlobal mg = session.generateNewMetaGlobal(); session.wipeServer( session.getAuthHeaderProvider(), new WipeServerDelegate() { @Override public void onWiped(long timestamp) { Logger.debug( LOG_TAG, "Successfully wiped server. Resetting all stages and purging cached meta/global and crypto/keys records."); session.resetAllStages(); session.config.purgeMetaGlobal(); session.config.purgeCryptoKeys(); session.config.persistToPrefs(); Logger.info(LOG_TAG, "Uploading new meta/global with sync ID " + mg.syncID + "."); // It would be good to set the X-If-Unmodified-Since header to `timestamp` // for this PUT to ensure at least some level of transactionality. // Unfortunately, the servers don't support it after a wipe right now // (bug 693893), so we're going to defer this until bug 692700. mg.upload( new MetaGlobalDelegate() { @Override public void handleSuccess( MetaGlobal uploadedGlobal, SyncStorageResponse uploadResponse) { Logger.info( LOG_TAG, "Uploaded new meta/global with sync ID " + uploadedGlobal.syncID + "."); // Generate new keys. CollectionKeys keys = null; try { keys = session.generateNewCryptoKeys(); } catch (CryptoException e) { Logger.warn( LOG_TAG, "Got exception generating new keys; failing fresh start.", e); freshStartDelegate.onFreshStartFailed(e); } if (keys == null) { Logger.warn( LOG_TAG, "Got null keys from generateNewKeys; failing fresh start."); freshStartDelegate.onFreshStartFailed(null); } // Upload new keys. Logger.info(LOG_TAG, "Uploading new crypto/keys."); session.uploadKeys( keys, new KeyUploadDelegate() { @Override public void onKeysUploaded() { Logger.info(LOG_TAG, "Uploaded new crypto/keys."); freshStartDelegate.onFreshStart(); } @Override public void onKeyUploadFailed(Exception e) { Logger.warn(LOG_TAG, "Got exception uploading new keys.", e); freshStartDelegate.onFreshStartFailed(e); } }); } @Override public void handleMissing(MetaGlobal global, SyncStorageResponse response) { // Shouldn't happen on upload. Logger.warn(LOG_TAG, "Got 'missing' response uploading new meta/global."); freshStartDelegate.onFreshStartFailed( new Exception("meta/global missing while uploading.")); } @Override public void handleFailure(SyncStorageResponse response) { Logger.warn( LOG_TAG, "Got failure " + response.getStatusCode() + " uploading new meta/global."); session.interpretHTTPFailure(response.httpResponse()); freshStartDelegate.onFreshStartFailed(new HTTPFailureException(response)); } @Override public void handleError(Exception e) { Logger.warn(LOG_TAG, "Got error uploading new meta/global.", e); freshStartDelegate.onFreshStartFailed(e); } }); } @Override public void onWipeFailed(Exception e) { Logger.warn(LOG_TAG, "Wipe failed."); freshStartDelegate.onFreshStartFailed(e); } }); }