/*
 * Copyright (c) 2008-2013, 2015 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:
 *    Simon McDuff - initial API and implementation
 *    Eike Stepper - maintenance
 *    Caspar De Groot - write options
 */
package org.eclipse.emf.cdo.tests;

import org.eclipse.emf.cdo.CDOLock;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.server.IView;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.spi.server.InternalLockManager;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
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.util.CommitException;
import org.eclipse.emf.cdo.util.LockTimeoutException;
import org.eclipse.emf.cdo.util.ObjectNotFoundException;
import org.eclipse.emf.cdo.util.StaleRevisionLockException;
import org.eclipse.emf.cdo.view.CDOView;

import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
import org.eclipse.net4j.util.concurrent.RWOLockManager;
import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState;
import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

import junit.framework.AssertionFailedError;

/**
 * @author Simon McDuff
 */
public class LockingManagerTest extends AbstractLockingTest
{
  public void testUnlockAll() throws Exception
  {
    final RWOLockManager<Integer, Integer> lockingManager = new RWOLockManager<Integer, Integer>();

    Set<Integer> keys = new HashSet<Integer>();
    keys.add(1);
    keys.add(2);
    keys.add(3);

    lockingManager.lock(LockType.READ, 1, keys, 100);
    lockingManager.unlock(1);
  }

  public void testWriteOptions() throws Exception
  {
    final RWOLockManager<Integer, Integer> lockingManager = new RWOLockManager<Integer, Integer>();

    Set<Integer> keys = new HashSet<Integer>();
    keys.add(1);
    lockingManager.lock(LockType.OPTION, 1, keys, 100);

    // (R=Read, W=Write, WO=WriteOption)
    // Scenario 1: 1 has WO, 2 requests W -> fail
    keys.clear();
    keys.add(1);

    try
    {
      lockingManager.lock(LockType.WRITE, 2, keys, 100); // Must fail
      fail("Should have thrown an exception");
    }
    catch (TimeoutRuntimeException e)
    {
    }

    // Scenario 2: 1 has WO, 2 requests R -> succeed
    try
    {
      lockingManager.lock(LockType.READ, 2, keys, 100); // Must succeed
    }
    catch (TimeoutRuntimeException e)
    {
      fail("Should not have thrown an exception");
    }

    // Scenario 3: 1 has WO, 2 has R, 1 requests W -> fail
    try
    {
      lockingManager.lock(LockType.WRITE, 1, keys, 100); // Must fail
      fail("Should have thrown an exception");
    }
    catch (TimeoutRuntimeException e)
    {
    }

    // Scenario 4: 1 has WO, 2 has R, 2 requests WO -> fail
    try
    {
      lockingManager.lock(LockType.OPTION, 2, keys, 100); // Must fail
      fail("Should have thrown an exception");
    }
    catch (TimeoutRuntimeException e)
    {
    }

    // Scenario 5: 1 has WO, 2 has nothing, 2 requests WO -> fail
    lockingManager.unlock(LockType.READ, 2, keys);
    try
    {
      lockingManager.lock(LockType.OPTION, 2, keys, 100); // Must fail
      fail("Should have thrown an exception");
    }
    catch (TimeoutRuntimeException e)
    {
    }

    // Scenario 6: 1 has W, 2 has nothing, 2 requests WO -> fail
    lockingManager.unlock(LockType.OPTION, 1, keys);
    lockingManager.lock(LockType.WRITE, 1, keys, 100);
    try
    {
      lockingManager.lock(LockType.OPTION, 2, keys, 100); // Must fail
      fail("Should have thrown an exception");
    }
    catch (TimeoutRuntimeException e)
    {
    }

    // Scenario 7: 1 has W, 1 request WO -> succeed
    try
    {
      lockingManager.lock(LockType.OPTION, 1, keys, 100); // Must succeed
    }
    catch (TimeoutRuntimeException e)
    {
      fail("Should not have thrown an exception");
    }

    // Scenario 8: 1 has W, 2 has R, 1 request WO -> succeed
    lockingManager.unlock(LockType.OPTION, 1, keys);
    lockingManager.lock(LockType.READ, 1, keys, 100);
    try
    {
      lockingManager.lock(LockType.OPTION, 1, keys, 100); // Must succeed
    }
    catch (TimeoutRuntimeException e)
    {
      fail("Should not have thrown an exception");
    }
  }

  public void testBasicUpgradeFromReadToWriteLock() throws Exception
  {
    final RWOLockManager<Integer, Integer> lockingManager = new RWOLockManager<Integer, Integer>();

    Runnable step1 = new Runnable()
    {
      public void run()
      {
        Set<Integer> keys = new HashSet<Integer>();
        keys.add(1);
        try
        {
          lockingManager.lock(LockType.WRITE, 1, keys, 50000);
        }
        catch (InterruptedException ex)
        {
          fail("Should not have exception");
        }
      }
    };

    ExecutorService executors = getExecutorService();
    Set<Integer> keys = new HashSet<Integer>();
    keys.add(1);
    keys.add(2);
    keys.add(3);
    keys.add(4);

    msg("Context 1 have readlock 1,2,3,4");
    lockingManager.lock(LockType.READ, 1, keys, 1000);
    assertEquals(true, lockingManager.hasLock(LockType.READ, 1, 1));
    assertEquals(true, lockingManager.hasLock(LockType.READ, 1, 2));
    assertEquals(true, lockingManager.hasLock(LockType.READ, 1, 3));
    assertEquals(true, lockingManager.hasLock(LockType.READ, 1, 4));

    keys.clear();
    keys.add(1);
    keys.add(2);
    keys.add(3);

    msg("Context 2 have readlock 1,2,3");
    lockingManager.lock(LockType.READ, 2, keys, 1000);
    assertEquals(true, lockingManager.hasLock(LockType.READ, 2, 1));
    assertEquals(true, lockingManager.hasLock(LockType.READ, 2, 2));
    assertEquals(true, lockingManager.hasLock(LockType.READ, 2, 3));
    assertEquals(true, lockingManager.hasLockByOthers(LockType.READ, 2, 1));
    assertEquals(true, lockingManager.hasLockByOthers(LockType.READ, 1, 1));

    keys.clear();
    keys.add(4);

    msg("Context 1 have readlock 1,2,3,4 and writeLock 4");
    lockingManager.lock(LockType.WRITE, 1, keys, 1000);
    assertEquals(true, lockingManager.hasLock(LockType.READ, 1, 4));
    assertEquals(true, lockingManager.hasLock(LockType.WRITE, 1, 4));

    keys.clear();
    keys.add(1);

    try
    {
      lockingManager.lock(LockType.WRITE, 1, keys, 1000);
      fail("Should not have exception");
    }
    catch (RuntimeException expected)
    {
    }

    executors.execute(step1);
    executors.execute(step1);

    sleep(1000);

    keys.clear();
    keys.add(1);
    keys.add(2);
    keys.add(3);
    lockingManager.unlock(LockType.READ, 2, keys);

    new PollingTimeOuter()
    {
      @Override
      protected boolean successful()
      {
        return lockingManager.hasLock(LockType.WRITE, 1, 1);
      }
    }.assertNoTimeOut();
  }

  public void testBasicWrongUnlock() throws Exception
  {
    final RWOLockManager<Integer, Integer> lockingManager = new RWOLockManager<Integer, Integer>();
    Set<Integer> keys = new HashSet<Integer>();
    keys.add(1);
    lockingManager.lock(LockType.READ, 1, keys, 10000);
    lockingManager.unlock(LockType.READ, 1, keys);

    // As of 4.4 should not fail anymore.
    lockingManager.unlock(LockType.READ, 1, keys);
  }

  public void testReadTimeout() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    writeLock(company);

    CDOTransaction transaction2 = session.openTransaction();
    Company company2 = transaction2.getObject(company);

    long start = System.currentTimeMillis();
    assertWriteLock(false, company2);
    assertEquals(true, System.currentTimeMillis() - start < 300);

    start = System.currentTimeMillis();
    assertEquals(false, CDOUtil.getCDOObject(company2).cdoWriteLock().tryLock(1000, TimeUnit.MILLISECONDS));
    assertEquals(true, System.currentTimeMillis() - start >= 1000);
  }

  public void testReadLockByOthers() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    readLock(company);

    CDOTransaction transaction2 = session.openTransaction();
    final Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);

    new PollingTimeOuter()
    {
      @Override
      protected boolean successful()
      {
        try
        {
          CDOObject cdoCompany2 = CDOUtil.getCDOObject(company2);
          assertEquals(false, cdoCompany2.cdoWriteLock().isLockedByOthers());
          assertEquals(true, cdoCompany2.cdoReadLock().isLockedByOthers());
          return true;
        }
        catch (AssertionFailedError ex)
        {
          return false;
        }
      }
    }.assertNoTimeOut();
  }

  public void testDetachedObjects() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    CDOTransaction transaction2 = session.openTransaction();
    final Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);
    res.getContents().remove(0);

    transaction.commit();

    try
    {
      readLock(company2);
      fail("IllegalArgumentException expected");
    }
    catch (IllegalArgumentException expected)
    {
    }

    assertReadLock(false, company2);

    new PollingTimeOuter()
    {
      @Override
      protected boolean successful()
      {
        try
        {
          assertEquals(false, CDOUtil.getCDOObject(company2).cdoReadLock().isLockedByOthers());
          return true;
        }
        catch (AssertionFailedError ex)
        {
          return false;
        }
      }
    }.assertNoTimeOut();
  }

  public void testWriteLockByOthers() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    writeLock(company);

    CDOTransaction transaction2 = session.openTransaction();
    final Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);

    new PollingTimeOuter()
    {
      @Override
      protected boolean successful()
      {
        try
        {
          CDOObject cdoCompany2 = CDOUtil.getCDOObject(company2);
          assertEquals(true, cdoCompany2.cdoWriteLock().isLockedByOthers());
          assertEquals(false, cdoCompany2.cdoReadLock().isLockedByOthers());
          return true;
        }
        catch (AssertionFailedError ex)
        {
          return false;
        }
      }
    }.assertNoTimeOut();
  }

  public void testWriteLock() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    CDOTransaction transaction2 = session.openTransaction();
    Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);

    CDOObject cdoCompany = CDOUtil.getCDOObject(company);
    CDOObject cdoCompany2 = CDOUtil.getCDOObject(company2);

    transaction.lockObjects(Collections.singletonList(cdoCompany), LockType.WRITE, CDOLock.WAIT);

    try
    {
      transaction2.lockObjects(Collections.singletonList(cdoCompany2), LockType.WRITE, 1000);
      fail("LockTimeoutException expected");
    }
    catch (LockTimeoutException expected)
    {
    }

    company2.setCity("Ottawa");
    commitAndTimeout(transaction2);
  }

  public void testWriteLockViaObject() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    CDOTransaction transaction2 = session.openTransaction();
    Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);

    writeLock(company);
    assertWriteLock(false, company2);

    company2.setCity("Ottawa");
    commitAndTimeout(transaction2);
  }

  public void testWriteLockFromDifferenceTransaction() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    CDOTransaction transaction2 = session.openTransaction();
    Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);

    CDOObject cdoCompany = CDOUtil.getCDOObject(company);
    CDOObject cdoCompany2 = CDOUtil.getCDOObject(company2);

    transaction.lockObjects(Collections.singletonList(cdoCompany), LockType.WRITE, DEFAULT_TIMEOUT);

    try
    {
      transaction2.lockObjects(Collections.singletonList(cdoCompany2), LockType.WRITE, 1000);
      fail("LockTimeoutException expected");
    }
    catch (LockTimeoutException expected)
    {
    }
  }

  public void testWriteLockMultiple() throws Exception
  {
    Company company = getModel1Factory().createCompany();
    List<CDOObject> objects = new ArrayList<CDOObject>();

    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    transaction.lockObjects(objects, LockType.WRITE, DEFAULT_TIMEOUT);

    assertWriteLock(false, company);
    assertReadLock(false, company);
    for (CDOObject object : objects)
    {
      assertWriteLock(true, object);
      assertReadLock(false, object);
    }
  }

  public void testWriteUnlockMultiple() throws Exception
  {
    Company company = getModel1Factory().createCompany();
    List<CDOObject> objects = new ArrayList<CDOObject>();

    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    transaction.lockObjects(objects, LockType.WRITE, DEFAULT_TIMEOUT);

    assertWriteLock(false, company);
    assertReadLock(false, company);
    for (CDOObject object : objects)
    {
      assertWriteLock(true, object);
      assertReadLock(false, object);
    }

    transaction.unlockObjects(objects, LockType.WRITE);

    assertWriteLock(false, company);
    assertReadLock(false, company);
    for (CDOObject object : objects)
    {
      assertWriteLock(false, object);
      assertReadLock(false, object);
    }
  }

  public void testReadLockMultiple() throws Exception
  {
    Company company = getModel1Factory().createCompany();
    List<CDOObject> objects = new ArrayList<CDOObject>();

    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    transaction.lockObjects(objects, LockType.READ, DEFAULT_TIMEOUT);

    assertReadLock(false, company);
    assertWriteLock(false, company);
    for (CDOObject object : objects)
    {
      assertReadLock(true, object);
      assertWriteLock(false, object);
    }
  }

  public void testReadUnlockMultiple() throws Exception
  {
    Company company = getModel1Factory().createCompany();
    List<CDOObject> objects = new ArrayList<CDOObject>();

    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);
    addCategory(company, objects);

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    transaction.lockObjects(objects, LockType.READ, DEFAULT_TIMEOUT);

    assertReadLock(false, company);
    assertWriteLock(false, company);
    for (CDOObject object : objects)
    {
      assertReadLock(true, object);
      assertWriteLock(false, object);
    }

    transaction.unlockObjects(objects, LockType.READ);

    assertWriteLock(false, company);
    assertReadLock(false, company);
    for (CDOObject object : objects)
    {
      assertWriteLock(false, object);
      assertReadLock(false, object);
    }
  }

  public void testReadLockAndCommitFromDifferentTransaction() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    CDOTransaction transaction2 = session.openTransaction();
    Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);
    CDOObject cdoCompany = CDOUtil.getCDOObject(company);

    transaction.lockObjects(Collections.singletonList(cdoCompany), LockType.READ, DEFAULT_TIMEOUT);
    company2.setCity("Ottawa");
    commitAndTimeout(transaction2);
  }

  public void testWriteLockAndCommitFromDifferentTransaction() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    CDOTransaction transaction2 = session.openTransaction();
    Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);
    CDOObject cdoCompany = CDOUtil.getCDOObject(company);

    transaction.lockObjects(Collections.singletonList(cdoCompany), LockType.WRITE, DEFAULT_TIMEOUT);
    company2.setCity("Ottawa");
    commitAndTimeout(transaction2);
  }

  public void testReadLockAndCommitSameTransaction() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    readLock(company);

    company.setCity("Ottawa");
    transaction.commit();
  }

  public void testWriteLockAndCommitSameTransaction() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    writeLock(company);

    company.setCity("Ottawa");
    assertWriteLock(true, company);
    assertReadLock(false, company);

    transaction.commit();

    assertWriteLock(false, company);
    assertReadLock(false, company);
  }

  public void testWriteLockAndRollback() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    writeLock(company);
    company.setCity("Ottawa");

    transaction.rollback();
    assertWriteLock(false, company);
  }

  public void testLockUnlock() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();
    CDOObject cdoCompany = CDOUtil.getCDOObject(company);

    readLock(company);
    assertReadLock(true, company);
    assertWriteLock(false, company);

    writeLock(company);
    assertReadLock(true, company);
    assertWriteLock(true, company);

    readLock(company);
    assertReadLock(true, company);
    assertWriteLock(true, company);

    writeLock(company);
    assertReadLock(true, company);
    assertWriteLock(true, company);

    readUnlock(cdoCompany);
    assertReadLock(true, company);
    assertWriteLock(true, company);

    readUnlock(cdoCompany);
    assertReadLock(false, company);
    assertWriteLock(true, company);

    writeUnlock(cdoCompany);
    assertReadLock(false, company);
    assertWriteLock(true, company);

    writeUnlock(cdoCompany);
    assertReadLock(false, company);
    assertWriteLock(false, company);

    /********************/

    readLock(company);
    assertReadLock(true, company);
    assertWriteLock(false, company);

    writeLock(company);
    assertReadLock(true, company);
    assertWriteLock(true, company);

    readLock(company);
    assertReadLock(true, company);
    assertWriteLock(true, company);

    writeLock(company);
    assertReadLock(true, company);
    assertWriteLock(true, company);

    writeUnlock(cdoCompany);
    assertReadLock(true, company);
    assertWriteLock(true, company);

    writeUnlock(cdoCompany);
    assertReadLock(true, company);
    assertWriteLock(false, company);

    readUnlock(cdoCompany);
    assertReadLock(true, company);
    assertWriteLock(false, company);

    readUnlock(cdoCompany);
    assertReadLock(false, company);
    assertWriteLock(false, company);
  }

  /**
   * Bug 352191.
   */
  public void testLockDetached() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    res.getContents().remove(0);
    assertTransient(company);

    CDOObject cdoObject = CDOUtil.getCDOObject(company);
    transaction.lockObjects(Collections.singleton(cdoObject), LockType.WRITE, DEFAULT_TIMEOUT);

    // Verify
    CDOTransaction transaction2 = session.openTransaction();
    CDOResource res2 = transaction2.getResource(getResourcePath("/res1"));
    Company company2 = (Company)res2.getContents().get(0);
    company2.setName("NewName");
    commitAndTimeout(transaction2);
  }

  public void testTransactionClose() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    InternalRepository repo = getRepository();
    CDOSession session = openSession();

    CDOTransaction transaction = session.openTransaction();
    IView view = repo.getSessionManager().getSession(session.getSessionID()).getView(transaction.getViewID());
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    CDOObject cdoCompany = CDOUtil.getCDOObject(company);
    readLock(company);
    transaction.close();
    assertEquals(false, repo.getLockingManager().hasLock(LockType.READ, view, cdoCompany.cdoID()));
  }

  public void testSessionClose() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    InternalRepository repo = getRepository();
    CDOSession session = openSession();

    CDOTransaction transaction = session.openTransaction();
    IView view = repo.getSessionManager().getSession(session.getSessionID()).getView(transaction.getViewID());
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    CDOObject cdoCompany = CDOUtil.getCDOObject(company);
    readLock(company);
    session.close();

    sleep(100);
    assertEquals(false, repo.getLockingManager().hasLock(LockType.READ, view, cdoCompany.cdoID()));
  }

  public void testBugzilla_270345() throws Exception
  {
    Company company1 = getModel1Factory().createCompany();
    Company company2 = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction1 = session.openTransaction();
    CDOTransaction transaction2 = session.openTransaction();
    CDOResource res = transaction1.getOrCreateResource(getResourcePath("/res1"));
    res.getContents().add(company1);
    res.getContents().add(company2);
    transaction1.commit();

    writeLock(company1);
    assertWriteLock(true, company1);

    Company companyFrom2 = (Company)CDOUtil.getEObject(transaction2.getObject(company2));
    companyFrom2.setCity("sss");
    transaction2.commit();
    assertWriteLock(true, company1);
  }

  public void testAutoReleaseLockFalse_commit() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();
    transaction.options().setAutoReleaseLocksEnabled(false);

    writeLock(company);
    readLock(company);

    msg("Test with read/write lock");
    assertWriteLock(true, company);
    assertReadLock(true, company);

    company.setCity("Ottawa");
    transaction.commit();
    assertWriteLock(true, company);
    assertReadLock(true, company);

    msg("Clean locks");
    transaction.unlockObjects(null, null);

    msg("Test with read lock");
    readLock(company);
    assertReadLock(true, company);

    company.setCity("Toronto");
    transaction.commit();
    assertReadLock(true, company);

    transaction.options().setAutoReleaseLocksEnabled(true);
    transaction.commit();
    assertReadLock(false, company);
  }

  public void testAutoReleaseLockFalse_rollback() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();
    transaction.options().setAutoReleaseLocksEnabled(false);

    writeLock(company);
    readLock(company);

    msg("Test with read/write lock");
    assertWriteLock(true, company);
    assertReadLock(true, company);

    company.setCity("Ottawa");
    transaction.rollback();
    assertWriteLock(true, company);
    assertReadLock(true, company);

    msg("Clean locks");
    transaction.unlockObjects(null, null);

    msg("Test with read lock");
    readLock(company);
    assertReadLock(true, company);

    company.setCity("Toronto");
    transaction.rollback();
    assertReadLock(true, company);

    transaction.options().setAutoReleaseLocksEnabled(true);
    transaction.rollback();
    assertReadLock(false, company);
  }

  public void testWriteLockPerformance() throws Exception
  {
    final int ITERATION = 100;
    Company company = getModel1Factory().createCompany();

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));
    res.getContents().add(company);
    transaction.commit();

    long start = System.currentTimeMillis();

    // 335-418 locks/sec
    for (int i = 0; i < ITERATION; i++)
    {
      writeLock(company);
    }

    msg("Lock " + ITERATION / ((double)(System.currentTimeMillis() - start) / 1000) + " objects/sec");
  }

  public void testReadLockStaleRevision() throws Exception
  {
    lockStaleRevision(LockType.READ);
  }

  public void testWriteLockStaleRevision() throws Exception
  {
    lockStaleRevision(LockType.WRITE);
  }

  private void lockStaleRevision(LockType type) throws Exception
  {
    CDOSession session = openSession();
    session.options().setPassiveUpdateEnabled(false);
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));

    Company company = getModel1Factory().createCompany();
    company.setName("AAA");
    res.getContents().add(company);
    transaction.commit();

    updateInOtherSession();

    try
    {
      if (type == LockType.WRITE)
      {
        writeLock(company);
      }
      else if (type == LockType.READ)
      {
        readLock(company);
      }

      fail("StaleRevisionLockException expected");
    }
    catch (StaleRevisionLockException expected)
    {
    }

    session.close();
  }

  private void updateInOtherSession() throws CommitException
  {
    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.getResource(getResourcePath("/res1"));

    Company company = (Company)res.getContents().get(0);
    company.setName("BBB");
    transaction.commit();

    session.close();
  }

  private void addCategory(Company company, List<CDOObject> objects)
  {
    Category category = getModel1Factory().createCategory();
    company.getCategories().add(category);
    objects.add(CDOUtil.getCDOObject(category));
  }

  public void testRecursiveLock() throws Exception
  {
    CDOSession session = openSession();
    session.options().setPassiveUpdateEnabled(false);
    CDOTransaction transaction = session.openTransaction();
    CDOResource res = transaction.createResource(getResourcePath("/res1"));

    Category category1 = getModel1Factory().createCategory();
    Category category2_1 = getModel1Factory().createCategory();
    Category category2_2 = getModel1Factory().createCategory();
    Category category3 = getModel1Factory().createCategory();
    res.getContents().add(category1);
    category1.getCategories().add(category2_1);
    category1.getCategories().add(category2_2);
    category2_1.getCategories().add(category3);

    transaction.commit();

    CDOObject top = CDOUtil.getCDOObject(category1);
    transaction.lockObjects(Collections.singleton(top), LockType.WRITE, 5000, true);

    assertWriteLock(true, category1);
    assertWriteLock(true, category2_1);
    assertWriteLock(true, category2_2);
    assertWriteLock(true, category3);

    transaction.unlockObjects(Collections.singleton(top), LockType.WRITE, true);

    assertWriteLock(false, category1);
    assertWriteLock(false, category2_1);
    assertWriteLock(false, category2_2);
    assertWriteLock(false, category3);

    session.close();
  }

  public void testLockOnNewObject() throws Exception
  {
    CDOSession session1 = openSession();
    CDOSession session2 = openSession();

    CDOTransaction transaction = session1.openTransaction();
    transaction.options().setAutoReleaseLocksEnabled(false);
    CDOResource resource = transaction.createResource(getResourcePath("/res1"));
    transaction.commit();

    Category category1 = getModel1Factory().createCategory();
    Category category2 = getModel1Factory().createCategory();
    Category category3 = getModel1Factory().createCategory();
    resource.getContents().add(category1);
    resource.getContents().add(category2);
    resource.getContents().add(category3);

    readLock(category1);
    writeLock(category2);
    writeOption(category3);

    assertReadLock(true, category1);
    assertWriteLock(true, category2);
    assertWriteOption(true, category3);

    readUnlock(category1);
    writeUnlock(category2);
    writeUnoption(category3);

    assertReadLock(false, category1);
    assertWriteLock(false, category2);
    assertWriteLock(false, category3);

    readLock(category1);
    writeLock(category2);
    writeOption(category3);

    transaction.commit();

    CDOView controlView = session2.openView();
    controlView.options().setLockNotificationEnabled(true);
    CDOResource r = controlView.getResource(getResourcePath("/res1"));

    final CDOObject category1cv = CDOUtil.getCDOObject(r.getContents().get(0));
    final CDOObject category2cv = CDOUtil.getCDOObject(r.getContents().get(1));
    final CDOObject category3cv = CDOUtil.getCDOObject(r.getContents().get(2));

    new PollingTimeOuter()
    {
      @Override
      protected boolean successful()
      {
        try
        {
          assertEquals(true, category1cv.cdoReadLock().isLockedByOthers());
          assertEquals(true, category2cv.cdoWriteLock().isLockedByOthers());
          assertEquals(true, category3cv.cdoWriteOption().isLockedByOthers());
          return true;
        }
        catch (AssertionFailedError ex)
        {
          return false;
        }
      }
    }.assertNoTimeOut();

    readUnlock(category1);
    writeUnlock(category2);
    writeUnoption(category3);

    new PollingTimeOuter()
    {
      @Override
      protected boolean successful()
      {
        try
        {
          assertEquals(false, category1cv.cdoReadLock().isLockedByOthers());
          assertEquals(false, category2cv.cdoReadLock().isLockedByOthers());
          assertEquals(false, category3cv.cdoReadLock().isLockedByOthers());
          return true;
        }
        catch (AssertionFailedError ex)
        {
          return false;
        }
      }
    }.assertNoTimeOut();

    session1.close();
    session2.close();
  }

  public void testDeleteLockedObject() throws Exception
  {
    CDOSession session1 = openSession();
    CDOSession session2 = openSession();

    CDOTransaction tx = session1.openTransaction();
    tx.options().setAutoReleaseLocksEnabled(false);
    CDOResource resource = tx.createResource(getResourcePath("/res1"));
    Category category1 = getModel1Factory().createCategory();
    resource.getContents().add(category1);
    tx.commit();

    CDOID id = CDOUtil.getCDOObject(category1).cdoID();

    writeLock(category1);

    resource.getContents().remove(category1);
    tx.commit();

    CDOView controlView = session2.openView();

    try
    {
      controlView.getObject(id);
      fail("Should have thrown " + ObjectNotFoundException.class.getSimpleName());
    }
    catch (ObjectNotFoundException ignore)
    {
      // Do nothing
    }

    InternalLockManager mgr = getRepository().getLockingManager();
    boolean branching = getRepository().isSupportingBranches();
    Object key = branching ? CDOIDUtil.createIDAndBranch(id, tx.getBranch()) : id;
    LockState<Object, IView> state = mgr.getLockState(key);
    assertNull(state);
  }

  public void testAutoReleaseLocksOnUnchangedObject() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    Category category1 = getModel1Factory().createCategory();
    company.getCategories().add(category1);

    Category category2 = getModel1Factory().createCategory();
    company.getCategories().add(category2);

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();

    CDOResource resource = transaction.createResource(getResourcePath("/res1"));
    resource.getContents().add(company);
    transaction.commit();

    CDOLock writeLock = CDOUtil.getCDOObject(category1).cdoWriteLock();
    writeLock.lock(DEFAULT_TIMEOUT);

    // Check that explicit lock on unchanged object is not released
    transaction.options().setAutoReleaseLocksEnabled(false);
    category2.setName("NewName");
    transaction.commit();
    assertEquals(true, writeLock.isLocked()); // Explicit lock not released because of AutoReleaseLocks=false
    assertEquals(false, CDOUtil.getCDOObject(category2).cdoWriteLock().isLocked()); // Implicit locks always released

    // Check that explicit lock on unchanged object is released
    transaction.options().setAutoReleaseLocksEnabled(true);
    category2.setName("NewName2");
    transaction.commit();
    assertEquals(false, writeLock.isLocked()); // Explicit lock released because of AutoReleaseLocks=true
    assertEquals(false, CDOUtil.getCDOObject(category2).cdoWriteLock().isLocked()); // Implicit locks always released
  }

  public void testAutoReleaseLocksOnChangedObject() throws Exception
  {
    Company company = getModel1Factory().createCompany();

    Category category1 = getModel1Factory().createCategory();
    company.getCategories().add(category1);

    Category category2 = getModel1Factory().createCategory();
    company.getCategories().add(category2);

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();

    CDOResource resource = transaction.createResource(getResourcePath("/res1"));
    resource.getContents().add(company);
    transaction.commit();

    CDOLock writeLock = CDOUtil.getCDOObject(category1).cdoWriteLock();
    writeLock.lock(DEFAULT_TIMEOUT);

    // Check that explicit lock on changed object is not released
    transaction.options().setAutoReleaseLocksEnabled(false);
    category1.setName("NewName");
    transaction.commit();
    assertEquals(true, writeLock.isLocked());

    // Check that explicit lock on changed object is released
    transaction.options().setAutoReleaseLocksEnabled(true);
    category1.setName("NewName2");
    transaction.commit();
    assertEquals(false, writeLock.isLocked());
  }

  private void commitAndTimeout(CDOTransaction transaction)
  {
    InternalRepository repository = getRepository();
    long oldTimeout = repository.getOptimisticLockingTimeout();
    repository.setOptimisticLockingTimeout(1000);

    try
    {
      transaction.commit();
      fail("CommitException expected");
    }
    catch (CommitException expected)
    {
      // SUCCESS
    }
    finally
    {
      repository.setOptimisticLockingTimeout(oldTimeout);
    }
  }
}
