xref: /haiku/src/tests/system/kernel/unit/TestSuite.cpp (revision 933764d70e74117ea1e4a3cc19184b40a6aa44d1)
1*933764d7SIngo Weinhold /*
2*933764d7SIngo Weinhold  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3*933764d7SIngo Weinhold  * Distributed under the terms of the MIT License.
4*933764d7SIngo Weinhold  */
5*933764d7SIngo Weinhold 
6*933764d7SIngo Weinhold 
7*933764d7SIngo Weinhold #include "TestSuite.h"
8*933764d7SIngo Weinhold 
9*933764d7SIngo Weinhold #include <new>
10*933764d7SIngo Weinhold 
11*933764d7SIngo Weinhold #include <string.h>
12*933764d7SIngo Weinhold 
13*933764d7SIngo Weinhold #include "TestVisitor.h"
14*933764d7SIngo Weinhold 
15*933764d7SIngo Weinhold 
TestSuite(const char * name)16*933764d7SIngo Weinhold TestSuite::TestSuite(const char* name)
17*933764d7SIngo Weinhold 	:
18*933764d7SIngo Weinhold 	Test(name),
19*933764d7SIngo Weinhold 	fTests(NULL),
20*933764d7SIngo Weinhold 	fTestCount(0)
21*933764d7SIngo Weinhold {
22*933764d7SIngo Weinhold }
23*933764d7SIngo Weinhold 
24*933764d7SIngo Weinhold 
~TestSuite()25*933764d7SIngo Weinhold TestSuite::~TestSuite()
26*933764d7SIngo Weinhold {
27*933764d7SIngo Weinhold 	for (int32 i = 0; i < fTestCount; i++)
28*933764d7SIngo Weinhold 		delete fTests[i];
29*933764d7SIngo Weinhold 	delete[] fTests;
30*933764d7SIngo Weinhold }
31*933764d7SIngo Weinhold 
32*933764d7SIngo Weinhold 
33*933764d7SIngo Weinhold int32
CountTests() const34*933764d7SIngo Weinhold TestSuite::CountTests() const
35*933764d7SIngo Weinhold {
36*933764d7SIngo Weinhold 	return fTestCount;
37*933764d7SIngo Weinhold }
38*933764d7SIngo Weinhold 
39*933764d7SIngo Weinhold 
40*933764d7SIngo Weinhold Test*
TestAt(int32 index) const41*933764d7SIngo Weinhold TestSuite::TestAt(int32 index) const
42*933764d7SIngo Weinhold {
43*933764d7SIngo Weinhold 	return index >= 0 && index < fTestCount ? fTests[index] : NULL;
44*933764d7SIngo Weinhold }
45*933764d7SIngo Weinhold 
46*933764d7SIngo Weinhold 
47*933764d7SIngo Weinhold Test*
FindTest(const char * name,int32 nameLength) const48*933764d7SIngo Weinhold TestSuite::FindTest(const char* name, int32 nameLength) const
49*933764d7SIngo Weinhold {
50*933764d7SIngo Weinhold 	if (nameLength < 0)
51*933764d7SIngo Weinhold 		nameLength = strlen(name);
52*933764d7SIngo Weinhold 
53*933764d7SIngo Weinhold 	for (int32 i = 0; Test* test = TestAt(i); i++) {
54*933764d7SIngo Weinhold 		if (strlen(test->Name()) == (size_t)nameLength
55*933764d7SIngo Weinhold 			&& strncmp(test->Name(), name, nameLength) == 0) {
56*933764d7SIngo Weinhold 			return test;
57*933764d7SIngo Weinhold 		}
58*933764d7SIngo Weinhold 	}
59*933764d7SIngo Weinhold 
60*933764d7SIngo Weinhold 	return NULL;
61*933764d7SIngo Weinhold }
62*933764d7SIngo Weinhold 
63*933764d7SIngo Weinhold 
64*933764d7SIngo Weinhold bool
AddTest(Test * test)65*933764d7SIngo Weinhold TestSuite::AddTest(Test* test)
66*933764d7SIngo Weinhold {
67*933764d7SIngo Weinhold 	if (test == NULL)
68*933764d7SIngo Weinhold 		return test;
69*933764d7SIngo Weinhold 
70*933764d7SIngo Weinhold 	Test** tests = new(std::nothrow) Test*[fTestCount + 1];
71*933764d7SIngo Weinhold 	if (tests == NULL) {
72*933764d7SIngo Weinhold 		delete test;
73*933764d7SIngo Weinhold 		return false;
74*933764d7SIngo Weinhold 	}
75*933764d7SIngo Weinhold 
76*933764d7SIngo Weinhold 	if (fTestCount > 0)
77*933764d7SIngo Weinhold 		memcpy(tests, fTests, sizeof(Test*) * fTestCount);
78*933764d7SIngo Weinhold 
79*933764d7SIngo Weinhold 	delete[] fTests;
80*933764d7SIngo Weinhold 
81*933764d7SIngo Weinhold 	fTests = tests;
82*933764d7SIngo Weinhold 	fTests[fTestCount++] = test;
83*933764d7SIngo Weinhold 
84*933764d7SIngo Weinhold 	test->SetSuite(this);
85*933764d7SIngo Weinhold 
86*933764d7SIngo Weinhold 	return true;
87*933764d7SIngo Weinhold }
88*933764d7SIngo Weinhold 
89*933764d7SIngo Weinhold 
90*933764d7SIngo Weinhold bool
IsLeafTest() const91*933764d7SIngo Weinhold TestSuite::IsLeafTest() const
92*933764d7SIngo Weinhold {
93*933764d7SIngo Weinhold 	return false;
94*933764d7SIngo Weinhold }
95*933764d7SIngo Weinhold 
96*933764d7SIngo Weinhold 
97*933764d7SIngo Weinhold bool
Run(TestContext & context)98*933764d7SIngo Weinhold TestSuite::Run(TestContext& context)
99*933764d7SIngo Weinhold {
100*933764d7SIngo Weinhold 	for (int32 i = 0; Test* test = TestAt(i); i++) {
101*933764d7SIngo Weinhold 		bool result = _Run(context, test, NULL);
102*933764d7SIngo Weinhold 		if (!result && context.Options().quitAfterFailure)
103*933764d7SIngo Weinhold 			return false;
104*933764d7SIngo Weinhold 	}
105*933764d7SIngo Weinhold 
106*933764d7SIngo Weinhold 	return true;
107*933764d7SIngo Weinhold }
108*933764d7SIngo Weinhold 
109*933764d7SIngo Weinhold 
110*933764d7SIngo Weinhold bool
Run(TestContext & context,const char * name)111*933764d7SIngo Weinhold TestSuite::Run(TestContext& context, const char* name)
112*933764d7SIngo Weinhold {
113*933764d7SIngo Weinhold 	const char* separator = strstr(name, "::");
114*933764d7SIngo Weinhold 	Test* test = FindTest(name, separator != NULL ? separator - name : -1);
115*933764d7SIngo Weinhold 	if (test == NULL) {
116*933764d7SIngo Weinhold 		context.Print("No such test: \"%.*s\"\n",
117*933764d7SIngo Weinhold 			int(separator != NULL ? separator - name : strlen(name)), name);
118*933764d7SIngo Weinhold 		return !context.Options().quitAfterFailure;
119*933764d7SIngo Weinhold 	}
120*933764d7SIngo Weinhold 
121*933764d7SIngo Weinhold 	return _Run(context, test, separator != NULL ? separator + 2 : NULL)
122*933764d7SIngo Weinhold 		|| !context.Options().quitAfterFailure;
123*933764d7SIngo Weinhold }
124*933764d7SIngo Weinhold 
125*933764d7SIngo Weinhold 
126*933764d7SIngo Weinhold Test*
Visit(TestVisitor & visitor)127*933764d7SIngo Weinhold TestSuite::Visit(TestVisitor& visitor)
128*933764d7SIngo Weinhold {
129*933764d7SIngo Weinhold 	if (visitor.VisitTestSuitePre(this))
130*933764d7SIngo Weinhold 		return this;
131*933764d7SIngo Weinhold 
132*933764d7SIngo Weinhold 	for (int32 i = 0; Test* test = TestAt(i); i++) {
133*933764d7SIngo Weinhold 		if (Test* foundTest = test->Visit(visitor))
134*933764d7SIngo Weinhold 			return foundTest;
135*933764d7SIngo Weinhold 	}
136*933764d7SIngo Weinhold 
137*933764d7SIngo Weinhold 	return visitor.VisitTestSuitePost(this) ? this : NULL;
138*933764d7SIngo Weinhold }
139*933764d7SIngo Weinhold 
140*933764d7SIngo Weinhold 
141*933764d7SIngo Weinhold bool
_Run(TestContext & context,Test * test,const char * name)142*933764d7SIngo Weinhold TestSuite::_Run(TestContext& context, Test* test, const char* name)
143*933764d7SIngo Weinhold {
144*933764d7SIngo Weinhold 	TestContext subContext(context, test);
145*933764d7SIngo Weinhold 
146*933764d7SIngo Weinhold 	status_t error = test->Setup(subContext);
147*933764d7SIngo Weinhold 	if (error != B_OK) {
148*933764d7SIngo Weinhold 		subContext.Error("setup failed\n");
149*933764d7SIngo Weinhold 		test->Cleanup(subContext, false);
150*933764d7SIngo Weinhold 		subContext.TestDone(false);
151*933764d7SIngo Weinhold 		return false;
152*933764d7SIngo Weinhold 	}
153*933764d7SIngo Weinhold 
154*933764d7SIngo Weinhold 	bool result = name != NULL
155*933764d7SIngo Weinhold 		? test->Run(subContext, name) : test->Run(subContext);
156*933764d7SIngo Weinhold 	test->Cleanup(subContext, true);
157*933764d7SIngo Weinhold 
158*933764d7SIngo Weinhold 	subContext.TestDone(result);
159*933764d7SIngo Weinhold 
160*933764d7SIngo Weinhold 	return result;
161*933764d7SIngo Weinhold }
162