mobile/android/tests/background/junit3/src/sync/TestResetting.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 package org.mozilla.gecko.background.sync;
michael@0 5
michael@0 6 import java.io.IOException;
michael@0 7
michael@0 8 import org.json.simple.parser.ParseException;
michael@0 9 import org.mozilla.gecko.background.helpers.AndroidSyncTestCase;
michael@0 10 import org.mozilla.gecko.background.testhelpers.BaseMockServerSyncStage;
michael@0 11 import org.mozilla.gecko.background.testhelpers.DefaultGlobalSessionCallback;
michael@0 12 import org.mozilla.gecko.background.testhelpers.MockRecord;
michael@0 13 import org.mozilla.gecko.background.testhelpers.MockSharedPreferences;
michael@0 14 import org.mozilla.gecko.background.testhelpers.WBORepository;
michael@0 15 import org.mozilla.gecko.background.testhelpers.WaitHelper;
michael@0 16 import org.mozilla.gecko.sync.EngineSettings;
michael@0 17 import org.mozilla.gecko.sync.GlobalSession;
michael@0 18 import org.mozilla.gecko.sync.MetaGlobalException;
michael@0 19 import org.mozilla.gecko.sync.NonObjectJSONException;
michael@0 20 import org.mozilla.gecko.sync.SyncConfiguration;
michael@0 21 import org.mozilla.gecko.sync.SyncConfigurationException;
michael@0 22 import org.mozilla.gecko.sync.SynchronizerConfiguration;
michael@0 23 import org.mozilla.gecko.sync.crypto.CryptoException;
michael@0 24 import org.mozilla.gecko.sync.crypto.KeyBundle;
michael@0 25 import org.mozilla.gecko.sync.delegates.GlobalSessionCallback;
michael@0 26 import org.mozilla.gecko.sync.net.AuthHeaderProvider;
michael@0 27 import org.mozilla.gecko.sync.net.BasicAuthHeaderProvider;
michael@0 28 import org.mozilla.gecko.sync.repositories.domain.Record;
michael@0 29 import org.mozilla.gecko.sync.stage.NoSuchStageException;
michael@0 30 import org.mozilla.gecko.sync.synchronizer.Synchronizer;
michael@0 31
michael@0 32 import android.content.SharedPreferences;
michael@0 33
michael@0 34 /**
michael@0 35 * Test the on-device side effects of reset operations on a stage.
michael@0 36 *
michael@0 37 * See also "TestResetCommands" in the unit test suite.
michael@0 38 */
michael@0 39 public class TestResetting extends AndroidSyncTestCase {
michael@0 40 private static final String TEST_USERNAME = "johndoe";
michael@0 41 private static final String TEST_PASSWORD = "password";
michael@0 42 private static final String TEST_SYNC_KEY = "abcdeabcdeabcdeabcdeabcdea";
michael@0 43
michael@0 44 @Override
michael@0 45 public void setUp() {
michael@0 46 assertTrue(WaitHelper.getTestWaiter().isIdle());
michael@0 47 }
michael@0 48
michael@0 49 /**
michael@0 50 * Set up a mock stage that synchronizes two mock repositories. Apply various
michael@0 51 * reset/sync/wipe permutations and check state.
michael@0 52 */
michael@0 53 public void testResetAndWipeStage() throws Exception {
michael@0 54
michael@0 55 final long startTime = System.currentTimeMillis();
michael@0 56 final GlobalSessionCallback callback = createGlobalSessionCallback();
michael@0 57 final GlobalSession session = createDefaultGlobalSession(callback);
michael@0 58
michael@0 59 final ExecutableMockServerSyncStage stage = new ExecutableMockServerSyncStage() {
michael@0 60 @Override
michael@0 61 public void onSynchronized(Synchronizer synchronizer) {
michael@0 62 try {
michael@0 63 assertTrue(startTime <= synchronizer.bundleA.getTimestamp());
michael@0 64 assertTrue(startTime <= synchronizer.bundleB.getTimestamp());
michael@0 65
michael@0 66 // Call up to allow the usual persistence etc. to happen.
michael@0 67 super.onSynchronized(synchronizer);
michael@0 68 } catch (Throwable e) {
michael@0 69 performNotify(e);
michael@0 70 return;
michael@0 71 }
michael@0 72 performNotify();
michael@0 73 }
michael@0 74 };
michael@0 75
michael@0 76 final boolean bumpTimestamps = true;
michael@0 77 WBORepository local = new WBORepository(bumpTimestamps);
michael@0 78 WBORepository remote = new WBORepository(bumpTimestamps);
michael@0 79
michael@0 80 stage.name = "mock";
michael@0 81 stage.collection = "mock";
michael@0 82 stage.local = local;
michael@0 83 stage.remote = remote;
michael@0 84
michael@0 85 stage.executeSynchronously(session);
michael@0 86
michael@0 87 // Verify the persisted values.
michael@0 88 assertConfigTimestampsGreaterThan(stage.leakConfig(), startTime, startTime);
michael@0 89
michael@0 90 // Reset.
michael@0 91 stage.resetLocal(session);
michael@0 92
michael@0 93 // Verify that they're gone.
michael@0 94 assertConfigTimestampsEqual(stage.leakConfig(), 0, 0);
michael@0 95
michael@0 96 // Now sync data, ensure that timestamps come back.
michael@0 97 final long afterReset = System.currentTimeMillis();
michael@0 98 final String recordGUID = "abcdefghijkl";
michael@0 99 local.wbos.put(recordGUID, new MockRecord(recordGUID, "mock", startTime, false));
michael@0 100
michael@0 101 // Sync again with data and verify timestamps and data.
michael@0 102 stage.executeSynchronously(session);
michael@0 103
michael@0 104 assertConfigTimestampsGreaterThan(stage.leakConfig(), afterReset, afterReset);
michael@0 105 assertEquals(1, remote.wbos.size());
michael@0 106 assertEquals(1, local.wbos.size());
michael@0 107
michael@0 108 Record remoteRecord = remote.wbos.get(recordGUID);
michael@0 109 assertNotNull(remoteRecord);
michael@0 110 assertNotNull(local.wbos.get(recordGUID));
michael@0 111 assertEquals(recordGUID, remoteRecord.guid);
michael@0 112 assertTrue(afterReset <= remoteRecord.lastModified);
michael@0 113
michael@0 114 // Reset doesn't clear data.
michael@0 115 stage.resetLocal(session);
michael@0 116 assertConfigTimestampsEqual(stage.leakConfig(), 0, 0);
michael@0 117 assertEquals(1, remote.wbos.size());
michael@0 118 assertEquals(1, local.wbos.size());
michael@0 119 remoteRecord = remote.wbos.get(recordGUID);
michael@0 120 assertNotNull(remoteRecord);
michael@0 121 assertNotNull(local.wbos.get(recordGUID));
michael@0 122
michael@0 123 // Wipe does. Recover from reset...
michael@0 124 final long beforeWipe = System.currentTimeMillis();
michael@0 125 stage.executeSynchronously(session);
michael@0 126 assertEquals(1, remote.wbos.size());
michael@0 127 assertEquals(1, local.wbos.size());
michael@0 128 assertConfigTimestampsGreaterThan(stage.leakConfig(), beforeWipe, beforeWipe);
michael@0 129
michael@0 130 // ... then wipe.
michael@0 131 stage.wipeLocal(session);
michael@0 132 assertConfigTimestampsEqual(stage.leakConfig(), 0, 0);
michael@0 133 assertEquals(1, remote.wbos.size()); // We don't wipe the server.
michael@0 134 assertEquals(0, local.wbos.size()); // We do wipe local.
michael@0 135 }
michael@0 136
michael@0 137 /**
michael@0 138 * A stage that joins two Repositories with no wrapping.
michael@0 139 */
michael@0 140 public class ExecutableMockServerSyncStage extends BaseMockServerSyncStage {
michael@0 141 /**
michael@0 142 * Run this stage synchronously.
michael@0 143 */
michael@0 144 public void executeSynchronously(final GlobalSession session) {
michael@0 145 final BaseMockServerSyncStage self = this;
michael@0 146 performWait(new Runnable() {
michael@0 147 @Override
michael@0 148 public void run() {
michael@0 149 try {
michael@0 150 self.execute(session);
michael@0 151 } catch (NoSuchStageException e) {
michael@0 152 performNotify(e);
michael@0 153 }
michael@0 154 }
michael@0 155 });
michael@0 156 }
michael@0 157 }
michael@0 158
michael@0 159 private GlobalSession createDefaultGlobalSession(final GlobalSessionCallback callback) throws SyncConfigurationException, IllegalArgumentException, NonObjectJSONException, IOException, ParseException, CryptoException {
michael@0 160
michael@0 161 final KeyBundle keyBundle = new KeyBundle(TEST_USERNAME, TEST_SYNC_KEY);
michael@0 162 final AuthHeaderProvider authHeaderProvider = new BasicAuthHeaderProvider(TEST_USERNAME, TEST_PASSWORD);
michael@0 163 final SharedPreferences prefs = new MockSharedPreferences();
michael@0 164 final SyncConfiguration config = new SyncConfiguration(TEST_USERNAME, authHeaderProvider, prefs);
michael@0 165 config.syncKeyBundle = keyBundle;
michael@0 166 return new GlobalSession(config, callback, getApplicationContext(), null, callback) {
michael@0 167 @Override
michael@0 168 public boolean isEngineRemotelyEnabled(String engineName,
michael@0 169 EngineSettings engineSettings)
michael@0 170 throws MetaGlobalException {
michael@0 171 return true;
michael@0 172 }
michael@0 173
michael@0 174 @Override
michael@0 175 public void advance() {
michael@0 176 // So we don't proceed and run other stages.
michael@0 177 }
michael@0 178 };
michael@0 179 }
michael@0 180
michael@0 181 private static GlobalSessionCallback createGlobalSessionCallback() {
michael@0 182 return new DefaultGlobalSessionCallback() {
michael@0 183
michael@0 184 @Override
michael@0 185 public void handleAborted(GlobalSession globalSession, String reason) {
michael@0 186 performNotify(new Exception("Aborted"));
michael@0 187 }
michael@0 188
michael@0 189 @Override
michael@0 190 public void handleError(GlobalSession globalSession, Exception ex) {
michael@0 191 performNotify(ex);
michael@0 192 }
michael@0 193 };
michael@0 194 }
michael@0 195
michael@0 196 private static void assertConfigTimestampsGreaterThan(SynchronizerConfiguration config, long local, long remote) {
michael@0 197 assertTrue(local <= config.localBundle.getTimestamp());
michael@0 198 assertTrue(remote <= config.remoteBundle.getTimestamp());
michael@0 199 }
michael@0 200
michael@0 201 private static void assertConfigTimestampsEqual(SynchronizerConfiguration config, long local, long remote) {
michael@0 202 assertEquals(local, config.localBundle.getTimestamp());
michael@0 203 assertEquals(remote, config.remoteBundle.getTimestamp());
michael@0 204 }
michael@0 205 }

mercurial