1 #include "RegistrarThreadManagerTest.h"
3 #include <cppunit/Test.h>
4 #include <cppunit/TestCaller.h>
5 #include <cppunit/TestSuite.h>
10 #include "RegistrarThread.h"
11 #include "RegistrarThreadManager.h"
18 RegistrarThreadManagerTest::Suite() {
19 CppUnit::TestSuite
*suite
= new CppUnit::TestSuite();
20 typedef CppUnit::TestCaller
<RegistrarThreadManagerTest
> TC
;
22 suite
->addTest( new TC("RegistrarThreadManager::Shutdown Test",
23 &RegistrarThreadManagerTest::ShutdownTest
) );
24 suite
->addTest( new TC("RegistrarThreadManager::Thread Limit Test",
25 &RegistrarThreadManagerTest::ThreadLimitTest
) );
32 // Base test thread class
33 class TestThread
: public RegistrarThread
{
35 TestThread(const char *name
, int32 priority
, BMessenger managerMessenger
)
36 : RegistrarThread(name
, priority
, managerMessenger
)
40 void DoSomethingUseless() {
49 // Test thread that terminates quickly
50 class TerminatingThread
: public TestThread
{
52 TerminatingThread(const char *name
, int32 priority
, BMessenger managerMessenger
)
53 : TestThread(name
, priority
, managerMessenger
)
58 virtual status_t
ThreadFunction() {
65 // Test thread that never terminates, but pays attention
66 // to its fShouldExit member
67 class WellBehavedInfiniteThread
: public TestThread
{
69 WellBehavedInfiniteThread(const char *name
, int32 priority
, BMessenger managerMessenger
)
70 : TestThread(name
, priority
, managerMessenger
)
75 virtual status_t
ThreadFunction() {
86 // Test thread that never terminates and completely ignores
87 // its fShouldExit member
88 class NaughtyInfiniteThread
: public TestThread
{
90 NaughtyInfiniteThread(const char *name
, int32 priority
, BMessenger managerMessenger
)
91 : TestThread(name
, priority
, managerMessenger
)
96 virtual status_t
ThreadFunction() {
109 RegistrarThreadManagerTest::setUp()
113 // Setup our application
114 fApplication
= new BTestApp("application/x-vnd.obos.RegistrarThreadManagerTest");
115 if (fApplication
->Init() != B_OK
) {
116 fprintf(stderr
, "Failed to initialize application (perhaps the obos registrar isn't running?).\n");
125 RegistrarThreadManagerTest::tearDown()
128 // Terminate the Application
130 fApplication
->Terminate();
135 BTestCase::tearDown();
139 RegistrarThreadManagerTest::ShutdownTest()
142 Outputf("(no tests performed for R5 version)\n");
147 RegistrarThreadManager manager
;
149 CHK(fApplication
&& fApplication
->InitCheck() == B_OK
);
151 // fApplication->AddHandler(&manager);
153 BMessenger
managerMessenger(NULL
, fApplication
, &err
);
154 // TODO: Do something about this...
156 fprintf(stderr
, "Fails because we try to init an Haiku BMessenger with a "
157 "BLooper from R5's libbe (more precisely a BTestApp living in libcppunit, "
158 "which is only linked against R5's libbe).\n");
161 CHK(err
== B_OK
&& managerMessenger
.IsValid());
164 // Launch a bunch of threads
165 const uint termThreads
= 2;
166 const uint niceThreads
= 2;
167 const uint evilThreads
= 2;
169 for (uint i
= 0; i
< termThreads
; i
++) {
172 sprintf(name
, "terminating #%d", i
);
173 RegistrarThread
*thread
= new TerminatingThread(name
, B_NORMAL_PRIORITY
, managerMessenger
);
175 CHK(thread
->InitCheck() == B_OK
);
176 CHK(manager
.LaunchThread(thread
) == B_OK
);
179 for (uint i
= 0; i
< niceThreads
; i
++) {
182 sprintf(name
, "nice #%d", i
);
183 RegistrarThread
*thread
= new WellBehavedInfiniteThread(name
, B_NORMAL_PRIORITY
, managerMessenger
);
185 CHK(thread
->InitCheck() == B_OK
);
186 CHK(manager
.LaunchThread(thread
) == B_OK
);
189 for (uint i
= 0; i
< evilThreads
; i
++) {
192 sprintf(name
, "evil #%d", i
);
193 RegistrarThread
*thread
= new NaughtyInfiniteThread(name
, B_NORMAL_PRIORITY
, managerMessenger
);
195 CHK(thread
->InitCheck() == B_OK
);
196 CHK(manager
.LaunchThread(thread
) == B_OK
);
199 // Check the number of threads before doing a cleanup
200 NextSubTest(); // <= 13
201 CHK(manager
.ThreadCount() == (termThreads
+ niceThreads
+ evilThreads
));
203 // Do the cleanup and check again (the terminating threads
206 snooze(500000); // give them time to terminate
207 CHK(manager
.CleanupThreads() == B_OK
);
208 CHK(manager
.ThreadCount() == (niceThreads
+ evilThreads
));
210 // Now do a shutdown and check again (the nice infinite threads
213 CHK(manager
.ShutdownThreads() == B_OK
);
214 snooze(1000000); // give them time to quit nicely
215 CHK(manager
.CleanupThreads() == B_OK
);
216 CHK(manager
.ThreadCount() == evilThreads
);
219 // Now finally kill any remaining threads (which should rid us of
220 // the naughty infinite threads)
222 CHK(manager
.KillThreads() == B_OK
);
223 CHK(manager
.ThreadCount() == 0);
229 RegistrarThreadManagerTest::ThreadLimitTest()
232 Outputf("(no tests performed for R5 version)\n");
236 RegistrarThreadManager manager
;
237 CHK(fApplication
&& fApplication
->InitCheck() == B_OK
);
238 BMessenger
managerMessenger(NULL
, fApplication
, &err
);
239 // TODO: Do something about this...
241 fprintf(stderr
, "Fails because we try to init an Haiku BMessenger with a "
242 "BLooper from R5's libbe (more precisely a BTestApp living in libcppunit, "
243 "which is only linked against R5's libbe).\n");
245 CHK(err
== B_OK
&& managerMessenger
.IsValid());
247 const uint termThreads
= 2;
249 // This test is only useful if the thread limit of the manager
250 // class is > kTermThreads
251 CHK(termThreads
< RegistrarThreadManager::kThreadLimit
);
253 // Launch some terminating threads
255 for (i
= 0; i
< termThreads
; i
++) {
258 sprintf(name
, "terminating #%d", i
);
259 RegistrarThread
*thread
= new TerminatingThread(name
, B_NORMAL_PRIORITY
, managerMessenger
);
261 CHK(thread
->InitCheck() == B_OK
);
262 CHK(manager
.LaunchThread(thread
) == B_OK
);
265 // Now fill up the manager with non-terminating threads
266 for (; i
< RegistrarThreadManager::kThreadLimit
; i
++) {
269 sprintf(name
, "nice #%d", i
);
270 RegistrarThread
*thread
= new WellBehavedInfiniteThread(name
, B_NORMAL_PRIORITY
, managerMessenger
);
272 CHK(thread
->InitCheck() == B_OK
);
273 CHK(manager
.LaunchThread(thread
) == B_OK
);
275 CHK(manager
.ThreadCount() == RegistrarThreadManager::kThreadLimit
);
277 // Now try to launch just one more...
280 char *name
= "hopeless thread";
281 RegistrarThread
*thread
= new WellBehavedInfiniteThread(name
, B_NORMAL_PRIORITY
, managerMessenger
);
283 CHK(thread
->InitCheck() == B_OK
);
284 CHK(manager
.LaunchThread(thread
) == B_NO_MORE_THREADS
);
288 // Now wait a little bit for our terminating threads to quit,
289 // cleanup after them, and make sure we can now launch that
290 // many threads again
293 manager
.CleanupThreads();
295 for (i
= 0; i
< termThreads
; i
++) {
298 sprintf(name
, "2nd round nice #%d", i
);
299 RegistrarThread
*thread
= new TerminatingThread(name
, B_NORMAL_PRIORITY
, managerMessenger
);
301 CHK(thread
->InitCheck() == B_OK
);
302 CHK(manager
.LaunchThread(thread
) == B_OK
);
305 // Now try once more to launch just one more...
308 char *name
= "hopeless thread";
309 RegistrarThread
*thread
= new WellBehavedInfiniteThread(name
, B_NORMAL_PRIORITY
, managerMessenger
);
311 CHK(thread
->InitCheck() == B_OK
);
312 CHK(manager
.LaunchThread(thread
) == B_NO_MORE_THREADS
);
318 manager
.ShutdownThreads();