Package com.sun.sgs.test.impl.kernel

Source Code of com.sun.sgs.test.impl.kernel.TestLockingAccessCoordinator

/*
* Copyright 2007-2010 Sun Microsystems, Inc.
*
* This file is part of Project Darkstar Server.
*
* Project Darkstar Server is free software: you can redistribute it
* and/or modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation and
* distributed hereunder to you.
*
* Project Darkstar Server is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* --
*/

package com.sun.sgs.test.impl.kernel;

import com.sun.sgs.app.TransactionConflictException;
import com.sun.sgs.app.TransactionTimeoutException;
import com.sun.sgs.impl.kernel.LockingAccessCoordinator;
import com.sun.sgs.kernel.AccessReporter;
import com.sun.sgs.kernel.AccessReporter.AccessType;
import com.sun.sgs.profile.AccessedObjectsDetail;
import com.sun.sgs.profile.AccessedObjectsDetail.ConflictType;
import com.sun.sgs.test.util.DummyTransaction;
import com.sun.sgs.tools.test.FilteredNameRunner;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;

/** Tests the {@link LockingAccessCoordinator} class. */
@RunWith(FilteredNameRunner.class)
public class TestLockingAccessCoordinator
    extends BasicAccessCoordinatorTest<LockingAccessCoordinator>
{
    /** Override for the lock timeout. */
    private static long lockTimeout;

    /** Override for the number of key maps. */
    private static int numKeyMaps;

    /** Update the lock timeout and number of key maps. */
    @BeforeClass
    public static void beforeClass() {
  lockTimeout = Long.getLong("test.lockTimeout", -1);
  numKeyMaps = Integer.getInteger("test.numKeyMaps", -1);
    }

    /** Initialize fields for test methods. */
    protected void init() {
  init(lockTimeout, numKeyMaps);
    }

    /**
     * Initialize fields with the specified lock timeout and number of key
     * maps.
     */
    protected void init(long lockTimeout, int numKeyMaps) {
  if (lockTimeout > 0 &&
      properties.getProperty(
    LockingAccessCoordinator.LOCK_TIMEOUT_PROPERTY) == null)
  {
      properties.setProperty(
    LockingAccessCoordinator.LOCK_TIMEOUT_PROPERTY,
    String.valueOf(lockTimeout));
  }
  if (numKeyMaps > 0 &&
      properties.getProperty(
    LockingAccessCoordinator.NUM_KEY_MAPS_PROPERTY) == null)
  {
      properties.setProperty(
    LockingAccessCoordinator.NUM_KEY_MAPS_PROPERTY,
    String.valueOf(numKeyMaps));
  }
  super.init();
    }

    /** Creates a {@code LockingAccessCoordinator}. */
    protected LockingAccessCoordinator createAccessCoordinator() {
  return new LockingAccessCoordinator(
      properties, txnProxy, profileCollector);
    }

    /* -- Tests -- */

    /* -- Test constructor -- */

    @Test(expected=NullPointerException.class)
    public void testConstructorNullProperties() {
  new LockingAccessCoordinator(null, txnProxy, profileCollector);
    }

    @Test(expected=NullPointerException.class)
    public void testConstructorNullTxnProxy() {
  new LockingAccessCoordinator(properties, null, profileCollector);
    }

    @Test(expected=NullPointerException.class)
    public void testConstructorNullProfileCollector() {
  new LockingAccessCoordinator(properties, txnProxy, null);
    }

    @Test
    public void testConstructorIllegalLockTimeout() {
  String[] values = { "0", "-37" };
  for (String value : values) {
      properties.setProperty(
    LockingAccessCoordinator.LOCK_TIMEOUT_PROPERTY, value);
      try {
    new LockingAccessCoordinator(
        properties, txnProxy, profileCollector);
    fail("Expected IllegalArgumentException");
      } catch (IllegalArgumentException e) {
    System.err.println(e);
      }
  }
    }

    @Test
    public void testConstructorIllegalNumKeyMaps() {
  String[] values = { "0", "-50" };
  for (String value : values) {
      properties.setProperty(
    LockingAccessCoordinator.NUM_KEY_MAPS_PROPERTY, value);
      try {
    new LockingAccessCoordinator(
        properties, txnProxy, profileCollector);
    fail("Expected IllegalArgumentException");
      } catch (IllegalArgumentException e) {
    System.err.println(e);
      }
  }
    }

    /* -- Test AccessedObjectsDetail more -- */

    @Test
    public void testAccessedObjectsDetailTimeout() throws Exception {
  reporter.reportObjectAccess(txn, "o1", AccessType.WRITE);
  DummyTransaction txn2 = new DummyTransaction(1);
  coordinator.notifyNewTransaction(txn2, 0, 1);
  Thread.sleep(2);
  try {
      reporter.reportObjectAccess(
    txn2, "o1", AccessType.WRITE, "Object 1");
      fail("Expected TransactionTimeoutException");
  } catch (TransactionTimeoutException e) {
      System.err.println(e);
  }
  AccessedObjectsDetail detail =
      profileCollector.getAccessedObjectsDetail();
  assertObjectDetails(detail, "s", "o1", AccessType.WRITE, "Object 1");
  assertEquals(ConflictType.ACCESS_NOT_GRANTED,
         detail.getConflictType());
  assertArrayEquals(txn.getId(), detail.getConflictingId());
  txn.abort(ABORT_EXCEPTION);
  txn = null;
  detail = profileCollector.getAccessedObjectsDetail();
  assertObjectDetails(detail, "s", "o1", AccessType.WRITE, null);
  assertEquals(ConflictType.NONE, detail.getConflictType());
  assertEquals(null, detail.getConflictingId());
    }

    @Test
    public void testAccessedObjectsDetailTimeoutDescriptionFails()
  throws Exception
    {
  reporter.reportObjectAccess(txn, "o1", AccessType.WRITE);
  DummyTransaction txn2 = new DummyTransaction(1);
  coordinator.notifyNewTransaction(txn2, 0, 1);
  Thread.sleep(2);
  try {
      reporter.reportObjectAccess(
    txn2, "o1", AccessType.WRITE,
    new Object() {
        public String toString() {
      throw new RuntimeException();
        }
    });
      fail("Expected TransactionTimeoutException");
  } catch (TransactionTimeoutException e) {
      System.err.println(e);
  }
    }

    @Test
    public void testAccessedObjectsDetailDeadlock() throws Exception {
  init(100, -1);
  DummyTransaction txn2 = new DummyTransaction();
  coordinator.notifyNewTransaction(txn2, 1000, 1);
  reporter.reportObjectAccess(txn, "o1", AccessType.READ);
  reporter.reportObjectAccess(txn2, "o2", AccessType.READ);
  FutureTask<Exception> attempt =
      new FutureTask<Exception>(
    new Callable<Exception>() {
        public Exception call() throws Exception {
      try {
          reporter.reportObjectAccess(
        txn, "o2", AccessType.WRITE);
          return null;
      } catch (Exception e) {
          e.printStackTrace();
          return e;
      }
        }
    });
  new Thread(attempt).start();
  try {
      attempt.get(20, TimeUnit.MILLISECONDS);
      fail("Expected timeout");
  } catch (TimeoutException e) {
  }
  try {
      reporter.reportObjectAccess(txn2, "o1", AccessType.WRITE);
      fail("Expected TransactionConflictException");
  } catch (TransactionConflictException e) {
      System.err.println(e);
  }
  assertEquals(null, attempt.get());
  AccessedObjectsDetail detail =
      profileCollector.getAccessedObjectsDetail();
  assertObjectDetails(detail,
          "s", "o2", AccessType.READ, null,
          "s", "o1", AccessType.WRITE, null);
  assertEquals(ConflictType.DEADLOCK, detail.getConflictType());
  assertArrayEquals(txn.getId(), detail.getConflictingId());
  txn.commit();
  txn = null;
  detail = profileCollector.getAccessedObjectsDetail();
  assertObjectDetails(detail,
          "s", "o1", AccessType.READ, null,
          "s", "o2", AccessType.WRITE, null);
  assertEquals(ConflictType.NONE, detail.getConflictType());
  assertEquals(null, detail.getConflictingId());
    }

    /* -- Other tests -- */

    /**
     * Tests requesting shared locks simultaneously from multiple threads, to
     * measure performance for what should be the fastest case.
     */
    @Test
    public void testPerformance() throws Exception {
  int repeat = Integer.getInteger("test.repeat", 4);
  int threads = Integer.getInteger("test.threads", 4);
  /* Use 5000 for a good stress test */
  final int count = Integer.getInteger("test.count", 100);
  final int locks = Integer.getInteger("test.locks", 100);
  System.err.println("repeat: " + repeat +
         "\nthreads: " + threads +
         "\ncount: " + count +
         "\nlocks: " + locks);
  for (int r = 0; r < repeat; r++) {
      final CountDownLatch counter = new CountDownLatch(threads);
      long start = System.currentTimeMillis();
      for (int i = 0; i < threads; i++) {
    new Thread() {
        public void run() {
      for (int c = 0; c < count; c++) {
          DummyTransaction txn = new DummyTransaction();
          coordinator.notifyNewTransaction(txn, 0, 1);
          for (int i = 0; i < locks; i++) {
        reporter.reportObjectAccess(
            txn, "o" + i, AccessType.READ);
          }
          txn.abort(ABORT_EXCEPTION);
      }
      counter.countDown();
        }
    }.start();
      }
      counter.await();
      long time = System.currentTimeMillis() - start;
      System.err.println(
    time + " ms" +
    ", " + ((double) time / (count * locks)) + " ms/lock");
  }
    }
}
TOP

Related Classes of com.sun.sgs.test.impl.kernel.TestLockingAccessCoordinator

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.