Package com.sleepycat.je.txn

Source Code of com.sleepycat.je.txn.LockManagerTest

/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2002-2005
*      Sleepycat Software.  All rights reserved.
*
* $Id: LockManagerTest.java,v 1.38 2005/01/28 17:43:09 mark Exp $
*/

package com.sleepycat.je.txn;

import java.io.File;

import junit.framework.TestCase;

import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.LockNotGrantedException;
import com.sleepycat.je.config.EnvironmentParams;
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.junit.JUnitThread;
import com.sleepycat.je.util.TestUtils;

public class LockManagerTest extends TestCase {
   
    private LockManager lockManager = null;
    private Locker txn1;
    private Locker txn2;
    private Locker txn3;
    private Locker txn4;
    private Long nid;
    private volatile int sequence;

    private EnvironmentImpl env;
    private File envHome;

    public LockManagerTest() {
        envHome =  new File(System.getProperty(TestUtils.DEST_DIR));
    }

    public void setUp()
  throws DatabaseException {

        EnvironmentConfig envConfig = TestUtils.initEnvConfig();
        envConfig.setConfigParam(EnvironmentParams.NODE_MAX.getName(), "6");
        envConfig.setAllowCreate(true);
        env = new EnvironmentImpl(envHome, envConfig);

        TxnManager txnManager = env.getTxnManager();
  lockManager = txnManager.getLockManager();
  txn1 = new BasicLocker(env);
  txn2 = new BasicLocker(env);
  txn3 = new BasicLocker(env);
  txn4 = new BasicLocker(env);
  nid = new Long(1);
  sequence = 0;
    }

    public void tearDown()
  throws DatabaseException {

        txn1.operationEnd();
        txn2.operationEnd();
        txn3.operationEnd();
        txn4.operationEnd();
        env.close();
    }

    public void testNegatives()
        throws Exception {

  try {
      assertFalse(lockManager.isOwner(nid, txn1, LockType.READ));
      assertFalse(lockManager.isOwner(nid, txn1, LockType.WRITE));
      assertFalse(lockManager.isLocked(nid));
      assertFalse(lockManager.isWaiter(nid, txn1));
      lockManager.lock(1, txn1, LockType.READ, 0, false, null);

      /* already holds this lock */
      assertEquals(LockGrantType.EXISTING,
                         lockManager.lock(1, txn1, LockType.READ, 0,
            false, null));
      assertFalse(lockManager.isOwner(nid, txn2, LockType.READ));
      assertFalse(lockManager.isOwner(nid, txn2, LockType.WRITE));
      assertTrue(lockManager.isLocked(nid));
      assertTrue(lockManager.nOwners(new Long(2)) == -1);
      assertTrue(lockManager.nWaiters(new Long(2)) == -1);

            /* lock 2 doesn't exist, shouldn't affect any the existing lock */
      lockManager.release(2L, txn1);
      assertTrue(lockManager.isLocked(nid));
           
            /* txn2 is not the owner, shouldn't release lock 1. */
      lockManager.release(1L, txn2);
      assertTrue(lockManager.isLocked(nid));
            assertTrue(lockManager.isOwner(nid, txn1, LockType.READ));
      assertTrue(lockManager.nOwners(nid) == 1);

            /* Now really release. */
      lockManager.release(1L, txn1);
      assertFalse(lockManager.isLocked(nid));
            assertFalse(lockManager.isOwner(nid, txn1, LockType.READ));
      assertFalse(lockManager.nOwners(nid) == 1);

      lockManager.lock(1, txn1, LockType.WRITE, 0, false, null);
      /* holds write and subsequent request for READ is ok */
      lockManager.lock(1, txn1, LockType.READ, 0, false, null);
      /* already holds this lock */
      assertTrue(lockManager.lock(1, txn1, LockType.WRITE,
          0, false, null) ==
           LockGrantType.EXISTING);
      assertFalse(lockManager.isWaiter(nid, txn1));
  } catch (Exception e) {
            e.printStackTrace();
            throw e;
  }
    }

    /**
     * Acquire three read locks and make sure that they share nicely.
     */
    public void testMultipleReaders()
  throws Throwable {

  JUnitThread tester1 =
      new JUnitThread("testMultipleReaders1") {
    public void testBody() {
        try {
      lockManager.lock(1, txn1, LockType.READ, 0,
           false, null);
      assertTrue
          (lockManager.isOwner(nid, txn1, LockType.READ));
      sequence++;
      while (sequence < 3) {
          Thread.yield();
      }
      lockManager.release(1L, txn1);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  JUnitThread tester2 =
      new JUnitThread("testMultipleReaders2") {
    public void testBody() {
        try {
      lockManager.lock(1, txn2, LockType.READ, 0,
           false, null);
      assertTrue
          (lockManager.isOwner(nid, txn2, LockType.READ));
      sequence++;
      while (sequence < 3) {
          Thread.yield();
      }
      lockManager.release(1L, txn2);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  JUnitThread tester3 =
      new JUnitThread("testMultipleReaders3") {
    public void testBody() {
        try {
      lockManager.lock(1, txn3, LockType.READ, 0,
           false, null);
      assertTrue
          (lockManager.isOwner(nid, txn3, LockType.READ));
      sequence++;
      while (sequence < 3) {
          Thread.yield();
      }
      lockManager.release(1L, txn3);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  tester1.start();
  tester2.start();
  tester3.start();
  tester1.finishTest();
  tester2.finishTest();
  tester3.finishTest();
    }

    /**
     * Grab two read locks, hold them, and make sure that a write lock
     * waits for them to be released.
     */
    public void testMultipleReadersSingleWrite1()
  throws Throwable {

  JUnitThread tester1 =
      new JUnitThread("testMultipleReaders1") {
    public void testBody() {
        try {
      lockManager.lock(1, txn1, LockType.READ, 0,
           false, null);
      assertTrue
          (lockManager.isOwner(nid, txn1, LockType.READ));
      while (lockManager.nWaiters(nid) < 1) {
          Thread.yield();
      }
      assertTrue(lockManager.isWaiter(nid, txn3));
      assertFalse(lockManager.isWaiter(nid, txn1));
      lockManager.release(1L, txn1);
      assertFalse
          (lockManager.isOwner(nid, txn1, LockType.READ));
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  JUnitThread tester2 =
      new JUnitThread("testMultipleReaders2") {
    public void testBody() {
        try {
      lockManager.lock(1, txn2, LockType.READ, 0,
           false, null);
      assertTrue
          (lockManager.isOwner(nid, txn2, LockType.READ));
      while (lockManager.nWaiters(nid) < 1) {
          Thread.yield();
      }
      assertTrue(lockManager.isWaiter(nid, txn3));
      lockManager.release(1L, txn2);
      assertFalse
          (lockManager.isOwner(nid, txn2, LockType.READ));
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  JUnitThread tester3 =
      new JUnitThread("testMultipleReaders3") {
    public void testBody() {
        try {
      while (lockManager.nOwners(nid) < 2) {
          Thread.yield();
      }
      lockManager.lock(1, txn3, LockType.WRITE, 0,
           false, null);
      assertTrue
          (lockManager.isOwner(nid, txn3, LockType.WRITE));
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  tester1.start();
  tester2.start();
  tester3.start();
  tester1.finishTest();
  tester2.finishTest();
  tester3.finishTest();
    }

    /**
     * Acquire two read locks, put a write locker behind the two
     * read lockers, and then queue a read locker behind the writer.
     * Ensure that the third reader is not granted until the writer
     * releases the lock.
     */
    public void testMultipleReadersSingleWrite2()
  throws Throwable {

  JUnitThread tester1 =
      new JUnitThread("testMultipleReaders1") {
    public void testBody() {
        try {
      lockManager.lock(1, txn1, LockType.READ, 0,
           false, null);
      assertTrue
          (lockManager.isOwner(nid, txn1, LockType.READ));
      while (lockManager.nWaiters(nid) < 2) {
          Thread.yield();
      }
      lockManager.release(1L, txn1);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  JUnitThread tester2 =
      new JUnitThread("testMultipleReaders2") {
    public void testBody() {
        try {
      lockManager.lock(1, txn2, LockType.READ, 0,
           false, null);
      assertTrue
          (lockManager.isOwner(nid, txn2, LockType.READ));
      while (lockManager.nWaiters(nid) < 2) {
          Thread.yield();
      }
      lockManager.release(1L, txn2);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  JUnitThread tester3 =
      new JUnitThread("testMultipleReaders3") {
    public void testBody() {
        try {
      while (lockManager.nOwners(nid) < 2) {
          Thread.yield();
      }
      lockManager.lock(1, txn3, LockType.WRITE, 0,
           false, null);
      while (lockManager.nWaiters(nid) < 1) {
          Thread.yield();
      }
      assertTrue
          (lockManager.isOwner(nid, txn3, LockType.WRITE));
      lockManager.release(1L, txn3);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  JUnitThread tester4 =
      new JUnitThread("testMultipleReaders4") {
    public void testBody() {
        try {
      while (lockManager.nWaiters(nid) < 1) {
          Thread.yield();
      }
      lockManager.lock(1, txn4, LockType.READ, 0,
           false, null);
      assertTrue
          (lockManager.isOwner(nid, txn4, LockType.READ));
      lockManager.release(1L, txn4);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  tester1.start();
  tester2.start();
  tester3.start();
  tester4.start();
  tester1.finishTest();
  tester2.finishTest();
  tester3.finishTest();
  tester4.finishTest();
    }

    /**
     * Acquire two read locks for two transactions, then request a write
     * lock for a third transaction.  Then request a write lock for one
     * of the first transactions that already has a read lock (i.e.
     * request an upgrade lock).  Make sure it butts in front of the
     * existing wait lock.
     */
    public void testUpgradeLock()
  throws Throwable {

  JUnitThread tester1 =
      new JUnitThread("testUpgradeLock1") {
    public void testBody() {
        try {
      lockManager.lock(1, txn1, LockType.READ, 0,
           false, null);
      assertTrue
          (lockManager.isOwner(nid, txn1, LockType.READ));
      while (lockManager.nWaiters(nid) < 2) {
          Thread.yield();
      }
      lockManager.release(1L, txn1);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  JUnitThread tester2 =
      new JUnitThread("testUpgradeLock2") {
    public void testBody() {
        try {
      lockManager.lock(1, txn2, LockType.READ, 0,
           false, null);
      assertTrue
          (lockManager.isOwner(nid, txn2, LockType.READ));
      while (lockManager.nWaiters(nid) < 1) {
          Thread.yield();
      }
      lockManager.lock(1, txn2, LockType.WRITE, 0,
           false, null);
      assertTrue(lockManager.nWaiters(nid) == 1);
      lockManager.release(1L, txn2);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  JUnitThread tester3 =
      new JUnitThread("testUpgradeLock3") {
    public void testBody() {
        try {
      while (lockManager.nOwners(nid) < 2) {
          Thread.yield();
      }
      lockManager.lock(1, txn3, LockType.WRITE, 0,
           false, null);
      assertTrue
          (lockManager.isOwner(nid, txn3, LockType.WRITE));
      lockManager.release(1L, txn3);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  tester1.start();
  tester2.start();
  tester3.start();
  tester1.finishTest();
  tester2.finishTest();
  tester3.finishTest();
    }

    /**
     * Acquire a read lock, then request a write lock for a second
     * transaction in non-blocking mode.  Make sure it fails.
     */
    public void testNonBlockingLock1()
  throws Throwable {

  JUnitThread tester1 =
      new JUnitThread("testNonBlocking1") {
    public void testBody() {
        try {
      lockManager.lock(1, txn1, LockType.READ, 0,
           false, null);
      assertTrue
          (lockManager.isOwner(nid, txn1, LockType.READ));
      while (sequence < 1) {
          Thread.yield();
      }
      lockManager.release(1L, txn1);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  JUnitThread tester2 =
      new JUnitThread("testNonBlocking2") {
    public void testBody() {
        try {
      /* wait for tester1 */
      while (lockManager.nOwners(nid) < 1) {
          Thread.yield();
      }
      try {
          lockManager.lock(1, txn2, LockType.WRITE,
               0, true, null);
                            fail();
                        } catch (LockNotGrantedException expected) {}
      assertFalse
          (lockManager.isOwner(nid, txn2, LockType.WRITE));
      assertFalse
          (lockManager.isOwner(nid, txn2, LockType.READ));
      assertTrue(lockManager.nWaiters(nid) == 0);
      assertTrue(lockManager.nOwners(nid) == 1);
      sequence++;
      /* wait for tester1 to release the lock */
      while (lockManager.nOwners(nid) > 0) {
          Thread.yield();
      }
      assertTrue
          (lockManager.lock(1, txn2, LockType.WRITE, 0,
                                              false, null) ==
           LockGrantType.NEW);
      assertTrue
          (lockManager.isOwner(nid, txn2, LockType.WRITE));
      assertTrue
          (lockManager.isOwner(nid, txn2, LockType.READ));
      assertTrue(lockManager.nWaiters(nid) == 0);
      assertTrue(lockManager.nOwners(nid) == 1);
      lockManager.release(1L, txn2);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  tester1.start();
  tester2.start();
  tester1.finishTest();
  tester2.finishTest();
    }

    /**
     * Acquire a write lock, then request a read lock for a second
     * transaction in non-blocking mode.  Make sure it fails.
     */
    public void testNonBlockingLock2()
  throws Throwable {

  JUnitThread tester1 =
      new JUnitThread("testNonBlocking1") {
    public void testBody() {
        try {
      lockManager.lock(1, txn1, LockType.WRITE, 0,
           false, null);
      assertTrue
          (lockManager.isOwner(nid, txn1, LockType.WRITE));
      sequence++;
      while (sequence < 2) {
          Thread.yield();
      }
      lockManager.release(1L, txn1);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  JUnitThread tester2 =
      new JUnitThread("testNonBlocking2") {
    public void testBody() {
        try {
      /* wait for tester1 */
      while (sequence < 1) {
          Thread.yield();
      }
                        try {
          lockManager.lock(1, txn2, LockType.READ,
               0, true, null);
                            fail();
                        } catch (LockNotGrantedException expected) {}
      assertFalse
          (lockManager.isOwner(nid, txn2, LockType.READ));
      assertFalse
          (lockManager.isOwner(nid, txn2, LockType.WRITE));
      assertTrue(lockManager.nWaiters(nid) == 0);
      assertTrue(lockManager.nOwners(nid) == 1);
      sequence++;
      /* wait for tester1 to release the lock */
      while (lockManager.nOwners(nid) > 0) {
          Thread.yield();
      }
      assertTrue
          (lockManager.lock(1, txn2, LockType.READ, 0,
                                              false, null) ==
           LockGrantType.NEW);
      assertTrue
          (lockManager.isOwner(nid, txn2, LockType.READ));
      assertFalse
          (lockManager.isOwner(nid, txn2, LockType.WRITE));
      assertTrue(lockManager.nWaiters(nid) == 0);
      assertTrue(lockManager.nOwners(nid) == 1);
      lockManager.release(1L, txn2);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  tester1.start();
  tester2.start();
  tester1.finishTest();
  tester2.finishTest();
    }

    /**
     * Acquire a write lock, then request a read lock for a second
     * transaction in blocking mode.  Make sure it waits.
     */
    public void testWaitingLock()
  throws Throwable {

  JUnitThread tester1 =
      new JUnitThread("testBlocking1") {
    public void testBody() {
        try {
      lockManager.lock(1, txn1, LockType.WRITE, 0,
           false, null);
      assertTrue
          (lockManager.isOwner(nid, txn1, LockType.WRITE));
      sequence++;
      while (sequence < 2) {
          Thread.yield();
      }
      lockManager.release(1L, txn1);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  JUnitThread tester2 =
      new JUnitThread("testBlocking2") {
    public void testBody() {
        try {
      /* wait for tester1 */
      while (sequence < 1) {
          Thread.yield();
      }
      try {
          lockManager.lock(1, txn2, LockType.READ, 500,
                                             false, null);
          fail("didn't time out");
      } catch (LockTimeOutException e) {
      }
      assertFalse
          (lockManager.isOwner(nid, txn2, LockType.READ));
      assertFalse
          (lockManager.isOwner(nid, txn2, LockType.WRITE));
      assertTrue(lockManager.nWaiters(nid) == 0);
      assertTrue(lockManager.nOwners(nid) == 1);
      sequence++;
      /* wait for tester1 to release the lock */
      while (lockManager.nOwners(nid) > 0) {
          Thread.yield();
      }
      assertTrue
          (lockManager.lock(1, txn2, LockType.READ, 0,
                                              false, null) ==
           LockGrantType.NEW);
      assertTrue
          (lockManager.isOwner(nid, txn2, LockType.READ));
      assertFalse
          (lockManager.isOwner(nid, txn2, LockType.WRITE));
      assertTrue(lockManager.nWaiters(nid) == 0);
      assertTrue(lockManager.nOwners(nid) == 1);
      lockManager.release(1L, txn2);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("caught DatabaseException " + DBE);
        }
    }
      };

  tester1.start();
  tester2.start();
  tester1.finishTest();
  tester2.finishTest();
    }

    public void xtestDeadlock()
  throws Throwable {

  JUnitThread tester1 =
      new JUnitThread("testDeadlock1") {
    public void testBody() {
        try {
      lockManager.lock(1, txn1, LockType.WRITE, 0,
           false, null);
      System.out.println("t1 has locked 1");
      assertTrue
          (lockManager.isOwner(nid, txn1, LockType.WRITE));
      sequence++;     // bump to 1

      /* wait for tester2 */
      while (sequence < 2) {
          Thread.yield();
      }

      lockManager.lock(2, txn1, LockType.READ, 1000,
           false, null);
      System.out.println("t1 about to sleep");
      Thread.sleep(5000);

      lockManager.release(1, txn1);
      lockManager.release(2, txn1);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("tester1 caught DatabaseException " + DBE);
        } catch (InterruptedException IE) {
      fail("tester1 caught InterruptedException " + IE);
        }
    }
      };

  JUnitThread tester2 =
      new JUnitThread("testDeadlock2") {
    public void testBody() {
        try {
      /* wait for tester1 */
      while (sequence < 1) {
          Thread.yield();
      }

      lockManager.lock(2, txn2, LockType.WRITE, 0,
           false, null);
      System.out.println("t2 has locked 2");

      sequence++;   // bump to 2

      System.out.println("t2 about to lock 1");
      lockManager.lock(1, txn2, LockType.READ, 1000,
           false, null);
      System.out.println("t2 about to sleep");
      Thread.sleep(5000);

      lockManager.release(1, txn2);
      lockManager.release(2, txn1);
        } catch (DatabaseException DBE) {
                        DBE.printStackTrace();
      fail("tester2 caught DatabaseException " + DBE);
        } catch (InterruptedException IE) {
      fail("tester2 caught InterruptedException " + IE);
        }
    }
      };

  tester1.start();
  tester2.start();
  //tester3.start();
  tester1.finishTest();
  tester2.finishTest();
  //tester3.finishTest();
    }
}
TOP

Related Classes of com.sleepycat.je.txn.LockManagerTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.