You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by fu...@apache.org on 2005/03/03 02:30:45 UTC

svn commit: r155990 [5/15] - in incubator/derby/code/trunk: ./ java/testing/ java/testing/org/apache/derbyTesting/functionTests/harness/ java/testing/org/apache/derbyTesting/functionTests/master/ java/testing/org/apache/derbyTesting/functionTests/suites/ java/testing/org/apache/derbyTesting/functionTests/tests/lang/ java/testing/org/apache/derbyTesting/functionTests/tests/store/ java/testing/org/apache/derbyTesting/functionTests/tests/unit/ java/testing/org/apache/derbyTesting/unitTests/ java/testing/org/apache/derbyTesting/unitTests/crypto/ java/testing/org/apache/derbyTesting/unitTests/harness/ java/testing/org/apache/derbyTesting/unitTests/lang/ java/testing/org/apache/derbyTesting/unitTests/services/ java/testing/org/apache/derbyTesting/unitTests/store/ java/testing/org/apache/derbyTesting/unitTests/util/

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_Key.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_Key.java?view=auto&rev=155990
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_Key.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_Key.java Wed Mar  2 17:30:05 2005
@@ -0,0 +1,130 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.unitTests.services.T_Key
+
+   Copyright 1997, 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.unitTests.services;
+
+/**
+
+	Key for these objects is an array of objects
+
+	value - Integer or String - implies what object should be used in the cache.
+	waitms - time to wait in ms on a set or create (simulates the object being loaded into the cache).
+	canFind - true of the object can be found on a set, false if it can't. (simulates a request for a non-existent object)
+	raiseException - true if an exception should be raised during set or create identity
+
+
+*/
+public class T_Key  {
+
+	private Object	value;
+	private long		waitms;
+	private boolean   canFind;
+	private boolean   raiseException;
+
+	public static T_Key		simpleInt(int value) {
+		return new T_Key(new Integer(value), 0, true, false);
+	}
+	public static T_Key		dontFindInt(int value) {
+		return new T_Key(new Integer(value), 0, false, false);
+	}
+	public static T_Key		exceptionInt(int value) {
+		return new T_Key(new Integer(value), 0, true, true);
+	}
+	
+	/**
+		48%/48%/4% chance of Int/String/invalid key
+		90%/5%/5% chance of can find / can't find / raise exception
+	*/
+	public static T_Key randomKey() {
+
+		double rand = Math.random();
+		T_Key tkey = new T_Key();
+
+		if (rand < 0.48)
+			tkey.value = new Integer((int) (100.0 * rand));
+		else if (rand < 0.96)
+			tkey.value = new Integer((int) (100.0 * rand));
+		else
+			tkey.value = Boolean.FALSE;
+
+		rand = Math.random();
+
+		if (rand < 0.90)
+			tkey.canFind = true;
+		else if (rand < 0.95)
+			tkey.canFind = false;
+		else {
+			tkey.canFind = true;
+			tkey.raiseException = false;
+		}
+
+		rand = Math.random();
+
+		if (rand < 0.30) {
+			tkey.waitms = (long) (rand * 1000.0); // Range 0 - 0.3 secs
+		}
+
+		return tkey;
+	}
+
+	private T_Key() {
+	}
+
+
+	private T_Key(Object value, long waitms, boolean canFind, boolean raiseException) {
+
+		this.value = value;
+		this.waitms = waitms;
+		this.canFind = canFind;
+		this.raiseException = raiseException;
+	}
+
+	public Object getValue() {
+		return value;
+	}
+
+	public long getWait() {
+		return waitms;
+	}
+
+	public boolean canFind() {
+		return canFind;
+	}
+
+	public boolean raiseException() {
+		return raiseException;
+	}
+
+	public boolean equals(Object other) {
+		if (other instanceof T_Key) {
+			return value.equals(((T_Key) other).value);
+		}
+		return false;
+	}
+
+	public int hashCode() {
+		return value.hashCode();
+	}
+
+	public String toString() {
+		return value + " " + waitms + " " + canFind + " " + raiseException;
+	}
+}
+

Propchange: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_Key.java
------------------------------------------------------------------------------
    snv:eol-style = native

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_L1.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_L1.java?view=auto&rev=155990
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_L1.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_L1.java Wed Mar  2 17:30:05 2005
@@ -0,0 +1,88 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.unitTests.services.T_L1
+
+   Copyright 1997, 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.unitTests.services;
+
+import org.apache.derby.iapi.services.locks.*;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+import java.util.Hashtable;
+
+/**
+	Unit test Lockable
+	<BR>
+	A simple Lockable that allows a single locker, but that locker
+	can lock the object multiple times, standard Lockable behaviour.
+*/
+
+class T_L1 implements Lockable {
+
+	long value = 0;
+	int count = 0;
+
+	Latch latch;
+
+	T_L1() {
+	}
+
+	/*
+	** Lockable methods (Simple, qualifier assumed to be null).
+	*/
+
+	/** 
+		Qualififier is assumed to be null.
+	@see Lockable#lockEvent
+	*/
+	public void lockEvent(Latch lockInfo) {
+        if (SanityManager.DEBUG)
+            SanityManager.ASSERT(lockInfo.getQualifier() == null);
+
+		latch = lockInfo;
+
+		count++;
+	}
+
+	public boolean requestCompatible(Object requestedQualifier, Object grantedQualifier) {
+		return false;
+	}
+
+	public boolean lockerAlwaysCompatible() {
+		return true;
+	}
+
+	/** 
+		Qualififier is assumed to be null.
+	@see Lockable#unlockEvent
+	*/
+	public void unlockEvent(Latch lockInfo) {
+        if (SanityManager.DEBUG)
+            SanityManager.ASSERT(lockInfo.getQualifier() == null);
+		
+		count--;
+        if (SanityManager.DEBUG)
+            SanityManager.ASSERT(count >= 0);
+		latch = null;
+	}
+
+	public boolean lockAttributes(int flag, Hashtable t)
+	{
+		return false;
+	}
+}

Propchange: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_L1.java
------------------------------------------------------------------------------
    snv:eol-style = native

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_L2.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_L2.java?view=auto&rev=155990
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_L2.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_L2.java Wed Mar  2 17:30:05 2005
@@ -0,0 +1,101 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.unitTests.services.T_L2
+
+   Copyright 1997, 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.unitTests.services;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+import java.util.Hashtable;
+import org.apache.derby.iapi.services.locks.*;
+
+/**
+	A semaphore that implements Lockable for unit testing.
+*/
+class T_L2 implements Lockable {
+
+	private int allowed;
+	private Object[]	lockers;
+	private int[]		counts;
+
+	T_L2(int allowed) {
+		this.allowed = allowed;
+		lockers = new Object[allowed];
+		counts = new int[allowed];
+	}
+
+	/*
+	** Lockable methods (Simple, qualifier assumed to be null), allows
+	** up to 'allowed' lockers in at the same time.
+	*/
+
+	public void lockEvent(Latch lockInfo) {
+
+		int empty = -1;
+		for (int i = 0; i < allowed; i++) {
+			if (lockers[i] == lockInfo.getCompatabilitySpace()) {
+				counts[i]++;
+				return;
+			}
+
+			if (lockers[i] == null)
+				empty = i;
+		}
+
+        if (SanityManager.DEBUG)
+            SanityManager.ASSERT(empty != -1);
+		lockers[empty] = lockInfo.getCompatabilitySpace();
+		counts[empty] = 1;
+
+	}
+
+	public boolean requestCompatible(Object requestedQualifier, Object grantedQualifier) {
+		return false;
+	}
+
+	public boolean lockerAlwaysCompatible() {
+		return true;
+	}
+
+	public void unlockEvent(Latch lockInfo) {
+
+		for (int i = 0; i < allowed; i++) {
+
+			if (lockers[i] == lockInfo.getCompatabilitySpace()) {
+				counts[i]--;
+                if (SanityManager.DEBUG)
+                    SanityManager.ASSERT(counts[i] >= 0);
+				if (counts[i] == 0) {
+					lockers[i] = null;
+					return;
+				}
+
+				return;
+			}
+		}
+
+        if (SanityManager.DEBUG)
+            SanityManager.THROWASSERT("unlocked by a compatability space that does not exist");
+	}
+
+	public boolean lockAttributes(int flag, Hashtable t)
+	{
+		return false;
+	}
+	
+}

Propchange: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_L2.java
------------------------------------------------------------------------------
    snv:eol-style = native

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_LockFactory.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_LockFactory.java?view=auto&rev=155990
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_LockFactory.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_LockFactory.java Wed Mar  2 17:30:05 2005
@@ -0,0 +1,791 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.unitTests.services.T_LockFactory
+
+   Copyright 1997, 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.unitTests.services;
+
+import org.apache.derbyTesting.unitTests.harness.T_MultiIterations;
+import org.apache.derbyTesting.unitTests.harness.T_Fail;
+
+import org.apache.derby.iapi.services.locks.*;
+
+import org.apache.derby.iapi.services.monitor.Monitor;
+
+import org.apache.derby.iapi.reference.SQLState;
+
+import org.apache.derby.iapi.error.StandardException;
+
+/**
+	Protocol unit test for the LockManager.
+
+	@see LockFactory
+	@see org.apache.derbyTesting.unitTests.harness..UnitTest
+*/
+
+public class T_LockFactory extends T_MultiIterations
+{
+	protected final static int ITERATIONS = 100;	// iterations of multi-user tests
+
+	protected LockFactory	lf;
+
+	public T_LockFactory() {
+		super();
+	}
+
+	/*
+	** The tests
+	*/
+
+	protected String getModuleToTestProtocolName() {
+
+		return org.apache.derby.iapi.reference.Module.LockFactory;
+	}
+
+	/**
+		Run all the tests, each test that starts with 'S' is a single user
+		test, each test that starts with 'M' is a multi-user test.
+
+		@exception T_Fail The test failed in some way.
+	*/
+	protected  void setupTest() throws T_Fail {
+
+		try {
+			lf = (LockFactory) Monitor.startSystemModule(getModuleToTestProtocolName());
+		} catch (StandardException mse) {
+			throw T_Fail.exceptionFail(mse);
+		}
+		if (lf == null) {
+			throw T_Fail.testFailMsg(getModuleToTestProtocolName() + " module not started.");
+		}
+	}
+
+	/**
+		Run once per-iteration to run the actual test.
+		@exception T_Fail the test failed in some way.
+	*/
+	protected void runTestSet() throws T_Fail {
+
+		// Set up the expected error handling
+		try {
+			
+			S001();
+			S002();
+			S003();
+			S004();
+			S005();
+			S007();
+			S008();
+
+			M001();
+			M002();
+			M003();
+			M004();
+			
+
+		} catch (StandardException se) {
+
+			throw T_Fail.exceptionFail(se);
+
+		}
+	}
+
+	/*
+	** Test functions
+	*/
+
+	/**
+		Single user API test 001.
+
+		Lock an single object in a single group with all lock methods and
+		then unlock the object with all unlock methods.
+
+		@exception StandardException	An exception thrown by a method of LockFactory
+		@exception T_Fail	Some behaviour of the LockFactory is incorrect
+	*/
+	void S001() throws StandardException, T_Fail {
+
+		Object cs = new Object();	// create an object for the compatability space
+		Object g0 = new Object();	// create an object for a lock group
+		Lockable l0 = new T_L1();		// simple lockable
+
+		int count;
+		
+		// check we have no locks held
+		checkLockCount(cs, 0);
+
+		// lock and unlock specifically (no timeout)
+		lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
+		checkLockCount(cs, 1);
+		count = lf.unlock(cs, g0, l0, null);
+		if (count != 1)
+			throw T_Fail.testFailMsg("invalid unlock count, expected 1, got " + count);
+
+		// check we have no locks held
+		checkLockCount(cs, 0);
+
+		// lock twice and unlock all ...
+		lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
+		checkLockCount(cs, 2);
+		lf.unlock(cs, g0, l0, null);
+		lf.unlock(cs, g0, l0, null);
+
+		// check we have no locks held
+		checkLockCount(cs, 0);
+
+		// lock three times and unlock by group
+		lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
+		checkLockCount(cs, 3);
+		lf.unlockGroup(cs, g0);
+
+		// check we have no locks held
+		checkLockCount(cs, 0);
+
+
+		// lock three times and unlock explicitly
+		lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
+		checkLockCount(cs, 3);
+
+		lf.unlock(cs, g0, l0, null);
+		checkLockCount(cs, 2);
+
+		lf.unlock(cs, g0, l0, null);
+		checkLockCount(cs, 1);
+
+		lf.unlock(cs, g0, l0, null);
+		checkLockCount(cs, 0);
+
+		// lock and unlock specifically with timeout
+		lf.lockObject(cs, g0, l0, null, 1000 /*ms*/);
+		checkLockCount(cs, 1);
+		count = lf.unlock(cs, g0, l0, null);
+		if (count != 1)
+			throw T_Fail.testFailMsg("invalid unlock count, expected 1, got " + count);
+
+		PASS("S001");
+	}
+
+	/**
+		Single user API test 002.
+
+		Lock an object in different groups and check unlocks
+		apply to a single group.
+
+		@exception StandardException	An exception thrown by a method of LockFactory
+		@exception T_Fail	Some behaviour of the LockFactory is incorrect
+	*/
+
+	void S002() throws StandardException, T_Fail {
+
+		Object cs = new Object();	// create an object for the compatability space
+		Object g0 = new Object();	// create an object for a lock group
+		Object g1 = new Object();
+		Lockable l0 = new T_L1();		// simple lockable
+
+		int count;
+		
+		// check we have no locks held
+		checkLockCount(cs, 0);
+
+		// lock object in two groups and unlock specifically
+		lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(cs, g1, l0, null, C_LockFactory.WAIT_FOREVER);
+		checkLockGroupCount(cs, g0, 1);
+		checkLockGroupCount(cs, g1, 1);
+		checkLockCount(cs, 2);
+
+		count = lf.unlock(cs, g0, l0, null);
+		if (count != 1)
+			throw T_Fail.testFailMsg("invalid unlock count, expected 1, got " + count);
+		checkLockGroupCount(cs, g0, 0);
+		checkLockGroupCount(cs, g1, 1);
+		checkLockCount(cs, 1);
+
+		count = lf.unlock(cs, g1, l0, null);
+		if (count != 1)
+			throw T_Fail.testFailMsg("invalid unlock count, expected 1, got " + count);
+		checkLockGroupCount(cs, g0, 0);
+		checkLockGroupCount(cs, g1, 0);
+
+
+		// check we have no locks held
+		checkLockCount(cs, 0);
+
+		// lock object in two groups and unlock by group
+		lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(cs, g1, l0, null, C_LockFactory.WAIT_FOREVER);
+		checkLockCount(cs, 2);
+
+		lf.unlockGroup(cs, g1);
+		checkLockGroupCount(cs, g0, 1);
+		checkLockGroupCount(cs, g1, 0);
+		checkLockCount(cs, 1);
+
+		lf.unlockGroup(cs, g0);
+		checkLockGroupCount(cs, g0, 0);
+		checkLockGroupCount(cs, g1, 0);
+
+		// check we have no locks held
+		checkLockCount(cs, 0);
+
+		PASS("S002");
+	}
+
+	/**
+		Single user API test 003.
+
+		Lock multiple objects in different groups and check unlocks
+		apply to a single group.
+
+		@exception StandardException	An exception thrown by a method of LockFactory
+		@exception T_Fail	Some behaviour of the LockFactory is incorrect
+
+	*/
+
+	void S003() throws StandardException, T_Fail {
+
+		Object cs = new Object();	// create an object for the compatability space
+		Object g0 = new Object();	// create an object for a lock group
+		Object g1 = new Object();
+		Lockable l0 = new T_L1();		// simple lockable
+		Lockable l1 = new T_L1();
+		Lockable l2 = new T_L1();
+
+		int count;
+		
+		// check we have no locks held
+		checkLockCount(cs, 0);
+
+		// lock l0 object in two groups and l1,l2 in group l1
+		lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(cs, g1, l0, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(cs, g1, l1, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(cs, g1, l2, null, C_LockFactory.WAIT_FOREVER);
+
+		checkLockGroupCount(cs, g0, 1);
+		checkLockGroupCount(cs, g1, 3);
+		checkLockCount(cs, 4);
+
+		// quick check to see that no one is blocked
+		if (lf.anyoneBlocked())
+			throw T_Fail.testFailMsg("anyoneBlocked() returned true on a set of private locks");
+
+		lf.unlock(cs, g1, l1, null);
+		checkLockGroupCount(cs, g0, 1);
+		checkLockGroupCount(cs, g1, 2);
+		checkLockCount(cs, 3);
+
+		lf.unlockGroup(cs, g1);
+		checkLockGroupCount(cs, g0, 1);
+		checkLockGroupCount(cs, g1, 0);
+		checkLockCount(cs, 1);
+
+		lf.unlockGroup(cs, g0);
+		checkLockGroupCount(cs, g0, 0);
+		checkLockGroupCount(cs, g1, 0);
+
+		// check we have no locks held
+		checkLockCount(cs, 0);
+
+		PASS("S003");
+	}
+
+	/**
+		Single user API test 004.
+
+		Lock multiple objects in different groups and transfer
+		locks between groups.
+
+		@exception StandardException	An exception thrown by a method of LockFactory
+		@exception T_Fail	Some behaviour of the LockFactory is incorrect
+	*/
+
+	void S004() throws StandardException, T_Fail {
+
+		Object cs = new Object();	// create an object for the compatability space
+		Object g0 = new Object();	// create an object for a lock group
+		Object g1 = new Object();
+		Object g2 = new Object();
+		Lockable l0 = new T_L1();		// simple lockable
+		Lockable l1 = new T_L1();
+		Lockable l2 = new T_L1();
+
+		int count = 0;
+
+		// check we have no locks held
+		checkLockCount(cs, 0);
+
+		// lock l0 object in two groups and l1,l2 in group l1
+		lf.lockObject(cs, g0, l0, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(cs, g1, l0, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(cs, g1, l1, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(cs, g1, l2, null, C_LockFactory.WAIT_FOREVER);
+
+		checkLockGroupCount(cs, g0, 1);
+		checkLockGroupCount(cs, g1, 3);
+		checkLockCount(cs, 4);
+
+		lf.transfer(cs, g0, g1);
+		checkLockGroupCount(cs, g0, 0);
+		checkLockGroupCount(cs, g1, 4);
+		checkLockCount(cs, 4);
+
+		// transfer an empty to a non-existent one
+		lf.transfer(cs, g0, g2);
+		checkLockGroupCount(cs, g0, 0);
+		checkLockGroupCount(cs, g1, 4);
+		checkLockGroupCount(cs, g2, 0);
+		checkLockCount(cs, 4);
+		
+		lf.lockObject(cs, g2, l0, null, C_LockFactory.WAIT_FOREVER);
+		checkLockGroupCount(cs, g2, 1);
+		checkLockCount(cs, 5);
+
+		lf.transfer(cs, g1, g2);
+		checkLockGroupCount(cs, g1, 0);
+		checkLockGroupCount(cs, g2, 5);
+		checkLockCount(cs, 5);
+
+		lf.transfer(cs, g2, g1);
+		checkLockGroupCount(cs, g1, 5);
+		checkLockGroupCount(cs, g2, 0);
+		checkLockCount(cs, 5);
+
+
+		lf.unlockGroup(cs, g2);
+		checkLockGroupCount(cs, g1, 5);
+		checkLockGroupCount(cs, g2, 0);
+		checkLockCount(cs, 5);
+
+		lf.unlockGroup(cs, g1);
+		checkLockGroupCount(cs, g1, 0);
+		checkLockGroupCount(cs, g2, 0);
+
+		// check we have no locks held
+		checkLockCount(cs, 0);
+
+		PASS("S004");
+	}
+
+	/**
+		Single user API test 005.
+
+		Create two compatability spaces and ensure that locks
+		block each other out.
+
+		@exception StandardException	An exception thrown by a method of LockFactory
+		@exception T_Fail	Some behaviour of the LockFactory is incorrect
+	*/
+	void S005() throws StandardException, T_Fail {
+
+		Object cs0 = new Object();	// create an object for the compatability space
+		Object cs1 = new Object();	// create an object for the compatability space
+
+		Object g0 = new Object();	// create an object for a lock group
+		Object g1 = new Object();	// create an object for a lock group
+		Lockable l0 = new T_L1();
+		Lockable l1 = new T_L1();
+		Lockable l2 = new T_L1();
+
+		int count;
+
+		// check we have no locks held
+		checkLockCount(cs0, 0);
+		checkLockCount(cs1, 0);
+
+		lf.lockObject(cs0, g0, l0, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(cs1, g1, l1, null, C_LockFactory.WAIT_FOREVER);
+		checkLockCount(cs0, 1);
+		checkLockCount(cs1, 1);
+
+		lf.lockObject(cs0, g0, l2, null, C_LockFactory.WAIT_FOREVER);
+		checkLockCount(cs0, 2);
+		checkLockCount(cs1, 1);
+
+		// now attempt to lock l2 in cs1 with a timeout, should fail
+		try {
+			lf.lockObject(cs1, g1, l2, null, 200 /* ms */);
+			throw T_Fail.testFailMsg("lock succeeded on already locked object");
+		}
+		catch (StandardException lfe) {
+			// we are expecting the timout exception, anything else is an error
+			if (!lfe.getMessageId().equals(SQLState.LOCK_TIMEOUT)) {
+				throw lfe;
+			}
+			checkLockCount(cs0, 2);
+			checkLockCount(cs1, 1);
+
+		}
+
+		// now unlock the object, and re-attempt the lock
+		lf.unlock(cs0, g0, l2, null);
+		checkLockCount(cs0, 1);
+		checkLockCount(cs1, 1);
+		lf.lockObject(cs1, g1, l2, null, C_LockFactory.WAIT_FOREVER);
+		checkLockCount(cs0, 1);
+		checkLockCount(cs1, 2);
+
+		lf.unlockGroup(cs0, g0);
+		lf.unlockGroup(cs1, g1);
+		checkLockCount(cs0, 0);
+		checkLockCount(cs1, 0);
+
+		PASS("S005");
+
+
+
+	}	
+
+
+	/**
+		Single user API test 007.
+
+		Tests on groups and compatibility spaces
+		never seen by the lock manager.
+		
+
+		@exception StandardException	An exception thrown by a method of LockFactory
+		@exception T_Fail	Some behaviour of the LockFactory is incorrect
+	*/
+	void S007() throws StandardException, T_Fail {
+
+		Object cs = new Object();	// create an object for the compatability space
+		Object g0 = new Object();	// create an object for a lock group
+		Object g1 = new Object();	// create an object for a lock group
+		Lockable l0 = new T_L1();
+
+		int count;
+
+		// check we have no locks held
+		checkLockCount(cs, 0);
+		checkLockGroupCount(cs, g0, 0);
+
+		lf.unlockGroup(cs, g0);
+		lf.unlockGroup(cs, cs);
+		lf.unlock(cs, g0, l0, null);
+
+		lf.transfer(cs, g0, g1);
+		lf.transfer(cs, g1, g0);
+
+		if (lf.anyoneBlocked())
+			throw T_Fail.testFailMsg("anyoneBlocked() returned true on an empty space");
+
+		// check we have no locks held
+		checkLockCount(cs, 0);
+		checkLockGroupCount(cs, g0, 0);
+		checkLockGroupCount(cs, g1, 0);
+
+		PASS("S007");
+	}
+
+	/**
+		Single user API test 008.
+
+		Create two compatability spaces and ensure that locks/latches
+		block each other out.
+
+		@exception StandardException	An exception thrown by a method of LockFactory
+		@exception T_Fail	Some behaviour of the LockFactory is incorrect
+	*/
+	void S008() throws StandardException, T_Fail {
+
+		Object cs0 = new Object();	// create an object for the compatability space
+		Object cs1 = new Object();	// create an object for the compatability space
+
+		Object g0 = new Object();
+		Object g1 = new Object();
+
+		T_L1 page = new T_L1();
+		Lockable rA = new T_L1();
+		Lockable rB = new T_L1();
+
+		int count;
+
+		// Simulate a page/row lock type access
+		lf.latchObject(cs0, page, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(g0, rA, null, C_LockFactory.WAIT_FOREVER, page.latch);		// would release the latch if it had to wait
+		lf.unlatch(page.latch);
+
+		lf.latchObject(cs1, page, null, C_LockFactory.WAIT_FOREVER);
+		lf.lockObject(g1, rB, null, C_LockFactory.WAIT_FOREVER, page.latch);		// would release the latch if it had to wait
+
+		checkLockCount(cs0, 1);
+		checkLockCount(cs1, 2);
+
+		// this wait should release the latch, while waiting
+        // on lock, but then re-get the latch after the timeout.
+		try {
+			lf.lockObject(g1, rA, null, 5000, page.latch);
+			throw T_Fail.testFailMsg("lock succeeded on already locked object");
+		}
+		catch (StandardException lfe) {
+			// we are expecting the timoeut exception, anything else is an error
+			if (!lfe.getMessageId().equals(SQLState.LOCK_TIMEOUT)) {
+				throw lfe;
+			}
+			checkLockCount(cs0, 1);
+			checkLockCount(cs1, 1);
+		}
+
+        try {
+            // make sure latch is held
+            lf.latchObject(cs0, page, null, 5000);
+			throw T_Fail.testFailMsg("latch succeeded on already latch object");
+        }
+		catch (StandardException lfe) {
+			// we are expecting timoeut exception, anything else is an error
+			if (!lfe.getMessageId().equals(SQLState.LOCK_TIMEOUT)) {
+				throw lfe;
+			}
+		}
+
+		lf.unlatch(page.latch);
+
+		lf.unlock(cs0,  g0, rA, null);
+		lf.unlock(cs1,  g0, rB, null);
+
+		PASS("S008");
+
+
+	}	
+
+
+
+	/*
+	** Multi-user tests.
+	*/
+
+	/**
+		Multi-user test 001.
+
+		Create two lockable objects and pass them off to two threads.
+		Each thread will run lock the first object, set its value then lock
+		the second object & set its value, yield and then release the lock
+		on one and then on two. Various checks are made to ensure the
+		values are as expected.
+
+		@exception StandardException	An exception thrown by a method of LockFactory
+		@exception T_Fail	Some behaviour of the LockFactory is incorrect
+	*/
+
+	void M001() throws StandardException, T_Fail {
+
+		Lockable[] locks = new T_L1[2];
+		locks[0] = new T_L1();
+		locks[1] = new T_L1();
+
+		T_User u1 = new T_User(1, lf, locks, ITERATIONS, 10 * ITERATIONS);
+		T_User u2 = new T_User(1, lf, locks, ITERATIONS, 20 * ITERATIONS);
+		Thread t1 = new Thread(u1);
+		Thread t2 = new Thread(u2);
+
+		t1.start();
+		t2.start();
+
+		try {
+			t1.join();
+			t2.join();
+		} catch (InterruptedException ie) {
+			throw T_Fail.exceptionFail(ie);
+		}
+
+		if (u1.error != null)
+			throw T_Fail.exceptionFail(u1.error);
+		if (u2.error != null)
+			throw T_Fail.exceptionFail(u2.error);
+
+		PASS("M001");
+	}
+	
+
+	/**
+		Multi-user test 002
+
+		Create a single lockable and have three threads lock it, yield and
+		then release it. The single lockable can only have one locker.
+
+		@exception StandardException	An exception thrown by a method of LockFactory
+		@exception T_Fail	Some behaviour of the LockFactory is incorrect
+	*/
+
+		
+	void M002() throws StandardException, T_Fail {
+
+		Lockable[] locks = new T_L1[1];
+		locks[0] = new T_L1();
+
+		T_User u1 = new T_User(2, lf, locks, ITERATIONS, 10 * ITERATIONS);
+		T_User u2 = new T_User(2, lf, locks, ITERATIONS, 20 * ITERATIONS);
+		T_User u3 = new T_User(2, lf, locks, ITERATIONS, 30 * ITERATIONS);
+		Thread t1 = new Thread(u1);
+		Thread t2 = new Thread(u2);
+		Thread t3 = new Thread(u3);
+
+		t1.start();
+		t2.start();
+		t3.start();
+
+		try {
+			t1.join();
+			t2.join();
+			t3.join();
+		} catch (InterruptedException ie) {
+			throw T_Fail.exceptionFail(ie);
+		}
+
+		if (u1.error != null)
+			throw T_Fail.exceptionFail(u1.error);
+		if (u2.error != null)
+			throw T_Fail.exceptionFail(u2.error);
+		if (u3.error != null)
+			throw T_Fail.exceptionFail(u3.error);
+
+
+		PASS("M002");
+	}
+	/**
+		Multi-user test 003
+
+		Create a single lockable and have three threads lock it, yield and
+		then release it. The single lockable is a semaphore that can have two lockers.
+
+		@exception StandardException	An exception thrown by a method of LockFactory
+		@exception T_Fail	Some behaviour of the LockFactory is incorrect
+	*/
+
+		
+	void M003() throws StandardException, T_Fail {
+
+		Lockable[] locks = new Lockable[1];
+		locks[0] = new T_L2(2);
+
+		T_User u1 = new T_User(3, lf, locks, ITERATIONS, 0);
+		T_User u2 = new T_User(3, lf, locks, ITERATIONS, 0);
+		T_User u3 = new T_User(3, lf, locks, ITERATIONS, 0);
+		Thread t1 = new Thread(u1);
+		Thread t2 = new Thread(u2);
+		Thread t3 = new Thread(u3);
+
+		t1.start();
+		t2.start();
+		t3.start();
+
+		try {
+			t1.join();
+			t2.join();
+			t3.join();
+		} catch (InterruptedException ie) {
+			throw T_Fail.exceptionFail(ie);
+		}
+
+		if (u1.error != null)
+			throw T_Fail.exceptionFail(u1.error);
+		if (u2.error != null)
+			throw T_Fail.exceptionFail(u2.error);
+		if (u3.error != null)
+			throw T_Fail.exceptionFail(u3.error);
+
+
+		PASS("M003");
+	}
+	/**
+		Multi-user test 004
+
+		As M003 but each thread will lock the object twice, to ensure that
+		lock manager grantes the lock when the compatability space and qualifier
+		match.
+
+		@exception StandardException	An exception thrown by a method of LockFactory
+		@exception T_Fail	Some behaviour of the LockFactory is incorrect
+	*/
+
+		
+	void M004() throws StandardException, T_Fail {
+
+		Lockable[] locks = new Lockable[1];
+		locks[0] = new T_L2(2);
+
+		T_User u1 = new T_User(4, lf, locks, ITERATIONS, 0);
+		T_User u2 = new T_User(4, lf, locks, ITERATIONS, 0);
+		T_User u3 = new T_User(4, lf, locks, ITERATIONS, 0);
+		Thread t1 = new Thread(u1);
+		Thread t2 = new Thread(u2);
+		Thread t3 = new Thread(u3);
+
+		t1.start();
+		t2.start();
+		t3.start();
+
+		try {
+			t1.join();
+			t2.join();
+			t3.join();
+		} catch (InterruptedException ie) {
+			throw  T_Fail.exceptionFail(ie);
+		}
+
+		if (u1.error != null)
+			throw  T_Fail.exceptionFail(u1.error);
+		if (u2.error != null)
+			throw T_Fail.exceptionFail(u2.error);
+		if (u3.error != null)
+			throw T_Fail.exceptionFail(u3.error);
+
+
+		PASS("M004");
+	}
+
+
+
+	/*
+	** Utility functions
+	*/
+
+	/**
+		Check to see if the total number of locks we have is as expected.
+
+		@exception T_Fail	Number of locks is not as expected.
+	*/
+	void checkLockCount(Object cs, int expected) throws T_Fail {
+		boolean expect = expected != 0;
+		boolean got = lf.areLocksHeld(cs);
+		if (got != expect)
+			throw T_Fail.testFailMsg("Expected lock count (" + expect + "), got (" + got + ")");
+	}
+
+	/**
+		Check to see if the number of locks in a group we have is as expected.
+
+		@exception T_Fail	Number of locks is not as expected.
+	*/
+
+	void checkLockGroupCount(Object cs, Object group, int expected) throws T_Fail {
+		boolean expect = expected != 0;
+		boolean got = lf.areLocksHeld(cs, group);
+		if (got != expect)
+			throw T_Fail.testFailMsg("Expected lock count (" + expect + "), got (" + got + ")");
+	}
+
+}
+
+

Propchange: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_LockFactory.java
------------------------------------------------------------------------------
    snv:eol-style = native

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_MarkedLimitInputStream.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_MarkedLimitInputStream.java?view=auto&rev=155990
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_MarkedLimitInputStream.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_MarkedLimitInputStream.java Wed Mar  2 17:30:05 2005
@@ -0,0 +1,273 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.unitTests.services.T_MarkedLimitInputStream
+
+   Copyright 2001, 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.unitTests.services;
+
+import org.apache.derbyTesting.unitTests.harness.T_Generic;
+import org.apache.derbyTesting.unitTests.harness.T_Fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+  A simple unit test for a MarkedLimitInputStream.
+  */
+public class T_MarkedLimitInputStream extends T_Generic
+{
+
+    private static final int TEST_SIZE = 10000;
+    private static final int BLOCK_SIZE = 256;
+
+
+    private static MarkedLimitInputStream setup(byte[] data)
+        throws Exception
+    {
+        // make an InputStream on top of an array
+        InputStream inputStream = new ByteArrayInputStream(data);
+
+        // make an OutputStream on top of an empty array
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(TEST_SIZE + 200);
+        // make it into a DataOutputStream
+        DataOutputStream dos = new DataOutputStream(baos);
+        // fill it with data in the correct (block) format
+        writeDos(inputStream,dos);
+
+        // make a MarkedLimitInputStream
+        return makeMLIS(baos.toByteArray());
+
+	}
+
+	private static void writeDos(InputStream x, DataOutputStream out)
+        throws Exception
+	{
+        boolean isLastBlock = false;
+        byte[] b = new byte[BLOCK_SIZE];
+
+        while (isLastBlock == false)
+        {
+            int len = x.read(b);
+            if (len != BLOCK_SIZE)
+            {
+                isLastBlock = true;
+                if (len < 0)
+                {
+                    len = 0;
+                }
+            }
+            out.writeBoolean(isLastBlock);
+            out.writeInt(len);
+            for (int i = 0; i < len; i++)
+            {
+                out.writeByte(b[i]);
+            }
+        }
+    }
+
+
+    private static MarkedLimitInputStream makeMLIS(byte[] b)
+        throws Exception
+    {
+        // make an InputStream
+        InputStream inputStream = new ByteArrayInputStream(b);
+        // make a DataInputStream
+        DataInputStream dataInputStream = new DataInputStream(inputStream);
+        // make a MarkedLimitInputStream
+        return new MarkedLimitInputStream(dataInputStream);
+    }
+
+
+    private static boolean readAndCompare(MarkedLimitInputStream mlis, byte[] x)
+        throws Exception
+    {
+        int b;
+        int i = 0;
+        while ((b = mlis.read()) != -1)
+        {
+            if (x[i] != (byte) b)
+            {
+                System.out.println("Stream and array differ at position " + i);
+                return false;
+            }
+            i++;
+        }
+        // read to end of stream, check array size
+        if (i != x.length)
+        {
+            System.out.println("array size and stream size differ");
+            return false;
+        }
+        return true;
+
+    }
+
+
+    private static boolean readAndCompareChunks(MarkedLimitInputStream mlis,
+        byte[] x)
+        throws Exception
+    {
+        int chunkSize = 10;
+        byte[] chunk = new byte[chunkSize];
+        int c = 0;
+        int base = 0;
+        while ((c = mlis.read(chunk)) > 0)
+        {
+            for (int offset = 0; offset < c; offset++)
+            {
+                if (x[base + offset] != chunk[offset])
+                {
+                    System.out.println("Stream and array differ at position " +
+                        (base + offset));
+                    System.out.println("Array : x[" + (base + offset) + "] = " + x[base+offset]);
+                    System.out.println("Stream : chunk[" + offset + "] = " + chunk[offset]);
+                    return false;
+                }
+            }
+            base += c;
+        }
+
+        // read to end of stream, check array size
+        if (base != x.length)
+        {
+            System.out.println("array size ( " + x.length +
+                " ) and stream size ( " + base + " ) differ");
+            return false;
+        }
+        return true;
+
+    }
+
+
+    private static boolean skipAndCompare(MarkedLimitInputStream mlis, byte[] x,
+        long skipTo)
+        throws Exception
+    {
+        long c = mlis.skip(skipTo);
+        T_Fail.T_ASSERT(c == skipTo);
+        byte[] y = new byte[x.length - (int) c];
+        System.arraycopy(x,(int) skipTo, y, 0, x.length - (int) c);
+        return readAndCompare(mlis,y);
+    }
+
+
+	/** Methods required by T_Generic
+	*/
+	public String getModuleToTestProtocolName()
+	{
+		return "internalUtils.MarkedLimitInputStream";
+	}
+
+
+	protected void runTests()
+        throws Exception
+    {
+        boolean success = true;
+        // create and initialize array
+        byte[] data = new byte[TEST_SIZE];
+        for (int i = 0; i < data.length; i++)
+        {
+            data[i] = (byte)(i & 0xFF);
+        }
+
+        MarkedLimitInputStream mlis = setup(data);
+        // compare MarkedLimitInputStream with original byte array
+        if (readAndCompare(mlis, data))
+        {
+            PASS("test1");
+        }
+        else
+        {
+            FAIL("test1");
+            success = false;
+        }
+
+        MarkedLimitInputStream mlis2 = setup(data);
+        // compare MarkedLimitInputStream with original byte array
+        // read in chunks
+        if (readAndCompareChunks(mlis2, data))
+        {
+            PASS("test2");
+        }
+        else
+        {
+            FAIL("test2");
+            success = false;
+        }
+
+        MarkedLimitInputStream mlis3 = setup(data);
+        // skip and compare MarkedLimitInputStream with original byte array
+        if (skipAndCompare(mlis3, data, TEST_SIZE/2))
+        {
+            PASS("test3");
+        }
+        else
+        {
+            FAIL("test3");
+            success = false;
+        }
+
+        MarkedLimitInputStream mlis4 = setup(data);
+        // skip and compare MarkedLimitInputStream with original byte array
+        if (skipAndCompare(mlis4, data, TEST_SIZE-1))
+        {
+            PASS("test4");
+        }
+        else
+        {
+            FAIL("test4");
+            success = false;
+        }
+
+        if (!success)
+        {
+            throw T_Fail.testFail();
+        }
+
+
+        // create and initialize array with size BLOCK_SIZE
+        byte[] data2 = new byte[BLOCK_SIZE];
+        for (int i = 0; i < data.length; i++)
+        {
+            data[i] = (byte)(i & 0xFF);
+        }
+        MarkedLimitInputStream mlis5 = setup(data2);
+        // skip and compare MarkedLimitInputStream with original byte array
+        if (readAndCompare(mlis5, data2))
+        {
+            PASS("test5");
+        }
+        else
+        {
+            FAIL("test5");
+            success = false;
+        }
+
+        if (!success)
+        {
+            throw T_Fail.testFail();
+        }
+
+    }
+
+}

Propchange: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_MarkedLimitInputStream.java
------------------------------------------------------------------------------
    snv:eol-style = native

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_Serviceable.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_Serviceable.java?view=auto&rev=155990
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_Serviceable.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_Serviceable.java Wed Mar  2 17:30:05 2005
@@ -0,0 +1,130 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.unitTests.services.T_Serviceable
+
+   Copyright 1997, 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.unitTests.services;
+
+import org.apache.derbyTesting.unitTests.harness.T_Generic;
+import org.apache.derbyTesting.unitTests.harness.T_Fail;
+
+import org.apache.derby.iapi.services.context.Context;
+import org.apache.derby.iapi.services.context.ContextManager;
+import org.apache.derby.iapi.services.monitor.Monitor;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.services.daemon.*;
+
+/**
+	This test implements serviceable for testing.  To facility testing, when
+	this object is being serviced, it will synchronize on itself and notity all
+	waiters.  Test driver may wait on this object and check timesServiced to
+	make sure the background daemon has run.
+*/
+public class T_Serviceable implements Serviceable
+{
+	// synchronized on this to look at the number 
+	// of times this object has been serviced
+	protected int timesServiced;
+
+	// constant for checking
+	protected final int timesRequeue;
+	protected final boolean onDemandOnly;
+	protected final boolean subscribed;
+
+	// use this to unsubscribe
+	protected int clientNumber;
+
+	// test enqueueing, t = number of times to requeue
+	public T_Serviceable(int t)
+	{
+		timesServiced = 0;
+		timesRequeue = t;
+		onDemandOnly = false;	// not looked at
+		subscribed = false;
+		clientNumber = -1;
+	}
+
+	// test subscription 
+	public T_Serviceable(boolean onDemandOnly)
+	{
+		timesServiced = 0;
+		timesRequeue = 0;		// not looked at
+		this.onDemandOnly = onDemandOnly;
+		subscribed = true;
+	}
+
+	protected void setClientNumber(int n)
+	{
+		clientNumber = n;
+	}
+
+	protected int getClientNumber()
+	{
+		return clientNumber;
+	}
+
+	/*
+	 *  Serviceable interface
+	 */
+	public synchronized int performWork(ContextManager context) 
+	{
+		context.toString();	// make sure context manager is not null;
+
+		timesServiced++;
+		notifyAll();			// notify anyone waiting for me to be serviced
+
+		if (!subscribed && timesRequeue > timesServiced)
+			return Serviceable.REQUEUE;
+		else
+			return Serviceable.DONE;
+	}
+	
+	public boolean serviceASAP()
+	{
+		return true;
+	}
+
+
+	// @return true, if this work needs to be done on a user thread immediately
+	public boolean serviceImmediately()
+	{
+		return false;
+	}	
+
+
+	/*
+	 * test utilities
+	 */
+
+	protected synchronized void t_wait(int n)
+	{
+		try
+		{
+			while (timesServiced < n)
+				wait();
+		}
+		catch (InterruptedException ie) {}
+	}
+
+	protected synchronized void t_check(int n) throws T_Fail
+	{
+		if (timesServiced != n)
+			throw T_Fail.testFailMsg("Expect to be serviced " + n + " times, instead serviced " + timesServiced);
+	}
+
+}

Propchange: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_Serviceable.java
------------------------------------------------------------------------------
    snv:eol-style = native

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_StandardException.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_StandardException.java?view=auto&rev=155990
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_StandardException.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_StandardException.java Wed Mar  2 17:30:05 2005
@@ -0,0 +1,71 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.unitTests.services.T_StandardException
+
+   Copyright 1999, 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.unitTests.services;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import java.text.MessageFormat;
+/**
+  A standard exception for testing.
+
+  The messages for this exception are not localized or stored
+  with the product.
+ */
+public class T_StandardException extends StandardException
+{
+	String msgText = "Message text not set";
+
+	protected T_StandardException(String messageID, String msgText)
+	{
+		super(messageID);
+		myConstructorCommon( messageID, msgText );
+	}
+	protected T_StandardException(String messageID, String msgText, Throwable t)
+	{
+		super(messageID, t, (Object[]) null);
+		myConstructorCommon( messageID, msgText );
+	}
+	protected T_StandardException(String messageID, String msgText, Throwable t, Object[] args)
+	{
+		super(messageID, t, args);
+		myConstructorCommon( messageID, msgText );
+	}
+
+	protected	void	myConstructorCommon( String messageID, String msgText )
+	{
+		this.msgText = msgText;
+	}
+
+	public static
+	StandardException newT_StandardException(String messageID, Throwable t, String msgText)
+	{
+		return new T_StandardException(messageID,msgText,t);
+	}
+
+	public static
+	StandardException newT_StandardException(String messageID, String msgText)
+	{
+		return new T_StandardException(messageID,msgText);
+	}
+
+	public String getMessage() {return MessageFormat.format(msgText, getArguments());}
+	public String getErrorProperty() {throw new Error("method not supported");}
+}

Propchange: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_StandardException.java
------------------------------------------------------------------------------
    snv:eol-style = native

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_UUIDFactory.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_UUIDFactory.java?view=auto&rev=155990
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_UUIDFactory.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_UUIDFactory.java Wed Mar  2 17:30:05 2005
@@ -0,0 +1,175 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.unitTests.services.T_UUIDFactory
+
+   Copyright 1997, 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.unitTests.services;
+
+import org.apache.derbyTesting.unitTests.harness.T_Generic;
+import org.apache.derbyTesting.unitTests.harness.T_Fail;
+
+import  org.apache.derby.catalog.UUID;
+
+import org.apache.derby.iapi.services.monitor.Monitor;
+import org.apache.derby.iapi.error.StandardException;
+
+import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
+
+import org.apache.derby.iapi.services.uuid.UUIDFactory;
+
+/**
+	Test to ensure a implementation of the UUID module
+	implements the protocol correctly. 
+*/
+
+public class T_UUIDFactory extends T_Generic {
+
+	protected UUIDFactory factory;
+	boolean resultSoFar;
+
+	public 	T_UUIDFactory() {
+		super();
+	}
+
+	protected String getModuleToTestProtocolName() {
+
+		return "A.Dummy.Name";
+	}
+
+	/**
+		Run all the tests, each test that starts with 'S' is a single user
+		test, each test that starts with 'M' is a multi-user test.
+
+		@exception T_Fail The test failed in some way.
+	*/
+	protected void runTests() throws T_Fail {
+
+		factory = Monitor.getMonitor().getUUIDFactory();
+		if (factory == null) {
+			throw T_Fail.testFailMsg(getModuleToTestProtocolName() + " module not started.");
+		}
+
+		if (!testUUID())
+			throw T_Fail.testFailMsg("testUUID indicated failure");
+	}
+
+
+	/*
+	** Tests
+	*/
+
+	protected boolean testUUID() {
+		resultSoFar = true;
+
+		UUID uuid1 = factory.createUUID();
+		UUID uuid2 = factory.createUUID();
+
+		if (uuid1.equals(uuid2)){
+			// Resolve: format this with a message factory
+			String message =  
+				"UUID factory created matching UUIDS '%0' and '%1'";
+			out.printlnWithHeader(message);
+			resultSoFar =  false;
+		}
+
+		if (!uuid1.equals(uuid1)){
+			// Resolve: format this with a message factory
+			String message = 
+				"UUID '%0' does not equal itself";
+			resultSoFar =  false;
+		}
+
+		if (uuid1.hashCode() != uuid1.hashCode()){
+			// Resolve: format this with a message factory
+			String message = 
+				"UUID '%0' does not hash to the same thing twice.";
+			out.printlnWithHeader(message);
+			resultSoFar =  false;
+		}
+
+		// Check that we can go from UUID to string and back.
+		
+		String suuid1 = uuid1.toString();
+		UUID uuid3 = factory.recreateUUID(suuid1);
+		if (!uuid3.equals(uuid1)){
+			// Resolve: format this with a message factory
+			String message = 
+				"Couldn't recreate UUID: "
+				+ uuid3.toString() 
+				+ " != "
+				+ uuid1.toString();
+			out.printlnWithHeader(message);
+			resultSoFar =  false;
+		}
+
+		// Check that we can transform from string to UUID and back
+		// for a few "interesting" UUIDs.
+
+		// This one came from GUIDGEN.EXE.
+		testUUIDConversions(out, "7878FCD0-DA09-11d0-BAFE-0060973F0942");
+
+		// Interesting bit patterns.
+		testUUIDConversions(out, "80706050-4030-2010-8070-605040302010");
+		testUUIDConversions(out, "f0e0d0c0-b0a0-9080-7060-504030201000");
+		testUUIDConversions(out, "00000000-0000-0000-0000-000000000000");
+		testUUIDConversions(out, "ffffffff-ffff-ffff-ffff-ffffffffffff");
+
+		// A couple self-generated ones for good measure.
+		testUUIDConversions(out, factory.createUUID().toString());
+ 		testUUIDConversions(out, factory.createUUID().toString());
+
+		return resultSoFar;
+	
+	}
+
+	private void testUUIDConversions(HeaderPrintWriter out, String uuidstring)
+	{
+		UUID uuid = factory.recreateUUID(uuidstring);
+		if (!uuidstring.equalsIgnoreCase(uuid.toString())){
+			// Resolve: format this with a message factory
+			String message = 
+				"Couldn't recreate UUID String: "
+				+ uuidstring 
+				+ " != " 
+				+ uuid.toString();
+			out.printlnWithHeader(message);
+			resultSoFar =  false;
+		}
+
+		byte[] uuidByteArray = uuid.toByteArray();
+		UUID uuid_b = factory.recreateUUID(uuidByteArray);
+		if (!uuid_b.equals(uuid))
+		{
+			// Resolve: format this with a message factory
+			String badByteArrayString = "";
+			for (int ix = 0; ix < 16; ix++)
+			{
+				badByteArrayString +=
+					Integer.toHexString(0x00ff&uuidByteArray[ix])+".";
+			}
+
+			String message = 
+				"Conversion error: "
+				+ uuidstring 
+				+ " != " 
+				+ badByteArrayString;
+			out.printlnWithHeader(message);
+			resultSoFar =  false;
+		}
+	}
+}

Propchange: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_UUIDFactory.java
------------------------------------------------------------------------------
    snv:eol-style = native

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_User.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_User.java?view=auto&rev=155990
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_User.java (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_User.java Wed Mar  2 17:30:05 2005
@@ -0,0 +1,195 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.unitTests.services.T_User
+
+   Copyright 1997, 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.unitTests.services;
+
+import org.apache.derbyTesting.unitTests.harness.T_Fail;
+
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.services.sanity.SanityManager;
+import org.apache.derby.iapi.services.locks.*;
+
+class T_User implements Runnable {
+
+	private LockFactory lf;
+	private Lockable[] refs;
+	private long iterations;
+	private long offset;
+	private int test;
+
+	Throwable error = null;
+
+
+
+	T_User(int test, LockFactory lf, Lockable[] refs, long iterations, long offset) {
+
+		this.lf = lf;
+		this.refs = refs;
+		this.iterations = iterations;
+		this.test = test;
+		this.offset = offset;
+	}
+
+	public void run() {
+
+		try {
+			switch (test) {
+			case 1:
+				T001();
+				break;
+			case 2:
+				T002();
+				break;
+			case 3:
+				T003();
+				break;
+			}
+		} catch (Throwable t) {
+			error = t;
+		}
+	}
+
+	private void T001() throws StandardException, T_Fail {
+
+		Object cs = new Object();	// create an object for the compatability space
+		Integer g0 = new Integer(1);	// create an object for a lock group
+
+		// check we have no locks held
+		checkLockCount(cs, 0);
+
+		T_L1 ref;
+
+		while (--iterations > 0) {
+			long value = offset + iterations;
+
+			lf.lockObject(cs, g0, refs[0], null, C_LockFactory.WAIT_FOREVER);
+			ref = (T_L1) refs[0];
+			ref.value = value;
+			checkLockCount(cs, 1);
+			Thread.yield();
+			checkValue(ref, value);
+
+			lf.lockObject(cs, g0, refs[1], null, C_LockFactory.WAIT_FOREVER);
+			ref = (T_L1) refs[1];
+			ref.value = value;
+			Thread.yield();
+
+			checkValue((T_L1) refs[0], value);
+			checkValue((T_L1) refs[1], value);
+
+			lf.unlock(cs, g0, refs[0], null);
+			checkValue((T_L1) refs[1], value);
+
+			Thread.yield();
+
+			lf.unlock(cs, g0, refs[1], null);
+
+			// check we have no locks held
+			checkLockCount(cs, 0);
+
+			Thread.yield();
+
+		}
+	}
+
+	private void T002() throws StandardException, T_Fail {
+
+		Object cs = new Object();	// create an object for the compatability space
+		Integer g0 = new Integer(1);	// create an object for a lock group
+
+		// check we have no locks held
+		checkLockCount(cs, 0);
+
+		while (--iterations > 0) {
+			long value = offset + iterations;
+			T_L1 ref = (T_L1) refs[0];
+
+			lf.lockObject(cs, g0, refs[0], null, C_LockFactory.WAIT_FOREVER);
+			ref.value = value;
+			checkLockCount(cs, 1);
+			Thread.yield();
+			checkValue(ref, value);
+
+			lf.unlock(cs, g0, refs[0], null);
+
+			// check we have no locks held
+			checkLockCount(cs, 0);
+		}
+	}
+
+	private void T003() throws StandardException, T_Fail {
+
+		Object cs = new Object();	// create an object for the compatability space
+		Integer g0 = new Integer(1);	// create an object for a lock group
+
+		// check we have no locks held
+		checkLockCount(cs, 0);
+
+		while (--iterations > 0) {
+
+			lf.lockObject(cs, g0, refs[0], null, C_LockFactory.WAIT_FOREVER);
+			checkLockCount(cs, 1);
+			Thread.yield();
+			lf.unlock(cs, g0, refs[0], null);
+
+			// check we have no locks held
+			checkLockCount(cs, 0);
+		}
+	}
+	private void T004() throws StandardException, T_Fail {
+
+		Object cs = new Object();	// create an object for the compatability space
+		Integer g0 = new Integer(1);	// create an object for a lock group
+
+		// check we have no locks held
+		checkLockCount(cs, 0);
+
+		while (--iterations > 0) {
+
+			lf.lockObject(cs, g0, refs[0], null, C_LockFactory.WAIT_FOREVER);
+			checkLockCount(cs, 1);
+			Thread.yield();
+
+
+			lf.lockObject(cs, g0, refs[0], null, C_LockFactory.WAIT_FOREVER);
+			checkLockCount(cs, 2);
+			Thread.yield();
+
+			lf.unlockGroup(cs, g0);
+
+			// check we have no locks held
+			checkLockCount(cs, 0);
+		}
+	}
+
+	private void checkValue(T_L1 item, long value) throws T_Fail {
+		if (item.value  != value)
+			throw T_Fail.testFailMsg("value corrupted in multi-user test, exapected " + value + ", got " + item.value);
+	}
+
+	void checkLockCount(Object cs, int expected) throws T_Fail {
+		boolean expect = expected != 0;
+		boolean got = lf.areLocksHeld(cs);
+		if (got != expect)
+			throw T_Fail.testFailMsg("Expected lock count (" + expect + "), got (" + got + ")");
+	}
+
+
+}

Propchange: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/services/T_User.java
------------------------------------------------------------------------------
    snv:eol-style = native