Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2019-11-05 18:18:14 +0000
committerEike Stepper2019-11-05 18:18:14 +0000
commit808fd8e4ef743959c8b66c062c9a4b9491f5cf55 (patch)
treef921fe8ba8bb770599db99d50cdc89346994fe00 /plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo
parent9ca6a5b419a5212e3d2b06f414c6aff27fa032ba (diff)
downloadcdo-808fd8e4ef743959c8b66c062c9a4b9491f5cf55.tar.gz
cdo-808fd8e4ef743959c8b66c062c9a4b9491f5cf55.tar.xz
cdo-808fd8e4ef743959c8b66c062c9a4b9491f5cf55.zip
[547640] Support server-side commit conflict resolution
https://bugs.eclipse.org/bugs/show_bug.cgi?id=547640
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo')
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_547640_Test.java225
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java14
2 files changed, 239 insertions, 0 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_547640_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_547640_Test.java
new file mode 100644
index 0000000000..494f2b9f64
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_547640_Test.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2018 Eike Stepper (Loehne, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.tests.bugzilla;
+
+import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.internal.server.SessionManager;
+import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.spi.server.ICommitConflictResolver;
+import org.eclipse.emf.cdo.tests.AbstractCDOTest;
+import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
+import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesAfter;
+import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesBefore;
+import org.eclipse.emf.cdo.tests.config.impl.RepositoryConfig;
+import org.eclipse.emf.cdo.tests.model1.Company;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.util.CDOUtil;
+
+import org.eclipse.emf.internal.cdo.session.CDOTransactionContainerImpl.TransactionCreator;
+import org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl;
+
+import org.eclipse.net4j.util.io.IOUtil;
+
+import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Bug 547640 - Support server-side commit conflict resolution.
+ *
+ * @author Eike Stepper
+ */
+@CleanRepositoriesBefore(reason = "server-side merging")
+@CleanRepositoriesAfter(reason = "server-side merging")
+public class Bugzilla_547640_Test extends AbstractCDOTest
+{
+ @Requires(IRepositoryConfig.CAPABILITY_AUDITING)
+ public void testCommitConflictResolver_OneCommit() throws Exception
+ {
+ run(new TestLogic()
+ {
+ private int expectedVersion;
+
+ public void modifyAndCommit1(CDOTransaction transaction, Company company) throws Exception
+ {
+ company.getCategories().add(getModel1Factory().createCategory());
+ transaction.commit();
+ expectedVersion = CDOUtil.getCDOObject(company).cdoRevision().getVersion() + 1;
+ }
+
+ public void modify2(CDOTransaction transaction, Company company) throws Exception
+ {
+ company.getCategories().add(getModel1Factory().createCategory());
+ }
+
+ public void verify2(CDOTransaction transaction, Company company) throws Exception
+ {
+ CDORevision cdoRevision = CDOUtil.getCDOObject(company).cdoRevision();
+ assertEquals(expectedVersion, cdoRevision.getVersion());
+
+ assertEquals(2, company.getCategories().size());
+ }
+ });
+ }
+
+ @Requires(IRepositoryConfig.CAPABILITY_AUDITING)
+ public void testCommitConflictResolver_TwoCommits() throws Exception
+ {
+ run(new TestLogic()
+ {
+ private int expectedVersion;
+
+ public void modifyAndCommit1(CDOTransaction transaction, Company company) throws Exception
+ {
+ company.getCategories().add(getModel1Factory().createCategory());
+ transaction.commit();
+ company.getCategories().add(getModel1Factory().createCategory());
+ transaction.commit();
+ expectedVersion = CDOUtil.getCDOObject(company).cdoRevision().getVersion() + 1;
+ }
+
+ public void modify2(CDOTransaction transaction, Company company) throws Exception
+ {
+ company.getCategories().add(getModel1Factory().createCategory());
+ }
+
+ public void verify2(CDOTransaction transaction, Company company) throws Exception
+ {
+ CDORevision cdoRevision = CDOUtil.getCDOObject(company).cdoRevision();
+ assertEquals(expectedVersion, cdoRevision.getVersion());
+ }
+ });
+ }
+
+ @Override
+ protected void doSetUp() throws Exception
+ {
+ super.doSetUp();
+ getTestProperties().put(RepositoryConfig.PROP_TEST_COMMIT_CONFLICT_RESOLVER, new ICommitConflictResolver.Merging());
+ getTestProperties().put(RepositoryConfig.PROP_TEST_SESSION_MANAGER, new SuspendableSessionManager());
+ }
+
+ @Override
+ protected void doTearDown() throws Exception
+ {
+ TransactionCreator.reset();
+ super.doTearDown();
+ }
+
+ protected SuspendableSessionManager getSessionManager()
+ {
+ return (SuspendableSessionManager)getTestProperties().get(RepositoryConfig.PROP_TEST_SESSION_MANAGER);
+ }
+
+ private void run(final TestLogic testLogic) throws Exception
+ {
+ CDOSession session1 = openSession();
+ CDOTransaction transaction1 = session1.openTransaction();
+ Company company1 = getModel1Factory().createCompany();
+ transaction1.createResource(getResourcePath("resource")).getContents().add(company1);
+ transaction1.commit();
+
+ CDOSession session2 = openSession();
+ session2.options().setPassiveUpdateMode(PassiveUpdateMode.CHANGES);
+ TransactionCreator.set(new TransactionCreator()
+ {
+ @Override
+ public InternalCDOTransaction createTransaction(CDOSession session, CDOBranch branch)
+ {
+ return new CDOTransactionImpl(session, branch)
+ {
+ @Override
+ protected void waitForBaseline(long previousTimeStamp)
+ {
+ getSessionManager().resume();
+ super.waitForBaseline(previousTimeStamp);
+ }
+ };
+ }
+ });
+
+ final CDOTransaction transaction2 = session2.openTransaction();
+ TransactionCreator.reset();
+
+ final Company company2 = (Company)transaction2.getResource(getResourcePath("resource")).getContents().get(0);
+
+ // Let client2 modify the model (but not commit, yet).
+ testLogic.modify2(transaction2, company2);
+
+ // Let client1 modify the model and commit (but hold back commit notifications to client2).
+ getSessionManager().suspend();
+ testLogic.modifyAndCommit1(transaction1, company1);
+
+ // Let client2 commit and verify the result.
+ transaction2.commit();
+ testLogic.verify2(transaction2, company2);
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private static class SuspendableSessionManager extends SessionManager
+ {
+ private List<CommitNotificationInfo> queue;
+
+ public synchronized void suspend()
+ {
+ IOUtil.OUT().println("Suspending commit notifications");
+ queue = new ArrayList<CommitNotificationInfo>();
+ }
+
+ public synchronized void resume()
+ {
+ IOUtil.OUT().println("Resuming commit notifications");
+
+ try
+ {
+ for (CommitNotificationInfo info : queue)
+ {
+ super.sendCommitNotification(info);
+ }
+ }
+ finally
+ {
+ queue = null;
+ }
+ }
+
+ @Override
+ public synchronized void sendCommitNotification(CommitNotificationInfo info)
+ {
+ if (queue != null)
+ {
+ queue.add(info);
+ }
+ else
+ {
+ super.sendCommitNotification(info);
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public interface TestLogic
+ {
+ public void modifyAndCommit1(CDOTransaction transaction, Company company) throws Exception;
+
+ public void modify2(CDOTransaction transaction, Company company) throws Exception;
+
+ public void verify2(CDOTransaction transaction, Company company) throws Exception;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
index 98ce494644..4348251407 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
@@ -52,6 +52,7 @@ import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.spi.server.ICommitConflictResolver;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.spi.server.InternalRepositorySynchronizer;
import org.eclipse.emf.cdo.spi.server.InternalSessionManager;
@@ -131,6 +132,8 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
public static final String PROP_TEST_QUERY_HANDLER_PROVIDER = "test.repository.QueryHandlerProvider";
+ public static final String PROP_TEST_COMMIT_CONFLICT_RESOLVER = "test.repository.CommitConflictResolver";
+
public static final String PROP_TEST_ENABLE_SERVER_BROWSER = "test.repository.EnableServerBrowser";
private static final boolean LOG_MULTI_VIEW_COMMIT = false;
@@ -776,6 +779,12 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
repository.setQueryHandlerProvider(queryHandlerProvider);
}
+ ICommitConflictResolver commitConflictResolver = getTestCommitConflictResolver();
+ if (commitConflictResolver != null)
+ {
+ repository.setCommitConflictResolver(commitConflictResolver);
+ }
+
return repository;
}
@@ -824,6 +833,11 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
return (IQueryHandlerProvider)getTestProperty(PROP_TEST_QUERY_HANDLER_PROVIDER);
}
+ protected ICommitConflictResolver getTestCommitConflictResolver()
+ {
+ return (ICommitConflictResolver)getTestProperty(PROP_TEST_COMMIT_CONFLICT_RESOLVER);
+ }
+
protected boolean needsCleanRepos()
{
IScenario scenario = getCurrentTest().getScenario();

Back to the top