/*
* Copyright (c) 2011-2013 Eike Stepper (Berlin, 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.offline;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.tests.AbstractSyncingTest;
import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Requires;
import org.eclipse.emf.cdo.tests.model1.Category;
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.cdo.view.CDOView;
import org.eclipse.net4j.util.om.OMPlatform;
import org.eclipse.net4j.util.om.trace.PrintTraceHandler;
import org.eclipse.emf.common.util.EList;
/**
* Support raw replication in HorizontalBranchingMappingStrategyWithRanges.
* <p>
* See bug 351078
*
* @author Eike Stepper
*/
@Requires(IRepositoryConfig.CAPABILITY_OFFLINE)
public class Bugzilla_351078_Test extends AbstractSyncingTest
{
@Override
protected void doSetUp() throws Exception
{
OMPlatform.INSTANCE.setDebugging(false);
OMPlatform.INSTANCE.removeTraceHandler(PrintTraceHandler.CONSOLE);
super.doSetUp();
}
public void testDoNothing() throws Exception
{
run(new CompanyChanger());
}
public void testAddTwoRemoveFirst_DoNothing() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.remove(0);
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
});
}
public void testAddTwoRemoveFirst_AddTwo() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.remove(0);
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
});
}
public void testAddTwoRemoveSecond_DoNothing() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.remove(1);
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
});
}
public void testAddTwoRemoveSecond_AddTwo() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.remove(1);
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
}
});
}
public void testAddTwo_RemoveFirst() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.remove(0);
transaction.commit();
}
});
}
public void testAddTwo_RemoveFirstAddOne() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.remove(0);
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
});
}
public void testAddTwo_RemoveSecond() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.remove(1);
transaction.commit();
}
});
}
public void testAddTwo_RemoveSecondAddOne() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.remove(1);
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
});
}
public void testAddTwo_AddOneRemoveThird() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.remove(2);
transaction.commit();
}
});
}
public void testAddOne_AddOne() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
});
}
public void testAddTwo_AddTwo() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
});
}
public void testAddThree_MoveFirst() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
categories.add(getModel1Factory().createCategory());
categories.add(getModel1Factory().createCategory());
categories.add(getModel1Factory().createCategory());
categories.add(getModel1Factory().createCategory());
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.move(5, 0);
transaction.commit();
}
});
}
public void testAddThree_MoveLast() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
categories.add(getModel1Factory().createCategory());
categories.add(getModel1Factory().createCategory());
categories.add(getModel1Factory().createCategory());
categories.add(getModel1Factory().createCategory());
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.move(0, 5);
transaction.commit();
}
});
}
public void testAddOne_ReplaceIt() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.set(0, getModel1Factory().createCategory());
transaction.commit();
}
});
}
public void testAddOneAddOne_ReplaceFirst() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.set(0, getModel1Factory().createCategory());
transaction.commit();
}
});
}
public void testAddOneRemoveIt() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.remove(0);
transaction.commit();
}
});
}
public void testAddOneAddOne_RemoveFirst() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.remove(0);
transaction.commit();
}
});
}
public void testAddOneReplaceFirst_ReplaceFirst() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.set(0, getModel1Factory().createCategory());
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.set(0, getModel1Factory().createCategory());
transaction.commit();
}
});
}
public void testAddOneAddOneReplaceFirst_ReplaceFirst() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.set(0, getModel1Factory().createCategory());
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.set(0, getModel1Factory().createCategory());
transaction.commit();
}
});
}
public void testAddAddReplaceAddRmove_ReplaceAdd() throws Exception
{
run(new CompanyChanger()
{
@Override
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.set(0, getModel1Factory().createCategory());
transaction.commit();
categories.add(getModel1Factory().createCategory());
transaction.commit();
categories.remove(0);
transaction.commit();
}
@Override
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
categories.set(0, getModel1Factory().createCategory());
transaction.commit();
categories.add(0, getModel1Factory().createCategory());
transaction.commit();
}
});
}
protected void run(CompanyChanger changer) throws Exception
{
// Create master session & transaction.
InternalRepository master = getRepository("master");
CDOSession masterSession = openSession(master.getName());
CDOTransaction masterTransaction = masterSession.openTransaction();
// Create resource and base model.
CDOResource resource = masterTransaction.createResource(getResourcePath("/my/resource"));
Company masterCompany = getModel1Factory().createCompany();
resource.getContents().add(masterCompany);
masterTransaction.commit();
changer.beforeConnect(masterCompany.getCategories(), masterTransaction);
// Create an offline clone.
InternalRepository clone = getRepository();
waitForOnline(clone);
sleep(500); // TODO Clarify why waitForOnline() alone is not enough
check(master, masterCompany, "after connect");
getOfflineConfig().stopMasterTransport();
waitForOffline(clone);
sleep(500);
changer.beforeReconnect(masterCompany.getCategories(), masterTransaction);
getOfflineConfig().startMasterTransport();
waitForOnline(clone);
sleep(500);
check(master, masterCompany, "after reconnect");
}
protected void check(InternalRepository master, Company masterCompany, String when)
{
EList<Category> masterCategories = masterCompany.getCategories();
CDOSession session = openSession();
CDOView view = session.openView();
CDOID id = CDOUtil.getCDOObject(masterCompany).cdoID();
Company company = (Company)view.getObject(id);
EList<Category> categories = company.getCategories();
assertEquals("Size (" + when + ")", masterCategories.size(), categories.size());
for (int i = 0; i < masterCategories.size(); i++)
{
CDOObject masterCategory = CDOUtil.getCDOObject(masterCategories.get(i));
CDOObject category = CDOUtil.getCDOObject(categories.get(i));
assertEquals("Element " + i + " (" + when + ")", masterCategory.cdoID(), category.cdoID());
}
session.close();
}
/**
* @author Eike Stepper
*/
protected static class CompanyChanger
{
public void beforeConnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
}
public void beforeReconnect(EList<Category> categories, CDOTransaction transaction) throws Exception
{
}
}
}