javacommons/utils/tsrc/javasrc/com/nokia/mj/impl/utils/concurrent/ConcurrentTests.java
changeset 26 dc7c549001d5
child 67 63b81d807542
--- /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);
+    }
+}