Repository navigation
Expand file tree
/
Copy pathboostTest.cpp
More file actions
204 lines (183 loc) · 6.83 KB
/
Copy pathboostTest.cpp
File metadata and controls
204 lines (183 loc) · 6.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/*
This file is part of cpp-ethereum.
cpp-ethereum 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 3 of the License, or
(at your option) any later version.
cpp-ethereum 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file
* Stub for generating main boost.test module.
* Original code taken from boost sources.
*/
#define BOOST_TEST_MODULE EthereumTests
#define BOOST_TEST_NO_MAIN
#include <boost/test/included/unit_test.hpp>
#include <test/tools/jsontests/BlockChainTests.h>
#include <test/tools/jsontests/StateTests.h>
#include <test/tools/jsontests/TransactionTests.h>
#include <test/tools/jsontests/vm.h>
#include <test/tools/libtesteth/TestHelper.h>
#include <clocale>
#include <cstdlib>
#include <iostream>
#include <thread>
using namespace boost::unit_test;
static std::ostringstream strCout;
std::streambuf* oldCoutStreamBuf;
std::streambuf* oldCerrStreamBuf;
void customTestSuite()
{
// restore output for creating test
std::cout.rdbuf(oldCoutStreamBuf);
std::cerr.rdbuf(oldCerrStreamBuf);
dev::test::Options const& opt = dev::test::Options::get();
// if generating a random test
if (opt.createRandomTest)
{
if (!dev::test::createRandomTest())
throw framework::internal_error(
"Create random test error! See std::error for more details.");
}
// if running a singletest
if (opt.singleTestFile.is_initialized())
{
boost::filesystem::path file(opt.singleTestFile.get());
if (opt.rCurrentTestSuite.find_first_of("GeneralStateTests") != std::string::npos)
{
dev::test::StateTestSuite suite;
suite.runTestWithoutFiller(file);
}
else if (opt.rCurrentTestSuite.find_first_of("BlockchainTests") != std::string::npos)
{
dev::test::BlockchainTestSuite suite;
suite.runTestWithoutFiller(file);
}
else if (opt.rCurrentTestSuite.find_first_of("TransitionTests") != std::string::npos)
{
dev::test::TransitionTestsSuite suite;
suite.runTestWithoutFiller(file);
}
else if (opt.rCurrentTestSuite.find_first_of("VMtests") != std::string::npos)
{
dev::test::VmTestSuite suite;
suite.runTestWithoutFiller(file);
}
else if (opt.rCurrentTestSuite.find_first_of("TransactionTests") != std::string::npos)
{
dev::test::TransactionTestSuite suite;
suite.runTestWithoutFiller(file);
}
}
}
void travisOut(std::atomic_bool* _stopTravisOut)
{
int tickCounter = 0;
while (!*_stopTravisOut)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
++tickCounter;
if (tickCounter % 10 == 0)
std::cout << ".\n" << std::flush; // Output dot every 10s.
}
}
/*
The equivalent of setlocale(LC_ALL, “C”) is called before any user code is run.
If the user has an invalid environment setting then it is possible for the call
to set locale to fail, so there are only two possible actions, the first is to
throw a runtime exception and cause the program to quit (default behaviour),
or the second is to modify the environment to something sensible (least
surprising behaviour).
The follow code produces the least surprising behaviour. It will use the user
specified default locale if it is valid, and if not then it will modify the
environment the process is running in to use a sensible default. This also means
that users do not need to install language packs for their OS.
*/
void setDefaultOrCLocale()
{
#if __unix__
if (!std::setlocale(LC_ALL, ""))
{
setenv("LC_ALL", "C", 1);
}
#endif
}
// Custom Boost Unit Test Main
int main(int argc, const char* argv[])
{
std::string const dynamicTestSuiteName = "customTestSuite";
setDefaultOrCLocale();
// Initialize options
try
{
dev::test::Options::get(argc, argv);
}
catch (dev::test::InvalidOption const& e)
{
std::cerr << *boost::get_error_info<errinfo_comment>(e) << "\n";
exit(1);
}
dev::test::Options const& opt = dev::test::Options::get();
if (opt.createRandomTest || opt.singleTestFile.is_initialized())
{
bool testSuiteFound = false;
for (int i = 0; i < argc; i++)
{
// replace test suite to custom tests
std::string arg = std::string{argv[i]};
if (arg == "-t" && i + 1 < argc)
{
testSuiteFound = true;
argv[i + 1] = (char*)dynamicTestSuiteName.c_str();
break;
}
}
// BOOST ERROR could not be used here because boost main is not initialized
if (!testSuiteFound && opt.createRandomTest)
{
std::cerr << "createRandomTest requires a test suite to be set -t <TestSuite>\n";
return -1;
}
if (!testSuiteFound && opt.singleTestFile.is_initialized())
{
std::cerr
<< "singletest <file> <testname> requires a test suite to be set -t <TestSuite>\n";
return -1;
}
// Disable initial output as the random test will output valid json to std
oldCoutStreamBuf = std::cout.rdbuf();
oldCerrStreamBuf = std::cerr.rdbuf();
std::cout.rdbuf(strCout.rdbuf());
std::cerr.rdbuf(strCout.rdbuf());
// add custom test suite
test_suite* ts1 = BOOST_TEST_SUITE("customTestSuite");
ts1->add(BOOST_TEST_CASE(&customTestSuite));
framework::master_test_suite().add(ts1);
}
std::cout << "Running tests using path: " << test::getTestPath() << std::endl;
int result = 0;
auto fakeInit = [](int, char* []) -> boost::unit_test::test_suite* { return nullptr; };
if (opt.jsontrace || opt.vmtrace || opt.statediff)
{
// Do not use travis '.' output thread if debug is defined
result = unit_test_main(fakeInit, argc, const_cast<char**>(argv));
dev::test::TestOutputHelper::get().printTestExecStats();
return result;
}
else
{
// Initialize travis '.' output thread for log activity
std::atomic_bool stopTravisOut{false};
std::thread outputThread(travisOut, &stopTravisOut);
result = unit_test_main(fakeInit, argc, const_cast<char**>(argv));
stopTravisOut = true;
outputThread.join();
dev::test::TestOutputHelper::get().printTestExecStats();
return result;
}
}