/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.android.sync.test;
import java.util.concurrent.ExecutorService;
import org.mozilla.android.sync.test.helpers.DefaultBeginDelegate;
import org.mozilla.android.sync.test.helpers.DefaultCleanDelegate;
import org.mozilla.android.sync.test.helpers.DefaultFetchDelegate;
import org.mozilla.android.sync.test.helpers.DefaultFinishDelegate;
import org.mozilla.android.sync.test.helpers.DefaultSessionCreationDelegate;
import org.mozilla.android.sync.test.helpers.DefaultStoreDelegate;
import org.mozilla.android.sync.test.helpers.ExpectBeginDelegate;
import org.mozilla.android.sync.test.helpers.ExpectBeginFailDelegate;
import org.mozilla.android.sync.test.helpers.ExpectFetchDelegate;
import org.mozilla.android.sync.test.helpers.ExpectFetchSinceDelegate;
import org.mozilla.android.sync.test.helpers.ExpectFinishDelegate;
import org.mozilla.android.sync.test.helpers.ExpectFinishFailDelegate;
import org.mozilla.android.sync.test.helpers.ExpectGuidsSinceDelegate;
import org.mozilla.android.sync.test.helpers.ExpectInvalidRequestFetchDelegate;
import org.mozilla.android.sync.test.helpers.ExpectManyStoredDelegate;
import org.mozilla.android.sync.test.helpers.ExpectStoreCompletedDelegate;
import org.mozilla.android.sync.test.helpers.ExpectStoredDelegate;
import org.mozilla.android.sync.test.helpers.SessionTestHelper;
import org.mozilla.android.sync.test.helpers.WaitHelper;
import org.mozilla.gecko.db.BrowserContract;
import org.mozilla.gecko.sync.Logger;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.sync.repositories.InactiveSessionException;
import org.mozilla.gecko.sync.repositories.InvalidSessionTransitionException;
import org.mozilla.gecko.sync.repositories.NoStoreDelegateException;
import org.mozilla.gecko.sync.repositories.Repository;
import org.mozilla.gecko.sync.repositories.RepositorySession;
import org.mozilla.gecko.sync.repositories.android.AndroidBrowserRepositoryDataAccessor;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionGuidsSinceDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionWipeDelegate;
import org.mozilla.gecko.sync.repositories.domain.Record;
import android.content.ContentValues;
import android.content.Context;
public abstract class AndroidBrowserRepositoryTest extends AndroidSyncTestCase {
protected static String LOG_TAG = "BrowserRepositoryTest";
protected static void wipe(AndroidBrowserRepositoryDataAccessor helper) {
Logger.debug(LOG_TAG, "Wiping.");
try {
helper.wipe();
} catch (NullPointerException e) {
// This will be handled in begin, here we can just ignore
// the error if it actually occurs since this is just test
// code. We will throw a ProfileDatabaseException. This
// error shouldn't occur in the future, but results from
// trying to access content providers before Fennec has
// been run at least once.
Logger.error(LOG_TAG, "ProfileDatabaseException seen in wipe. Begin should fail");
fail("NullPointerException in wipe.");
}
}
@Override
public void setUp() {
AndroidBrowserRepositoryDataAccessor helper = getDataAccessor();
wipe(helper);
assertTrue(WaitHelper.getTestWaiter().isIdle());
closeDataAccessor(helper);
}
public void tearDown() {
assertTrue(WaitHelper.getTestWaiter().isIdle());
}
protected RepositorySession createSession() {
return SessionTestHelper.createSession(
getApplicationContext(),
getRepository());
}
protected RepositorySession createAndBeginSession() {
return SessionTestHelper.createAndBeginSession(
getApplicationContext(),
getRepository());
}
protected static void dispose(RepositorySession session) {
if (session != null) {
session.abort();
}
}
/**
* Hook to return an ExpectFetchDelegate, possibly with special GUIDs ignored.
*/
public ExpectFetchDelegate preparedExpectFetchDelegate(Record[] expected) {
return new ExpectFetchDelegate(expected);
}
/**
* Hook to return an ExpectGuidsSinceDelegate, possibly with special GUIDs ignored.
*/
public ExpectGuidsSinceDelegate preparedExpectGuidsSinceDelegate(String[] expected) {
return new ExpectGuidsSinceDelegate(expected);
}
/**
* Hook to return an ExpectGuidsSinceDelegate expecting only special GUIDs (if there are any).
*/
public ExpectGuidsSinceDelegate preparedExpectOnlySpecialGuidsSinceDelegate() {
return new ExpectGuidsSinceDelegate(new String[] {});
}
/**
* Hook to return an ExpectFetchSinceDelegate, possibly with special GUIDs ignored.
*/
public ExpectFetchSinceDelegate preparedExpectFetchSinceDelegate(long timestamp, String[] expected) {
return new ExpectFetchSinceDelegate(timestamp, expected);
}
public static Runnable storeRunnable(final RepositorySession session, final Record record, final DefaultStoreDelegate delegate) {
return new Runnable() {
@Override
public void run() {
session.setStoreDelegate(delegate);
try {
session.store(record);
session.storeDone();
} catch (NoStoreDelegateException e) {
fail("NoStoreDelegateException should not occur.");
}
}
};
}
public static Runnable storeRunnable(final RepositorySession session, final Record record) {
return storeRunnable(session, record, new ExpectStoredDelegate(record.guid));
}
public static Runnable storeManyRunnable(final RepositorySession session, final Record[] records, final DefaultStoreDelegate delegate) {
return new Runnable() {
@Override
public void run() {
session.setStoreDelegate(delegate);
try {
for (Record record : records) {
session.store(record);
}
session.storeDone();
} catch (NoStoreDelegateException e) {
fail("NoStoreDelegateException should not occur.");
}
}
};
}
public static Runnable storeManyRunnable(final RepositorySession session, final Record[] records) {
return storeManyRunnable(session, records, new ExpectManyStoredDelegate(records));
}
/**
* Store a record and don't expect a store callback until we're done.
*
* @param session
* @param record
* @return Runnable.
*/
public static Runnable quietStoreRunnable(final RepositorySession session, final Record record) {
return storeRunnable(session, record, new ExpectStoreCompletedDelegate());
}
public static Runnable beginRunnable(final RepositorySession session, final DefaultBeginDelegate delegate) {
return new Runnable() {
@Override
public void run() {
try {
session.begin(delegate);
} catch (InvalidSessionTransitionException e) {
performNotify(e);
}
}
};
}
public static Runnable finishRunnable(final RepositorySession session, final DefaultFinishDelegate delegate) {
return new Runnable() {
@Override
public void run() {
try {
session.finish(delegate);
} catch (InactiveSessionException e) {
performNotify(e);
}
}
};
}
public static Runnable fetchAllRunnable(final RepositorySession session, final ExpectFetchDelegate delegate) {
return new Runnable() {
@Override
public void run() {
session.fetchAll(delegate);
}
};
}
public Runnable fetchAllRunnable(final RepositorySession session, final Record[] expectedRecords) {
return fetchAllRunnable(session, preparedExpectFetchDelegate(expectedRecords));
}
public Runnable guidsSinceRunnable(final RepositorySession session, final long timestamp, final String[] expected) {
return new Runnable() {
@Override
public void run() {
session.guidsSince(timestamp, preparedExpectGuidsSinceDelegate(expected));
}
};
}
public Runnable fetchSinceRunnable(final RepositorySession session, final long timestamp, final String[] expected) {
return new Runnable() {
@Override
public void run() {
session.fetchSince(timestamp, preparedExpectFetchSinceDelegate(timestamp, expected));
}
};
}
public static Runnable fetchRunnable(final RepositorySession session, final String[] guids, final DefaultFetchDelegate delegate) {
return new Runnable() {
@Override
public void run() {
try {
session.fetch(guids, delegate);
} catch (InactiveSessionException e) {
performNotify(e);
}
}
};
}
public Runnable fetchRunnable(final RepositorySession session, final String[] guids, final Record[] expected) {
return fetchRunnable(session, guids, preparedExpectFetchDelegate(expected));
}
public static Runnable cleanRunnable(final Repository repository, final boolean success, final Context context, final DefaultCleanDelegate delegate) {
return new Runnable() {
@Override
public void run() {
repository.clean(success, delegate, context);
}
};
}
protected abstract Repository getRepository();
protected abstract AndroidBrowserRepositoryDataAccessor getDataAccessor();
protected static void doStore(RepositorySession session, Record[] records) {
performWait(storeManyRunnable(session, records));
}
// Tests to implement
public abstract void testFetchAll();
public abstract void testGuidsSinceReturnMultipleRecords();
public abstract void testGuidsSinceReturnNoRecords();
public abstract void testFetchSinceOneRecord();
public abstract void testFetchSinceReturnNoRecords();
public abstract void testFetchOneRecordByGuid();
public abstract void testFetchMultipleRecordsByGuids();
public abstract void testFetchNoRecordByGuid();
public abstract void testWipe();
public abstract void testStore();
public abstract void testRemoteNewerTimeStamp();
public abstract void testLocalNewerTimeStamp();
public abstract void testDeleteRemoteNewer();
public abstract void testDeleteLocalNewer();
public abstract void testDeleteRemoteLocalNonexistent();
public abstract void testStoreIdenticalExceptGuid();
public abstract void testCleanMultipleRecords();
/*
* Test abstractions
*/
protected void basicStoreTest(Record record) {
final RepositorySession session = createAndBeginSession();
performWait(storeRunnable(session, record));
}
protected void basicFetchAllTest(Record[] expected) {
Logger.debug("rnewman", "Starting testFetchAll.");
RepositorySession session = createAndBeginSession();
Logger.debug("rnewman", "Prepared.");
AndroidBrowserRepositoryDataAccessor helper = getDataAccessor();
helper.dumpDB();
performWait(storeManyRunnable(session, expected));
helper.dumpDB();
performWait(fetchAllRunnable(session, expected));
closeDataAccessor(helper);
dispose(session);
}
/*
* Tests for clean
*/
// Input: 4 records; 2 which are to be cleaned, 2 which should remain after the clean
protected void cleanMultipleRecords(Record delete0, Record delete1, Record keep0, Record keep1, Record keep2) {
RepositorySession session = createAndBeginSession();
doStore(session, new Record[] {
delete0, delete1, keep0, keep1, keep2
});
// Force two records to appear deleted.
AndroidBrowserRepositoryDataAccessor db = getDataAccessor();
ContentValues cv = new ContentValues();
cv.put(BrowserContract.SyncColumns.IS_DELETED, 1);
db.updateByGuid(delete0.guid, cv);
db.updateByGuid(delete1.guid, cv);
final DefaultCleanDelegate delegate = new DefaultCleanDelegate() {
public void onCleaned(Repository repo) {
performNotify();
}
};
final Runnable cleanRunnable = cleanRunnable(
getRepository(),
true,
getApplicationContext(),
delegate);
performWait(cleanRunnable);
performWait(fetchAllRunnable(session, preparedExpectFetchDelegate(new Record[] { keep0, keep1, keep2})));
closeDataAccessor(db);
dispose(session);
}
/*
* Tests for guidsSince
*/
protected void guidsSinceReturnMultipleRecords(Record record0, Record record1) {
RepositorySession session = createAndBeginSession();
long timestamp = System.currentTimeMillis();
String[] expected = new String[2];
expected[0] = record0.guid;
expected[1] = record1.guid;
Logger.debug(getName(), "Storing two records...");
performWait(storeManyRunnable(session, new Record[] { record0, record1 }));
Logger.debug(getName(), "Getting guids since " + timestamp + "; expecting " + expected.length);
performWait(guidsSinceRunnable(session, timestamp, expected));
dispose(session);
}
protected void guidsSinceReturnNoRecords(Record record0) {
RepositorySession session = createAndBeginSession();
// Store 1 record in the past.
performWait(storeRunnable(session, record0));
String[] expected = {};
performWait(guidsSinceRunnable(session, System.currentTimeMillis() + 1000, expected));
dispose(session);
}
/*
* Tests for fetchSince
*/
protected void fetchSinceOneRecord(Record record0, Record record1) {
RepositorySession session = createAndBeginSession();
performWait(storeRunnable(session, record0));
long timestamp = System.currentTimeMillis();
Logger.debug("fetchSinceOneRecord", "Entering synchronized section. Timestamp " + timestamp);
synchronized(this) {
try {
wait(1000);
} catch (InterruptedException e) {
Logger.warn("fetchSinceOneRecord", "Interrupted.", e);
}
}
Logger.debug("fetchSinceOneRecord", "Storing.");
performWait(storeRunnable(session, record1));
Logger.debug("fetchSinceOneRecord", "Fetching record 1.");
String[] expectedOne = new String[] { record1.guid };
performWait(fetchSinceRunnable(session, timestamp + 10, expectedOne));
Logger.debug("fetchSinceOneRecord", "Fetching both, relying on inclusiveness.");
String[] expectedBoth = new String[] { record0.guid, record1.guid };
performWait(fetchSinceRunnable(session, timestamp - 3000, expectedBoth));
Logger.debug("fetchSinceOneRecord", "Done.");
dispose(session);
}
protected void fetchSinceReturnNoRecords(Record record) {
RepositorySession session = createAndBeginSession();
performWait(storeRunnable(session, record));
long timestamp = System.currentTimeMillis();
performWait(fetchSinceRunnable(session, timestamp + 2000, new String[] {}));
dispose(session);
}
protected void fetchOneRecordByGuid(Record record0, Record record1) {
RepositorySession session = createAndBeginSession();
Record[] store = new Record[] { record0, record1 };
performWait(storeManyRunnable(session, store));
String[] guids = new String[] { record0.guid };
Record[] expected = new Record[] { record0 };
performWait(fetchRunnable(session, guids, expected));
dispose(session);
}
protected void fetchMultipleRecordsByGuids(Record record0,
Record record1, Record record2) {
RepositorySession session = createAndBeginSession();
Record[] store = new Record[] { record0, record1, record2 };
performWait(storeManyRunnable(session, store));
String[] guids = new String[] { record0.guid, record2.guid };
Record[] expected = new Record[] { record0, record2 };
performWait(fetchRunnable(session, guids, expected));
dispose(session);
}
protected void fetchNoRecordByGuid(Record record) {
RepositorySession session = createAndBeginSession();
performWait(storeRunnable(session, record));
performWait(fetchRunnable(session,
new String[] { Utils.generateGuid() },
new Record[] {}));
dispose(session);
}
/*
* Test wipe
*/
protected void doWipe(final Record record0, final Record record1) {
final RepositorySession session = createAndBeginSession();
final Runnable run = new Runnable() {
@Override
public void run() {
session.wipe(new RepositorySessionWipeDelegate() {
public void onWipeSucceeded() {
performNotify();
}
public void onWipeFailed(Exception ex) {
fail("wipe should have succeeded");
performNotify();
}
@Override
public RepositorySessionWipeDelegate deferredWipeDelegate(final ExecutorService executor) {
final RepositorySessionWipeDelegate self = this;
return new RepositorySessionWipeDelegate() {
@Override
public void onWipeSucceeded() {
new Thread(new Runnable() {
@Override
public void run() {
self.onWipeSucceeded();
}}).start();
}
@Override
public void onWipeFailed(final Exception ex) {
new Thread(new Runnable() {
@Override
public void run() {
self.onWipeFailed(ex);
}}).start();
}
@Override
public RepositorySessionWipeDelegate deferredWipeDelegate(ExecutorService newExecutor) {
if (newExecutor == executor) {
return this;
}
throw new IllegalArgumentException("Can't re-defer this delegate.");
}
};
}
});
}
};
// Store 2 records.
Record[] records = new Record[] { record0, record1 };
performWait(storeManyRunnable(session, records));
performWait(fetchAllRunnable(session, records));
// Wipe.
performWait(run);
dispose(session);
}
/*
* TODO adding or subtracting from lastModified timestamps does NOTHING
* since it gets overwritten when we store stuff. See other tests
* for ways to do this properly.
*/
/*
* Record being stored has newer timestamp than existing local record, local
* record has not been modified since last sync.
*/
protected void remoteNewerTimeStamp(Record local, Record remote) {
final RepositorySession session = createAndBeginSession();
// Record existing and hasn't changed since before lastSync.
// Automatically will be assigned lastModified = current time.
performWait(storeRunnable(session, local));
remote.guid = local.guid;
// Get the timestamp and make remote newer than it
ExpectFetchDelegate timestampDelegate = preparedExpectFetchDelegate(new Record[] { local });
performWait(fetchRunnable(session, new String[] { remote.guid }, timestampDelegate));
remote.lastModified = timestampDelegate.records.get(0).lastModified + 1000;
performWait(storeRunnable(session, remote));
Record[] expected = new Record[] { remote };
ExpectFetchDelegate delegate = preparedExpectFetchDelegate(expected);
performWait(fetchAllRunnable(session, delegate));
dispose(session);
}
/*
* Local record has a newer timestamp than the record being stored. For now,
* we just take newer (local) record)
*/
protected void localNewerTimeStamp(Record local, Record remote) {
final RepositorySession session = createAndBeginSession();
performWait(storeRunnable(session, local));
remote.guid = local.guid;
// Get the timestamp and make remote older than it
ExpectFetchDelegate timestampDelegate = preparedExpectFetchDelegate(new Record[] { local });
performWait(fetchRunnable(session, new String[] { remote.guid }, timestampDelegate));
remote.lastModified = timestampDelegate.records.get(0).lastModified - 1000;
performWait(storeRunnable(session, remote));
// Do a fetch and make sure that we get back the local record.
Record[] expected = new Record[] { local };
performWait(fetchAllRunnable(session, preparedExpectFetchDelegate(expected)));
dispose(session);
}
/*
* Insert a record that is marked as deleted, remote has newer timestamp
*/
protected void deleteRemoteNewer(Record local, Record remote) {
final RepositorySession session = createAndBeginSession();
// Record existing and hasn't changed since before lastSync.
// Automatically will be assigned lastModified = current time.
performWait(storeRunnable(session, local));
// Pass the same record to store, but mark it deleted and modified
// more recently
ExpectFetchDelegate timestampDelegate = preparedExpectFetchDelegate(new Record[] { local });
performWait(fetchRunnable(session, new String[] { local.guid }, timestampDelegate));
remote.lastModified = timestampDelegate.records.get(0).lastModified + 1000;
remote.deleted = true;
remote.guid = local.guid;
performWait(storeRunnable(session, remote));
performWait(fetchAllRunnable(session, preparedExpectFetchDelegate(new Record[]{})));
dispose(session);
}
// Store two records that are identical (this has different meanings based on the
// type of record) other than their guids. The record existing locally already
// should have its guid replaced (the assumption is that the record existed locally
// and then sync was enabled and this record existed on another sync'd device).
public void storeIdenticalExceptGuid(Record record0) {
Logger.debug("storeIdenticalExceptGuid", "Started.");
final RepositorySession session = createAndBeginSession();
Logger.debug("storeIdenticalExceptGuid", "Session is " + session);
performWait(storeRunnable(session, record0));
Logger.debug("storeIdenticalExceptGuid", "Stored record0.");
DefaultFetchDelegate timestampDelegate = getTimestampDelegate(record0.guid);
performWait(fetchRunnable(session, new String[] { record0.guid }, timestampDelegate));
Logger.debug("storeIdenticalExceptGuid", "fetchRunnable done.");
record0.lastModified = timestampDelegate.records.get(0).lastModified + 3000;
record0.guid = Utils.generateGuid();
Logger.debug("storeIdenticalExceptGuid", "Storing modified...");
performWait(storeRunnable(session, record0));
Logger.debug("storeIdenticalExceptGuid", "Stored modified.");
Record[] expected = new Record[] { record0 };
performWait(fetchAllRunnable(session, preparedExpectFetchDelegate(expected)));
Logger.debug("storeIdenticalExceptGuid", "Fetched all. Returning.");
dispose(session);
}
// Special delegate so that we don't verify parenting is correct since
// at some points it won't be since parent folder hasn't been stored.
private DefaultFetchDelegate getTimestampDelegate(final String guid) {
return new DefaultFetchDelegate() {
@Override
public void onFetchCompleted(final long fetchEnd) {
assertEquals(guid, this.records.get(0).guid);
performNotify();
}
};
}
/*
* Insert a record that is marked as deleted, local has newer timestamp
* and was not marked deleted (so keep it)
*/
protected void deleteLocalNewer(Record local, Record remote) {
Logger.debug("deleteLocalNewer", "Begin.");
final RepositorySession session = createAndBeginSession();
Logger.debug("deleteLocalNewer", "Storing local...");
performWait(storeRunnable(session, local));
// Create an older version of a record with the same GUID.
remote.guid = local.guid;
Logger.debug("deleteLocalNewer", "Fetching...");
// Get the timestamp and make remote older than it
Record[] expected = new Record[] { local };
ExpectFetchDelegate timestampDelegate = preparedExpectFetchDelegate(expected);
performWait(fetchRunnable(session, new String[] { remote.guid }, timestampDelegate));
Logger.debug("deleteLocalNewer", "Fetched.");
remote.lastModified = timestampDelegate.records.get(0).lastModified - 1000;
Logger.debug("deleteLocalNewer", "Last modified is " + remote.lastModified);
remote.deleted = true;
Logger.debug("deleteLocalNewer", "Storing deleted...");
performWait(quietStoreRunnable(session, remote)); // This appears to do a lot of work...?!
// Do a fetch and make sure that we get back the first (local) record.
performWait(fetchAllRunnable(session, preparedExpectFetchDelegate(expected)));
Logger.debug("deleteLocalNewer", "Fetched and done!");
dispose(session);
}
/*
* Insert a record that is marked as deleted, record never existed locally
*/
protected void deleteRemoteLocalNonexistent(Record remote) {
final RepositorySession session = createAndBeginSession();
long timestamp = 1000000000;
// Pass a record marked deleted to store, doesn't exist locally
remote.lastModified = timestamp;
remote.deleted = true;
performWait(quietStoreRunnable(session, remote));
ExpectFetchDelegate delegate = preparedExpectFetchDelegate(new Record[]{});
performWait(fetchAllRunnable(session, delegate));
dispose(session);
}
/*
* Tests that don't require specific records based on type of repository.
* These tests don't need to be overriden in subclasses, they will just work.
*/
public void testCreateSessionNullContext() {
Logger.debug(LOG_TAG, "In testCreateSessionNullContext.");
Repository repo = getRepository();
try {
repo.createSession(new DefaultSessionCreationDelegate(), null);
fail("Should throw.");
} catch (Exception ex) {
assertNotNull(ex);
}
}
public void testStoreNullRecord() {
final RepositorySession session = createAndBeginSession();
try {
session.setStoreDelegate(new DefaultStoreDelegate());
session.store(null);
fail("Should throw.");
} catch (Exception ex) {
assertNotNull(ex);
}
dispose(session);
}
public void testFetchNoGuids() {
final RepositorySession session = createAndBeginSession();
performWait(fetchRunnable(session, new String[] {}, new ExpectInvalidRequestFetchDelegate()));
dispose(session);
}
public void testFetchNullGuids() {
final RepositorySession session = createAndBeginSession();
performWait(fetchRunnable(session, null, new ExpectInvalidRequestFetchDelegate()));
dispose(session);
}
public void testBeginOnNewSession() {
final RepositorySession session = createSession();
performWait(beginRunnable(session, new ExpectBeginDelegate()));
dispose(session);
}
public void testBeginOnRunningSession() {
final RepositorySession session = createAndBeginSession();
try {
session.begin(new ExpectBeginFailDelegate());
} catch (InvalidSessionTransitionException e) {
dispose(session);
return;
}
fail("Should have caught InvalidSessionTransitionException.");
}
public void testBeginOnFinishedSession() throws InactiveSessionException {
final RepositorySession session = createAndBeginSession();
performWait(finishRunnable(session, new ExpectFinishDelegate()));
try {
session.begin(new ExpectBeginFailDelegate());
} catch (InvalidSessionTransitionException e) {
Logger.debug(getName(), "Yay! Got an exception.", e);
dispose(session);
return;
} catch (Exception e) {
Logger.debug(getName(), "Yay! Got an exception.", e);
dispose(session);
return;
}
fail("Should have caught InvalidSessionTransitionException.");
}
public void testFinishOnFinishedSession() throws InactiveSessionException {
final RepositorySession session = createAndBeginSession();
performWait(finishRunnable(session, new ExpectFinishDelegate()));
try {
session.finish(new ExpectFinishFailDelegate());
} catch (InactiveSessionException e) {
dispose(session);
return;
}
fail("Should have caught InactiveSessionException.");
}
public void testFetchOnInactiveSession() throws InactiveSessionException {
final RepositorySession session = createSession();
try {
session.fetch(new String[] { Utils.generateGuid() }, new DefaultFetchDelegate());
} catch (InactiveSessionException e) {
// Yay.
dispose(session);
return;
};
fail("Should have caught InactiveSessionException.");
}
public void testFetchOnFinishedSession() {
final RepositorySession session = createAndBeginSession();
Logger.debug(getName(), "Finishing...");
performWait(finishRunnable(session, new ExpectFinishDelegate()));
try {
session.fetch(new String[] { Utils.generateGuid() }, new DefaultFetchDelegate());
} catch (InactiveSessionException e) {
// Yay.
dispose(session);
return;
};
fail("Should have caught InactiveSessionException.");
}
public void testGuidsSinceOnUnstartedSession() {
final RepositorySession session = createSession();
Runnable run = new Runnable() {
@Override
public void run() {
session.guidsSince(System.currentTimeMillis(),
new RepositorySessionGuidsSinceDelegate() {
public void onGuidsSinceSucceeded(String[] guids) {
fail("Session inactive, should fail");
performNotify();
}
public void onGuidsSinceFailed(Exception ex) {
verifyInactiveException(ex);
performNotify();
}
});
}
};
performWait(run);
dispose(session);
}
private static void verifyInactiveException(Exception ex) {
if (!(ex instanceof InactiveSessionException)) {
fail("Wrong exception type");
}
}
protected void closeDataAccessor(AndroidBrowserRepositoryDataAccessor dataAccessor) {
}
}