blob: 17aaf461a1efc8ecac8552f9fc39230ad60c17bf [file] [log] [blame]
/*
* Copyright (c) 2020-2022 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 static org.junit.Assert.assertArrayEquals;
import org.eclipse.emf.cdo.common.branch.CDOBranchManager;
import org.eclipse.emf.cdo.common.branch.CDOBranchManager.CDOTagList;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.branch.CDOBranchTag;
import org.eclipse.emf.cdo.internal.common.branch.CDOBranchManagerImpl;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesBefore;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Requires;
import org.eclipse.emf.cdo.tests.config.impl.SessionConfig;
import org.eclipse.net4j.util.container.IContainerDelta;
import org.eclipse.net4j.util.container.IContainerEvent;
import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.net4j.util.tests.TestListener;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
/**
* Bug 297491 - Provide support for storing named branch points, also called tags
*
* @author Eike Stepper
*/
@Requires(IRepositoryConfig.CAPABILITY_AUDITING)
@CleanRepositoriesBefore(reason = "Querying tags")
public class Bugzilla_297491_Test extends AbstractCDOTest
{
private InternalRepository repository;
private CDOSession session1;
private CDOSession session2;
private InternalCDOBranchManager repositoryBranchManager;
private InternalCDOBranchManager branchManager1;
private InternalCDOBranchManager branchManager2;
@Override
protected void doSetUp() throws Exception
{
super.doSetUp();
start();
}
private long getTimeStamp()
{
return repository.getTimeStamp();
}
private void start()
{
repository = getRepository();
repositoryBranchManager = repository.getBranchManager();
session1 = openSession();
branchManager1 = (InternalCDOBranchManager)session1.getBranchManager();
reopenSession2(null);
}
private boolean restart()
{
if (isRestartable())
{
session2.close();
session2 = null;
session1.close();
session1 = null;
IOUtil.OUT().println("RESTARTING...\n");
restartRepository();
start();
return true;
}
IOUtil.OUT().println("SKIPPING RESTART!!!\n");
return false;
}
private void reopenSession2(CDOBranchManager branchManager)
{
if (session2 != null)
{
session2.close();
}
if (branchManager != null)
{
getTestProperties().put(SessionConfig.PROP_TEST_BRANCH_MANAGER, branchManager);
}
session2 = openSession();
branchManager2 = (InternalCDOBranchManager)session2.getBranchManager();
}
private void waitForSession2() throws InterruptedException
{
int expected = branchManager1.getTagModCount();
assertNoTimeout(() -> branchManager2.getTagModCount() >= expected);
}
@SuppressWarnings("unchecked")
public void testCreateAndChangeTags() throws Exception
{
int modCount = 0;
/*
* Create tag1.
*/
CDOBranchPoint point1 = branchManager1.getMainBranch().getPoint(getTimeStamp());
CDOBranchTag tag1 = branchManager1.createTag("tag1", point1);
assertEquals("tag1", tag1.getName());
assertEquals(point1.getBranch(), tag1.getBranch());
assertEquals(point1.getTimeStamp(), tag1.getTimeStamp());
assertEquals(++modCount, branchManager1.getTagModCount());
assertEquals(modCount, repositoryBranchManager.getTagModCount());
waitForSession2();
assertEquals(modCount, branchManager2.getTagModCount());
if (restart())
{
modCount = 0;
}
tag1 = branchManager1.getTag("tag1");
assertEquals("tag1", tag1.getName());
/*
* Create tag2.
*/
sleep(100);
CDOBranchTag tag2 = branchManager1.createTag("tag2", null);
assertEquals("tag2", tag2.getName());
assertEquals(tag1.getBranch(), tag2.getBranch());
assertTrue(tag1.getTimeStamp() < tag2.getTimeStamp());
assertEquals(++modCount, branchManager1.getTagModCount());
assertEquals(modCount, repositoryBranchManager.getTagModCount());
waitForSession2();
assertEquals(modCount, branchManager2.getTagModCount());
CDOTagList tagList1 = branchManager1.getTagList();
{
CDOBranchTag[] actual = tagList1.getTags();
CDOBranchTag[] expected = new CDOBranchTag[] { tag1, tag2 };
Arrays.sort(expected);
assertArrayEquals(expected, actual);
// Check sorting.
expected = new CDOBranchTag[] { tag2, tag1 };
Arrays.sort(expected);
assertArrayEquals(expected, actual);
}
CDOTagList tagList2 = branchManager2.getTagList();
{
CDOBranchTag[] actual = tagList2.getTags();
CDOBranchTag[] expected = new CDOBranchTag[] { branchManager2.getTag("tag1"), branchManager2.getTag("tag2") };
Arrays.sort(expected);
assertArrayEquals(expected, actual);
// Check sorting.
expected = new CDOBranchTag[] { branchManager2.getTag("tag2"), branchManager2.getTag("tag1") };
Arrays.sort(expected);
assertArrayEquals(expected, actual);
}
/*
* Create tag3.
*/
TestListener listener1 = new TestListener(tagList1);
TestListener listener2 = new TestListener(tagList2);
CDOBranchTag tag3 = branchManager1.createTag("tag3", null);
assertEquals(++modCount, branchManager1.getTagModCount());
assertEquals(modCount, repositoryBranchManager.getTagModCount());
waitForSession2();
assertEquals(modCount, branchManager2.getTagModCount());
listener1.assertEvent(IContainerEvent.class, e -> {
IContainerEvent<CDOBranchTag> event = (IContainerEvent<CDOBranchTag>)e;
assertEquals(1, event.getDeltas().length);
assertEquals(tag3, event.getDeltaElement());
assertEquals(IContainerDelta.Kind.ADDED, event.getDeltaKind());
});
listener2.assertEvent(IContainerEvent.class, e -> {
IContainerEvent<CDOBranchTag> event = (IContainerEvent<CDOBranchTag>)e;
assertEquals(1, event.getDeltas().length);
assertEquals(branchManager2.getTag("tag3"), event.getDeltaElement());
assertEquals(IContainerDelta.Kind.ADDED, event.getDeltaKind());
});
/*
* Rename tag3 -> renamed.
*/
listener1.clearEvents();
listener2.clearEvents();
tag3.setName("renamed");
assertEquals(++modCount, branchManager1.getTagModCount());
assertEquals(modCount, repositoryBranchManager.getTagModCount());
waitForSession2();
assertEquals(modCount, branchManager2.getTagModCount());
assertEquals("renamed", tag3.getName());
assertEquals(null, branchManager1.getTag("tag3"));
assertEquals(tag3, branchManager1.getTag("renamed"));
assertEquals(null, branchManager2.getTag("tag3"));
CDOBranchTag renamed2 = branchManager2.getTag("renamed");
assertEquals(tag3.getTimeStamp(), renamed2.getTimeStamp());
assertEquals(3, tagList1.getTags().length);
assertEquals(3, tagList2.getTags().length);
listener1.assertEvent(CDOTagList.TagRenamedEvent.class, e -> {
CDOTagList.TagRenamedEvent event = (CDOTagList.TagRenamedEvent)e;
assertEquals(tag3, event.getTag());
assertEquals("tag3", event.getOldName());
assertEquals("renamed", event.getNewName());
});
listener2.assertEvent(CDOTagList.TagRenamedEvent.class, e -> {
CDOTagList.TagRenamedEvent event = (CDOTagList.TagRenamedEvent)e;
assertEquals(renamed2, event.getTag());
assertEquals("tag3", event.getOldName());
assertEquals("renamed", event.getNewName());
});
/*
* Delete tag "renamed".
*/
listener1.clearEvents();
listener2.clearEvents();
tag3.delete();
assertEquals(++modCount, branchManager1.getTagModCount());
assertEquals(modCount, repositoryBranchManager.getTagModCount());
waitForSession2();
assertEquals(modCount, branchManager2.getTagModCount());
assertEquals("renamed", tag3.getName());
assertEquals(null, tag3.getBranch());
assertEquals(CDOBranchPoint.UNSPECIFIED_DATE, tag3.getTimeStamp());
assertEquals(true, tag3.isDeleted());
assertEquals(null, branchManager1.getTag("renamed"));
assertEquals("renamed", renamed2.getName());
assertEquals(null, renamed2.getBranch());
assertEquals(CDOBranchPoint.UNSPECIFIED_DATE, renamed2.getTimeStamp());
assertEquals(true, renamed2.isDeleted());
assertEquals(null, branchManager1.getTag("renamed"));
assertEquals(2, tagList1.getTags().length);
assertEquals(2, tagList2.getTags().length);
listener1.assertEvent(IContainerEvent.class, e -> {
IContainerEvent<CDOBranchTag> event = (IContainerEvent<CDOBranchTag>)e;
assertEquals(1, event.getDeltas().length);
assertEquals(tag3, event.getDeltaElement());
assertEquals(IContainerDelta.Kind.REMOVED, event.getDeltaKind());
});
listener2.assertEvent(IContainerEvent.class, e -> {
IContainerEvent<CDOBranchTag> event = (IContainerEvent<CDOBranchTag>)e;
assertEquals(1, event.getDeltas().length);
assertEquals(renamed2, event.getDeltaElement());
assertEquals(IContainerDelta.Kind.REMOVED, event.getDeltaKind());
});
reopenSession2(null);
assertEquals(branchManager1.getTagModCount(), branchManager2.getTagModCount());
}
public void testLoadTags() throws Exception
{
branchManager1.createTag("tag1", null);
waitForSession2();
CountDownLatch running = new CountDownLatch(1);
CountDownLatch startModCounting = new CountDownLatch(1);
CountDownLatch modCountingStarted = new CountDownLatch(1);
Thread thread = new Thread()
{
@Override
public void run()
{
reopenSession2(new CDOBranchManagerImpl()
{
@Override
public void setTagModCount(int tagModCount)
{
if (modCountingStarted.getCount() == 1)
{
running.countDown();
await(startModCounting);
IOUtil.OUT().println("Branch manager 2 started with modCount=" + tagModCount);
}
super.setTagModCount(tagModCount);
modCountingStarted.countDown();
}
@Override
public void handleTagChanged(int modCount, String oldName, String newName, CDOBranchPoint branchPoint)
{
IOUtil.OUT().println("Scheduling tag change " + modCount + ": " + oldName + " --> " + newName + ", " + branchPoint);
super.handleTagChanged(modCount, oldName, newName, branchPoint);
}
@Override
protected void executeTagChange(String oldName, String newName, CDOBranchPoint branchPoint)
{
IOUtil.OUT().println("Executing tag change: " + oldName + " --> " + newName + ", " + branchPoint);
super.executeTagChange(oldName, newName, branchPoint);
}
});
}
};
thread.start();
await(running);
branchManager1.createTag("tag2", null);
startModCounting.countDown();
await(modCountingStarted);
thread.join(DEFAULT_TIMEOUT);
// TODO
// sleep(1000);
// assertEquals(branchManager1.getTagModCount(), branchManager2.getTagModCount());
}
}