📄 testsuite.cpp
字号:
/*
* TOPPERS/JSP Kernel
* Toyohashi Open Platform for Embedded Real-Time Systems/
* Just Standard Profile Kernel
*
* Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
* Toyohashi Univ. of Technology, JAPAN
*
* 忋婰挊嶌尃幰偼丆埲壓偺 (1)乣(4) 偺忦審偐丆Free Software Foundation
* 偵傛偭偰岞昞偝傟偰偄傞 GNU General Public License 偺 Version 2 偵婰
* 弎偝傟偰偄傞忦審傪枮偨偡応崌偵尷傝丆杮僜僼僩僂僃傾乮杮僜僼僩僂僃傾
* 傪夵曄偟偨傕偺傪娷傓丏埲壓摨偠乯傪巊梡丒暋惢丒夵曄丒嵞攝晍乮埲壓丆
* 棙梡偲屇傇乯偡傞偙偲傪柍彏偱嫋戻偡傞丏
* (1) 杮僜僼僩僂僃傾傪僜乕僗僐乕僪偺宍偱棙梡偡傞応崌偵偼丆忋婰偺挊嶌
* 尃昞帵丆偙偺棙梡忦審偍傛傃壓婰偺柍曐徹婯掕偑丆偦偺傑傑偺宍偱僜乕
* 僗僐乕僪拞偵娷傑傟偰偄傞偙偲丏
* (2) 杮僜僼僩僂僃傾傪丆儔僀僽儔儕宍幃側偳丆懠偺僜僼僩僂僃傾奐敪偵巊
* 梡偱偒傞宍偱嵞攝晍偡傞応崌偵偼丆嵞攝晍偵敽偆僪僉儏儊儞僩乮棙梡
* 幰儅僯儏傾儖側偳乯偵丆忋婰偺挊嶌尃昞帵丆偙偺棙梡忦審偍傛傃壓婰
* 偺柍曐徹婯掕傪宖嵹偡傞偙偲丏
* (3) 杮僜僼僩僂僃傾傪丆婡婍偵慻傒崬傓側偳丆懠偺僜僼僩僂僃傾奐敪偵巊
* 梡偱偒側偄宍偱嵞攝晍偡傞応崌偵偼丆師偺偄偢傟偐偺忦審傪枮偨偡偙
* 偲丏
* (a) 嵞攝晍偵敽偆僪僉儏儊儞僩乮棙梡幰儅僯儏傾儖側偳乯偵丆忋婰偺挊
* 嶌尃昞帵丆偙偺棙梡忦審偍傛傃壓婰偺柍曐徹婯掕傪宖嵹偡傞偙偲丏
* (b) 嵞攝晍偺宍懺傪丆暿偵掕傔傞曽朄偵傛偭偰丆TOPPERS僾儘僕僃僋僩偵
* 曬崘偡傞偙偲丏
* (4) 杮僜僼僩僂僃傾偺棙梡偵傛傝捈愙揑傑偨偼娫愙揑偵惗偠傞偄偐側傞懝
* 奞偐傜傕丆忋婰挊嶌尃幰偍傛傃TOPPERS僾儘僕僃僋僩傪柶愑偡傞偙偲丏
*
* 杮僜僼僩僂僃傾偼丆柍曐徹偱採嫙偝傟偰偄傞傕偺偱偁傞丏忋婰挊嶌尃幰偍
* 傛傃TOPPERS僾儘僕僃僋僩偼丆杮僜僼僩僂僃傾偵娭偟偰丆偦偺揔梡壜擻惈傕
* 娷傔偰丆偄偐側傞曐徹傕峴傢側偄丏傑偨丆杮僜僼僩僂僃傾偺棙梡偵傛傝捈
* 愙揑傑偨偼娫愙揑偵惗偠偨偄偐側傞懝奞偵娭偟偰傕丆偦偺愑擟傪晧傢側偄丏
*
* @(#) $Id: testsuite.cpp,v 1.1 2006/04/14 02:46:07 9564907 Exp $
*/
// $Header: J:\\SapporoSoft\\usb20\\S1R72V05\\Debug\\Repository/S1R72V05_Toppers/Toppers/cfg/base/testsuite.cpp,v 1.1 2006/04/14 02:46:07 9564907 Exp $
#include "base/testsuite.h"
#include "base/coverage_defs.h"
#include "base/coverage_undefs.h"
#ifdef TESTSUITE
#undef main //僥僗僩僗傿乕僩梡偺main傪掕媊偡傞偺偱undef偡傞
#undef cin
#undef cout
#undef cerr
#include <stdlib.h> //EXIT_SUCCESS|EXIT_FAILURE梡
#include <fstream> //嶌嬈娭悢梡
#include <cstdio>
#include <iomanip>
using namespace std;
/* 僗僩儕乕儉擖姺偊梡偺曄悢掕媊 */
namespace std {
stringstream _cin;
stringstream _cout;
stringstream _cerr;
}
/*
* 僥僗僩僗傿乕僩偺幚峴惂屼僋儔僗 ; class TestSuiteControl
*/
//僐儞僗僩儔僋僞
TestSuiteControl::TestSuiteControl(ostream & _out, const char * _pattern) : target_session(_pattern), out(&_out), fail(false), verbose(false), case_count(0), fail_count(0)
{}
//僔僫儕僆柤偺庢摼
string TestSuiteControl::get_suitename(const char * name) const
{
string result;
list<string>::const_iterator scope;
scope = session.begin();
while(scope != session.end()) {
result += *scope;
result += '.';
++ scope;
}
if(name != NULL)
result += name;
return result;
}
//僥僗僩僔僫儕僆偺昞戣愝掕 (曉媝抣 : 幚峴偡傞昁梫偑偁傞偐偳偆偐)
bool TestSuiteControl::_enter_case(const char * session, const char * description, const char * filename, long lineno)
{
bool result;
stringstream buf;
//昞戣偺愝掕
current_session.assign(get_suitename(session));
//徻嵶忣曬偺愝掕
if(description != 0)
buf << description;
//僼傽僀儖柤 (filename:lineno) 偺惗惉
if(filename != 0) {
string work(filename);
string::size_type pos;
//僼儖僷僗偱棃偨傜抁偔愗傞
pos = work.find_last_of("/\\");
if(pos != string::npos)
work.erase(0, pos + 1);
buf << '(' << work;
if(lineno != -1)
buf << ':' << lineno;
buf << ')';
}
current_description = buf.str();
//幚峴偡傞昁梫偺桳柍偺妋擣
result = (target_session.empty() || current_session.find(target_session) != string::npos);
if(result) {
if(verbose) {
string indent;
indent.assign(2 * this->session.size(), ' ');
(*out) << indent << '[' << session << "] " << current_description << endl;
//(*out) << '[' << current_session << "] " << current_description << endl;
}
enter_session(session);
++ case_count;
}
return result;
}
//僥僗僩僙僢僔儑儞柤 (僔僫儕僆僾儗僼傿僋僗) 偺愝掕
void TestSuiteControl::enter_session(const string & _session)
{ session.push_back(_session); }
//僥僗僩僙僢僔儑儞柤 (僔僫儕僆僾儗僼傿僋僗) 偺夝彍
void TestSuiteControl::leave_session(void)
{ session.pop_back(); }
//僥僗僩僔僫儕僆偺幐攕曬崘
void TestSuiteControl::fail_in_suite(string msg)
{
fail = true;
(*out) << "Failed : [" << current_session << "]\n " << current_description << endl;
if(!msg.empty())
(*out) << " #" << msg << endl;
++ fail_count;
}
//僗傿乕僩忣曬僐儞僗僩儔僋僞
TestSuite::SuiteContainerNode::SuiteContainerNode(const char * _session, SuiteFunction _suite) : session(_session), suite(_suite)
{}
//僗傿乕僩忣曬僐儞僗僩儔僋僞
TestSuite::SuiteContainerNode::SuiteContainerNode(const SuiteContainerNode & src) : session(src.session), suite(src.suite)
{}
//僗傿乕僩偺幚峴
bool TestSuite::SuiteContainerNode::invoke(TestSuiteControl & suite_control)
{
if(suite != 0) {
suite_control.enter_session(session);
(*suite)(suite_control);
suite_control.leave_session();
}
return !suite_control.is_failed();
}
/*
* 僥僗僩僗傿乕僩幚峴僋儔僗
*/
//僐儞僗僩儔僋僞
TestSuite::TestSuite(const char * session, SuiteFunction suite) : fail(false)
{ Singleton<SuiteContainer>::getInstance()->push_back(SuiteContainerNode(session, suite)); }
//僨僗僩儔僋僞
TestSuite::~TestSuite(void)
{}
//僥僗僩僗傿乕僩偺幚峴 (曉媝抣:僗傿乕僩傪幚峴偟偨偐偳偆偐)
bool TestSuite::performTestSuite(int flags, const char * pattern)
{
bool result;
TestSuiteControl suite_control(cerr, pattern);
SuiteContainer * container;
SuiteContainer::iterator scope;
//幚峴僗傿乕僩儕僗僩偺嶲徠
container = Singleton<SuiteContainer>::getInstance();
//忕挿弌椡愝掕
if( (flags & VERBOSE) != 0 )
suite_control.set_verbose();
//慡搊榐僗傿乕僩偺幚峴
scope = container->begin();
while(scope != container->end()) {
result = scope->invoke(suite_control);
//偄偪偄偪巭傔傞 or 捠偟偱幚峴
if( !result && (flags & THROUGH) == 0)
break;
++ scope;
}
//僄儔乕偑側偗傟偽OK昞帵
if(!suite_control.is_failed())
cerr << "OK (" << suite_control.countCases() << " passed)" << endl;
else
cerr << "Failed (" << suite_control.countFails() << '/' << suite_control.countCases() << ')' << endl;
return !suite_control.is_failed(); //僗傿乕僩傪惓忢偵幚峴偱偒偨傜true
}
//搊榐偝傟偰偄傞僩僢僾儗儀儖僗傿乕僩偺堦棗昞帵
void TestSuite::listTestSuite(void)
{
SuiteContainer::iterator scope;
int count;
SuiteContainer * container;
count = 0;
container = Singleton<SuiteContainer>::getInstance();
scope = container->begin();
while(scope != container->end()) {
cout << " ";
cout.width(3);
cout << count << ':' << scope->getName() << endl;
++ count;
++ scope;
}
cout << "Total " << count << " sets of suite exist.\n";
}
/*
* 僠僃僢僋億僀儞僩梡娭悢
*/
bool TestSuite::isReached(std::string checkname)
{
set<string>::iterator scope;
scope = Singleton<Checkpoint>::getInstance()->find(checkname);
return scope != Singleton<Checkpoint>::getInstance()->end();
}
/*
* 僥僗僩僗傿乕僩幚峴梡嶌嬈娭悢
*/
//僼傽僀儖撪梕斾妑
bool TestSuite::compareFileContents(const char * filename, const char * filecontents, bool _remove)
{
fstream file(filename,ios::in);
int ch;
bool result = true;
//撪梕僠僃僢僋
while(result && *filecontents != '\x0' && file.good()) {
ch = file.get();
if(ch != (int)*filecontents)
result = false;
++ filecontents;
}
//EOF偵払偟偰偄傞偐
if(result) {
if(!file.good() || file.get() != EOF)
result = false;
}
file.close();
if(_remove)
::remove(filename);
return result;
}
/*
* 僥僗僩僗傿乕僩幚峴梡main娭悢
*/
int main(int argc, char ** argv)
{
int result;
int pos;
int flags;
string category;
flags = TestSuite::DEFAULT;
for(pos = 1; pos < argc; ++ pos) {
if(*argv[pos] == '-') {
switch(argv[pos][1]) {
case 'v':
flags |= TestSuite::VERBOSE;
break;
case 'V':
flags &= ~TestSuite::VERBOSE;
break;
case 't':
flags |= TestSuite::THROUGH;
break;
case 'T':
flags &= ~TestSuite::THROUGH;
break;
case 'l':
TestSuite::listTestSuite();
return EXIT_SUCCESS;
case 'h':
cerr << "Usage : program (option) (suite)\n"
" -v, -V : Verbose output on(-v) / off(-V)\n"
" -t, -T : Go through with the suite, on(-t) / off(-T)\n"
" -l : List the top level suites\n";
return EXIT_SUCCESS;
default:
cerr << "Unknown option [" << argv[pos] << "]\n";
return EXIT_FAILURE;
}
}
else {
if(!category.empty()) {
cerr << "Two or more category specified.\n";
return EXIT_FAILURE;
}
category.assign(argv[pos]);
}
}
result = EXIT_FAILURE;
if(TestSuite::performTestSuite(flags, category.c_str()))
result = EXIT_SUCCESS;
#ifdef COVERAGE
fstream fout("coverage.txt",ios::out);
if(fout.is_open()) {
Coverage::printCoverage(fout);
fout.close();
}
#endif
return result;
}
#endif //TESTSUITE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -