/* This file is part of Valgrind, a dynamic binary instrumentation framework. Copyright (C) 2008-2008 Google Inc opensource@google.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. The GNU General Public License is contained in the file COPYING. */ /* Author: Konstantin Serebryany <opensource@google.com> This file contains a simple test suite for some of our old unit-tests. These tests are likely to be moved to googletest framework over time. */ #include <algorithm> #include <gtest/gtest.h> #include <string> #include <ostream> #include "old_test_suite.h" Mutex printf_mu; std::map<int, Test> *TheMapOfTests = NULL; std::vector<int> tests_to_run; std::set<int> tests_to_exclude; #ifndef MAIN_INIT_ACTION #define MAIN_INIT_ACTION #endif int ParseInt(const char *str) { int ret = 0; const char *cur = str; do { if (!isdigit(*cur)) { printf("\"%s\" is not a valid number\n", str); exit(1); } ret = ret*10 + (*cur - '0'); } while (*(++cur)); return ret; } class RandomGenerator { public: RandomGenerator(int seed) { srand(seed); } size_t operator( )(size_t n) const { return rand() % n; } }; TEST(NonGtestTests, All) { for (size_t i = 0; i < tests_to_run.size(); i++) { int test_id = tests_to_run[i]; if (tests_to_exclude.count(test_id) > 0) { printf("test%i was excluded\n", test_id); } else { (*TheMapOfTests)[test_id].Run(); ANNOTATE_FLUSH_EXPECTED_RACES(); } } } #ifndef ANDROID // GTest version is too old. class PerformanceTestEventListener: public ::testing::EmptyTestEventListener { public: virtual void OnTestEnd(const ::testing::TestInfo& test_info) { if (strcmp(test_info.test_case_name(), "StressTests") == 0 || strcmp(test_info.test_case_name(), "PerformanceTests") == 0) { const ::testing::TestResult* result = test_info.result(); times_[test_info.name()].push_back(result->elapsed_time()); } } virtual void OnTestProgramEnd(const ::testing::UnitTest& unit_test) { for (std::map<string, std::vector<long long int> >::iterator it = times_.begin(); it != times_.end(); ++it) { printf("*RESULT %s: time= %s ms\n", it->first.c_str(), join_str(it->second).c_str()); } } private: std::map<string, std::vector<long long int> > times_; string join_str(std::vector<long long int> values) { bool first = true; bool single = (values.size() == 1); std::ostringstream st; if (!single) { st << "["; } for (std::vector<long long int>::iterator it = values.begin(); it != values.end(); ++it) { if (first) { first = false; } else { st << " "; } st << *it; } if (!single) { st << "]"; } return st.str(); } }; #endif int main(int argc, char** argv) { MAIN_INIT_ACTION; testing::InitGoogleTest(&argc, argv); printf("FLAGS [phb=%i, rv=%i]\n", Tsan_PureHappensBefore(), Tsan_RaceVerifier()); int shuffle_seed = 0; // non-zero to shuffle. int id = 1; while (id < argc) { char *cur_arg = argv[id]; if (!strcmp(cur_arg, "benchmark")) { for (std::map<int,Test>::iterator it = TheMapOfTests->begin(); it != TheMapOfTests->end(); ++it) { if(it->second.flags_ & PERFORMANCE) tests_to_run.push_back(it->first); } } else if (!strcmp(cur_arg, "demo")) { for (std::map<int,Test>::iterator it = TheMapOfTests->begin(); it != TheMapOfTests->end(); ++it) { if(it->second.flags_ & RACE_DEMO) tests_to_run.push_back(it->first); } } else if (!strncmp(cur_arg, "shuffle", 7)) { if (strlen(cur_arg) == 7) { shuffle_seed = GetTimeInMs(); printf("Shuffling with seed = %i\n", shuffle_seed); } else { CHECK(cur_arg[7] == '='); shuffle_seed = ParseInt(cur_arg + 8); } } else { if (isdigit(cur_arg[0])) { // Enqueue the test specified. int test_id = ParseInt(cur_arg); if (!TheMapOfTests->count(test_id)) { printf("Unknown test id: %d\n", test_id); exit(1); } tests_to_run.push_back(test_id); } else if (cur_arg[0] == '-') { // Exclude the test specified. int test_id = ParseInt(cur_arg + 1); if (!TheMapOfTests->count(test_id)) { printf("Unknown test id: %d\n", test_id); exit(1); } tests_to_exclude.insert(test_id); } else { printf("Unknown argument: %s\n", cur_arg); exit(1); } } id++; } if (tests_to_run.size() == 0) { printf("No tests specified.\nRunning default set of tests...\n"); for (std::map<int,Test>::iterator it = TheMapOfTests->begin(); it != TheMapOfTests->end(); ++it) { if(it->second.flags_ & EXCLUDE_FROM_ALL) continue; if(it->second.flags_ & RACE_DEMO) continue; tests_to_run.push_back(it->first); } } if (shuffle_seed > 0) { RandomGenerator rnd(shuffle_seed); random_shuffle(tests_to_run.begin(), tests_to_run.end(), rnd); } #ifndef ANDROID // GTest version is too old. ::testing::TestEventListeners& listeners = ::testing::UnitTest::GetInstance()->listeners(); // Adds a listener to the end. Google Test takes the ownership. listeners.Append(new PerformanceTestEventListener()); #endif return RUN_ALL_TESTS(); } // End {{{1 // vim:shiftwidth=2:softtabstop=2:expandtab:foldmethod=marker