xref: /haiku/src/tests/kits/support/blocker/DestructionTest1.cpp (revision 1deede7388b04dbeec5af85cae7164735ea9e70d)
1 /*
2 	$Id: DestructionTest1.cpp 301 2002-07-18 05:32:00Z tylerdauwalder $
3 
4 	This file implements a test class for testing BLocker functionality.
5 	It tests use cases "Destruction" and "Locking 3".
6 
7 	The test works like the following:
8 		- the main thread acquires the lock
9 		- the second thread sleeps
10 		- the second thread then attempts to acquire the lock
11 		- the first thread releases the lock
12 		- at this time, the new thread acquires the lock and goes to sleep
13 		- the first thread attempts to acquire the lock
14 		- the second thread deletes the lock
15 		- the first thread is woken up indicating that the lock wasn't acquired.
16 
17 	*/
18 
19 
20 #include "ThreadedTestCaller.h"
21 #include "DestructionTest1.h"
22 #include "cppunit/TestSuite.h"
23 #include <Locker.h>
24 
25 // This constant is used to determine the number of microseconds to
26 // sleep during major steps of the test.
27 
28 const bigtime_t SNOOZE_TIME = 200000;
29 
30 
31 /*
32  *  Method:  DestructionTest1::DestructionTest1()
33  *   Descr:  This is the only constructor for this test class.
34  */
35 
36 
37 	DestructionTest1::DestructionTest1(std::string name,
38 											   bool isBenaphore) :
39 		LockerTestCase(name, isBenaphore)
40 {
41 	}
42 
43 
44 /*
45  *  Method:  DestructionTest1::~DestructionTest1()
46  *   Descr:  This is the only destructor for this test class.
47  */
48 
49 
50 	DestructionTest1::~DestructionTest1()
51 {
52 	}
53 
54 
55 /*
56  *  Method:  DestructionTest1::TestThread1()
57  *   Descr:  This method immediately acquires the lock, sleeps
58  *           for SNOOZE_TIME and then releases the lock.  It sleeps
59  *           again for SNOOZE_TIME and then tries to re-acquire the
60  *           lock.  By this time, the other thread should have
61  *           deleted the lock.  This acquisition should fail.
62  */
63 
64 void DestructionTest1::TestThread1(void)
65 {
66 	CPPUNIT_ASSERT(theLocker->Lock());
67 	NextSubTest();
68 	snooze(SNOOZE_TIME);
69 	NextSubTest();
70 	theLocker->Unlock();
71 	NextSubTest();
72 	snooze(SNOOZE_TIME);
73 	NextSubTest();
74 	CPPUNIT_ASSERT(!theLocker->Lock());
75 	NextSubTest();
76 	}
77 
78 
79 /*
80  *  Method:  DestructionTest1::TestThread2()
81  *   Descr:  This method sleeps for SNOOZE_TIME and then acquires the lock.
82  *           It sleeps again for 2*SNOOZE_TIME and then deletes the lock.
83  *           This should wake up the other thread.
84  */
85 
86 void DestructionTest1::TestThread2(void)
87 {
88 	BLocker *tmpLock;
89 
90 	snooze(SNOOZE_TIME);
91 	NextSubTest();
92 	CPPUNIT_ASSERT(theLocker->Lock());
93 	NextSubTest();
94 	snooze(SNOOZE_TIME);
95 	NextSubTest();
96 	snooze(SNOOZE_TIME);
97 	NextSubTest();
98 	tmpLock = theLocker;
99 	NextSubTest();
100 	theLocker = NULL;
101 	NextSubTest();
102 	delete tmpLock;
103 }
104 
105 
106 /*
107  *  Method:  DestructionTest1::suite()
108  *   Descr:  This static member function returns a test suite for performing
109  *           all combinations of "DestructionTest1".  The test suite contains
110  *           two instances of the test.  One is performed on a benaphore,
111  *           the other on a semaphore based BLocker.  Each individual test
112  *           is created as a ThreadedTestCase (typedef'd as
113  *           DestructionTest1Caller) with two independent threads.
114  */
115 
116 CppUnit::Test *DestructionTest1::suite(void)
117 {
118 	typedef BThreadedTestCaller <DestructionTest1 >
119 		DestructionTest1Caller;
120 	CppUnit::TestSuite *testSuite = new CppUnit::TestSuite("DestructionTest1");
121 
122 	// Make a benaphore based test object, create a ThreadedTestCase for it and add
123 	// two threads to it.
124 	DestructionTest1 *theTest = new DestructionTest1("Benaphore", true);
125 	DestructionTest1Caller *threadedTest1 = new DestructionTest1Caller("BLocker::Destruction Test #1 (benaphore)", theTest);
126 	threadedTest1->addThread("A", &DestructionTest1::TestThread1);
127 	threadedTest1->addThread("B", &DestructionTest1::TestThread2);
128 
129 	// Make a semaphore based test object, create a ThreadedTestCase for it and add
130 	// three threads to it.
131 	theTest = new DestructionTest1("Semaphore", false);
132 	DestructionTest1Caller *threadedTest2 = new DestructionTest1Caller("BLocker::Destruction Test #1 (semaphore)", theTest);
133 	threadedTest2->addThread("A", &DestructionTest1::TestThread1);
134 	threadedTest2->addThread("B", &DestructionTest1::TestThread2);
135 
136 	testSuite->addTest(threadedTest1);
137 	testSuite->addTest(threadedTest2);
138 	return(testSuite);
139 	}
140 
141