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 34 LockTargetTester::LockTargetTester() 35 : BThreadedTestCase(), 36 fHandler(NULL), 37 fLooper(NULL) 38 { 39 } 40 41 // constructor 42 LockTargetTester::LockTargetTester(std::string name) 43 : BThreadedTestCase(name), 44 fHandler(NULL), 45 fLooper(NULL) 46 { 47 } 48 49 // destructor 50 LockTargetTester::~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 */ 67 void 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 */ 79 void 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 */ 98 void 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 */ 128 void 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 */ 146 void 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 */ 170 void 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 */ 188 void 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 */ 208 void 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 */ 221 void LockTargetTester::LockTargetTest7() 222 { 223 RemoteSMTarget target(false); 224 BMessenger messenger(target.Messenger()); 225 CHK(messenger.LockTarget() == false); 226 } 227 228 229 Test* 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