Bug 1408585 - Remove RepositorySession begin delegates r=rnewman

'begin' now throws in case things go wrong.

MozReview-Commit-ID: 8jcxYiPcsii

--HG--
extra : rebase_source : 3a6cd6b5dd68f8674d4de827a4228f1e3807724a
This commit is contained in:
Grigory Kruglov 2017-11-13 14:29:49 -05:00
parent 7ef9d1e0fd
commit 45de7880f9
24 changed files with 242 additions and 607 deletions

View File

@ -975,11 +975,9 @@ sync_java_files = [TOPSRCDIR + '/mobile/android/services/src/main/java/org/mozil
'sync/repositories/BookmarksRepository.java',
'sync/repositories/ConfigurableServer15Repository.java',
'sync/repositories/delegates/DeferrableRepositorySessionCreationDelegate.java',
'sync/repositories/delegates/DeferredRepositorySessionBeginDelegate.java',
'sync/repositories/delegates/DeferredRepositorySessionFetchRecordsDelegate.java',
'sync/repositories/delegates/DeferredRepositorySessionFinishDelegate.java',
'sync/repositories/delegates/DeferredRepositorySessionStoreDelegate.java',
'sync/repositories/delegates/RepositorySessionBeginDelegate.java',
'sync/repositories/delegates/RepositorySessionCleanDelegate.java',
'sync/repositories/delegates/RepositorySessionCreationDelegate.java',
'sync/repositories/delegates/RepositorySessionFetchRecordsDelegate.java',

View File

@ -14,16 +14,15 @@ import org.mozilla.gecko.R;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.background.helpers.AndroidSyncTestCase;
import org.mozilla.gecko.background.sync.helpers.BookmarkHelpers;
import org.mozilla.gecko.background.sync.helpers.SimpleSuccessBeginDelegate;
import org.mozilla.gecko.background.sync.helpers.SimpleSuccessCreationDelegate;
import org.mozilla.gecko.background.sync.helpers.SimpleSuccessFetchDelegate;
import org.mozilla.gecko.background.sync.helpers.SimpleSuccessFinishDelegate;
import org.mozilla.gecko.background.sync.helpers.SimpleSuccessStoreDelegate;
import org.mozilla.gecko.db.BrowserContract;
import org.mozilla.gecko.db.BrowserContract.Bookmarks;
import org.mozilla.gecko.sync.SyncException;
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.NullCursorException;
import org.mozilla.gecko.sync.repositories.RepositorySession;
@ -31,8 +30,6 @@ import org.mozilla.gecko.sync.repositories.RepositorySessionBundle;
import org.mozilla.gecko.sync.repositories.android.BookmarksDataAccessor;
import org.mozilla.gecko.sync.repositories.android.BookmarksRepository;
import org.mozilla.gecko.sync.repositories.android.BrowserContractHelpers;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionCreationDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFetchRecordsDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionStoreDelegate;
import org.mozilla.gecko.sync.repositories.domain.BookmarkRecord;
@ -569,22 +566,21 @@ public class TestBookmarks extends AndroidSyncTestCase {
* Create and begin a new session, handing control to the delegate when started.
* Returns when the delegate has notified.
*/
public void inBegunSession(final BookmarksRepository repo,
final RepositorySessionBeginDelegate beginDelegate) {
private void inBegunSession(final BookmarksRepository repo) {
Runnable go = new Runnable() {
@Override
public void run() {
RepositorySessionCreationDelegate delegate = new SimpleSuccessCreationDelegate() {
repo.createSession(new SimpleSuccessCreationDelegate() {
@Override
public void onSessionCreated(final RepositorySession session) {
try {
session.begin(beginDelegate);
} catch (InvalidSessionTransitionException e) {
performNotify(e);
session.begin();
performNotify();
} catch (SyncException e) {
performNotify("Begin failed", e);
}
}
};
repo.createSession(delegate, getApplicationContext());
}, getApplicationContext());
}
};
performWait(go);
@ -609,75 +605,6 @@ public class TestBookmarks extends AndroidSyncTestCase {
}
}
/**
* Simple helper class for fetching all records.
* The fetched records' GUIDs are stored in `fetchedGUIDs`.
*/
public class SimpleFetchAllBeginDelegate extends SimpleSuccessBeginDelegate {
public final ArrayList<String> fetchedGUIDs = new ArrayList<String>();
@Override
public void onBeginSucceeded(final RepositorySession session) {
RepositorySessionFetchRecordsDelegate fetchDelegate = new SimpleSuccessFetchDelegate() {
@Override
public void onFetchedRecord(Record record) {
fetchedGUIDs.add(record.guid);
}
@Override
public void onFetchCompleted() {
finishAndNotify(session);
}
@Override
public void onBatchCompleted() {
}
};
session.fetchModified(fetchDelegate);
}
}
/**
* Simple helper class for fetching a single record by GUID.
* The fetched record is stored in `fetchedRecord`.
*/
public class SimpleFetchOneBeginDelegate extends SimpleSuccessBeginDelegate {
public final String guid;
public Record fetchedRecord = null;
public SimpleFetchOneBeginDelegate(String guid) {
this.guid = guid;
}
@Override
public void onBeginSucceeded(final RepositorySession session) {
RepositorySessionFetchRecordsDelegate fetchDelegate = new SimpleSuccessFetchDelegate() {
@Override
public void onFetchedRecord(Record record) {
fetchedRecord = record;
}
@Override
public void onFetchCompleted() {
finishAndNotify(session);
}
@Override
public void onBatchCompleted() {
}
};
try {
session.fetch(new String[] { guid }, fetchDelegate);
} catch (InactiveSessionException e) {
performNotify("Session is inactive.", e);
}
}
}
/**
* Create a new session for the given repository, storing each record
* from the provided array. Notifies on failure or success.
@ -687,14 +614,19 @@ public class TestBookmarks extends AndroidSyncTestCase {
* @param records
* @param tracked
*/
public void storeRecordsInSession(BookmarksRepository repo,
private void storeRecordsInSession(BookmarksRepository repo,
final BookmarkRecord[] records,
final Collection<String> tracked) {
SimpleSuccessBeginDelegate beginDelegate = new SimpleSuccessBeginDelegate() {
repo.createSession(new SimpleSuccessCreationDelegate() {
@Override
public void onBeginSucceeded(final RepositorySession session) {
RepositorySessionStoreDelegate storeDelegate = new SimpleSuccessStoreDelegate() {
public void onSessionCreated(final RepositorySession session) {
try {
session.begin();
} catch (SyncException e) {
performNotify("Begin failed", e);
}
RepositorySessionStoreDelegate storeDelegate = new SimpleSuccessStoreDelegate() {
@Override
public void onStoreCompleted() {
// Pass back whatever we tracked.
@ -730,24 +662,87 @@ public class TestBookmarks extends AndroidSyncTestCase {
}
session.storeDone();
}
};
inBegunSession(repo, beginDelegate);
}, getApplicationContext());
}
public ArrayList<String> fetchGUIDs(BookmarksRepository repo) {
SimpleFetchAllBeginDelegate beginDelegate = new SimpleFetchAllBeginDelegate();
inBegunSession(repo, beginDelegate);
return beginDelegate.fetchedGUIDs;
final ArrayList<String> fetchedGUIDs = new ArrayList<String>();
repo.createSession(new SimpleSuccessCreationDelegate() {
@Override
public void onSessionCreated(final RepositorySession session) {
try {
session.begin();
} catch (SyncException e) {
performNotify("Begin failed", e);
}
public BookmarkRecord fetchGUID(BookmarksRepository repo,
RepositorySessionFetchRecordsDelegate fetchDelegate = new SimpleSuccessFetchDelegate() {
@Override
public void onFetchedRecord(Record record) {
fetchedGUIDs.add(record.guid);
}
@Override
public void onFetchCompleted() {
finishAndNotify(session);
}
@Override
public void onBatchCompleted() {
}
};
session.fetchModified(fetchDelegate);
}
}, getApplicationContext());
return fetchedGUIDs;
}
private BookmarkRecord fetchGUID(BookmarksRepository repo,
final String guid) {
Logger.info(LOG_TAG, "Fetching for " + guid);
SimpleFetchOneBeginDelegate beginDelegate = new SimpleFetchOneBeginDelegate(guid);
inBegunSession(repo, beginDelegate);
Logger.info(LOG_TAG, "Fetched " + beginDelegate.fetchedRecord);
assertTrue(beginDelegate.fetchedRecord != null);
return (BookmarkRecord) beginDelegate.fetchedRecord;
final ArrayList<Record> fetchedRecords = new ArrayList<>();
repo.createSession(new SimpleSuccessCreationDelegate() {
@Override
public void onSessionCreated(final RepositorySession session) {
try {
session.begin();
} catch (SyncException e) {
performNotify("Begin failed", e);
}
RepositorySessionFetchRecordsDelegate fetchDelegate = new SimpleSuccessFetchDelegate() {
@Override
public void onFetchedRecord(Record record) {
fetchedRecords.add(record);
}
@Override
public void onFetchCompleted() {
finishAndNotify(session);
}
@Override
public void onBatchCompleted() {
}
};
try {
session.fetch(new String[] { guid }, fetchDelegate);
} catch (InactiveSessionException e) {
performNotify("Session is inactive.", e);
}
}
}, getApplicationContext());
assertEquals(1, fetchedRecords.size());
Record fetchedRecord = fetchedRecords.get(0);
Logger.info(LOG_TAG, "Fetched " + fetchedRecord);
return (BookmarkRecord) fetchedRecord;
}
public JSONArray fetchChildrenForGUID(BookmarksRepository repo,

View File

@ -7,14 +7,11 @@ import java.util.concurrent.ExecutorService;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.background.helpers.AndroidSyncTestCase;
import org.mozilla.gecko.background.sync.helpers.DefaultBeginDelegate;
import org.mozilla.gecko.background.sync.helpers.DefaultCleanDelegate;
import org.mozilla.gecko.background.sync.helpers.DefaultFetchDelegate;
import org.mozilla.gecko.background.sync.helpers.DefaultFinishDelegate;
import org.mozilla.gecko.background.sync.helpers.DefaultSessionCreationDelegate;
import org.mozilla.gecko.background.sync.helpers.DefaultStoreDelegate;
import org.mozilla.gecko.background.sync.helpers.ExpectBeginDelegate;
import org.mozilla.gecko.background.sync.helpers.ExpectBeginFailDelegate;
import org.mozilla.gecko.background.sync.helpers.ExpectFetchDelegate;
import org.mozilla.gecko.background.sync.helpers.ExpectFetchSinceDelegate;
import org.mozilla.gecko.background.sync.helpers.ExpectFinishDelegate;
@ -153,15 +150,18 @@ public abstract class ThreadedRepositoryTestCase extends AndroidSyncTestCase {
return storeRunnable(session, record, new ExpectStoreCompletedDelegate());
}
public static Runnable beginRunnable(final RepositorySession session, final DefaultBeginDelegate delegate) {
public static Runnable beginRunnable(final RepositorySession session) {
return new Runnable() {
@Override
public void run() {
try {
session.begin(delegate);
session.begin();
} catch (InvalidSessionTransitionException e) {
performNotify(e);
} catch (org.mozilla.gecko.sync.SyncException e) {
e.printStackTrace();
}
performNotify();
}
};
}
@ -658,17 +658,19 @@ public abstract class ThreadedRepositoryTestCase extends AndroidSyncTestCase {
public void testBeginOnNewSession() {
final RepositorySession session = createSession();
performWait(beginRunnable(session, new ExpectBeginDelegate()));
performWait(beginRunnable(session));
dispose(session);
}
public void testBeginOnRunningSession() {
final RepositorySession session = createAndBeginSession();
try {
session.begin(new ExpectBeginFailDelegate());
session.begin();
} catch (InvalidSessionTransitionException e) {
dispose(session);
return;
} catch (org.mozilla.gecko.sync.SyncException e) {
e.printStackTrace();
}
fail("Should have caught InvalidSessionTransitionException.");
}
@ -677,7 +679,7 @@ public abstract class ThreadedRepositoryTestCase extends AndroidSyncTestCase {
final RepositorySession session = createAndBeginSession();
performWait(finishRunnable(session, new ExpectFinishDelegate()));
try {
session.begin(new ExpectBeginFailDelegate());
session.begin();
} catch (InvalidSessionTransitionException e) {
Logger.debug(getName(), "Yay! Got an exception.", e);
dispose(session);

View File

@ -10,7 +10,6 @@ import junit.framework.AssertionFailedError;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.background.helpers.AndroidSyncTestCase;
import org.mozilla.gecko.background.sync.helpers.SimpleSuccessBeginDelegate;
import org.mozilla.gecko.background.sync.helpers.SimpleSuccessCreationDelegate;
import org.mozilla.gecko.background.sync.helpers.SimpleSuccessFetchDelegate;
import org.mozilla.gecko.background.sync.helpers.SimpleSuccessFinishDelegate;
@ -18,6 +17,7 @@ import org.mozilla.gecko.background.sync.helpers.SimpleSuccessStoreDelegate;
import org.mozilla.gecko.background.testhelpers.WBORepository;
import org.mozilla.gecko.sync.CryptoRecord;
import org.mozilla.gecko.sync.ExtendedJSONObject;
import org.mozilla.gecko.sync.SyncException;
import org.mozilla.gecko.sync.repositories.InactiveSessionException;
import org.mozilla.gecko.sync.repositories.InvalidSessionTransitionException;
import org.mozilla.gecko.sync.repositories.NoStoreDelegateException;
@ -151,12 +151,14 @@ public class TestStoreTracking extends AndroidSyncTestCase {
public void onSessionCreated(final RepositorySession session) {
Logger.debug(getName(), "Session created.");
try {
session.begin(new SimpleSuccessBeginDelegate() {
@Override
public void onBeginSucceeded(final RepositorySession session) {
session.begin();
} catch (SyncException e) {
e.printStackTrace();
performNotify(e);
}
// Now we get a result.
session.fetchModified(new SimpleSuccessFetchDelegate() {
@Override
public void onFetchedRecord(Record record) {
assertEq(expectedGUID, record.guid);
@ -180,15 +182,9 @@ public class TestStoreTracking extends AndroidSyncTestCase {
@Override
public void onBatchCompleted() {
}
});
}
});
} catch (InvalidSessionTransitionException e) {
performNotify(e);
}
}
};
Runnable create = new Runnable() {
@Override
@ -220,15 +216,13 @@ public class TestStoreTracking extends AndroidSyncTestCase {
public void onSessionCreated(RepositorySession session) {
Logger.debug(getName(), "Session created: " + session);
try {
session.begin(new SimpleSuccessBeginDelegate() {
@Override
public void onBeginSucceeded(final RepositorySession session) {
doTestStoreRetrieveByGUID(r, session, expectedGUID, record);
}
});
} catch (InvalidSessionTransitionException e) {
session.begin();
} catch (SyncException e) {
e.printStackTrace();
performNotify(e);
}
doTestStoreRetrieveByGUID(r, session, expectedGUID, record);
}
};

View File

@ -1,33 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.gecko.background.sync.helpers;
import java.util.concurrent.ExecutorService;
import org.mozilla.gecko.sync.repositories.RepositorySession;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
public class DefaultBeginDelegate extends DefaultDelegate implements RepositorySessionBeginDelegate {
@Override
public void onBeginFailed(Exception ex) {
performNotify("Begin failed", ex);
}
@Override
public void onBeginSucceeded(RepositorySession session) {
performNotify("Default begin delegate hit.", null);
}
@Override
public RepositorySessionBeginDelegate deferredBeginDelegate(ExecutorService executor) {
DefaultBeginDelegate copy;
try {
copy = (DefaultBeginDelegate) this.clone();
copy.executor = executor;
return copy;
} catch (CloneNotSupportedException e) {
return this;
}
}
}

View File

@ -1,22 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.gecko.background.sync.helpers;
import static junit.framework.Assert.assertNotNull;
import junit.framework.AssertionFailedError;
import org.mozilla.gecko.sync.repositories.RepositorySession;
public class ExpectBeginDelegate extends DefaultBeginDelegate {
@Override
public void onBeginSucceeded(RepositorySession session) {
try {
assertNotNull(session);
} catch (AssertionFailedError e) {
performNotify("Expected non-null session", e);
return;
}
performNotify();
}
}

View File

@ -1,16 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.gecko.background.sync.helpers;
import org.mozilla.gecko.sync.repositories.InvalidSessionTransitionException;
public class ExpectBeginFailDelegate extends DefaultBeginDelegate {
@Override
public void onBeginFailed(Exception ex) {
if (!(ex instanceof InvalidSessionTransitionException)) {
performNotify("Expected InvalidSessionTransititionException but got ", ex);
}
}
}

View File

@ -7,6 +7,7 @@ import static junit.framework.Assert.assertNotNull;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.background.testhelpers.WaitHelper;
import org.mozilla.gecko.sync.SyncException;
import org.mozilla.gecko.sync.repositories.InvalidSessionTransitionException;
import org.mozilla.gecko.sync.repositories.Repository;
import org.mozilla.gecko.sync.repositories.RepositorySession;
@ -41,10 +42,11 @@ public class SessionTestHelper {
Logger.info(logTag, "Calling session.begin on new session.");
// The begin callbacks will notify.
try {
session.begin(new ExpectBeginDelegate());
} catch (InvalidSessionTransitionException e) {
session.begin();
} catch (SyncException e) {
testWaiter.performNotify(e);
}
testWaiter.performNotify();
} else {
Logger.info(logTag, "Notifying after setting new session.");
testWaiter.performNotify();

View File

@ -1,20 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.gecko.background.sync.helpers;
import java.util.concurrent.ExecutorService;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
public abstract class SimpleSuccessBeginDelegate extends DefaultDelegate implements RepositorySessionBeginDelegate {
@Override
public void onBeginFailed(Exception ex) {
performNotify("Begin failed", ex);
}
@Override
public RepositorySessionBeginDelegate deferredBeginDelegate(ExecutorService executor) {
return this;
}
}

View File

@ -9,13 +9,12 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.sync.SyncException;
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.RecordFilter;
import org.mozilla.gecko.sync.repositories.Repository;
import org.mozilla.gecko.sync.repositories.StoreTrackingRepositorySession;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionCreationDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFetchRecordsDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate;
@ -176,10 +175,10 @@ public class WBORepository extends Repository {
}
@Override
public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException {
public void begin() throws SyncException {
this.wbos = wboRepository.cloneWBOs();
super.begin();
stats.begun = now();
super.begin(delegate);
}
@Override

View File

@ -6,12 +6,11 @@ package org.mozilla.gecko.sync.middleware;
import java.util.concurrent.ExecutorService;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.sync.SyncException;
import org.mozilla.gecko.sync.repositories.InactiveSessionException;
import org.mozilla.gecko.sync.repositories.InvalidSessionTransitionException;
import org.mozilla.gecko.sync.repositories.RepositorySession;
import org.mozilla.gecko.sync.repositories.RepositorySessionBundle;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionWipeDelegate;
@ -29,54 +28,9 @@ public abstract class MiddlewareRepositorySession extends RepositorySession {
inner.wipe(delegate);
}
public class MiddlewareRepositorySessionBeginDelegate implements RepositorySessionBeginDelegate {
private final MiddlewareRepositorySession outerSession;
private final RepositorySessionBeginDelegate next;
public MiddlewareRepositorySessionBeginDelegate(MiddlewareRepositorySession outerSession, RepositorySessionBeginDelegate next) {
this.outerSession = outerSession;
this.next = next;
}
@Override
public void onBeginFailed(Exception ex) {
next.onBeginFailed(ex);
}
@Override
public void onBeginSucceeded(RepositorySession session) {
next.onBeginSucceeded(outerSession);
}
@Override
public RepositorySessionBeginDelegate deferredBeginDelegate(ExecutorService executor) {
final RepositorySessionBeginDelegate deferred = next.deferredBeginDelegate(executor);
return new RepositorySessionBeginDelegate() {
@Override
public void onBeginSucceeded(RepositorySession session) {
if (inner != session) {
Logger.warn(LOG_TAG, "Got onBeginSucceeded for session " + session + ", not our inner session!");
}
deferred.onBeginSucceeded(outerSession);
}
@Override
public void onBeginFailed(Exception ex) {
deferred.onBeginFailed(ex);
}
@Override
public RepositorySessionBeginDelegate deferredBeginDelegate(ExecutorService executor) {
return this;
}
};
}
}
@Override
public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException {
inner.begin(new MiddlewareRepositorySessionBeginDelegate(this, delegate));
public void begin() throws SyncException {
inner.begin();
}
public static final class MiddlewareRepositorySessionFinishDelegate implements RepositorySessionFinishDelegate {

View File

@ -4,9 +4,6 @@
package org.mozilla.gecko.sync.repositories;
import android.support.annotation.Nullable;
import android.util.Log;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
@ -14,7 +11,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
import org.mozilla.gecko.sync.SyncException;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFetchRecordsDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionStoreDelegate;
@ -28,7 +25,7 @@ import org.mozilla.gecko.sync.repositories.domain.Record;
* <li>Construct, with a reference to its parent {@link Repository}, by calling
* {@link Repository#createSession(org.mozilla.gecko.sync.repositories.delegates.RepositorySessionCreationDelegate, android.content.Context)}.</li>
* <li>Populate with saved information by calling {@link #unbundle(RepositorySessionBundle)}.</li>
* <li>Begin a sync by calling {@link #begin(RepositorySessionBeginDelegate)}. <code>begin()</code>
* <li>Begin a sync by calling {@link #begin()}. <code>begin()</code>
* is an appropriate place to initialize expensive resources.</li>
* <li>Perform operations such as {@link #fetchModified(RepositorySessionFetchRecordsDelegate)} and
* {@link #store(Record)}.</li>
@ -216,15 +213,13 @@ public abstract class RepositorySession {
}
/**
* Start the session. This is an appropriate place to initialize
* data access components such as database handles.
* Start the session. Override this in your subclasses to initialize data access components such
* as database handles, and otherwise specify what "begin" means for your session.
*
* @param delegate
* @throws InvalidSessionTransitionException
* @throws InvalidSessionTransitionException if session wasn't {@link SessionStatus#UNSTARTED}.
*/
public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException {
public void begin() throws SyncException {
sharedBegin();
delegate.deferredBeginDelegate(delegateQueue).onBeginSucceeded(this);
}
public void unbundle(RepositorySessionBundle bundle) {

View File

@ -8,7 +8,7 @@ import java.util.Collection;
import java.util.Iterator;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
import org.mozilla.gecko.sync.SyncException;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate;
import org.mozilla.gecko.sync.repositories.domain.Record;
@ -25,17 +25,10 @@ public abstract class StoreTrackingRepositorySession extends RepositorySession {
}
@Override
public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException {
RepositorySessionBeginDelegate deferredDelegate = delegate.deferredBeginDelegate(delegateQueue);
try {
public void begin() throws SyncException {
super.sharedBegin();
} catch (InvalidSessionTransitionException e) {
deferredDelegate.onBeginFailed(e);
return;
}
// Or do this in your own subclass.
storeTracker = createStoreTracker();
deferredDelegate.onBeginSucceeded(this);
}
@Override

View File

@ -10,15 +10,13 @@ import java.util.Map;
import org.mozilla.gecko.R;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.sync.SyncException;
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.NullCursorException;
import org.mozilla.gecko.sync.repositories.ProfileDatabaseException;
import org.mozilla.gecko.sync.repositories.Repository;
import org.mozilla.gecko.sync.repositories.StoreTrackingRepositorySession;
import org.mozilla.gecko.sync.repositories.VersioningDelegateHelper;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFetchRecordsDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionStoreDelegate;
@ -216,30 +214,20 @@ public class BookmarksRepositorySession extends StoreTrackingRepositorySession {
}
@Override
public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException {
public void begin() throws SyncException {
// Check for the existence of special folders
// and insert them if they don't exist.
try {
Logger.debug(LOG_TAG, "Check and build special GUIDs.");
dataAccessor.checkAndBuildSpecialGuids();
Logger.debug(LOG_TAG, "Got GUIDs for folders.");
} catch (android.database.sqlite.SQLiteConstraintException e) {
Logger.error(LOG_TAG, "Got sqlite constraint exception working with Fennec bookmark DB.", e);
delegate.onBeginFailed(e);
return;
} catch (Exception e) {
delegate.onBeginFailed(e);
return;
Logger.error(LOG_TAG, "Got an exception while working with Fennec bookmark DB.", e);
throw e;
}
try {
sessionHelper.doBegin();
} catch (NullCursorException e) {
delegate.onBeginFailed(e);
return;
}
RepositorySessionBeginDelegate deferredDelegate = delegate.deferredBeginDelegate(delegateQueue);
super.sharedBegin();
try {
@ -249,14 +237,12 @@ public class BookmarksRepositorySession extends StoreTrackingRepositorySession {
sessionHelper.checkDatabase();
} catch (ProfileDatabaseException e) {
Logger.error(LOG_TAG, "ProfileDatabaseException from begin. Fennec must be launched once until this error is fixed");
deferredDelegate.onBeginFailed(e);
return;
throw e;
} catch (Exception e) {
deferredDelegate.onBeginFailed(e);
return;
Logger.error(LOG_TAG, "Hit an exception while checking a database in begin.", e);
throw e;
}
storeTracker = createStoreTracker();
deferredDelegate.onBeginSucceeded(this);
}
@Override

View File

@ -11,14 +11,13 @@ import android.os.SystemClock;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.sync.ExtendedJSONObject;
import org.mozilla.gecko.sync.SyncException;
import org.mozilla.gecko.sync.delegates.ClientsDataDelegate;
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.RepositorySessionBundle;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionCreationDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFetchRecordsDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate;
@ -98,43 +97,8 @@ public class BookmarksValidationRepository extends Repository {
@Override
public void begin(final RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException {
wrappedSession.begin(new RepositorySessionBeginDelegate() {
@Override
public void onBeginFailed(Exception ex) {
delegate.onBeginFailed(ex);
}
@Override
public void onBeginSucceeded(RepositorySession session) {
delegate.onBeginSucceeded(BookmarksValidationRepositorySession.this);
}
@Override
public RepositorySessionBeginDelegate deferredBeginDelegate(ExecutorService executor) {
final RepositorySessionBeginDelegate deferred = delegate.deferredBeginDelegate(executor);
return new RepositorySessionBeginDelegate() {
@Override
public void onBeginSucceeded(RepositorySession session) {
if (wrappedSession != session) {
Logger.warn(LOG_TAG, "Got onBeginSucceeded for session " + session + ", not our inner session!");
}
deferred.onBeginSucceeded(BookmarksValidationRepositorySession.this);
}
@Override
public void onBeginFailed(Exception ex) {
deferred.onBeginFailed(ex);
}
@Override
public RepositorySessionBeginDelegate deferredBeginDelegate(ExecutorService executor) {
return this;
}
};
}
});
public void begin() throws SyncException {
wrappedSession.begin();
}
@Override

View File

@ -6,13 +6,12 @@ package org.mozilla.gecko.sync.repositories.android;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.db.BrowserContract;
import org.mozilla.gecko.sync.SyncException;
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.ProfileDatabaseException;
import org.mozilla.gecko.sync.repositories.Repository;
import org.mozilla.gecko.sync.repositories.StoreTrackingRepositorySession;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFetchRecordsDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionWipeDelegate;
@ -27,14 +26,14 @@ public class HistoryRepositorySession extends StoreTrackingRepositorySession {
private final HistorySessionHelper sessionHelper;
private int storeCount = 0;
public HistoryRepositorySession(Repository repository, Context context) {
protected HistoryRepositorySession(Repository repository, Context context) {
super(repository);
dbHelper = new HistoryDataAccessor(context);
sessionHelper = new HistorySessionHelper(this, dbHelper);
}
@Override
public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException {
public void begin() throws SyncException {
// HACK: Fennec creates history records without a GUID. Mercilessly drop
// them on the floor. See Bug 739514.
try {
@ -42,7 +41,7 @@ public class HistoryRepositorySession extends StoreTrackingRepositorySession {
} catch (Exception e) {
// Ignore.
}
RepositorySessionBeginDelegate deferredDelegate = delegate.deferredBeginDelegate(delegateQueue);
super.sharedBegin();
try {
@ -52,14 +51,12 @@ public class HistoryRepositorySession extends StoreTrackingRepositorySession {
sessionHelper.checkDatabase();
} catch (ProfileDatabaseException e) {
Logger.error(LOG_TAG, "ProfileDatabaseException from begin. Fennec must be launched once until this error is fixed");
deferredDelegate.onBeginFailed(e);
return;
throw e;
} catch (Exception e) {
deferredDelegate.onBeginFailed(e);
return;
Logger.error(LOG_TAG, "Hit an exception while checking a database in begin.", e);
throw e;
}
storeTracker = createStoreTracker();
deferredDelegate.onBeginSucceeded(this);
}
@Override

View File

@ -1,46 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.sync.repositories.delegates;
import java.util.concurrent.ExecutorService;
import org.mozilla.gecko.sync.repositories.RepositorySession;
public class DeferredRepositorySessionBeginDelegate implements RepositorySessionBeginDelegate {
private final RepositorySessionBeginDelegate inner;
private final ExecutorService executor;
public DeferredRepositorySessionBeginDelegate(final RepositorySessionBeginDelegate inner, final ExecutorService executor) {
this.inner = inner;
this.executor = executor;
}
@Override
public void onBeginSucceeded(final RepositorySession session) {
executor.execute(new Runnable() {
@Override
public void run() {
inner.onBeginSucceeded(session);
}
});
}
@Override
public void onBeginFailed(final Exception ex) {
executor.execute(new Runnable() {
@Override
public void run() {
inner.onBeginFailed(ex);
}
});
}
@Override
public RepositorySessionBeginDelegate deferredBeginDelegate(ExecutorService newExecutor) {
if (newExecutor == executor) {
return this;
}
throw new IllegalArgumentException("Can't re-defer this delegate.");
}
}

View File

@ -1,23 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.sync.repositories.delegates;
import java.util.concurrent.ExecutorService;
import org.mozilla.gecko.sync.repositories.RepositorySession;
/**
* One of these two methods is guaranteed to be called after session.begin() is
* invoked (possibly during the invocation). The callback will be invoked prior
* to any other RepositorySession callbacks.
*
* @author rnewman
*
*/
public interface RepositorySessionBeginDelegate {
public void onBeginFailed(Exception ex);
public void onBeginSucceeded(RepositorySession session);
public RepositorySessionBeginDelegate deferredBeginDelegate(ExecutorService executor);
}

View File

@ -15,6 +15,7 @@ import org.mozilla.gecko.sync.MetaGlobalException;
import org.mozilla.gecko.sync.NoCollectionKeysSetException;
import org.mozilla.gecko.sync.NonObjectJSONException;
import org.mozilla.gecko.sync.ReflowIsNecessaryException;
import org.mozilla.gecko.sync.SyncException;
import org.mozilla.gecko.sync.SynchronizerConfiguration;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.sync.crypto.KeyBundle;
@ -34,7 +35,6 @@ import org.mozilla.gecko.sync.repositories.RepositorySession;
import org.mozilla.gecko.sync.repositories.RepositorySessionBundle;
import org.mozilla.gecko.sync.repositories.RepositoryStateProvider;
import org.mozilla.gecko.sync.repositories.Server15Repository;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionCreationDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionWipeDelegate;
@ -314,14 +314,19 @@ public abstract class ServerSyncStage extends AbstractSessionManagingSyncStage i
@Override
public void run() {
r.createSession(new RepositorySessionCreationDelegate() {
@Override
public void onSessionCreated(final RepositorySession session) {
try {
session.begin(new RepositorySessionBeginDelegate() {
session.begin();
} catch (SyncException e) {
Logger.error(LOG_TAG, "Couldn't begin session", e);
session.abort();
synchronized (monitor) {
monitor.notify(e, true);
}
return;
}
@Override
public void onBeginSucceeded(final RepositorySession session) {
session.wipe(new RepositorySessionWipeDelegate() {
@Override
public void onWipeSucceeded() {
@ -373,27 +378,6 @@ public abstract class ServerSyncStage extends AbstractSessionManagingSyncStage i
});
}
@Override
public void onBeginFailed(Exception ex) {
session.abort();
synchronized (monitor) {
monitor.notify(ex, true);
}
}
@Override
public RepositorySessionBeginDelegate deferredBeginDelegate(ExecutorService executor) {
return this;
}
});
} catch (InvalidSessionTransitionException e) {
session.abort();
synchronized (monitor) {
monitor.notify(e, true);
}
}
}
@Override
public void onSessionCreateFailed(Exception ex) {
synchronized (monitor) {

View File

@ -13,13 +13,12 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.sync.ReflowIsNecessaryException;
import org.mozilla.gecko.sync.SyncException;
import org.mozilla.gecko.sync.ThreadPool;
import org.mozilla.gecko.sync.repositories.InvalidSessionTransitionException;
import org.mozilla.gecko.sync.repositories.NoStoreDelegateException;
import org.mozilla.gecko.sync.repositories.RepositorySession;
import org.mozilla.gecko.sync.repositories.delegates.DeferredRepositorySessionBeginDelegate;
import org.mozilla.gecko.sync.repositories.delegates.DeferredRepositorySessionStoreDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFetchRecordsDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionStoreDelegate;
import org.mozilla.gecko.sync.repositories.domain.Record;
@ -67,8 +66,7 @@ import org.mozilla.gecko.sync.repositories.domain.Record;
public class RecordsChannel implements
RepositorySessionFetchRecordsDelegate,
RepositorySessionStoreDelegate,
RecordsConsumerDelegate,
RepositorySessionBeginDelegate {
RecordsConsumerDelegate {
private static final String LOG_TAG = "RecordsChannel";
public RepositorySession source;
@ -199,8 +197,17 @@ public class RecordsChannel implements
* @throws InvalidSessionTransitionException
*/
public void beginAndFlow() throws InvalidSessionTransitionException {
try {
Logger.trace(LOG_TAG, "Beginning source.");
source.begin(this);
source.begin();
Logger.trace(LOG_TAG, "Beginning sink.");
sink.begin();
} catch (SyncException e) {
delegate.onFlowBeginFailed(this, e);
return;
}
this.flow();
}
@Override
@ -332,41 +339,11 @@ public class RecordsChannel implements
delegate.onFlowCompleted(this);
}
@Override
public void onBeginFailed(Exception ex) {
delegate.onFlowBeginFailed(this, ex);
}
@Override
public void onBeginSucceeded(RepositorySession session) {
if (session == source) {
Logger.trace(LOG_TAG, "Source session began. Beginning sink session.");
try {
sink.begin(this);
} catch (InvalidSessionTransitionException e) {
onBeginFailed(e);
return;
}
}
if (session == sink) {
Logger.trace(LOG_TAG, "Sink session began. Beginning flow.");
this.flow();
return;
}
// TODO: error!
}
@Override
public RepositorySessionStoreDelegate deferredStoreDelegate(final ExecutorService executor) {
return new DeferredRepositorySessionStoreDelegate(this, executor);
}
@Override
public RepositorySessionBeginDelegate deferredBeginDelegate(final ExecutorService executor) {
return new DeferredRepositorySessionBeginDelegate(this, executor);
}
@Override
public RepositorySessionFetchRecordsDelegate deferredFetchDelegate(ExecutorService executor) {
// Lie outright. We know that all of our fetch methods are safe.

View File

@ -8,12 +8,11 @@ import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.background.testhelpers.WBORepository;
import org.mozilla.gecko.sync.CollectionConcurrentModificationException;
import org.mozilla.gecko.sync.SyncDeadlineReachedException;
import org.mozilla.gecko.sync.SyncException;
import org.mozilla.gecko.sync.repositories.FetchFailedException;
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.StoreFailedException;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionCreationDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFetchRecordsDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate;
@ -230,7 +229,7 @@ public class SynchronizerHelpers {
}
}
public static class BeginFailedException extends Exception {
public static class BeginFailedException extends SyncException {
private static final long serialVersionUID = -2349459755976915096L;
}
@ -251,8 +250,8 @@ public class SynchronizerHelpers {
}
@Override
public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException {
delegate.onBeginFailed(new BeginFailedException());
public void begin() throws SyncException {
throw new BeginFailedException();
}
}
}

View File

@ -1,38 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.android.sync.test.helpers;
import junit.framework.AssertionFailedError;
import org.mozilla.gecko.background.testhelpers.WaitHelper;
import org.mozilla.gecko.sync.repositories.RepositorySession;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
import java.util.concurrent.ExecutorService;
public class ExpectSuccessRepositorySessionBeginDelegate
extends ExpectSuccessDelegate
implements RepositorySessionBeginDelegate {
public ExpectSuccessRepositorySessionBeginDelegate(WaitHelper waitHelper) {
super(waitHelper);
}
@Override
public void onBeginFailed(Exception ex) {
log("Session begin failed.", ex);
performNotify(new AssertionFailedError("Session begin failed: " + ex.getMessage()));
}
@Override
public void onBeginSucceeded(RepositorySession session) {
log("Session begin succeeded.");
performNotify();
}
@Override
public RepositorySessionBeginDelegate deferredBeginDelegate(ExecutorService executor) {
log("Session begin delegate deferred.");
return this;
}
}

View File

@ -5,13 +5,12 @@ package org.mozilla.gecko.background.testhelpers;
import android.content.Context;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.sync.SyncException;
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.RecordFilter;
import org.mozilla.gecko.sync.repositories.Repository;
import org.mozilla.gecko.sync.repositories.StoreTrackingRepositorySession;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionCreationDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFetchRecordsDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate;
@ -175,10 +174,10 @@ public class WBORepository extends Repository {
}
@Override
public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException {
public void begin() throws SyncException {
this.wbos = wboRepository.cloneWBOs();
super.begin();
stats.begun = now();
super.begin(delegate);
}
@Override

View File

@ -7,7 +7,6 @@ import junit.framework.AssertionFailedError;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mozilla.android.sync.test.helpers.ExpectSuccessRepositorySessionBeginDelegate;
import org.mozilla.android.sync.test.helpers.ExpectSuccessRepositorySessionCreationDelegate;
import org.mozilla.android.sync.test.helpers.ExpectSuccessRepositorySessionFetchRecordsDelegate;
import org.mozilla.android.sync.test.helpers.ExpectSuccessRepositorySessionFinishDelegate;
@ -19,6 +18,7 @@ import org.mozilla.gecko.background.testhelpers.WBORepository;
import org.mozilla.gecko.background.testhelpers.WaitHelper;
import org.mozilla.gecko.sync.CryptoRecord;
import org.mozilla.gecko.sync.NonObjectJSONException;
import org.mozilla.gecko.sync.SyncException;
import org.mozilla.gecko.sync.crypto.CryptoException;
import org.mozilla.gecko.sync.crypto.KeyBundle;
import org.mozilla.gecko.sync.middleware.Crypto5MiddlewareRepository;
@ -54,7 +54,7 @@ public class TestCrypto5MiddlewareRepositorySession {
getTestWaiter().performNotify(failed);
}
protected static void performNotify(InvalidSessionTransitionException e) {
protected static void performNotify(SyncException e) {
final AssertionFailedError failed = new AssertionFailedError("Invalid session transition.");
failed.initCause(e);
getTestWaiter().performNotify(failed);
@ -96,16 +96,11 @@ public class TestCrypto5MiddlewareRepositorySession {
assertSame(RepositorySession.SessionStatus.UNSTARTED, cmwSession.getStatus());
try {
session.begin(new ExpectSuccessRepositorySessionBeginDelegate(getTestWaiter()) {
@Override
public void onBeginSucceeded(RepositorySession _session) {
assertSame(self.cmwSession, _session);
runnable.run();
}
});
} catch (InvalidSessionTransitionException e) {
session.begin();
} catch (SyncException e) {
TestCrypto5MiddlewareRepositorySession.performNotify(e);
}
runnable.run();
}
}, null);
}
@ -125,9 +120,9 @@ public class TestCrypto5MiddlewareRepositorySession {
} catch (InactiveSessionException e) {
performNotify(e);
}
assertSame(RepositorySession.SessionStatus.DONE, cmwSession.getStatus());
}
});
assertSame(RepositorySession.SessionStatus.DONE, cmwSession.getStatus());
}
@Test