2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file test_results_collector.h
18 * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
20 * @brief Implementation file some concrete TestResulstsCollector
23 #include <dpl/test/test_results_collector.h>
24 #include <dpl/colors.h>
25 #include <dpl/assert.h>
26 #include <dpl/foreach.h>
27 #include <dpl/scoped_fclose.h>
39 const char *DEFAULT_HTML_FILE_NAME = "index.html";
53 void AddTest(TestResultsCollectorBase::FailStatus::Type type)
57 case TestResultsCollectorBase::FailStatus::INTERNAL:
58 case TestResultsCollectorBase::FailStatus::FAILED: ++m_failed; break;
59 case TestResultsCollectorBase::FailStatus::IGNORED: ++m_ignored; break;
60 case TestResultsCollectorBase::FailStatus::TODO: ++m_todo; break;
61 case TestResultsCollectorBase::FailStatus::NONE: ++m_passed; break;
63 Assert(false && "Bad FailStatus");
67 size_t GetTotal() const { return m_count; }
68 size_t GetPassed() const { return m_passed; }
69 size_t GetSuccesed() const { return m_passed; }
70 size_t GetFailed() const { return m_failed; }
71 size_t GetTODO() const { return m_todo; }
72 size_t GetIgnored() const { return m_ignored; }
73 float GetPassedOrIgnoredPercend() const
75 float passIgnoredPercent =
76 100.0f * (static_cast<float>(m_passed)
77 + static_cast<float>(m_ignored))
78 / static_cast<float>(m_count);
79 return passIgnoredPercent;
90 class ConsoleCollector
91 : public TestResultsCollectorBase
94 static TestResultsCollectorBase* Constructor();
99 virtual void CollectCurrentTestGroupName(const std::string& name)
101 printf("Starting group %s\n", name.c_str());
102 m_currentGroup = name;
105 virtual void Finish()
107 using namespace DPL::Colors::Text;
110 FOREACH(group, m_groupsStats) {
111 PrintStats(group->first, group->second);
113 PrintStats("All tests together", m_stats);
116 virtual void CollectResult(const std::string& id,
117 const std::string& /*description*/,
118 const FailStatus::Type status = FailStatus::NONE,
119 const std::string& reason = "")
121 using namespace DPL::Colors::Text;
122 std::string tmp = "'" + id + "' ...";
124 printf("Running test case %-60s", tmp.c_str());
126 case TestResultsCollectorBase::FailStatus::NONE:
127 printf("[%s%s%s]\n", BOLD_GREEN_BEGIN, " OK ", BOLD_GREEN_END); break;
128 case TestResultsCollectorBase::FailStatus::FAILED:
129 PrintfErrorMessage( " FAILED ", reason, true); break;
130 case TestResultsCollectorBase::FailStatus::IGNORED:
131 PrintfIgnoredMessage("Ignored ", reason, true); break;
132 case TestResultsCollectorBase::FailStatus::TODO:
133 PrintfTODOMessage( " TODO ", reason, true); break;
134 case TestResultsCollectorBase::FailStatus::INTERNAL:
135 PrintfErrorMessage( "INTERNAL", reason, true); break;
137 Assert(false && "Bad status");
139 m_stats.AddTest(status);
140 m_groupsStats[m_currentGroup].AddTest(status);
143 void PrintfErrorMessage(const char* type,
144 const std::string& message,
147 using namespace DPL::Colors::Text;
149 printf("[%s%s%s] %s%s%s\n",
164 void PrintfTODOMessage(const char* type,
165 const std::string& message,
168 using namespace DPL::Colors::Text;
170 printf("[%s%s%s] %s%s%s\n",
185 void PrintfIgnoredMessage(const char* type,
186 const std::string& message,
189 using namespace DPL::Colors::Text;
191 printf("[%s%s%s] %s%s%s\n",
206 void PrintStats(const std::string& title, const Statistic& stats)
208 using namespace DPL::Colors::Text;
209 printf("\n%sResults [%s]: %s\n", BOLD_GREEN_BEGIN, title.c_str(), BOLD_GREEN_END);
210 printf("%s%s%3d%s\n", CYAN_BEGIN, "Total tests: ", stats.GetTotal(), CYAN_END);
211 printf("%s%s%3d%s\n", CYAN_BEGIN, "Succeeded or ignored: ", stats.GetPassed() + stats.GetIgnored(), CYAN_END);
212 printf(" %s%s%3d%s\n", CYAN_BEGIN, "Succeeded: ", stats.GetPassed(), CYAN_END);
213 printf(" %s%s%3d%s\n", CYAN_BEGIN, "Ignored: ", stats.GetIgnored(), CYAN_END);
214 printf("%s%s%3d%s\n", CYAN_BEGIN, "Failed: ", stats.GetFailed(), CYAN_END);
215 printf("%s%s%3d%s\n", CYAN_BEGIN, "Todo: ", stats.GetTODO(), CYAN_END);
216 printf("%s%s%3.0f%%%s\n", CYAN_BEGIN, "Succeeded or ignored %: ", stats.GetPassedOrIgnoredPercend(), CYAN_END);
220 std::map<std::string, Statistic> m_groupsStats;
221 std::string m_currentGroup;
225 TestResultsCollectorBase* ConsoleCollector::Constructor()
227 return new ConsoleCollector();
232 : public TestResultsCollectorBase
235 static TestResultsCollectorBase* Constructor();
238 HtmlCollector() : m_filename(DEFAULT_HTML_FILE_NAME) {}
240 virtual void CollectCurrentTestGroupName(const std::string& name)
242 fprintf(m_fp.Get(),"<b>Starting group %s", name.c_str());
243 m_currentGroup = name;
246 virtual bool Configure()
248 m_fp.Reset(fopen (m_filename.c_str(), "w"));
250 LogPedantic("Could not open file " << m_filename << " for writing");
255 virtual std::string CollectorSpecificHelp() const
257 return "--file=<filename> - name of file for output\n"
258 " default - index.html\n";
263 Assert(!!m_fp && "File handle must not be null");
265 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0"
266 "Transitional//EN\" "
267 "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\""
270 "<html xmlns=\"http://www.w3.org/1999/xhtml\" "
271 "lang=\"en\" dir=\"ltr\">\n");
272 fprintf(m_fp.Get(), "<body style=\"background-color: black;\">\n");
273 fprintf(m_fp.Get(), "<pre>\n");
274 fprintf(m_fp.Get(), "<font color=\"white\">\n");
277 virtual void Finish()
279 using namespace DPL::Colors::Html;
281 FOREACH(group, m_groupsStats) {
282 PrintStats(group->first, group->second);
284 PrintStats("All tests together", m_stats);
285 fprintf(m_fp.Get(), "</font>\n");
286 fprintf(m_fp.Get(), "</pre>\n");
287 fprintf(m_fp.Get(), "</body>\n");
288 fprintf(m_fp.Get(), "</html>\n");
291 virtual bool ParseCollectorSpecificArg(const std::string& arg)
293 const std::string argname = "--file=";
294 if (0 == arg.find(argname)) {
295 m_filename = arg.substr(argname.size());
302 virtual void CollectResult(const std::string& id,
303 const std::string& /*description*/,
304 const FailStatus::Type status = FailStatus::NONE,
305 const std::string& reason = "")
307 using namespace DPL::Colors::Html;
308 std::string tmp = "'" + id + "' ...";
310 fprintf(m_fp.Get(), "Running test case %-100s", tmp.c_str());
312 case TestResultsCollectorBase::FailStatus::NONE:
313 fprintf(m_fp.Get(), "[%s%s%s]\n", BOLD_GREEN_BEGIN, " OK ", BOLD_GREEN_END); break;
314 case TestResultsCollectorBase::FailStatus::FAILED:
315 PrintfErrorMessage( " FAILED ", reason, true); break;
316 case TestResultsCollectorBase::FailStatus::IGNORED:
317 PrintfIgnoredMessage("Ignored ", reason, true); break;
318 case TestResultsCollectorBase::FailStatus::TODO:
319 PrintfTODOMessage( " TODO ", reason, true); break;
320 case TestResultsCollectorBase::FailStatus::INTERNAL:
321 PrintfErrorMessage( "INTERNAL", reason, true); break;
323 Assert(false && "Bad status");
325 m_groupsStats[m_currentGroup].AddTest(status);
326 m_stats.AddTest(status);
329 void PrintfErrorMessage(const char* type,
330 const std::string& message,
333 using namespace DPL::Colors::Html;
352 void PrintfTODOMessage(const char* type,
353 const std::string& message,
356 using namespace DPL::Colors::Html;
375 void PrintfIgnoredMessage(const char* type,
376 const std::string& message,
379 using namespace DPL::Colors::Html;
399 void PrintStats(const std::string& name, const Statistic& stats)
401 using namespace DPL::Colors::Html;
402 fprintf(m_fp.Get(), "\n%sResults [%s]:%s\n", BOLD_GREEN_BEGIN, name.c_str(), BOLD_GREEN_END);
403 fprintf(m_fp.Get(), "%s%s%3d%s\n", CYAN_BEGIN, "Total tests: ", stats.GetTotal(), CYAN_END);
404 fprintf(m_fp.Get(), "%s%s%3d%s\n", CYAN_BEGIN, "Succeeded or ignored: ", stats.GetPassed() + stats.GetIgnored(), CYAN_END);
405 fprintf(m_fp.Get(), " %s%s%3d%s\n", CYAN_BEGIN, "Succeeded: ", stats.GetPassed(), CYAN_END);
406 fprintf(m_fp.Get(), " %s%s%3d%s\n", CYAN_BEGIN, "Ignored: ", stats.GetIgnored(), CYAN_END);
407 fprintf(m_fp.Get(), "%s%s%3d%s\n", CYAN_BEGIN, "Failed: ", stats.GetFailed(), CYAN_END);
408 fprintf(m_fp.Get(), "%s%s%3d%s\n", CYAN_BEGIN, "Todo: ", stats.GetTODO(), CYAN_END);
409 fprintf(m_fp.Get(), "%s%s%3.0f%%%s\n", CYAN_BEGIN, "Succeeded or ignored %: ", stats.GetPassedOrIgnoredPercend(), CYAN_END);
412 std::string m_filename;
415 std::string m_currentGroup;
416 std::map<std::string, Statistic> m_groupsStats;
419 TestResultsCollectorBase* HtmlCollector::Constructor()
421 return new HtmlCollector();
425 : public TestResultsCollectorBase
428 static TestResultsCollectorBase* Constructor();
433 virtual void Start() {
434 printf("GROUP;ID;RESULT;REASON\n");
437 virtual void CollectCurrentTestGroupName(const std::string& name)
439 m_currentGroup = name;
442 virtual void CollectResult(const std::string& id,
443 const std::string& /*description*/,
444 const FailStatus::Type status = FailStatus::NONE,
445 const std::string& reason = "")
447 std::string statusMsg = "";
449 case TestResultsCollectorBase::FailStatus::NONE: statusMsg = "OK"; break;
450 case TestResultsCollectorBase::FailStatus::FAILED: statusMsg = "FAILED"; break;
451 case TestResultsCollectorBase::FailStatus::IGNORED: statusMsg = "IGNORED"; break;
452 case TestResultsCollectorBase::FailStatus::TODO: statusMsg = "TODO"; break;
453 case TestResultsCollectorBase::FailStatus::INTERNAL: statusMsg = "FAILED"; break;
455 Assert(false && "Bad status");
457 printf("%s;%s;%s;%s\n",
458 m_currentGroup.c_str(),
464 std::string m_currentGroup;
468 TestResultsCollectorBase* CSVCollector::Constructor()
470 return new CSVCollector();
475 void TestResultsCollectorBase::RegisterCollectorConstructor(
476 const std::string& name,
477 TestResultsCollectorBase::CollectorConstructorFunc func)
479 Assert(m_constructorsMap.find(name) == m_constructorsMap.end());
480 m_constructorsMap[name] = func;
483 TestResultsCollectorBase* TestResultsCollectorBase::Create(
484 const std::string& name)
486 ConstructorsMap::iterator found = m_constructorsMap.find(name);
487 if (found != m_constructorsMap.end())
488 return found->second();
493 std::vector<std::string> TestResultsCollectorBase::GetCollectorsNames()
495 std::vector<std::string> list;
496 FOREACH(it, m_constructorsMap)
498 list.push_back(it->first);
503 TestResultsCollectorBase::ConstructorsMap TestResultsCollectorBase::m_constructorsMap;
507 static int RegisterCollectorConstructors();
508 static const int RegisterHelperVariable = RegisterCollectorConstructors();
509 int RegisterCollectorConstructors()
511 (void)RegisterHelperVariable;
513 TestResultsCollectorBase::RegisterCollectorConstructor(
515 &ConsoleCollector::Constructor);
516 TestResultsCollectorBase::RegisterCollectorConstructor(
518 &HtmlCollector::Constructor);
519 TestResultsCollectorBase::RegisterCollectorConstructor(
521 &CSVCollector::Constructor);