1c1289294SIngo Weinhold //------------------------------------------------------------------------------ 2c1289294SIngo Weinhold // LockTargetTester.cpp 3c1289294SIngo Weinhold // 4c1289294SIngo Weinhold //------------------------------------------------------------------------------ 5c1289294SIngo Weinhold 6c1289294SIngo Weinhold // Standard Includes ----------------------------------------------------------- 7c1289294SIngo Weinhold #include <stdio.h> 8c1289294SIngo Weinhold 9c1289294SIngo Weinhold // System Includes ------------------------------------------------------------- 10c1289294SIngo Weinhold #include <be/app/Message.h> 11c1289294SIngo Weinhold #include <be/kernel/OS.h> 12c1289294SIngo Weinhold 13c1289294SIngo Weinhold #include <Handler.h> 14c1289294SIngo Weinhold #include <Looper.h> 15c1289294SIngo Weinhold #include <Messenger.h> 16c1289294SIngo Weinhold 17c1289294SIngo Weinhold // Project Includes ------------------------------------------------------------ 1845962ab4SIngo Weinhold #include <TestUtils.h> 19c1289294SIngo Weinhold #include <ThreadedTestCaller.h> 20c1289294SIngo Weinhold #include <cppunit/TestSuite.h> 21c1289294SIngo Weinhold 22c1289294SIngo Weinhold // Local Includes -------------------------------------------------------------- 23c1289294SIngo Weinhold #include "Helpers.h" 24c1289294SIngo Weinhold #include "LockTargetTester.h" 2515df6f8aSIngo Weinhold #include "SMTarget.h" 26c1289294SIngo Weinhold 27c1289294SIngo Weinhold // Local Defines --------------------------------------------------------------- 28c1289294SIngo Weinhold 29c1289294SIngo Weinhold // Globals --------------------------------------------------------------------- 30c1289294SIngo Weinhold 31c1289294SIngo Weinhold //------------------------------------------------------------------------------ 32c1289294SIngo Weinhold 33c1289294SIngo Weinhold // constructor 34c1289294SIngo Weinhold LockTargetTester::LockTargetTester() 35c1289294SIngo Weinhold : BThreadedTestCase(), 36c1289294SIngo Weinhold fHandler(NULL), 37c1289294SIngo Weinhold fLooper(NULL) 38c1289294SIngo Weinhold { 39c1289294SIngo Weinhold } 40c1289294SIngo Weinhold 41c1289294SIngo Weinhold // constructor 42c1289294SIngo Weinhold LockTargetTester::LockTargetTester(std::string name) 43c1289294SIngo Weinhold : BThreadedTestCase(name), 44c1289294SIngo Weinhold fHandler(NULL), 45c1289294SIngo Weinhold fLooper(NULL) 46c1289294SIngo Weinhold { 47c1289294SIngo Weinhold } 48c1289294SIngo Weinhold 49c1289294SIngo Weinhold // destructor 50c1289294SIngo Weinhold LockTargetTester::~LockTargetTester() 51c1289294SIngo Weinhold { 52c1289294SIngo Weinhold if (fLooper) { 53c1289294SIngo Weinhold fLooper->Lock(); 54c1289294SIngo Weinhold if (fHandler) { 55c1289294SIngo Weinhold fLooper->RemoveHandler(fHandler); 56c1289294SIngo Weinhold delete fHandler; 57c1289294SIngo Weinhold } 58c1289294SIngo Weinhold fLooper->Quit(); 59c1289294SIngo Weinhold } 60c1289294SIngo Weinhold } 61c1289294SIngo Weinhold 62c1289294SIngo Weinhold /* 63c1289294SIngo Weinhold bool LockTarget() const 64c1289294SIngo Weinhold @case 1 this is uninitialized 65c1289294SIngo Weinhold @results should return false. 66c1289294SIngo Weinhold */ 67c1289294SIngo Weinhold void LockTargetTester::LockTargetTest1() 68c1289294SIngo Weinhold { 69c1289294SIngo Weinhold BMessenger messenger; 70c1289294SIngo Weinhold CHK(messenger.LockTarget() == false); 71c1289294SIngo Weinhold } 72c1289294SIngo Weinhold 73c1289294SIngo Weinhold /* 74c1289294SIngo Weinhold bool LockTarget() const 75c1289294SIngo Weinhold @case 2 this is initialized to local target with preferred handler, 76c1289294SIngo Weinhold looper is not locked 77c1289294SIngo Weinhold @results should lock the looper and return true. 78c1289294SIngo Weinhold */ 79c1289294SIngo Weinhold void LockTargetTester::LockTargetTest2() 80c1289294SIngo Weinhold { 81c1289294SIngo Weinhold status_t result = B_OK; 82c1289294SIngo Weinhold BLooper *looper = new BLooper; 83c1289294SIngo Weinhold looper->Run(); 84c1289294SIngo Weinhold LooperQuitter quitter(looper); 85c1289294SIngo Weinhold BMessenger messenger(NULL, looper, &result); 86c1289294SIngo Weinhold CHK(messenger.LockTarget() == true); 87c1289294SIngo Weinhold CHK(looper->IsLocked() == true); 88c1289294SIngo Weinhold looper->Unlock(); 89c1289294SIngo Weinhold CHK(looper->IsLocked() == false); 90c1289294SIngo Weinhold } 91c1289294SIngo Weinhold 92c1289294SIngo Weinhold /* 93c1289294SIngo Weinhold bool LockTarget() const 94c1289294SIngo Weinhold @case 3 this is initialized to local target with specific handler, 95c1289294SIngo Weinhold looper is not locked 96c1289294SIngo Weinhold @results should lock the looper and return true. 97c1289294SIngo Weinhold */ 98c1289294SIngo Weinhold void LockTargetTester::LockTargetTest3() 99c1289294SIngo Weinhold { 100c1289294SIngo Weinhold // create looper and handler 101c1289294SIngo Weinhold status_t result = B_OK; 102c1289294SIngo Weinhold BLooper *looper = new BLooper; 103c1289294SIngo Weinhold looper->Run(); 104c1289294SIngo Weinhold LooperQuitter quitter(looper); 105c1289294SIngo Weinhold BHandler *handler = new BHandler; 106c1289294SIngo Weinhold HandlerDeleter deleter(handler); 107c1289294SIngo Weinhold CHK(looper->Lock()); 108c1289294SIngo Weinhold looper->AddHandler(handler); 109c1289294SIngo Weinhold looper->Unlock(); 110c1289294SIngo Weinhold // create the messenger and do the checks 111c1289294SIngo Weinhold BMessenger messenger(handler, NULL, &result); 112c1289294SIngo Weinhold CHK(messenger.LockTarget() == true); 113c1289294SIngo Weinhold CHK(looper->IsLocked() == true); 114c1289294SIngo Weinhold looper->Unlock(); 115c1289294SIngo Weinhold CHK(looper->IsLocked() == false); 116c1289294SIngo Weinhold } 117c1289294SIngo Weinhold 118c1289294SIngo Weinhold /* 119c1289294SIngo Weinhold bool LockTarget() const 120c1289294SIngo Weinhold @case 4 this is initialized to local target with preferred handler, 121c1289294SIngo Weinhold looper is locked by another thread 122c1289294SIngo Weinhold @results should block until the looper is unlocked, lock it and 123c1289294SIngo Weinhold return true. 124c1289294SIngo Weinhold @thread A - locks the looper 125c1289294SIngo Weinhold - waits 100ms 126c1289294SIngo Weinhold - unlocks the looper 127c1289294SIngo Weinhold */ 128c1289294SIngo Weinhold void LockTargetTester::LockTargetTest4A() 129c1289294SIngo Weinhold { 130c1289294SIngo Weinhold CHK(fLooper->Lock() == true); 131c1289294SIngo Weinhold snooze(100000); 132c1289294SIngo Weinhold fLooper->Unlock(); 133c1289294SIngo Weinhold } 134c1289294SIngo Weinhold 135c1289294SIngo Weinhold /* 136c1289294SIngo Weinhold bool LockTarget() const 137c1289294SIngo Weinhold @case 4 this is initialized to local target with preferred handler, 138c1289294SIngo Weinhold looper is locked by another thread 139c1289294SIngo Weinhold @results should block until the looper is unlocked, lock it and 140c1289294SIngo Weinhold return true. 141c1289294SIngo Weinhold @thread B - waits 50ms (until thread A has acquired the looper lock) 142c1289294SIngo Weinhold - tries to lock the looper via messenger and blocks 143c1289294SIngo Weinhold - acquires the lock successfully after 50ms 144c1289294SIngo Weinhold - unlocks the looper 145c1289294SIngo Weinhold */ 146c1289294SIngo Weinhold void LockTargetTester::LockTargetTest4B() 147c1289294SIngo Weinhold { 148c1289294SIngo Weinhold enum { JITTER = 10000 }; // Maybe critical on slow machines. 149c1289294SIngo Weinhold snooze(50000); 150c1289294SIngo Weinhold BMessenger messenger(NULL, fLooper); 151c1289294SIngo Weinhold bigtime_t time = system_time(); 152c1289294SIngo Weinhold CHK(messenger.LockTarget() == true); 153c1289294SIngo Weinhold time = system_time() - time - 50000; 154c1289294SIngo Weinhold CHK(fLooper->IsLocked() == true); 155c1289294SIngo Weinhold fLooper->Unlock(); 156c1289294SIngo Weinhold CHK(fLooper->IsLocked() == false); 157c1289294SIngo Weinhold CHK(time > -JITTER && time < JITTER); 158c1289294SIngo Weinhold } 159c1289294SIngo Weinhold 160c1289294SIngo Weinhold /* 161c1289294SIngo Weinhold bool LockTarget() const 162c1289294SIngo Weinhold @case 5 this is initialized to local target with specific handler, 163c1289294SIngo Weinhold looper is locked by another thread 164c1289294SIngo Weinhold @results should block until the looper is unlocked, lock it and 165c1289294SIngo Weinhold return true. 166c1289294SIngo Weinhold @thread A - locks the looper 167c1289294SIngo Weinhold - waits 100ms 168c1289294SIngo Weinhold - unlocks the looper 169c1289294SIngo Weinhold */ 170c1289294SIngo Weinhold void LockTargetTester::LockTargetTest5A() 171c1289294SIngo Weinhold { 172c1289294SIngo Weinhold CHK(fLooper->Lock() == true); 173c1289294SIngo Weinhold snooze(100000); 174c1289294SIngo Weinhold fLooper->Unlock(); 175c1289294SIngo Weinhold } 176c1289294SIngo Weinhold 177c1289294SIngo Weinhold /* 178c1289294SIngo Weinhold bool LockTarget() const 179c1289294SIngo Weinhold @case 5 this is initialized to local target with specific handler, 180c1289294SIngo Weinhold looper is locked by another thread 181c1289294SIngo Weinhold @results should block until the looper is unlocked, lock it and 182c1289294SIngo Weinhold return true. 183c1289294SIngo Weinhold @thread B - waits 50ms (until thread A has acquired the looper lock) 184c1289294SIngo Weinhold - tries to lock the looper via messenger and blocks 185c1289294SIngo Weinhold - acquires the lock successfully after 50ms 186c1289294SIngo Weinhold - unlocks the looper 187c1289294SIngo Weinhold */ 188c1289294SIngo Weinhold void LockTargetTester::LockTargetTest5B() 189c1289294SIngo Weinhold { 190c1289294SIngo Weinhold enum { JITTER = 10000 }; // Maybe critical on slow machines. 191c1289294SIngo Weinhold snooze(50000); 192c1289294SIngo Weinhold BMessenger messenger(fHandler, NULL); 193c1289294SIngo Weinhold bigtime_t time = system_time(); 194c1289294SIngo Weinhold CHK(messenger.LockTarget() == true); 195c1289294SIngo Weinhold time = system_time() - time - 50000; 196c1289294SIngo Weinhold CHK(fLooper->IsLocked() == true); 197c1289294SIngo Weinhold fLooper->Unlock(); 198c1289294SIngo Weinhold CHK(fLooper->IsLocked() == false); 199c1289294SIngo Weinhold CHK(time > -JITTER && time < JITTER); 200c1289294SIngo Weinhold } 201c1289294SIngo Weinhold 202c1289294SIngo Weinhold /* 203c1289294SIngo Weinhold bool LockTarget() const 204c1289294SIngo Weinhold @case 6 this is initialized to remote target with preferred 205c1289294SIngo Weinhold handler, looper is not locked 206c1289294SIngo Weinhold @results should not lock the looper and return false. 207c1289294SIngo Weinhold */ 208c1289294SIngo Weinhold void LockTargetTester::LockTargetTest6() 209c1289294SIngo Weinhold { 21015df6f8aSIngo Weinhold RemoteSMTarget target(true); 21115df6f8aSIngo Weinhold BMessenger messenger(target.Messenger()); 21215df6f8aSIngo Weinhold CHK(messenger.LockTarget() == false); 213c1289294SIngo Weinhold } 214c1289294SIngo Weinhold 215c1289294SIngo Weinhold /* 216c1289294SIngo Weinhold bool LockTarget() const 217c1289294SIngo Weinhold @case 7 this is initialized to remote target with specific handler, 218c1289294SIngo Weinhold looper is not locked 219c1289294SIngo Weinhold @results should not lock the looper and return false. 220c1289294SIngo Weinhold */ 221c1289294SIngo Weinhold void LockTargetTester::LockTargetTest7() 222c1289294SIngo Weinhold { 22315df6f8aSIngo Weinhold RemoteSMTarget target(false); 22415df6f8aSIngo Weinhold BMessenger messenger(target.Messenger()); 22515df6f8aSIngo Weinhold CHK(messenger.LockTarget() == false); 226c1289294SIngo Weinhold } 227c1289294SIngo Weinhold 228c1289294SIngo Weinhold 229c1289294SIngo Weinhold Test* LockTargetTester::Suite() 230c1289294SIngo Weinhold { 231c1289294SIngo Weinhold typedef BThreadedTestCaller<LockTargetTester> TC; 232c1289294SIngo Weinhold 233c1289294SIngo Weinhold TestSuite* testSuite = new TestSuite; 234c1289294SIngo Weinhold 235*be2939caSTyler Dauwalder ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest1); 236*be2939caSTyler Dauwalder ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest2); 237*be2939caSTyler Dauwalder ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest3); 238c1289294SIngo Weinhold // test4 239c1289294SIngo Weinhold LockTargetTester *test4 24045962ab4SIngo Weinhold = new LockTargetTester("LockTargetTest4"); 241c1289294SIngo Weinhold test4->fLooper = new BLooper; 242c1289294SIngo Weinhold test4->fLooper->Run(); 243c1289294SIngo Weinhold // test4 test caller 244*be2939caSTyler Dauwalder TC *caller4 = new TC("BMessenger::LockTargetTest4", test4); 245c1289294SIngo Weinhold caller4->addThread("A", &LockTargetTester::LockTargetTest4A); 246c1289294SIngo Weinhold caller4->addThread("B", &LockTargetTester::LockTargetTest4B); 247c1289294SIngo Weinhold testSuite->addTest(caller4); 248c1289294SIngo Weinhold // test5 249c1289294SIngo Weinhold LockTargetTester *test5 25045962ab4SIngo Weinhold = new LockTargetTester("LockTargetTest5"); 251c1289294SIngo Weinhold // create looper and handler 252c1289294SIngo Weinhold test5->fLooper = new BLooper; 253c1289294SIngo Weinhold test5->fLooper->Run(); 254c1289294SIngo Weinhold test5->fHandler = new BHandler; 255c1289294SIngo Weinhold if (test5->fLooper->Lock()) { 256c1289294SIngo Weinhold test5->fLooper->AddHandler(test5->fHandler); 257c1289294SIngo Weinhold test5->fLooper->Unlock(); 258c1289294SIngo Weinhold } else 259c1289294SIngo Weinhold printf("ERROR: Can't init LockTargetTester test5!\n"); 260c1289294SIngo Weinhold // test5 test caller 261*be2939caSTyler Dauwalder TC *caller5 = new TC("BMessenger::LockTargetTest5", test5); 262c1289294SIngo Weinhold caller5->addThread("A", &LockTargetTester::LockTargetTest5A); 263c1289294SIngo Weinhold caller5->addThread("B", &LockTargetTester::LockTargetTest5B); 264c1289294SIngo Weinhold testSuite->addTest(caller5); 265c1289294SIngo Weinhold // tests 6-7 266*be2939caSTyler Dauwalder ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest6); 267*be2939caSTyler Dauwalder ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest7); 268c1289294SIngo Weinhold 269c1289294SIngo Weinhold return testSuite; 270c1289294SIngo Weinhold } 271c1289294SIngo Weinhold 272*be2939caSTyler Dauwalder 273