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 +
+ 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