xref: /haiku/src/tests/kits/app/RegistrarThreadManagerTest.cpp (revision 83f04694ae6d200e8b2b95a96af800bf53c9aa48)
1*83f04694STyler Dauwalder #include "RegistrarThreadManagerTest.h"
2*83f04694STyler Dauwalder 
3*83f04694STyler Dauwalder #include <cppunit/Test.h>
4*83f04694STyler Dauwalder #include <cppunit/TestCaller.h>
5*83f04694STyler Dauwalder #include <cppunit/TestSuite.h>
6*83f04694STyler Dauwalder #include <TestApp.h>
7*83f04694STyler Dauwalder #include <TestUtils.h>
8*83f04694STyler Dauwalder 
9*83f04694STyler Dauwalder #if !TEST_R5
10*83f04694STyler Dauwalder #include <RegistrarThread.h>
11*83f04694STyler Dauwalder #include <RegistrarThreadManager.h>
12*83f04694STyler Dauwalder #endif	// !TEST_R5
13*83f04694STyler Dauwalder 
14*83f04694STyler Dauwalder #include <stdio.h>
15*83f04694STyler Dauwalder 
16*83f04694STyler Dauwalder // Suite
17*83f04694STyler Dauwalder CppUnit::Test*
18*83f04694STyler Dauwalder RegistrarThreadManagerTest::Suite() {
19*83f04694STyler Dauwalder 	CppUnit::TestSuite *suite = new CppUnit::TestSuite();
20*83f04694STyler Dauwalder 	typedef CppUnit::TestCaller<RegistrarThreadManagerTest> TC;
21*83f04694STyler Dauwalder 
22*83f04694STyler Dauwalder 	suite->addTest( new TC("RegistrarThreadManager::Shutdown test",
23*83f04694STyler Dauwalder 						   &RegistrarThreadManagerTest::ShutdownTest) );
24*83f04694STyler Dauwalder 
25*83f04694STyler Dauwalder 
26*83f04694STyler Dauwalder 	return suite;
27*83f04694STyler Dauwalder }
28*83f04694STyler Dauwalder 
29*83f04694STyler Dauwalder #if !TEST_R5
30*83f04694STyler Dauwalder // Base test thread class
31*83f04694STyler Dauwalder class TestThread : public RegistrarThread {
32*83f04694STyler Dauwalder public:
33*83f04694STyler Dauwalder 	TestThread(const char *name, int32 priority, BMessenger managerMessenger)
34*83f04694STyler Dauwalder 		: RegistrarThread(name, priority, managerMessenger)
35*83f04694STyler Dauwalder 	{
36*83f04694STyler Dauwalder 	}
37*83f04694STyler Dauwalder 
38*83f04694STyler Dauwalder 	void DoSomethingUseless() {
39*83f04694STyler Dauwalder 		fIntVal++;
40*83f04694STyler Dauwalder 		snooze(1000);
41*83f04694STyler Dauwalder 	}
42*83f04694STyler Dauwalder 
43*83f04694STyler Dauwalder private:
44*83f04694STyler Dauwalder 	int64 fIntVal;
45*83f04694STyler Dauwalder };
46*83f04694STyler Dauwalder 
47*83f04694STyler Dauwalder // Test thread that terminates quickly
48*83f04694STyler Dauwalder class TerminatingThread : public TestThread {
49*83f04694STyler Dauwalder public:
50*83f04694STyler Dauwalder 	TerminatingThread(const char *name, int32 priority, BMessenger managerMessenger)
51*83f04694STyler Dauwalder 		: TestThread(name, priority, managerMessenger)
52*83f04694STyler Dauwalder 	{
53*83f04694STyler Dauwalder 	}
54*83f04694STyler Dauwalder 
55*83f04694STyler Dauwalder protected:
56*83f04694STyler Dauwalder 	virtual status_t ThreadFunction() {
57*83f04694STyler Dauwalder 		DoSomethingUseless();
58*83f04694STyler Dauwalder 		fIsFinished = true;
59*83f04694STyler Dauwalder 		return B_OK;
60*83f04694STyler Dauwalder 	}
61*83f04694STyler Dauwalder };
62*83f04694STyler Dauwalder 
63*83f04694STyler Dauwalder // Test thread that never terminates, but pays attention
64*83f04694STyler Dauwalder // to its fShouldExit member
65*83f04694STyler Dauwalder class WellBehavedInfiniteThread : public TestThread {
66*83f04694STyler Dauwalder public:
67*83f04694STyler Dauwalder 	WellBehavedInfiniteThread(const char *name, int32 priority, BMessenger managerMessenger)
68*83f04694STyler Dauwalder 		: TestThread(name, priority, managerMessenger)
69*83f04694STyler Dauwalder 	{
70*83f04694STyler Dauwalder 	}
71*83f04694STyler Dauwalder 
72*83f04694STyler Dauwalder protected:
73*83f04694STyler Dauwalder 	virtual status_t ThreadFunction() {
74*83f04694STyler Dauwalder 		while (true) {
75*83f04694STyler Dauwalder 			DoSomethingUseless();
76*83f04694STyler Dauwalder 			if (fShouldExit)
77*83f04694STyler Dauwalder 				break;
78*83f04694STyler Dauwalder 		}
79*83f04694STyler Dauwalder 		fIsFinished = true;
80*83f04694STyler Dauwalder 		return B_OK;
81*83f04694STyler Dauwalder 	}
82*83f04694STyler Dauwalder };
83*83f04694STyler Dauwalder 
84*83f04694STyler Dauwalder // Test thread that never terminates and completely ignores
85*83f04694STyler Dauwalder // its fShouldExit member
86*83f04694STyler Dauwalder class NaughtyInfiniteThread : public TestThread {
87*83f04694STyler Dauwalder public:
88*83f04694STyler Dauwalder 	NaughtyInfiniteThread(const char *name, int32 priority, BMessenger managerMessenger)
89*83f04694STyler Dauwalder 		: TestThread(name, priority, managerMessenger)
90*83f04694STyler Dauwalder 	{
91*83f04694STyler Dauwalder 	}
92*83f04694STyler Dauwalder 
93*83f04694STyler Dauwalder protected:
94*83f04694STyler Dauwalder 	virtual status_t ThreadFunction() {
95*83f04694STyler Dauwalder 		while (true) {
96*83f04694STyler Dauwalder 			DoSomethingUseless();
97*83f04694STyler Dauwalder 		}
98*83f04694STyler Dauwalder 		fIsFinished = true;
99*83f04694STyler Dauwalder 		return B_OK;
100*83f04694STyler Dauwalder 	}
101*83f04694STyler Dauwalder };
102*83f04694STyler Dauwalder #endif	// !TEST_R5
103*83f04694STyler Dauwalder 
104*83f04694STyler Dauwalder 
105*83f04694STyler Dauwalder // setUp
106*83f04694STyler Dauwalder void
107*83f04694STyler Dauwalder RegistrarThreadManagerTest::setUp()
108*83f04694STyler Dauwalder {
109*83f04694STyler Dauwalder 	BTestCase::setUp();
110*83f04694STyler Dauwalder #if !TEST_R5
111*83f04694STyler Dauwalder 	// Setup our application
112*83f04694STyler Dauwalder 	fApplication = new BTestApp("application/x-vnd.obos.RegistrarThreadManagerTest");
113*83f04694STyler Dauwalder 	if (fApplication->Init() != B_OK) {
114*83f04694STyler Dauwalder 		fprintf(stderr, "Failed to initialize application (perhaps the obos registrar isn't running?).\n");
115*83f04694STyler Dauwalder 		delete fApplication;
116*83f04694STyler Dauwalder 		fApplication = NULL;
117*83f04694STyler Dauwalder 	}
118*83f04694STyler Dauwalder #endif	// !TEST_R5
119*83f04694STyler Dauwalder }
120*83f04694STyler Dauwalder 
121*83f04694STyler Dauwalder // tearDown
122*83f04694STyler Dauwalder void
123*83f04694STyler Dauwalder RegistrarThreadManagerTest::tearDown()
124*83f04694STyler Dauwalder {
125*83f04694STyler Dauwalder #if !TEST_R5
126*83f04694STyler Dauwalder 	// Terminate the Application
127*83f04694STyler Dauwalder 	if (fApplication) {
128*83f04694STyler Dauwalder 		fApplication->Terminate();
129*83f04694STyler Dauwalder 		delete fApplication;
130*83f04694STyler Dauwalder 		fApplication = NULL;
131*83f04694STyler Dauwalder 	}
132*83f04694STyler Dauwalder #endif	// !TEST_R5
133*83f04694STyler Dauwalder 	BTestCase::tearDown();
134*83f04694STyler Dauwalder }
135*83f04694STyler Dauwalder 
136*83f04694STyler Dauwalder void
137*83f04694STyler Dauwalder RegistrarThreadManagerTest::ShutdownTest()
138*83f04694STyler Dauwalder {
139*83f04694STyler Dauwalder #if TEST_R5
140*83f04694STyler Dauwalder 	Outputf("(no tests performed for R5 version)\n");
141*83f04694STyler Dauwalder #else
142*83f04694STyler Dauwalder 	NextSubTest();
143*83f04694STyler Dauwalder 	status_t err = B_OK;
144*83f04694STyler Dauwalder 	NextSubTest();
145*83f04694STyler Dauwalder 	RegistrarThreadManager manager;
146*83f04694STyler Dauwalder 	NextSubTest();
147*83f04694STyler Dauwalder 	CHK(fApplication && fApplication->InitCheck() == B_OK);
148*83f04694STyler Dauwalder 	NextSubTest();
149*83f04694STyler Dauwalder //	fApplication->AddHandler(&manager);
150*83f04694STyler Dauwalder 	NextSubTest();
151*83f04694STyler Dauwalder 	BMessenger managerMessenger(NULL, fApplication, &err);
152*83f04694STyler Dauwalder 	NextSubTest();
153*83f04694STyler Dauwalder 	CHK(err == B_OK && managerMessenger.IsValid());
154*83f04694STyler Dauwalder 	NextSubTest();
155*83f04694STyler Dauwalder 
156*83f04694STyler Dauwalder 	// Launch a bunch of threads
157*83f04694STyler Dauwalder 	const uint termThreads = 2;
158*83f04694STyler Dauwalder 	const uint niceThreads = 2;
159*83f04694STyler Dauwalder 	const uint evilThreads = 2;
160*83f04694STyler Dauwalder 
161*83f04694STyler Dauwalder 	for (uint i = 0; i < termThreads; i++) {
162*83f04694STyler Dauwalder 		NextSubTest();
163*83f04694STyler Dauwalder 		char name[1024];
164*83f04694STyler Dauwalder 		sprintf(name, "terminating #%d", i);
165*83f04694STyler Dauwalder 		RegistrarThread *thread = new TerminatingThread(name, B_NORMAL_PRIORITY, managerMessenger);
166*83f04694STyler Dauwalder 		CHK(thread != NULL);
167*83f04694STyler Dauwalder 		CHK(thread->InitCheck() == B_OK);
168*83f04694STyler Dauwalder 		CHK(manager.LaunchThread(thread) == B_OK);
169*83f04694STyler Dauwalder 	}
170*83f04694STyler Dauwalder 
171*83f04694STyler Dauwalder 	for (uint i = 0; i < niceThreads; i++) {
172*83f04694STyler Dauwalder 		NextSubTest();
173*83f04694STyler Dauwalder 		char name[1024];
174*83f04694STyler Dauwalder 		sprintf(name, "nice #%d", i);
175*83f04694STyler Dauwalder 		RegistrarThread *thread = new WellBehavedInfiniteThread(name, B_NORMAL_PRIORITY, managerMessenger);
176*83f04694STyler Dauwalder 		CHK(thread != NULL);
177*83f04694STyler Dauwalder 		CHK(thread->InitCheck() == B_OK);
178*83f04694STyler Dauwalder 		CHK(manager.LaunchThread(thread) == B_OK);
179*83f04694STyler Dauwalder 	}
180*83f04694STyler Dauwalder 
181*83f04694STyler Dauwalder 	for (uint i = 0; i < evilThreads; i++) {
182*83f04694STyler Dauwalder 		NextSubTest();
183*83f04694STyler Dauwalder 		char name[1024];
184*83f04694STyler Dauwalder 		sprintf(name, "evil #%d", i);
185*83f04694STyler Dauwalder 		RegistrarThread *thread = new NaughtyInfiniteThread(name, B_NORMAL_PRIORITY, managerMessenger);
186*83f04694STyler Dauwalder 		CHK(thread != NULL);
187*83f04694STyler Dauwalder 		CHK(thread->InitCheck() == B_OK);
188*83f04694STyler Dauwalder 		CHK(manager.LaunchThread(thread) == B_OK);
189*83f04694STyler Dauwalder 	}
190*83f04694STyler Dauwalder 
191*83f04694STyler Dauwalder 	// Check the number of threads before doing a cleanup
192*83f04694STyler Dauwalder 	NextSubTest();	// <= 13
193*83f04694STyler Dauwalder 	CHK(manager.ThreadCount() == (termThreads + niceThreads + evilThreads));
194*83f04694STyler Dauwalder 
195*83f04694STyler Dauwalder 	// Do the cleanup and check again (the terminating threads
196*83f04694STyler Dauwalder 	// should be gone)
197*83f04694STyler Dauwalder 	NextSubTest();
198*83f04694STyler Dauwalder 	snooze(500000);		// give them time to terminate
199*83f04694STyler Dauwalder 	CHK(manager.CleanupThreads() == B_OK);
200*83f04694STyler Dauwalder 	CHK(manager.ThreadCount() == (niceThreads + evilThreads));
201*83f04694STyler Dauwalder 
202*83f04694STyler Dauwalder 	// Now do a shutdown and check again (the nice infinite threads
203*83f04694STyler Dauwalder 	// should be gone)
204*83f04694STyler Dauwalder 	NextSubTest();
205*83f04694STyler Dauwalder 	CHK(manager.ShutdownThreads() == B_OK);
206*83f04694STyler Dauwalder 	snooze(1000000);	// give them time to quit nicely
207*83f04694STyler Dauwalder 	CHK(manager.CleanupThreads() == B_OK);
208*83f04694STyler Dauwalder 	CHK(manager.ThreadCount() == evilThreads);
209*83f04694STyler Dauwalder 
210*83f04694STyler Dauwalder 
211*83f04694STyler Dauwalder 	// Now finally kill any remaining threads (which should rid us of
212*83f04694STyler Dauwalder 	// the naughty infinite threads)
213*83f04694STyler Dauwalder 	NextSubTest();
214*83f04694STyler Dauwalder 	CHK(manager.KillThreads() == B_OK);
215*83f04694STyler Dauwalder 	CHK(manager.ThreadCount() == 0);
216*83f04694STyler Dauwalder 
217*83f04694STyler Dauwalder #endif	// !TEST_R5
218*83f04694STyler Dauwalder }
219*83f04694STyler Dauwalder 
220