//------------------------------------------------------------------------------ // LockTargetTester.cpp // //------------------------------------------------------------------------------ // Standard Includes ----------------------------------------------------------- #include // System Includes ------------------------------------------------------------- #include #include #include #include #include // Project Includes ------------------------------------------------------------ #include #include #include // Local Includes -------------------------------------------------------------- #include "Helpers.h" #include "LockTargetTester.h" #include "SMTarget.h" // Local Defines --------------------------------------------------------------- // Globals --------------------------------------------------------------------- //------------------------------------------------------------------------------ // constructor LockTargetTester::LockTargetTester() : BThreadedTestCase(), fHandler(NULL), fLooper(NULL) { } // constructor LockTargetTester::LockTargetTester(std::string name) : BThreadedTestCase(name), fHandler(NULL), fLooper(NULL) { } // destructor LockTargetTester::~LockTargetTester() { if (fLooper) { fLooper->Lock(); if (fHandler) { fLooper->RemoveHandler(fHandler); delete fHandler; } fLooper->Quit(); } } /* bool LockTarget() const @case 1 this is uninitialized @results should return false. */ void LockTargetTester::LockTargetTest1() { BMessenger messenger; CHK(messenger.LockTarget() == false); } /* bool LockTarget() const @case 2 this is initialized to local target with preferred handler, looper is not locked @results should lock the looper and return true. */ void LockTargetTester::LockTargetTest2() { status_t result = B_OK; BLooper *looper = new BLooper; looper->Run(); LooperQuitter quitter(looper); BMessenger messenger(NULL, looper, &result); CHK(messenger.LockTarget() == true); CHK(looper->IsLocked() == true); looper->Unlock(); CHK(looper->IsLocked() == false); } /* bool LockTarget() const @case 3 this is initialized to local target with specific handler, looper is not locked @results should lock the looper and return true. */ void LockTargetTester::LockTargetTest3() { // create looper and handler status_t result = B_OK; BLooper *looper = new BLooper; looper->Run(); LooperQuitter quitter(looper); BHandler *handler = new BHandler; HandlerDeleter deleter(handler); CHK(looper->Lock()); looper->AddHandler(handler); looper->Unlock(); // create the messenger and do the checks BMessenger messenger(handler, NULL, &result); CHK(messenger.LockTarget() == true); CHK(looper->IsLocked() == true); looper->Unlock(); CHK(looper->IsLocked() == false); } /* bool LockTarget() const @case 4 this is initialized to local target with preferred handler, looper is locked by another thread @results should block until the looper is unlocked, lock it and return true. @thread A - locks the looper - waits 100ms - unlocks the looper */ void LockTargetTester::LockTargetTest4A() { CHK(fLooper->Lock() == true); snooze(100000); fLooper->Unlock(); } /* bool LockTarget() const @case 4 this is initialized to local target with preferred handler, looper is locked by another thread @results should block until the looper is unlocked, lock it and return true. @thread B - waits 50ms (until thread A has acquired the looper lock) - tries to lock the looper via messenger and blocks - acquires the lock successfully after 50ms - unlocks the looper */ void LockTargetTester::LockTargetTest4B() { enum { JITTER = 10000 }; // Maybe critical on slow machines. snooze(50000); BMessenger messenger(NULL, fLooper); bigtime_t time = system_time(); CHK(messenger.LockTarget() == true); time = system_time() - time - 50000; CHK(fLooper->IsLocked() == true); fLooper->Unlock(); CHK(fLooper->IsLocked() == false); CHK(time > -JITTER && time < JITTER); } /* bool LockTarget() const @case 5 this is initialized to local target with specific handler, looper is locked by another thread @results should block until the looper is unlocked, lock it and return true. @thread A - locks the looper - waits 100ms - unlocks the looper */ void LockTargetTester::LockTargetTest5A() { CHK(fLooper->Lock() == true); snooze(100000); fLooper->Unlock(); } /* bool LockTarget() const @case 5 this is initialized to local target with specific handler, looper is locked by another thread @results should block until the looper is unlocked, lock it and return true. @thread B - waits 50ms (until thread A has acquired the looper lock) - tries to lock the looper via messenger and blocks - acquires the lock successfully after 50ms - unlocks the looper */ void LockTargetTester::LockTargetTest5B() { enum { JITTER = 10000 }; // Maybe critical on slow machines. snooze(50000); BMessenger messenger(fHandler, NULL); bigtime_t time = system_time(); CHK(messenger.LockTarget() == true); time = system_time() - time - 50000; CHK(fLooper->IsLocked() == true); fLooper->Unlock(); CHK(fLooper->IsLocked() == false); CHK(time > -JITTER && time < JITTER); } /* bool LockTarget() const @case 6 this is initialized to remote target with preferred handler, looper is not locked @results should not lock the looper and return false. */ void LockTargetTester::LockTargetTest6() { RemoteSMTarget target(true); BMessenger messenger(target.Messenger()); CHK(messenger.LockTarget() == false); } /* bool LockTarget() const @case 7 this is initialized to remote target with specific handler, looper is not locked @results should not lock the looper and return false. */ void LockTargetTester::LockTargetTest7() { RemoteSMTarget target(false); BMessenger messenger(target.Messenger()); CHK(messenger.LockTarget() == false); } Test* LockTargetTester::Suite() { typedef BThreadedTestCaller TC; TestSuite* testSuite = new TestSuite; ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest1); ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest2); ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest3); // test4 LockTargetTester *test4 = new LockTargetTester("LockTargetTest4"); test4->fLooper = new BLooper; test4->fLooper->Run(); // test4 test caller TC *caller4 = new TC("BMessenger::LockTargetTest4", test4); caller4->addThread("A", &LockTargetTester::LockTargetTest4A); caller4->addThread("B", &LockTargetTester::LockTargetTest4B); testSuite->addTest(caller4); // test5 LockTargetTester *test5 = new LockTargetTester("LockTargetTest5"); // create looper and handler test5->fLooper = new BLooper; test5->fLooper->Run(); test5->fHandler = new BHandler; if (test5->fLooper->Lock()) { test5->fLooper->AddHandler(test5->fHandler); test5->fLooper->Unlock(); } else printf("ERROR: Can't init LockTargetTester test5!\n"); // test5 test caller TC *caller5 = new TC("BMessenger::LockTargetTest5", test5); caller5->addThread("A", &LockTargetTester::LockTargetTest5A); caller5->addThread("B", &LockTargetTester::LockTargetTest5B); testSuite->addTest(caller5); // tests 6-7 ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest6); ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest7); return testSuite; }