javacommons/utils/tsrc/javasrc/com/nokia/mj/impl/utils/concurrent/ConcurrentTests.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javacommons/utils/tsrc/javasrc/com/nokia/mj/impl/utils/concurrent/ConcurrentTests.java Thu May 27 12:49:31 2010 +0300
@@ -0,0 +1,573 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+package com.nokia.mj.impl.utils.concurrent;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.nokia.mj.impl.installer.utils.InstallerMain;
+import com.nokia.mj.impl.utils.DebugUtils;
+
+import j2meunit.framework.Test;
+import j2meunit.framework.TestCase;
+import j2meunit.framework.TestMethod;
+import j2meunit.framework.TestSuite;
+
+/**
+ * BufferedReader unit tests.
+ */
+public class ConcurrentTests extends TestCase implements InstallerMain
+{
+ private int mMaxThreadId;
+ private int mReleaseThreadId;
+ private int mNextReleasedThreadId;
+ private int mRunningThreadCount;
+ private Semaphore mSem;
+ private Object mLockEnd;
+
+ // Begin j2meunit test framework setup
+ public void installerMain(String[] args)
+ {
+ createDumperThread(false);
+ TestSuite suite = new TestSuite(this.getClass().getName());
+
+
+ suite.addTest(new ConcurrentTests("testLockBasic", new TestMethod()
+ {
+ public void run(TestCase tc)
+ {
+ ((ConcurrentTests)tc).testLockBasic();
+ }
+ }));
+
+ suite.addTest(new ConcurrentTests("testLockFair", new TestMethod()
+ {
+ public void run(TestCase tc)
+ {
+ ((ConcurrentTests)tc).testLockFair();
+ }
+ }));
+
+
+ suite.addTest(new ConcurrentTests("testLockFair2", new TestMethod()
+ {
+ public void run(TestCase tc)
+ {
+ ((ConcurrentTests)tc).testLockFair2();
+ }
+ }));
+
+ suite.addTest(new ConcurrentTests("testLockUnFair", new TestMethod()
+ {
+ public void run(TestCase tc)
+ {
+ ((ConcurrentTests)tc).testLockUnFair();
+ }
+ }));
+
+ suite.addTest(new ConcurrentTests("testLockUnFair2", new TestMethod()
+ {
+ public void run(TestCase tc)
+ {
+ ((ConcurrentTests)tc).testLockUnFair2();
+ }
+ }));
+
+ suite.addTest(new ConcurrentTests("testLockUnFair3", new TestMethod()
+ {
+ public void run(TestCase tc)
+ {
+ ((ConcurrentTests)tc).testLockUnFair3();
+ }
+ }));
+
+
+ suite.addTest(new ConcurrentTests("testCondition1", new TestMethod()
+ {
+ public void run(TestCase tc)
+ {
+ ((ConcurrentTests)tc).testCondition1();
+ }
+ }));
+
+ suite.addTest(new ConcurrentTests("testCondition10_10", new TestMethod()
+ {
+ public void run(TestCase tc)
+ {
+ ((ConcurrentTests)tc).testCondition10_10();
+ }
+ }));
+
+
+ suite.addTest(new ConcurrentTests("testCondition5_10", new TestMethod()
+ {
+ public void run(TestCase tc)
+ {
+ ((ConcurrentTests)tc).testCondition5_10();
+ }
+ }));
+
+
+
+ com.nokia.mj.impl.utils.OmjTestRunner.run(suite);
+
+ }
+
+ public ConcurrentTests()
+ {
+ }
+
+ public ConcurrentTests(String aTestName, TestMethod aTestMethod)
+ {
+ super(aTestName, aTestMethod);
+ }
+
+ private void createDumperThread(boolean doCreate)
+ {
+ if (doCreate)
+ {
+ new Thread(new Runnable(){
+ public void run()
+ {
+ threadSleep(5000);
+ }
+ }).start();
+ }
+ }
+
+
+ public void assertFalse(String aMsg, boolean aCondition)
+ {
+ assertTrue(aMsg, !aCondition);
+ }
+
+ // End j2meunit test framework setup
+
+ protected void setUp()
+ {
+ }
+
+ protected void tearDown()
+ {
+ }
+
+
+ private synchronized void incThreadCount()
+ {
+ mRunningThreadCount++;
+ }
+
+ private synchronized void decThreadCount()
+ {
+ mRunningThreadCount--;
+ }
+
+ private Vector /*String*/ mTrace = new Vector();
+
+ private void trace(String str)
+ {
+ trace(str, false);
+ }
+
+ private void trace(String str, boolean doTrace)
+ {
+ if (doTrace)
+ {
+ //System.out.println(str);
+ mTrace.addElement(str);
+ }
+ }
+
+
+ private void printTrace()
+ {
+ Enumeration enumer = mTrace.elements();
+ while (enumer.hasMoreElements())
+ {
+ String s = (String)enumer.nextElement();
+ System.out.println(s);
+ }
+ mTrace.removeAllElements();
+ }
+
+
+
+ // Test cases
+
+ /** LOCK TESTS*/
+
+ private void testLockBasic()
+ {
+ try
+ {
+ Semaphore sem = new Semaphore(1, true);
+ sem.acquire();
+ sem.release();
+ sem.acquire();
+ sem.release();
+ sem.acquire();
+ sem.release();
+ sem = null;
+
+ Semaphore sem2 = new Semaphore(1, false);
+ sem2.acquire();
+ sem2.release();
+ sem2.acquire();
+ sem2.release();
+ sem2.acquire();
+ sem2.release();
+ }
+ catch (Throwable t)
+ {
+ assertTrue(t.toString(), false);
+ t.printStackTrace();
+ }
+ }
+
+
+ private void testLockFair()
+ {
+ mRunningThreadCount = 0;
+ mNextReleasedThreadId = 1;
+ mReleaseThreadId = 10;
+ mMaxThreadId = 10;
+
+ try
+ {
+
+ testLock(true);
+ }
+ catch (Throwable t)
+ {
+ assertTrue(t.toString(), false);
+ t.printStackTrace();
+ }
+ }
+
+ private void testLockFair2()
+ {
+ mRunningThreadCount = 0;
+ mNextReleasedThreadId = 1;
+ mReleaseThreadId = 5;
+ mMaxThreadId = 10;
+
+ try
+ {
+
+ testLock(true);
+ }
+ catch (Throwable t)
+ {
+ assertTrue(t.toString(), false);
+ t.printStackTrace();
+ }
+ }
+
+ private void testLockUnFair()
+ {
+ mRunningThreadCount = 0;
+ mNextReleasedThreadId = 1;
+ mReleaseThreadId = 10;
+ mMaxThreadId = 10;
+
+ try
+ {
+
+ testLock(false);
+ }
+ catch (Throwable t)
+ {
+ assertTrue(t.toString(), false);
+ t.printStackTrace();
+ }
+ }
+
+ private void testLockUnFair2()
+ {
+ mRunningThreadCount = 0;
+ mNextReleasedThreadId = 1;
+ mReleaseThreadId = 5;
+ mMaxThreadId = 10;
+
+ try
+ {
+
+ testLock(false);
+ }
+ catch (Throwable t)
+ {
+ assertTrue(t.toString(), false);
+ t.printStackTrace();
+ }
+ }
+
+ private void testLockUnFair3()
+ {
+ try
+ {
+ mSem = new Semaphore(1, false);
+ mSem.acquire();
+ new Thread(new Runnable()
+ {
+ public void run()
+ {
+ threadSleep(100);
+ mSem.release();
+ }
+ }).start();
+ mSem.acquire();
+ mSem.release();
+ mSem.acquire();
+ new Thread(new Runnable()
+ {
+ public void run()
+ {
+ threadSleep(100);
+ mSem.release();
+ }
+ }).start();
+ mSem.acquire();
+ mSem.release();
+ }
+ catch (Throwable t)
+ {
+ assertTrue(t.toString(), false);
+ t.printStackTrace();
+ }
+ }
+
+
+
+
+ private class LockTestThread extends Thread
+ {
+ private int mId;
+ private boolean mCheck;
+
+ private LockTestThread(int id, boolean check)
+ {
+ mId = id;
+ mCheck = check;
+ }
+ public void run()
+ {
+ threadSleep(20);
+ trace("run: "+mId);
+ incThreadCount();
+ if (mId < mMaxThreadId)
+ {
+ // Need to create additional thread.
+ trace("creating new thread: "+mId);
+ new LockTestThread(mId+1, mCheck).start();
+ }
+ if (mReleaseThreadId == mId)
+ {
+ synchronized (mLockEnd)
+ {
+ trace("notify: "+mId);
+ mLockEnd.notify();
+ }
+ }
+ trace("Getting lock: "+mId);
+ mSem.acquire();
+ trace("Got lock: "+mId);
+ if (mCheck)
+ {
+ String errorTxt = "Incorrect release order. mId: "+ mId +
+ ", next: " +mNextReleasedThreadId;
+ assertTrue(errorTxt, mNextReleasedThreadId == mId);
+ }
+ mNextReleasedThreadId++;
+ trace("unlock: "+mId);
+ mSem.release();
+ decThreadCount();
+ trace("done: "+mId);
+ }
+ }
+
+ private void threadSleep(int ms)
+ {
+ try
+ {
+ Thread.sleep(ms);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ private void testLock(boolean isFair) throws Exception
+ {
+ mSem = new Semaphore(1,isFair);
+ mSem.acquire();
+ new LockTestThread(1, isFair).start();
+ mLockEnd = new Object();
+ synchronized (mLockEnd)
+ {
+ // Wait that all the threads has been started.
+ trace("Wait()");
+ mLockEnd.wait();
+ trace("wait ok()");
+ }
+ mSem.release();
+ trace("unlock after wait");
+ for (int i = 0; i < 5; ++i)
+ {
+ threadSleep(100);
+ trace("Woke from sleep.");
+ if (mRunningThreadCount == 0)
+ {
+ break;
+ }
+ }
+ printTrace();
+ assertTrue("Threads still running: " + mRunningThreadCount, mRunningThreadCount == 0);
+ }
+
+ /** CONDITION TESTS*/
+ private ConditionObject mCondition;
+
+ private void testCondition1()
+ {
+ mRunningThreadCount = 0;
+ mNextReleasedThreadId = 1;
+ mReleaseThreadId = 1;
+ mMaxThreadId = 1;
+
+ try
+ {
+ testCondtion();
+ }
+ catch (Throwable t)
+ {
+ assertTrue(t.toString(), false);
+ t.printStackTrace();
+ }
+ }
+
+ private void testCondition10_10()
+ {
+ mRunningThreadCount = 0;
+ mNextReleasedThreadId = 1;
+ mReleaseThreadId = 10;
+ mMaxThreadId = 10;
+
+ try
+ {
+ testCondtion();
+ }
+ catch (Throwable t)
+ {
+ assertTrue(t.toString(), false);
+ t.printStackTrace();
+ }
+ }
+
+ private void testCondition5_10()
+ {
+ mRunningThreadCount = 0;
+ mNextReleasedThreadId = 1;
+ mReleaseThreadId = 5;
+ mMaxThreadId = 10;
+
+ try
+ {
+ testCondtion();
+ }
+ catch (Throwable t)
+ {
+ assertTrue(t.toString(), false);
+ t.printStackTrace();
+ }
+ }
+
+
+ private class ConditionTestThread extends Thread
+ {
+ private int mId;
+
+ private ConditionTestThread(int id)
+ {
+ mId = id;
+ }
+ public void run()
+ {
+ threadSleep(20);
+ trace("run: "+mId);
+ incThreadCount();
+
+ if (mReleaseThreadId == mId)
+ {
+ synchronized (mLockEnd)
+ {
+ trace("notify: "+mId);
+ mLockEnd.notify();
+ }
+ threadSleep(50);
+ }
+
+ if (mId < mMaxThreadId)
+ {
+ // Need to create additional thread.
+ trace("creating new thread: "+mId);
+ new ConditionTestThread(mId+1).start();
+ }
+
+ trace("Going to await: "+mId);
+ mCondition.await();
+ trace("out from await: "+mId);
+ decThreadCount();
+ trace("done: "+mId);
+ }
+ }
+
+ private void testCondtion() throws Exception
+ {
+ mCondition = new ConditionObject();
+ new ConditionTestThread(1).start();
+
+ mLockEnd = new Object();
+ synchronized (mLockEnd)
+ {
+ // Wait that all the threads has been started.
+ trace("wait()-->");
+ mLockEnd.wait();
+ trace("<--wait()");
+ }
+
+ assertTrue("Not correct amount of threads waiting: " + mRunningThreadCount, mRunningThreadCount == mReleaseThreadId);
+ if (mMaxThreadId == 1)
+ {
+ threadSleep(100);
+ }
+ trace("before signal()");
+ mCondition.signal();
+ trace("after signal()");
+ for (int i = 0; i < 5; ++i)
+ {
+ threadSleep(100);
+ trace("Woke from sleep.");
+ if (mRunningThreadCount == 0)
+ {
+ break;
+ }
+ }
+ printTrace();
+ assertTrue("Threads still running: " + mRunningThreadCount, mRunningThreadCount == 0);
+ }
+}