152a38012Sejakowatz /*
2571d840aSOliver Tappe $Id: DestructionTest2.cpp 301 2002-07-18 05:32:00Z tylerdauwalder $
352a38012Sejakowatz
452a38012Sejakowatz This file implements a test class for testing BLocker functionality.
552a38012Sejakowatz It tests use cases "Destruction" and "Locking 4".
652a38012Sejakowatz
752a38012Sejakowatz The test works like the following:
852a38012Sejakowatz - the main thread acquires the lock
952a38012Sejakowatz - it creates a new thread and sleeps
1052a38012Sejakowatz - the new thread attempts to acquire the lock but times out
1152a38012Sejakowatz - the new thread then attempts to acquire the lock again
1252a38012Sejakowatz - before the new thread times out a second time, the first thread releases
1352a38012Sejakowatz the lock
1452a38012Sejakowatz - at this time, the new thread acquires the lock and goes to sleep
1552a38012Sejakowatz - the first thread attempts to acquire the lock
1652a38012Sejakowatz - the second thread deletes the lock
1752a38012Sejakowatz - the first thread is woken up indicating that the lock wasn't acquired.
1852a38012Sejakowatz
1952a38012Sejakowatz */
2052a38012Sejakowatz
2152a38012Sejakowatz
229285de51STyler Dauwalder #include <ThreadedTestCaller.h>
2352a38012Sejakowatz #include "DestructionTest2.h"
249285de51STyler Dauwalder #include <cppunit/TestSuite.h>
259285de51STyler Dauwalder #include <Locker.h>
2652a38012Sejakowatz
2752a38012Sejakowatz // This constant is used to determine the number of microseconds to
2852a38012Sejakowatz // sleep during major steps of the test.
2952a38012Sejakowatz
3052a38012Sejakowatz const bigtime_t SNOOZE_TIME = 200000;
3152a38012Sejakowatz
3252a38012Sejakowatz
3352a38012Sejakowatz /*
349285de51STyler Dauwalder * Method: DestructionTest2::DestructionTest2()
3552a38012Sejakowatz * Descr: This is the only constructor for this test class.
3652a38012Sejakowatz */
3752a38012Sejakowatz
389285de51STyler Dauwalder
DestructionTest2(std::string name,bool isBenaphore)399285de51STyler Dauwalder DestructionTest2::DestructionTest2(std::string name,
4052a38012Sejakowatz bool isBenaphore) :
419285de51STyler Dauwalder LockerTestCase(name, isBenaphore)
4252a38012Sejakowatz {
4352a38012Sejakowatz }
4452a38012Sejakowatz
4552a38012Sejakowatz
4652a38012Sejakowatz /*
479285de51STyler Dauwalder * Method: DestructionTest2::~DestructionTest2()
4852a38012Sejakowatz * Descr: This is the only destructor for this test class.
4952a38012Sejakowatz */
5052a38012Sejakowatz
519285de51STyler Dauwalder
~DestructionTest2()529285de51STyler Dauwalder DestructionTest2::~DestructionTest2()
5352a38012Sejakowatz {
5452a38012Sejakowatz }
5552a38012Sejakowatz
5652a38012Sejakowatz
5752a38012Sejakowatz /*
589285de51STyler Dauwalder * Method: DestructionTest2::TestThread1()
5952a38012Sejakowatz * Descr: This method immediately acquires the lock, sleeps
6052a38012Sejakowatz * for SNOOZE_TIME and then releases the lock. It sleeps
6152a38012Sejakowatz * again for SNOOZE_TIME and then tries to re-acquire the
6252a38012Sejakowatz * lock. By this time, the other thread should have
6352a38012Sejakowatz * deleted the lock. This acquisition should fail.
6452a38012Sejakowatz */
6552a38012Sejakowatz
TestThread1(void)669285de51STyler Dauwalder void DestructionTest2::TestThread1(void)
6752a38012Sejakowatz {
68*8a8c62d5SAxel Dörfler CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME) == B_OK);
699285de51STyler Dauwalder NextSubTest();
7052a38012Sejakowatz snooze(SNOOZE_TIME);
719285de51STyler Dauwalder NextSubTest();
7252a38012Sejakowatz theLocker->Unlock();
739285de51STyler Dauwalder NextSubTest();
7452a38012Sejakowatz snooze(SNOOZE_TIME);
759285de51STyler Dauwalder NextSubTest();
76*8a8c62d5SAxel Dörfler CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME * 10) == B_BAD_SEM_ID);
779285de51STyler Dauwalder NextSubTest();
7852a38012Sejakowatz }
7952a38012Sejakowatz
8052a38012Sejakowatz
8152a38012Sejakowatz /*
829285de51STyler Dauwalder * Method: DestructionTest2::TestThread2()
8352a38012Sejakowatz * Descr: This method sleeps for SNOOZE_TIME/10 and then attempts to acquire
8452a38012Sejakowatz * the lock for SNOOZE_TIME/10 seconds. This acquisition will timeout
8552a38012Sejakowatz * because the other thread is holding the lock. Then it acquires the
8652a38012Sejakowatz * lock by using a larger timeout. It sleeps again for 2*SNOOZE_TIME and
8752a38012Sejakowatz * then deletes the lock. This should wake up the other thread.
8852a38012Sejakowatz */
8952a38012Sejakowatz
TestThread2(void)909285de51STyler Dauwalder void DestructionTest2::TestThread2(void)
9152a38012Sejakowatz {
929285de51STyler Dauwalder BLocker *tmpLock;
9352a38012Sejakowatz
9452a38012Sejakowatz snooze(SNOOZE_TIME/10);
959285de51STyler Dauwalder NextSubTest();
96*8a8c62d5SAxel Dörfler CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME / 10) == B_TIMED_OUT);
979285de51STyler Dauwalder NextSubTest();
98*8a8c62d5SAxel Dörfler CPPUNIT_ASSERT(theLocker->LockWithTimeout(SNOOZE_TIME * 10) == B_OK);
999285de51STyler Dauwalder NextSubTest();
10052a38012Sejakowatz snooze(SNOOZE_TIME);
1019285de51STyler Dauwalder NextSubTest();
10252a38012Sejakowatz snooze(SNOOZE_TIME);
1039285de51STyler Dauwalder NextSubTest();
10452a38012Sejakowatz tmpLock = theLocker;
10552a38012Sejakowatz theLocker = NULL;
10652a38012Sejakowatz delete tmpLock;
10752a38012Sejakowatz }
10852a38012Sejakowatz
10952a38012Sejakowatz
11052a38012Sejakowatz /*
1119285de51STyler Dauwalder * Method: DestructionTest2::suite()
11252a38012Sejakowatz * Descr: This static member function returns a test suite for performing
11352a38012Sejakowatz * all combinations of "DestructionTest2". The test suite contains
11452a38012Sejakowatz * two instances of the test. One is performed on a benaphore,
11552a38012Sejakowatz * the other on a semaphore based BLocker. Each individual test
11652a38012Sejakowatz * is created as a ThreadedTestCase (typedef'd as
11752a38012Sejakowatz * DestructionTest2Caller) with two independent threads.
11852a38012Sejakowatz */
11952a38012Sejakowatz
suite(void)1209285de51STyler Dauwalder CppUnit::Test *DestructionTest2::suite(void)
12152a38012Sejakowatz {
1229285de51STyler Dauwalder typedef BThreadedTestCaller<DestructionTest2> DestructionTest2Caller;
1239285de51STyler Dauwalder CppUnit::TestSuite *testSuite = new CppUnit::TestSuite("DestructionTest2");
12452a38012Sejakowatz
12552a38012Sejakowatz // Make a benaphore based test object, create a ThreadedTestCase for it and add
12652a38012Sejakowatz // two threads to it.
1279285de51STyler Dauwalder DestructionTest2 *theTest = new DestructionTest2("Benaphore", true);
1289285de51STyler Dauwalder DestructionTest2Caller *threadedTest1 = new DestructionTest2Caller("BLocker::Destruction Test #2 (benaphore)", theTest);
1299285de51STyler Dauwalder threadedTest1->addThread("A", &DestructionTest2::TestThread1);
1309285de51STyler Dauwalder threadedTest1->addThread("B", &DestructionTest2::TestThread2);
13152a38012Sejakowatz
13252a38012Sejakowatz // Make a semaphore based test object, create a ThreadedTestCase for it and add
13352a38012Sejakowatz // three threads to it.
1349285de51STyler Dauwalder theTest = new DestructionTest2("Semaphore", false);
1359285de51STyler Dauwalder DestructionTest2Caller *threadedTest2 = new DestructionTest2Caller("BLocker::Destruction Test #2 (semaphore)", theTest);
1369285de51STyler Dauwalder threadedTest2->addThread("A", &DestructionTest2::TestThread1);
1379285de51STyler Dauwalder threadedTest2->addThread("B", &DestructionTest2::TestThread2);
13852a38012Sejakowatz
13952a38012Sejakowatz testSuite->addTest(threadedTest1);
14052a38012Sejakowatz testSuite->addTest(threadedTest2);
14152a38012Sejakowatz return(testSuite);
14252a38012Sejakowatz }
14352a38012Sejakowatz
1449285de51STyler Dauwalder
1459285de51STyler Dauwalder
1469285de51STyler Dauwalder
147