• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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