mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
216 lines
6.3 KiB
C++
216 lines
6.3 KiB
C++
// framework.cpp
|
|
|
|
/**
|
|
* Copyright (C) 2008 10gen Inc.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License, version 3,
|
|
* as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "../stdafx.h"
|
|
#include "framework.h"
|
|
|
|
#ifndef _WIN32
|
|
#include <cxxabi.h>
|
|
#endif
|
|
|
|
namespace mongo {
|
|
|
|
namespace regression {
|
|
|
|
map<string,Suite*> * mongo::regression::Suite::_suites = 0;
|
|
|
|
class Result {
|
|
public:
|
|
Result( string name ) : _name( name ) , _rc(0) , _tests(0) , _fails(0) , _asserts(0) {
|
|
}
|
|
|
|
string toString(){
|
|
stringstream ss;
|
|
ss << _name << " tests:" << _tests << " fails:" << _fails << " assert calls:" << _asserts << "\n";
|
|
for ( list<string>::iterator i=_messages.begin(); i!=_messages.end(); i++ ){
|
|
ss << "\t" << *i << "\n";
|
|
}
|
|
return ss.str();
|
|
}
|
|
|
|
int rc(){
|
|
return _rc;
|
|
}
|
|
|
|
string _name;
|
|
|
|
int _rc;
|
|
int _tests;
|
|
int _fails;
|
|
int _asserts;
|
|
list<string> _messages;
|
|
|
|
static Result * cur;
|
|
};
|
|
|
|
Result * Result::cur = 0;
|
|
|
|
Result * Suite::run(){
|
|
setupTests();
|
|
|
|
Result * r = new Result( _name );
|
|
Result::cur = r;
|
|
|
|
for ( list<TestCase*>::iterator i=_tests.begin(); i!=_tests.end(); i++ ){
|
|
TestCase * tc = *i;
|
|
|
|
r->_tests++;
|
|
|
|
bool passes = false;
|
|
|
|
log(1) << "\t" << tc->getName() << endl;
|
|
|
|
try {
|
|
tc->run();
|
|
passes = true;
|
|
}
|
|
catch ( ... ){
|
|
log() << "unknown exception in test: " << tc->getName() << endl;
|
|
}
|
|
|
|
if ( ! passes )
|
|
r->_fails++;
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
int Suite::run( bool debug , bool list_suites, vector<string> suites ){
|
|
if ( list_suites ) {
|
|
for ( map<string,Suite*>::iterator i = _suites->begin() ; i != _suites->end(); i++ )
|
|
cout << i->first << endl;
|
|
return 0;
|
|
}
|
|
if ( debug ) {
|
|
logLevel = 1;
|
|
}
|
|
for ( unsigned int i = 0; i < suites.size(); i++ ) {
|
|
if ( _suites->find( suites[i] ) == _suites->end() ) {
|
|
cout << "invalid test [" << suites[i] << "], use --list to see valid names" << endl;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
list<string> torun(suites.begin(), suites.end());
|
|
|
|
if ( torun.size() == 0 )
|
|
for ( map<string,Suite*>::iterator i=_suites->begin() ; i!=_suites->end(); i++ )
|
|
torun.push_back( i->first );
|
|
|
|
list<Result*> results;
|
|
|
|
for ( list<string>::iterator i=torun.begin(); i!=torun.end(); i++ ){
|
|
string name = *i;
|
|
Suite * s = (*_suites)[name];
|
|
assert( s );
|
|
|
|
log() << "going to run suite: " << name << endl;
|
|
results.push_back( s->run() );
|
|
}
|
|
|
|
cout << "**************************************************" << endl;
|
|
cout << "**************************************************" << endl;
|
|
cout << "**************************************************" << endl;
|
|
|
|
int rc = 0;
|
|
|
|
int tests = 0;
|
|
int fails = 0;
|
|
int asserts = 0;
|
|
|
|
for ( list<Result*>::iterator i=results.begin(); i!=results.end(); i++ ){
|
|
Result * r = *i;
|
|
cout << r->toString();
|
|
if ( abs( r->rc() ) > abs( rc ) )
|
|
rc = r->rc();
|
|
|
|
tests += r->_tests;
|
|
fails += r->_fails;
|
|
asserts += r->_asserts;
|
|
}
|
|
|
|
cout << "TOTALS tests:" << tests << " fails: " << fails << " asserts calls: " << asserts << endl;
|
|
|
|
return rc;
|
|
}
|
|
|
|
void Suite::registerSuite( string name , Suite * s ){
|
|
if ( ! _suites )
|
|
_suites = new map<string,Suite*>();
|
|
Suite*& m = (*_suites)[name];
|
|
uassert( "already have suite with that name" , ! m );
|
|
m = s;
|
|
}
|
|
|
|
void assert_pass(){
|
|
Result::cur->_asserts++;
|
|
}
|
|
|
|
void assert_fail( const char * exp , const char * file , unsigned line ){
|
|
Result::cur->_asserts++;
|
|
Result::cur->_fails++;
|
|
|
|
stringstream ss;
|
|
ss << "ASSERT FAILED! " << file << ":" << line << endl;
|
|
log() << ss.str() << endl;
|
|
Result::cur->_messages.push_back( ss.str() );
|
|
}
|
|
|
|
void fail( const char * exp , const char * file , unsigned line ){
|
|
assert(0);
|
|
}
|
|
|
|
string demangleName( const type_info& typeinfo ){
|
|
int status;
|
|
|
|
char * niceName = abi::__cxa_demangle(typeinfo.name(), 0, 0, &status);
|
|
if ( ! niceName )
|
|
return typeinfo.name();
|
|
|
|
string s = niceName;
|
|
free(niceName);
|
|
return s;
|
|
}
|
|
|
|
void MyAsserts::printLocation(){
|
|
log() << _file << ":" << _line << " " << _aexp << " != " << _bexp << " ";
|
|
}
|
|
|
|
void MyAsserts::ae( double a , double b ){
|
|
Result::cur->_asserts++;
|
|
if ( a == b )
|
|
return;
|
|
|
|
printLocation();
|
|
log() << a << " != " << b << endl;
|
|
throw -1;
|
|
}
|
|
|
|
void MyAsserts::ae( string a , string b ){
|
|
Result::cur->_asserts++;
|
|
if ( a == b )
|
|
return;
|
|
|
|
printLocation();
|
|
log() << a << " != " << b << endl;
|
|
throw -1;
|
|
}
|
|
|
|
}
|
|
}
|