/* $Id: DestructionTest1.cpp,v 1.2 2002/07/18 05:32:00 tylerdauwalder Exp $ This file implements a test class for testing BLocker functionality. It tests use cases "Destruction" and "Locking 3". The test works like the following: - the main thread acquires the lock - the second thread sleeps - the second thread then attempts to acquire the lock - the first thread releases the lock - at this time, the new thread acquires the lock and goes to sleep - the first thread attempts to acquire the lock - the second thread deletes the lock - the first thread is woken up indicating that the lock wasn't acquired. */ #include "ThreadedTestCaller.h" #include "DestructionTest1.h" #include "cppunit/TestSuite.h" #include // This constant is used to determine the number of microseconds to // sleep during major steps of the test. const bigtime_t SNOOZE_TIME = 200000; /* * Method: DestructionTest1::DestructionTest1() * Descr: This is the only constructor for this test class. */ DestructionTest1::DestructionTest1(std::string name, bool isBenaphore) : LockerTestCase(name, isBenaphore) { } /* * Method: DestructionTest1::~DestructionTest1() * Descr: This is the only destructor for this test class. */ DestructionTest1::~DestructionTest1() { } /* * Method: DestructionTest1::TestThread1() * Descr: This method immediately acquires the lock, sleeps * for SNOOZE_TIME and then releases the lock. It sleeps * again for SNOOZE_TIME and then tries to re-acquire the * lock. By this time, the other thread should have * deleted the lock. This acquisition should fail. */ void DestructionTest1::TestThread1(void) { assert(theLocker->Lock()); NextSubTest(); snooze(SNOOZE_TIME); NextSubTest(); theLocker->Unlock(); NextSubTest(); snooze(SNOOZE_TIME); NextSubTest(); assert(!theLocker->Lock()); NextSubTest(); } /* * Method: DestructionTest1::TestThread2() * Descr: This method sleeps for SNOOZE_TIME and then acquires the lock. * It sleeps again for 2*SNOOZE_TIME and then deletes the lock. * This should wake up the other thread. */ void DestructionTest1::TestThread2(void) { BLocker *tmpLock; snooze(SNOOZE_TIME); NextSubTest(); assert(theLocker->Lock()); NextSubTest(); snooze(SNOOZE_TIME); NextSubTest(); snooze(SNOOZE_TIME); NextSubTest(); tmpLock = theLocker; NextSubTest(); theLocker = NULL; NextSubTest(); delete tmpLock; } /* * Method: DestructionTest1::suite() * Descr: This static member function returns a test suite for performing * all combinations of "DestructionTest1". The test suite contains * two instances of the test. One is performed on a benaphore, * the other on a semaphore based BLocker. Each individual test * is created as a ThreadedTestCase (typedef'd as * DestructionTest1Caller) with two independent threads. */ CppUnit::Test *DestructionTest1::suite(void) { typedef BThreadedTestCaller DestructionTest1Caller; CppUnit::TestSuite *testSuite = new CppUnit::TestSuite("DestructionTest1"); // Make a benaphore based test object, create a ThreadedTestCase for it and add // two threads to it. DestructionTest1 *theTest = new DestructionTest1("Benaphore", true); DestructionTest1Caller *threadedTest1 = new DestructionTest1Caller("BLocker::Destruction Test #1 (benaphore)", theTest); threadedTest1->addThread("A", &DestructionTest1::TestThread1); threadedTest1->addThread("B", &DestructionTest1::TestThread2); // Make a semaphore based test object, create a ThreadedTestCase for it and add // three threads to it. theTest = new DestructionTest1("Semaphore", false); DestructionTest1Caller *threadedTest2 = new DestructionTest1Caller("BLocker::Destruction Test #1 (semaphore)", theTest); threadedTest2->addThread("A", &DestructionTest1::TestThread1); threadedTest2->addThread("B", &DestructionTest1::TestThread2); testSuite->addTest(threadedTest1); testSuite->addTest(threadedTest2); return(testSuite); }