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