1 /*
2 This file is part of Valgrind, a dynamic binary instrumentation
3 framework.
4
5 Copyright (C) 2008-2008 Google Inc
6 opensource@google.com
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 02111-1307, USA.
22
23 The GNU General Public License is contained in the file COPYING.
24 */
25
26 /* Author: Konstantin Serebryany <opensource@google.com>
27
28 This file contains a simple test suite for some of our old unit-tests.
29 These tests are likely to be moved to googletest framework over time.
30 */
31
32 #include <algorithm>
33 #include <gtest/gtest.h>
34 #include <string>
35 #include <ostream>
36
37 #include "old_test_suite.h"
38
39 Mutex printf_mu;
40 std::map<int, Test> *TheMapOfTests = NULL;
41 std::vector<int> tests_to_run;
42 std::set<int> tests_to_exclude;
43
44 #ifndef MAIN_INIT_ACTION
45 #define MAIN_INIT_ACTION
46 #endif
47
ParseInt(const char * str)48 int ParseInt(const char *str) {
49 int ret = 0;
50 const char *cur = str;
51 do {
52 if (!isdigit(*cur)) {
53 printf("\"%s\" is not a valid number\n", str);
54 exit(1);
55 }
56
57 ret = ret*10 + (*cur - '0');
58 } while (*(++cur));
59 return ret;
60 }
61
62 class RandomGenerator {
63 public:
RandomGenerator(int seed)64 RandomGenerator(int seed) { srand(seed); }
operator ( )(size_t n) const65 size_t operator( )(size_t n) const { return rand() % n; }
66 };
67
TEST(NonGtestTests,All)68 TEST(NonGtestTests, All) {
69 for (size_t i = 0; i < tests_to_run.size(); i++) {
70 int test_id = tests_to_run[i];
71 if (tests_to_exclude.count(test_id) > 0) {
72 printf("test%i was excluded\n", test_id);
73 } else {
74 (*TheMapOfTests)[test_id].Run();
75 ANNOTATE_FLUSH_EXPECTED_RACES();
76 }
77 }
78 }
79
80 #ifndef ANDROID // GTest version is too old.
81 class PerformanceTestEventListener: public ::testing::EmptyTestEventListener {
82 public:
OnTestEnd(const::testing::TestInfo & test_info)83 virtual void OnTestEnd(const ::testing::TestInfo& test_info) {
84 if (strcmp(test_info.test_case_name(), "StressTests") == 0 ||
85 strcmp(test_info.test_case_name(), "PerformanceTests") == 0) {
86 const ::testing::TestResult* result = test_info.result();
87 times_[test_info.name()].push_back(result->elapsed_time());
88 }
89 }
90
OnTestProgramEnd(const::testing::UnitTest & unit_test)91 virtual void OnTestProgramEnd(const ::testing::UnitTest& unit_test) {
92 for (std::map<string, std::vector<long long int> >::iterator it = times_.begin();
93 it != times_.end(); ++it) {
94 printf("*RESULT %s: time= %s ms\n", it->first.c_str(), join_str(it->second).c_str());
95 }
96 }
97
98 private:
99 std::map<string, std::vector<long long int> > times_;
100
join_str(std::vector<long long int> values)101 string join_str(std::vector<long long int> values) {
102 bool first = true;
103 bool single = (values.size() == 1);
104 std::ostringstream st;
105 if (!single) {
106 st << "[";
107 }
108 for (std::vector<long long int>::iterator it = values.begin();
109 it != values.end(); ++it) {
110 if (first) {
111 first = false;
112 } else {
113 st << " ";
114 }
115 st << *it;
116 }
117 if (!single) {
118 st << "]";
119 }
120 return st.str();
121 }
122 };
123 #endif
124
main(int argc,char ** argv)125 int main(int argc, char** argv) {
126 MAIN_INIT_ACTION;
127 testing::InitGoogleTest(&argc, argv);
128 printf("FLAGS [phb=%i, rv=%i]\n", Tsan_PureHappensBefore(),
129 Tsan_RaceVerifier());
130
131 int shuffle_seed = 0; // non-zero to shuffle.
132
133 int id = 1;
134 while (id < argc) {
135 char *cur_arg = argv[id];
136 if (!strcmp(cur_arg, "benchmark")) {
137 for (std::map<int,Test>::iterator it = TheMapOfTests->begin();
138 it != TheMapOfTests->end(); ++it) {
139 if(it->second.flags_ & PERFORMANCE)
140 tests_to_run.push_back(it->first);
141 }
142 } else if (!strcmp(cur_arg, "demo")) {
143 for (std::map<int,Test>::iterator it = TheMapOfTests->begin();
144 it != TheMapOfTests->end(); ++it) {
145 if(it->second.flags_ & RACE_DEMO)
146 tests_to_run.push_back(it->first);
147 }
148 } else if (!strncmp(cur_arg, "shuffle", 7)) {
149 if (strlen(cur_arg) == 7) {
150 shuffle_seed = GetTimeInMs();
151 printf("Shuffling with seed = %i\n", shuffle_seed);
152 } else {
153 CHECK(cur_arg[7] == '=');
154 shuffle_seed = ParseInt(cur_arg + 8);
155 }
156 } else {
157 if (isdigit(cur_arg[0])) {
158 // Enqueue the test specified.
159 int test_id = ParseInt(cur_arg);
160 if (!TheMapOfTests->count(test_id)) {
161 printf("Unknown test id: %d\n", test_id);
162 exit(1);
163 }
164 tests_to_run.push_back(test_id);
165 } else if (cur_arg[0] == '-') {
166 // Exclude the test specified.
167 int test_id = ParseInt(cur_arg + 1);
168 if (!TheMapOfTests->count(test_id)) {
169 printf("Unknown test id: %d\n", test_id);
170 exit(1);
171 }
172 tests_to_exclude.insert(test_id);
173 } else {
174 printf("Unknown argument: %s\n", cur_arg);
175 exit(1);
176 }
177 }
178
179 id++;
180 }
181
182 if (tests_to_run.size() == 0) {
183 printf("No tests specified.\nRunning default set of tests...\n");
184 for (std::map<int,Test>::iterator it = TheMapOfTests->begin();
185 it != TheMapOfTests->end();
186 ++it) {
187 if(it->second.flags_ & EXCLUDE_FROM_ALL) continue;
188 if(it->second.flags_ & RACE_DEMO) continue;
189 tests_to_run.push_back(it->first);
190 }
191 }
192
193 if (shuffle_seed > 0) {
194 RandomGenerator rnd(shuffle_seed);
195 random_shuffle(tests_to_run.begin(), tests_to_run.end(), rnd);
196 }
197
198 #ifndef ANDROID // GTest version is too old.
199 ::testing::TestEventListeners& listeners =
200 ::testing::UnitTest::GetInstance()->listeners();
201 // Adds a listener to the end. Google Test takes the ownership.
202 listeners.Append(new PerformanceTestEventListener());
203 #endif
204
205 return RUN_ALL_TESTS();
206 }
207 // End {{{1
208 // vim:shiftwidth=2:softtabstop=2:expandtab:foldmethod=marker
209