summaryrefslogtreecommitdiff
path: root/src/mongo/dbtests/framework.cpp
diff options
context:
space:
mode:
authorAntonin Kral <a.kral@bobek.cz>2012-08-29 20:54:51 +0200
committerAntonin Kral <a.kral@bobek.cz>2012-08-29 20:54:51 +0200
commit83957b73f9177f6e38bd5375bd93ca1f6a47188c (patch)
treef20b7d6ac9a9c64ff5bb6b5910a24abbb356b1d5 /src/mongo/dbtests/framework.cpp
parent5071d203970edd4c995493d810abe20987e76fe9 (diff)
Imported Upstream version 2.2.0upstream/2.2.0
Diffstat (limited to 'src/mongo/dbtests/framework.cpp')
-rw-r--r--src/mongo/dbtests/framework.cpp277
1 files changed, 277 insertions, 0 deletions
diff --git a/src/mongo/dbtests/framework.cpp b/src/mongo/dbtests/framework.cpp
new file mode 100644
index 00000000000..b27c0fbeb40
--- /dev/null
+++ b/src/mongo/dbtests/framework.cpp
@@ -0,0 +1,277 @@
+// 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 "pch.h"
+
+#include "mongo/dbtests/framework.h"
+
+#ifndef _WIN32
+#include <cxxabi.h>
+#include <sys/file.h>
+#endif
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/program_options.hpp>
+
+#include "mongo/db/client.h"
+#include "mongo/db/cmdline.h"
+#include "mongo/db/dur.h"
+#include "mongo/db/instance.h"
+#include "mongo/unittest/unittest.h"
+#include "mongo/util/background.h"
+#include "mongo/util/concurrency/mutex.h"
+#include "mongo/util/file_allocator.h"
+#include "mongo/util/version.h"
+
+namespace po = boost::program_options;
+
+namespace mongo {
+
+ CmdLine cmdLine;
+
+ namespace dbtests {
+
+ mutex globalCurrentTestNameMutex("globalCurrentTestNameMutex");
+ std::string globalCurrentTestName;
+
+ void show_help_text(const char* name, po::options_description options) {
+ cout << "usage: " << name << " [options] [suite]..." << endl
+ << options << "suite: run the specified test suite(s) only" << endl;
+ }
+
+ class TestWatchDog : public BackgroundJob {
+ public:
+ virtual string name() const { return "TestWatchDog"; }
+ virtual void run(){
+
+ int minutesRunning = 0;
+ std::string lastRunningTestName, currentTestName;
+
+ {
+ scoped_lock lk( globalCurrentTestNameMutex );
+ lastRunningTestName = globalCurrentTestName;
+ }
+
+ while (true) {
+ sleepsecs(60);
+ minutesRunning++;
+
+ {
+ scoped_lock lk( globalCurrentTestNameMutex );
+ currentTestName = globalCurrentTestName;
+ }
+
+ if (currentTestName != lastRunningTestName) {
+ minutesRunning = 0;
+ lastRunningTestName = currentTestName;
+ }
+
+ if (minutesRunning > 30){
+ log() << currentTestName << " has been running for more than 30 minutes. aborting." << endl;
+ ::abort();
+ }
+ else if (minutesRunning > 1){
+ warning() << currentTestName << " has been running for more than " << minutesRunning-1 << " minutes." << endl;
+ }
+ }
+ }
+ };
+
+ unsigned perfHist = 1;
+
+ int runDbTests( int argc , char** argv , string default_dbpath ) {
+ unsigned long long seed = time( 0 );
+ int runsPerTest = 1;
+ string dbpathSpec;
+
+ po::options_description shell_options("options");
+ po::options_description hidden_options("Hidden options");
+ po::options_description cmdline_options("Command line options");
+ po::positional_options_description positional_options;
+
+ shell_options.add_options()
+ ("help,h", "show this usage information")
+ ("dbpath", po::value<string>(&dbpathSpec)->default_value(default_dbpath),
+ "db data path for this test run. NOTE: the contents of this "
+ "directory will be overwritten if it already exists")
+ ("debug", "run tests with verbose output")
+ ("list,l", "list available test suites")
+ ("bigfiles", "use big datafiles instead of smallfiles which is the default")
+ ("filter,f" , po::value<string>() , "string substring filter on test name" )
+ ("verbose,v", "verbose")
+ ("dur", "enable journaling (currently the default)")
+ ("nodur", "disable journaling")
+ ("seed", po::value<unsigned long long>(&seed), "random number seed")
+ ("runs", po::value<int>(&runsPerTest), "number of times to run each test")
+ ("perfHist", po::value<unsigned>(&perfHist), "number of back runs of perf stats to display")
+ ;
+
+ hidden_options.add_options()
+ ("suites", po::value< vector<string> >(), "test suites to run")
+ ("nopreallocj", "disable journal prealloc")
+ ;
+
+ positional_options.add("suites", -1);
+
+ cmdline_options.add(shell_options).add(hidden_options);
+
+ po::variables_map params;
+ int command_line_style = (((po::command_line_style::unix_style ^
+ po::command_line_style::allow_guessing) |
+ po::command_line_style::allow_long_disguise) ^
+ po::command_line_style::allow_sticky);
+
+ try {
+ po::store(po::command_line_parser(argc, argv).options(cmdline_options).
+ positional(positional_options).
+ style(command_line_style).run(), params);
+ po::notify(params);
+ }
+ catch (po::error &e) {
+ cout << "ERROR: " << e.what() << endl << endl;
+ show_help_text(argv[0], shell_options);
+ return EXIT_BADOPTIONS;
+ }
+
+ if (params.count("help")) {
+ show_help_text(argv[0], shell_options);
+ return EXIT_CLEAN;
+ }
+
+ bool nodur = false;
+ if( params.count("nodur") ) {
+ nodur = true;
+ cmdLine.dur = false;
+ }
+ if( params.count("dur") || cmdLine.dur ) {
+ cmdLine.dur = true;
+ }
+
+ if( params.count("nopreallocj") ) {
+ cmdLine.preallocj = false;
+ }
+
+ if (params.count("debug") || params.count("verbose") ) {
+ logLevel = 1;
+ }
+
+ if (params.count("list")) {
+ std::vector<std::string> suiteNames = mongo::unittest::getAllSuiteNames();
+ for ( std::vector<std::string>::const_iterator i = suiteNames.begin();
+ i != suiteNames.end(); ++i ) {
+
+ std::cout << *i << std::endl;
+ }
+ return 0;
+ }
+
+ boost::filesystem::path p(dbpathSpec);
+
+ /* remove the contents of the test directory if it exists. */
+ if (boost::filesystem::exists(p)) {
+ if (!boost::filesystem::is_directory(p)) {
+ cout << "ERROR: path \"" << p.string() << "\" is not a directory" << endl << endl;
+ show_help_text(argv[0], shell_options);
+ return EXIT_BADOPTIONS;
+ }
+ boost::filesystem::directory_iterator end_iter;
+ for (boost::filesystem::directory_iterator dir_iter(p);
+ dir_iter != end_iter; ++dir_iter) {
+ boost::filesystem::remove_all(*dir_iter);
+ }
+ }
+ else {
+ boost::filesystem::create_directory(p);
+ }
+
+ string dbpathString = p.native_directory_string();
+ dbpath = dbpathString.c_str();
+
+ cmdLine.prealloc = false;
+
+ // dbtest defaults to smallfiles
+ cmdLine.smallfiles = true;
+ if( params.count("bigfiles") ) {
+ cmdLine.dur = true;
+ }
+
+ cmdLine.oplogSize = 10 * 1024 * 1024;
+ Client::initThread("testsuite");
+ acquirePathLock();
+
+ srand( (unsigned) seed );
+ printGitVersion();
+ printSysInfo();
+ DEV log() << "_DEBUG build" << endl;
+ if( sizeof(void*)==4 )
+ log() << "32bit" << endl;
+ log() << "random seed: " << seed << endl;
+
+ if( time(0) % 3 == 0 && !nodur ) {
+ cmdLine.dur = true;
+ log() << "****************" << endl;
+ log() << "running with journaling enabled to test that. dbtests will do this occasionally even if --dur is not specified." << endl;
+ log() << "****************" << endl;
+ }
+
+ FileAllocator::get()->start();
+
+ vector<string> suites;
+ if (params.count("suites")) {
+ suites = params["suites"].as< vector<string> >();
+ }
+
+ string filter = "";
+ if ( params.count( "filter" ) ) {
+ filter = params["filter"].as<string>();
+ }
+
+ dur::startup();
+
+ if( debug && cmdLine.dur ) {
+ log() << "_DEBUG: automatically enabling cmdLine.durOptions=8 (DurParanoid)" << endl;
+ // this was commented out. why too slow or something? :
+ cmdLine.durOptions |= 8;
+ }
+
+ TestWatchDog twd;
+ twd.go();
+
+ // set tlogLevel to -1 to suppress tlog() output in a test program
+ tlogLevel = -1;
+
+ int ret = ::mongo::unittest::Suite::run(suites,filter,runsPerTest);
+
+#if !defined(_WIN32) && !defined(__sunos__)
+ flock( lockFile, LOCK_UN );
+#endif
+
+ cc().shutdown();
+ dbexit( (ExitCode)ret ); // so everything shuts down cleanly
+ return ret;
+ }
+ } // namespace dbtests
+
+ void setupSignals( bool inFork ) {}
+
+} // namespace mongo
+
+void mongo::unittest::onCurrentTestNameChange( const std::string &testName ) {
+ scoped_lock lk( mongo::dbtests::globalCurrentTestNameMutex );
+ mongo::dbtests::globalCurrentTestName = testName;
+}