diff options
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_547640_Test.java')
-rw-r--r-- | plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_547640_Test.java | 225 |
1 files changed, 225 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; + } +} |