14
14
* limitations under the License.
15
15
*/
16
16
#include " test.hh"
17
+
18
+ #include < algorithm>
19
+
17
20
#include " libdecomp.hh"
18
21
19
22
vector<UnitTest *> UnitTest::tests;
20
23
21
24
// / Run all the tests unless a non-empty set of names is passed in.
22
25
// / In which case, only the named tests in the set are run.
23
26
// / \param testNames is the set of names
24
- void UnitTest::run (set<string> &testNames)
27
+ // / \return number of failed tests
28
+ int UnitTest::run (set<string> &testNames)
25
29
26
30
{
27
31
int total = 0 ;
@@ -42,6 +46,7 @@ void UnitTest::run(set<string> &testNames)
42
46
}
43
47
std::cerr << " ==============================" << std::endl;
44
48
std::cerr << passed << " /" << total << " tests passed." << std::endl;
49
+ return total - passed;
45
50
}
46
51
47
52
// / Create list of the absolute path of all tests to be run
@@ -75,6 +80,24 @@ void gatherDataTests(const string &dirname,set<string> &testNames,vector<string>
75
80
}
76
81
}
77
82
83
+ // / \brief This function performs a saturating add on two numbers where the
84
+ // / result is to be used as an exit code for a CLI application.
85
+ // /
86
+ // / \param current The current return code
87
+ // / \param add A number to add to the current return code
88
+ // / \return A number that can be used as an exit code up to 255.
89
+ int add_exit_code (int current, int add) {
90
+ const int CLAMP = 255 ;
91
+ int ret = current + add;
92
+ if (current < 0 || // Sanity checks
93
+ current > CLAMP ||
94
+ ret < current || // Can only happen due to overflow
95
+ ret > CLAMP) { // Check clamp value
96
+ ret = CLAMP; // Set to max exit code
97
+ }
98
+ return ret;
99
+ }
100
+
78
101
int main (int argc, char **argv) {
79
102
bool runUnitTests = true ;
80
103
bool runDataTests = true ;
@@ -85,7 +108,7 @@ int main(int argc, char **argv) {
85
108
set<string> dataTestNames;
86
109
string dirname (" ../datatests" );
87
110
string sleighdirname (" ../../../../../../.." );
88
- if (argc > 0 ) {
111
+ while (argc > 0 ) {
89
112
string command (argv[0 ]);
90
113
if (command == " -path" ) {
91
114
dirname = argv[1 ];
@@ -109,30 +132,39 @@ int main(int argc, char **argv) {
109
132
argv += 1 ;
110
133
argc -= 1 ;
111
134
}
112
- }
113
- if (argc > 0 ) {
114
- string command (argv[0 ]);
115
- if (command == " unittests" ) {
135
+ else if (command == " unittests" ) {
116
136
runUnitTests = true ;
117
137
runDataTests = false ; // Run only unit tests
118
138
unitTestNames.insert (argv + 1 ,argv + argc);
139
+ break ;
119
140
}
120
141
else if (command == " datatests" ) {
121
142
runUnitTests = false ; // Run only data-tests
122
143
runDataTests = true ;
123
144
dataTestNames.insert (argv + 1 ,argv + argc);
145
+ break ;
124
146
}
125
147
else {
126
- cout << " USAGE: ghidra_test [-path <datatestdir>] [[unittests|datatests] [testname1 testname2 ...]]" << endl;
148
+ cout << " USAGE: ghidra_test [-usesleighenv] [-sleighpath <sleighdir>] [-path <datatestdir>] [[unittests|datatests] [testname1 testname2 ...]]" << endl;
149
+ return -1 ;
127
150
}
128
151
}
129
152
startDecompilerLibrary (sleighdirname.c_str ());
130
- if (runUnitTests)
131
- UnitTest::run (unitTestNames);
153
+
154
+ // Keep track of failed tests as return code to indicate failures, clamped at
155
+ // max exit code value in add_exit_code
156
+ int failedTests = 0 ;
157
+ if (runUnitTests) {
158
+ int errors = UnitTest::run (unitTestNames);
159
+ failedTests = add_exit_code (failedTests, errors);
160
+ }
132
161
if (runDataTests) {
133
162
vector<string> testFiles;
134
163
gatherDataTests (dirname,dataTestNames,testFiles);
135
164
cout << endl << endl;
136
- FunctionTestCollection::runTestFiles (testFiles,cout);
165
+ int errors = FunctionTestCollection::runTestFiles (testFiles,cout);
166
+ failedTests = add_exit_code (failedTests, errors);
137
167
}
168
+
169
+ return failedTests;
138
170
}
0 commit comments