2 $Id: ConcurrencyTest1.cpp 301 2002-07-18 05:32:00Z tylerdauwalder $
4 This file implements a test class for testing BLocker functionality.
5 It tests use cases "Locking 1", "Locking 2", "Unlocking", "Is Locked",
6 "Locking Thread" and "Count Locks".
11 #include <ThreadedTestCaller.h>
12 #include "ConcurrencyTest1.h"
13 #include <cppunit/TestSuite.h>
17 // This constant indicates the number of times the thread should test the
18 // acquisition and release of the BLocker.
20 const int32 MAXLOOP
= 10000;
24 * Method: ConcurrencyTest1::ConcurrencyTest1()
25 * Descr: This is the only constructor for this test case. It takes a
26 * test name and a flag to indicate whether to test a benaphore
27 * or semaphore type BLocker.
31 ConcurrencyTest1::ConcurrencyTest1(std::string name
, bool benaphoreFlag
) :
32 LockerTestCase(name
, benaphoreFlag
), lockTestValue(false)
38 * Method: ConcurrencyTest1::~ConcurrencyTest1()
39 * Descr: This is the descriptor for this test case.
43 ConcurrencyTest1::~ConcurrencyTest1()
49 * Method: ConcurrencyTest1::setUp()
50 * Descr: This member is called before starting the actual test threads
51 * and is used to ensure that the class is initialized for the
52 * testing. It just sets the "lockTestValue" flag to false. This
53 * flag is used to show that there is mutual exclusion between the
58 ConcurrencyTest1::setUp(void)
60 lockTestValue
= false;
65 * Method: ConcurrencyTest1::suite()
66 * Descr: This static member function returns a test suite for performing
67 * all combinations of "ConcurrencyTest1". The test suite contains
68 * two instances of the test. One is performed on a benaphore,
69 * the other on a semaphore based BLocker. Each individual test
70 * is created as a ThreadedTestCase (typedef'd as
71 * ConcurrencyTest1Caller) with three independent threads.
74 CppUnit::Test
*ConcurrencyTest1::suite(void)
76 typedef BThreadedTestCaller
<ConcurrencyTest1
>
77 ConcurrencyTest1Caller
;
80 CppUnit::TestSuite
*testSuite
= new CppUnit::TestSuite("ConcurrencyTest1");
82 // Make a benaphore based test object, create a ThreadedTestCase for it and add
83 // three threads to it.
84 ConcurrencyTest1
*theTest
= new ConcurrencyTest1("Benaphore", true);
85 ConcurrencyTest1Caller
*threadedTest1
= new ConcurrencyTest1Caller("BLocker::Concurrency Test #1 (benaphore)", theTest
);
86 threadedTest1
->addThread("A", &ConcurrencyTest1::TestThread
);
87 threadedTest1
->addThread("B", &ConcurrencyTest1::TestThread
);
88 threadedTest1
->addThread("C", &ConcurrencyTest1::TestThread
);
90 // Make a semaphore based test object, create a ThreadedTestCase for it and add
91 // three threads to it.
92 theTest
= new ConcurrencyTest1("Semaphore", false);
93 ConcurrencyTest1Caller
*threadedTest2
= new ConcurrencyTest1Caller("BLocker::Concurrency Test #1 (semaphore)", theTest
);
94 threadedTest2
->addThread("A", &ConcurrencyTest1::TestThread
);
95 threadedTest2
->addThread("B", &ConcurrencyTest1::TestThread
);
96 threadedTest2
->addThread("C", &ConcurrencyTest1::TestThread
);
98 testSuite
->addTest(threadedTest1
);
99 testSuite
->addTest(threadedTest2
);
105 * Method: ConcurrencyTest1::AcquireLock()
106 * Descr: This member function is passed the number of times through the
107 * acquisition loop (lockAttempt) and whether or not this is
108 * the first acquisition of the lock within this iteration.
109 * Based on these values, it may do a LockWithTimeout() or just
110 * a plain Lock() on theLocker. This is done to get coverage of
111 * both lock acquisition methods on the BLocker.
114 bool ConcurrencyTest1::AcquireLock(int lockAttempt
,
115 bool firstAcquisition
)
120 if (firstAcquisition
) {
121 timeoutLock
= ((lockAttempt
% 2) == 1);
123 timeoutLock
= (((lockAttempt
/ 2) % 2) == 1);
126 result
= (theLocker
->LockWithTimeout(1000000) == B_OK
);
128 result
= theLocker
->Lock();
135 * Method: ConcurrencyTest1::TestThread()
136 * Descr: This method is the core of the test. Each of the three threads
137 * run this method to perform the concurrency test. First, the
138 * SafetyLock class (see LockerTestCase.h) is used to make sure that
139 * the lock is released if an assertion happens. Then, each thread
140 * iterates MAXLOOP times through the main loop where the following
141 * actions are performed:
142 * - CheckLock() is used to show that the thread does not have
144 * - The thread acquires the lock.
145 * - The thread confirms that mutual exclusion is OK by testing
147 * - The thread confirms the lock is held once by the thread.
148 * - The thread acquires the lock again.
149 * - The thread confirms the lock is held twice now by the thread.
150 * - The thread releases the lock once.
151 * - The thread confirms the lock is held once now.
152 * - The thread confirms that mutual exclusion is still OK by
153 * testing lockTestValue.
154 * - The thread releases the lock again.
155 * - The thread confirms that the lock is no longer held.
158 void ConcurrencyTest1::TestThread(void)
161 SafetyLock
theSafetyLock(theLocker
);
163 for (i
= 0; i
< MAXLOOP
; i
++) {
164 // Print out 10 sub test markers per thread
165 if (i
% (MAXLOOP
/ 10) == 0)
169 CPPUNIT_ASSERT(AcquireLock(i
, true));
171 CPPUNIT_ASSERT(!lockTestValue
);
172 lockTestValue
= true;
175 CPPUNIT_ASSERT(AcquireLock(i
, false));
181 CPPUNIT_ASSERT(lockTestValue
);
182 lockTestValue
= false;