1 //===- skypat.cpp ---------------------------------------------------------===//
2 //
3 // The SkyPat Team
4 //
5 // This file is distributed under the New BSD License.
6 // See LICENSE for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #include <skypat/skypat.h>
10 #include <skypat/Support/Timer.h>
11 #include <skypat/Support/Perf.h>
12 #include <skypat/Support/ManagedStatic.h>
13 #include <skypat/Support/OStrStream.h>
14 #include <vector>
15 #include <cassert>
16 #include <cstdlib>
17 #include <ios>
18 #include <ostream>
19 #include <iostream>
20 #include <stdint.h>
21 #include <algorithm>
22 #include <cstdio>
23 #include <time.h>
24
25 #include <skypat/Config/Config.h>
26
27 using namespace skypat;
28
29 /* Define the numebr of iteration of performance loop */
30 #define SKYPAT_PERFORM_LOOP_TIMES 1
31
32 namespace skypat{
33 /* Establish perf event string array */
34 char const *Perf_event_name[] = {
35 "CPU CYCLES", "INST NUM",
36 "CACHE REF", "CACHE MISS",
37 "BR INST", "BR MISSES",
38 "BUS CYCLES", "STALLFRONT",
39 "STALL BACK", "REF CYCLES",
40 "CPU CLOCK", "TASK CLOCK",
41 "PAGEFAULTS", "CTX SWITCH",
42 "CPUMIGRATE", "PG FAULT m",
43 "PG FAULT M", "ALIGNFAULT",
44 "EMU FAULT", "D U M M Y "
45 };
46 } // namespace of skypat
47
48 //===----------------------------------------------------------------------===//
49 // Non-member function
50 //===----------------------------------------------------------------------===//
51 testing::TestInfo*
MakeAndRegisterTestInfo(const char * pCaseName,const char * pTestName,testing::TestFactoryBase * pFactory)52 testing::MakeAndRegisterTestInfo(const char* pCaseName, const char* pTestName,
53 testing::TestFactoryBase* pFactory)
54 {
55 return testing::UnitTest::self()->addTestInfo(pCaseName, pTestName, *pFactory);
56 }
57
GetBoolAssertionFailureMessage(const skypat::testing::AssertionResult & pAssertionResult,const char * pExpressionText,const char * pActualPredicateValue,const char * pExpectedPredicateValue)58 std::string testing::GetBoolAssertionFailureMessage(
59 const skypat::testing::AssertionResult& pAssertionResult,
60 const char* pExpressionText,
61 const char* pActualPredicateValue,
62 const char* pExpectedPredicateValue)
63 {
64 std::string result;
65 OStrStream OS(result);
66 OS << "Value of: " << pExpressionText
67 << "\n Actual: " << pActualPredicateValue;
68 if (pAssertionResult.hasMessage())
69 OS << "(" << pAssertionResult.message() << ")";
70 OS << "\n Expected: " << pExpectedPredicateValue;
71 return result;
72 }
73
74 //===----------------------------------------------------------------------===//
75 // PerfIterator
76 //===----------------------------------------------------------------------===//
PerfIterator(const char * pFile,int pLine)77 testing::PerfIterator::PerfIterator(const char* pFile, int pLine)
78 : m_Counter(0),
79 m_pTimer(new internal::Timer()),
80 m_pPerf(new internal::Perf()),
81 m_pPerfResult(testing::UnitTest::self()->addPerfPartResult(pFile, pLine)) {
82
83 m_pTimer->start();
84 m_pPerf->start();
85 }
86
PerfIterator(const char * pFile,int pLine,enum PerfEvent pEvent)87 testing::PerfIterator::PerfIterator(const char* pFile, int pLine,\
88 enum PerfEvent pEvent)
89 : m_Counter(0),
90 m_pTimer(new internal::Timer()),
91 m_pPerf(new internal::Perf(pEvent)),
92 m_pPerfResult(testing::UnitTest::self()->addPerfPartResult(pFile, pLine)) {
93
94 m_pTimer->start();
95 m_pPerf->start();
96 }
97
~PerfIterator()98 testing::PerfIterator::~PerfIterator()
99 {
100 delete m_pTimer;
101 delete m_pPerf;
102 }
103
hasNext() const104 bool testing::PerfIterator::hasNext() const
105 {
106 if (m_Counter < SKYPAT_PERFORM_LOOP_TIMES)
107 return true;
108
109 m_pTimer->stop();
110 m_pPerf->stop();
111
112 m_pPerfResult->setTimerNum(m_pTimer->interval());
113 m_pPerfResult->setPerfEventNum(m_pPerf->interval());
114 m_pPerfResult->setPerfEventType(m_pPerf->eventType());
115 return false;
116 }
117
next()118 testing::PerfIterator& testing::PerfIterator::next()
119 {
120 ++m_Counter;
121 return *this;
122 }
123
124 //===----------------------------------------------------------------------===//
125 // PartResult
126 //===----------------------------------------------------------------------===//
PartResult(const std::string & pFileName,int pLoC)127 testing::PartResult::PartResult(const std::string& pFileName, int pLoC)
128 : m_FileName(pFileName), m_LoC(pLoC), m_Message() {
129 }
130
PartResult(const std::string & pFileName,int pLoC,const std::string & pMessage)131 testing::PartResult::PartResult(const std::string& pFileName,
132 int pLoC,
133 const std::string& pMessage)
134 : m_FileName(pFileName), m_LoC(pLoC), m_Message(pMessage) {
135 }
136
137 //===----------------------------------------------------------------------===//
138 // TestPartResult
139 //===----------------------------------------------------------------------===//
TestPartResult(Type pType,const std::string & pFileName,int pLoC,const std::string & pMessage)140 testing::TestPartResult::TestPartResult(Type pType,
141 const std::string& pFileName,
142 int pLoC,
143 const std::string& pMessage)
144 : PartResult(pFileName, pLoC, pMessage), m_Type(pType) {
145 }
146
147 testing::TestPartResult&
appendUserMessage(const std::string & pMessage)148 testing::TestPartResult::appendUserMessage(const std::string& pMessage)
149 {
150 if (!pMessage.empty())
151 update_message(message() + "\n" + pMessage);
152 return *this;
153 }
154
155 //===----------------------------------------------------------------------===//
156 // PerfPartResult
157 //===----------------------------------------------------------------------===//
PerfPartResult(const std::string & pFileName,int pLoC)158 testing::PerfPartResult::PerfPartResult(const std::string& pFileName,
159 int pLoC)
160 : PartResult(pFileName, pLoC) {
161 }
162
getTimerNum() const163 testing::Interval testing::PerfPartResult::getTimerNum() const
164 {
165 return m_PerfTimerNum;
166 }
167
getPerfEventNum() const168 testing::Interval testing::PerfPartResult::getPerfEventNum() const
169 {
170 return m_PerfEventNum;
171 }
172
getPerfEventType() const173 testing::Interval testing::PerfPartResult::getPerfEventType() const
174 {
175 return m_PerfEventType;
176 }
177
setTimerNum(testing::Interval pTimerNum)178 void testing::PerfPartResult::setTimerNum(testing::Interval pTimerNum)
179 {
180 m_PerfTimerNum = pTimerNum;
181 OStrStream os(m_Message);
182 os << pTimerNum << " ns;";
183 }
184
setPerfEventNum(testing::Interval pEventNum)185 void testing::PerfPartResult::setPerfEventNum(testing::Interval pEventNum)
186 {
187 m_PerfEventNum = pEventNum;
188 }
189
setPerfEventType(testing::Interval pEventType)190 void testing::PerfPartResult::setPerfEventType(testing::Interval pEventType)
191 {
192 m_PerfEventType = pEventType;
193 }
194
195 //===----------------------------------------------------------------------===//
196 // TestResult
197 //===----------------------------------------------------------------------===//
TestResult(const TestInfo & pInfo)198 testing::TestResult::TestResult(const TestInfo& pInfo)
199 : m_Info(pInfo), m_Conclusion(kNotTested) {
200 }
201
~TestResult()202 testing::TestResult::~TestResult()
203 {
204 }
205
isPassed() const206 bool testing::TestResult::isPassed() const
207 {
208 return (kPassed == m_Conclusion);
209 }
210
isFailed() const211 bool testing::TestResult::isFailed() const
212 {
213 return (kFailed == m_Conclusion);
214 }
215
reliability() const216 const testing::TestResult::Reliability& testing::TestResult::reliability() const
217 {
218 return m_Info.getTestResults();
219 }
220
performance() const221 const testing::TestResult::Performance& testing::TestResult::performance() const
222 {
223 return m_Info.getPerfResults();
224 }
225
226 //===----------------------------------------------------------------------===//
227 // TestCase
228 //===----------------------------------------------------------------------===//
TestCase(const std::string & pCaseName)229 testing::TestCase::TestCase(const std::string& pCaseName)
230 : m_CaseName(pCaseName)
231 {
232 }
233
~TestCase()234 testing::TestCase::~TestCase()
235 {
236 InfoList::iterator info, iEnd = m_InfoList.end();
237 for (info = m_InfoList.begin(); info != iEnd; ++info) {
238 delete (*info);
239 }
240 }
241
242 testing::TestInfo*
addTestInfo(const std::string & pTestName,testing::TestFactoryBase & pFactory)243 testing::TestCase::addTestInfo(const std::string& pTestName,
244 testing::TestFactoryBase& pFactory)
245 {
246 testing::TestInfo* info = new testing::TestInfo(this, pTestName, pFactory);
247 m_InfoList.push_back(info);
248 return info;
249 }
250
251 //===----------------------------------------------------------------------===//
252 // TestInfo
253 //===----------------------------------------------------------------------===//
TestInfo(TestCase * pTestCase,const std::string & pTestName,testing::TestFactoryBase & pFactory)254 testing::TestInfo::TestInfo(TestCase* pTestCase,
255 const std::string& pTestName,
256 testing::TestFactoryBase& pFactory)
257 : m_pTestCase(pTestCase),
258 m_TestName(pTestName),
259 m_Result(*this),
260 m_pFactory(&pFactory) {
261 }
262
~TestInfo()263 testing::TestInfo::~TestInfo()
264 {
265 delete m_pFactory;
266 TestPartResultList::iterator tt, tEnd = m_TestResultList.end();
267 for (tt = m_TestResultList.begin(); tt != tEnd; ++tt) {
268 delete (*tt);
269 }
270 PerfPartResultList::iterator pt, pEnd = m_PerfResultList.end();
271 for (pt = m_PerfResultList.begin(); pt != pEnd; ++pt) {
272 delete (*pt);
273 }
274 }
275
run()276 void testing::TestInfo::run()
277 {
278 UnitTest& unittest = *UnitTest::self();
279 Repeater& repeater = unittest.repeater();
280 skypat::Test* test = m_pFactory->CreateTest();
281 if (NULL != test) {
282 repeater.OnSetUpStart(unittest);
283 test->SetUp();
284 repeater.OnSetUpEnd(unittest);
285
286 repeater.OnTestStart(*this);
287 test->run();
288 repeater.OnTestEnd(*this);
289
290 repeater.OnTearDownStart(unittest);
291 test->TearDown();
292 repeater.OnTearDownEnd(unittest);
293 }
294 delete test;
295 }
296
addTestPartResult(const TestPartResult & pResult)297 void testing::TestInfo::addTestPartResult(const TestPartResult& pResult)
298 {
299 if (m_TestResultList.empty()) {
300 m_Result.setConclusion(testing::TestResult::kPassed);
301 }
302
303 if (testing::TestPartResult::kSuccess != pResult.type()) {
304 m_Result.setConclusion(testing::TestResult::kFailed);
305 m_TestResultList.push_back(new TestPartResult(pResult));
306 }
307 }
308
309 testing::PerfPartResult*
addPerfPartResult(const char * pFile,int pLine)310 testing::TestInfo::addPerfPartResult(const char* pFile, int pLine)
311 {
312 PerfPartResult* perf_pr = new PerfPartResult(pFile, pLine);
313 m_PerfResultList.push_back(perf_pr);
314 return perf_pr;
315 }
316
317 //===----------------------------------------------------------------------===//
318 // AssertionResult
319 //===----------------------------------------------------------------------===//
AssertionResult(const AssertionResult & pOther)320 skypat::testing::AssertionResult::AssertionResult(const AssertionResult& pOther)
321 : m_bSuccess(pOther.m_bSuccess), m_Message(pOther.m_Message) {
322 }
323
AssertionResult(bool pSuccess)324 skypat::testing::AssertionResult::AssertionResult(bool pSuccess)
325 : m_bSuccess(pSuccess) {
326 }
327
328 skypat::testing::AssertionResult
operator !() const329 skypat::testing::AssertionResult::operator!() const
330 {
331 AssertionResult negative(!m_bSuccess);
332 negative << m_Message;
333 return negative;
334 }
335
336 template <typename T> skypat::testing::AssertionResult&
operator <<(const T & pValue)337 skypat::testing::AssertionResult::operator<<(const T& pValue)
338 {
339 skypat::OStrStream OS(m_Message);
340 OS << pValue;
341 return *this;
342 }
343
344 skypat::testing::AssertionResult&
operator <<(::std::ostream & (* basic_manipulator)(::std::ostream & stream))345 skypat::testing::AssertionResult::operator<<(
346 ::std::ostream& (*basic_manipulator)(::std::ostream& stream))
347 {
348 skypat::OStrStream OS(m_Message);
349 OS << basic_manipulator;
350 return *this;
351 }
352
353 //===----------------------------------------------------------------------===//
354 // Message
355 //===----------------------------------------------------------------------===//
Message()356 skypat::testing::Message::Message()
357 : m_Message(), m_OSS(m_Message) {
358 }
359
360 //===----------------------------------------------------------------------===//
361 // AssertHelper
362 //===----------------------------------------------------------------------===//
AssertHelper(TestPartResult::Type pType,const std::string & pFile,int pLineOfCode,const std::string & pMessage)363 skypat::testing::AssertHelper::AssertHelper(TestPartResult::Type pType,
364 const std::string& pFile,
365 int pLineOfCode,
366 const std::string& pMessage)
367 : m_Result(pType, pFile, pLineOfCode, pMessage) {
368 // m_Result is a TestPartResult
369 }
370
371 // Store a run-time result
operator =(const Message & pMesg)372 void skypat::testing::AssertHelper::operator=(const Message& pMesg)
373 {
374 m_Result.appendUserMessage(pMesg.str());
375 UnitTest::self()->addTestPartResult(m_Result);
376 }
377
378 //===----------------------------------------------------------------------===//
379 // Log
380 //===----------------------------------------------------------------------===//
Log(Severity pSeverity,const std::string & pFileName,int pLoC)381 testing::Log::Log(Severity pSeverity,
382 const std::string& pFileName,
383 int pLoC)
384 : m_Severity(pSeverity) {
385 const char* const mesg =
386 kInfo == pSeverity ? "[ INFO ]" :
387 kWarning == pSeverity ? "[WARNING]" :
388 kError == pSeverity ? "[ ERROR ]" : "[ FATAL ]";
389
390 getOStream() << std::endl << mesg << FormatFileLocation(pFileName, pLoC)
391 << ": ";
392 }
393
~Log()394 testing::Log::~Log()
395 {
396 getOStream() << std::endl;
397 if (kFatal == m_Severity) {
398 shutdown();
399 fflush(stderr);
400 exit(1);
401 }
402 }
403
getOStream()404 ::std::ostream& testing::Log::getOStream()
405 {
406 return ::std::cerr;
407 }
408
409 std::string
FormatFileLocation(const std::string & pFileName,int pLoC)410 testing::Log::FormatFileLocation(const std::string& pFileName, int pLoC)
411 {
412 std::string result;
413 OStrStream OS(result);
414 if (pFileName.empty())
415 OS << "(unknown file)";
416 else
417 OS << pFileName;
418
419 if (pLoC < 0) {
420 OS << ":";
421 return result;
422 }
423 #ifdef _MSC_VER
424 OS << "(" << pLoC << "):";
425 #else
426 OS << ":" << pLoC << ":";
427 #endif // _MSC_VER
428 return result;
429 }
430