xref: /aosp_15_r20/external/vixl/test/test-runner.cc (revision f5c631da2f1efdd72b5fd1e20510e4042af13d77)
1*f5c631daSSadaf Ebrahimi // Copyright 2014, VIXL authors
2*f5c631daSSadaf Ebrahimi // All rights reserved.
3*f5c631daSSadaf Ebrahimi //
4*f5c631daSSadaf Ebrahimi // Redistribution and use in source and binary forms, with or without
5*f5c631daSSadaf Ebrahimi // modification, are permitted provided that the following conditions are met:
6*f5c631daSSadaf Ebrahimi //
7*f5c631daSSadaf Ebrahimi //   * Redistributions of source code must retain the above copyright notice,
8*f5c631daSSadaf Ebrahimi //     this list of conditions and the following disclaimer.
9*f5c631daSSadaf Ebrahimi //   * Redistributions in binary form must reproduce the above copyright notice,
10*f5c631daSSadaf Ebrahimi //     this list of conditions and the following disclaimer in the documentation
11*f5c631daSSadaf Ebrahimi //     and/or other materials provided with the distribution.
12*f5c631daSSadaf Ebrahimi //   * Neither the name of ARM Limited nor the names of its contributors may be
13*f5c631daSSadaf Ebrahimi //     used to endorse or promote products derived from this software without
14*f5c631daSSadaf Ebrahimi //     specific prior written permission.
15*f5c631daSSadaf Ebrahimi //
16*f5c631daSSadaf Ebrahimi // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17*f5c631daSSadaf Ebrahimi // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18*f5c631daSSadaf Ebrahimi // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19*f5c631daSSadaf Ebrahimi // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20*f5c631daSSadaf Ebrahimi // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*f5c631daSSadaf Ebrahimi // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22*f5c631daSSadaf Ebrahimi // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23*f5c631daSSadaf Ebrahimi // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24*f5c631daSSadaf Ebrahimi // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25*f5c631daSSadaf Ebrahimi // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*f5c631daSSadaf Ebrahimi 
27*f5c631daSSadaf Ebrahimi #include <cstdio>
28*f5c631daSSadaf Ebrahimi #include <cstdlib>
29*f5c631daSSadaf Ebrahimi #include <cstring>
30*f5c631daSSadaf Ebrahimi 
31*f5c631daSSadaf Ebrahimi #include "test-runner.h"
32*f5c631daSSadaf Ebrahimi 
33*f5c631daSSadaf Ebrahimi // Initialize the list as empty.
34*f5c631daSSadaf Ebrahimi vixl::Test* vixl::Test::first_ = NULL;
35*f5c631daSSadaf Ebrahimi vixl::Test* vixl::Test::last_ = NULL;
36*f5c631daSSadaf Ebrahimi 
37*f5c631daSSadaf Ebrahimi bool vixl::Test::verbose_ = false;
38*f5c631daSSadaf Ebrahimi 
39*f5c631daSSadaf Ebrahimi // No tracing to start with.
40*f5c631daSSadaf Ebrahimi bool vixl::Test::trace_sim_ = false;
41*f5c631daSSadaf Ebrahimi bool vixl::Test::trace_reg_ = false;
42*f5c631daSSadaf Ebrahimi bool vixl::Test::trace_write_ = false;
43*f5c631daSSadaf Ebrahimi bool vixl::Test::trace_branch_ = false;
44*f5c631daSSadaf Ebrahimi 
45*f5c631daSSadaf Ebrahimi // Do not disassemble by default.
46*f5c631daSSadaf Ebrahimi bool vixl::Test::disassemble_ = false;
47*f5c631daSSadaf Ebrahimi bool vixl::Test::disassemble_infrastructure_ = false;
48*f5c631daSSadaf Ebrahimi 
49*f5c631daSSadaf Ebrahimi // No colour highlight by default.
50*f5c631daSSadaf Ebrahimi bool vixl::Test::coloured_trace_ = false;
51*f5c631daSSadaf Ebrahimi 
52*f5c631daSSadaf Ebrahimi // Don't generate traces by default.
53*f5c631daSSadaf Ebrahimi bool vixl::Test::generate_test_trace_ = false;
54*f5c631daSSadaf Ebrahimi 
55*f5c631daSSadaf Ebrahimi // Look for 'search' in the arguments.
IsInArgs(const char * search,int argc,char * argv[])56*f5c631daSSadaf Ebrahimi static bool IsInArgs(const char* search, int argc, char* argv[]) {
57*f5c631daSSadaf Ebrahimi   for (int i = 1; i < argc; i++) {
58*f5c631daSSadaf Ebrahimi     if (strcmp(search, argv[i]) == 0) {
59*f5c631daSSadaf Ebrahimi       return true;
60*f5c631daSSadaf Ebrahimi     }
61*f5c631daSSadaf Ebrahimi   }
62*f5c631daSSadaf Ebrahimi   return false;
63*f5c631daSSadaf Ebrahimi }
64*f5c631daSSadaf Ebrahimi 
65*f5c631daSSadaf Ebrahimi 
IsOption(const char * arg)66*f5c631daSSadaf Ebrahimi static bool IsOption(const char* arg) {
67*f5c631daSSadaf Ebrahimi   // Any argument like "--option" is an option.
68*f5c631daSSadaf Ebrahimi   return ((arg[0] == '-') && (arg[1] == '-'));
69*f5c631daSSadaf Ebrahimi }
70*f5c631daSSadaf Ebrahimi 
71*f5c631daSSadaf Ebrahimi 
NormalizeOption(char * arg)72*f5c631daSSadaf Ebrahimi static void NormalizeOption(char* arg) {
73*f5c631daSSadaf Ebrahimi   // Squash all '_' characters in options. This allows --trace_sim and
74*f5c631daSSadaf Ebrahimi   // --trace-sim to be handled in the same way, for example.
75*f5c631daSSadaf Ebrahimi   VIXL_ASSERT(IsOption(arg));
76*f5c631daSSadaf Ebrahimi   for (char* c = arg; *c != '\0'; c++) {
77*f5c631daSSadaf Ebrahimi     if (*c == '_') {
78*f5c631daSSadaf Ebrahimi       *c = '-';
79*f5c631daSSadaf Ebrahimi     }
80*f5c631daSSadaf Ebrahimi   }
81*f5c631daSSadaf Ebrahimi }
82*f5c631daSSadaf Ebrahimi 
83*f5c631daSSadaf Ebrahimi 
PrintHelpMessage()84*f5c631daSSadaf Ebrahimi static void PrintHelpMessage() {
85*f5c631daSSadaf Ebrahimi   printf(
86*f5c631daSSadaf Ebrahimi       "Usage:  ./test [options] [test names]\n"
87*f5c631daSSadaf Ebrahimi       "Run all tests specified on the command line.\n"
88*f5c631daSSadaf Ebrahimi       "--help                   Print this help message.\n"
89*f5c631daSSadaf Ebrahimi       "--list                   List all available tests.\n"
90*f5c631daSSadaf Ebrahimi       "--run_all                Run all available tests.\n"
91*f5c631daSSadaf Ebrahimi       "--verbose                Print verbose output when available.\n"
92*f5c631daSSadaf Ebrahimi       "--trace_all              "
93*f5c631daSSadaf Ebrahimi       "Enable all trace options, plus --coloured_trace.\n"
94*f5c631daSSadaf Ebrahimi       "--trace_sim              "
95*f5c631daSSadaf Ebrahimi       "Generate a trace of simulated instructions, as\n"
96*f5c631daSSadaf Ebrahimi       "                         well as disassembly from the DISASM tests.\n"
97*f5c631daSSadaf Ebrahimi       "--trace_reg              Generate a trace of simulated registers.\n"
98*f5c631daSSadaf Ebrahimi       "--trace_write            Generate a trace of memory writes.\n"
99*f5c631daSSadaf Ebrahimi       "--trace_branch           Generate a trace of branches taken.\n"
100*f5c631daSSadaf Ebrahimi       "--disassemble            Disassemble and print generated instructions.\n"
101*f5c631daSSadaf Ebrahimi       "--disassemble-test-code  "
102*f5c631daSSadaf Ebrahimi       "As above, but don't disassemble infrastructure code.\n"
103*f5c631daSSadaf Ebrahimi       "--coloured_trace         Generate coloured trace.\n"
104*f5c631daSSadaf Ebrahimi       "--generate_test_trace    "
105*f5c631daSSadaf Ebrahimi       "Print result traces for SIM_* and TRACE_* tests.\n");
106*f5c631daSSadaf Ebrahimi }
107*f5c631daSSadaf Ebrahimi 
main(int argc,char * argv[])108*f5c631daSSadaf Ebrahimi int main(int argc, char* argv[]) {
109*f5c631daSSadaf Ebrahimi   // Parse the arguments. Option flags must appear first, followed by an
110*f5c631daSSadaf Ebrahimi   // optional list of tests to run.
111*f5c631daSSadaf Ebrahimi 
112*f5c631daSSadaf Ebrahimi   int test_specifiers = 0;
113*f5c631daSSadaf Ebrahimi   for (int i = 1; i < argc; i++) {
114*f5c631daSSadaf Ebrahimi     if (IsOption(argv[i])) {
115*f5c631daSSadaf Ebrahimi       NormalizeOption(argv[i]);
116*f5c631daSSadaf Ebrahimi     } else {
117*f5c631daSSadaf Ebrahimi       // Anything that isn't an option is a test specifier.
118*f5c631daSSadaf Ebrahimi       test_specifiers++;
119*f5c631daSSadaf Ebrahimi     }
120*f5c631daSSadaf Ebrahimi   }
121*f5c631daSSadaf Ebrahimi 
122*f5c631daSSadaf Ebrahimi   // Options controlling test conditions and debug output.
123*f5c631daSSadaf Ebrahimi 
124*f5c631daSSadaf Ebrahimi   if (IsInArgs("--trace-all", argc, argv)) {
125*f5c631daSSadaf Ebrahimi     vixl::Test::set_trace_reg(true);
126*f5c631daSSadaf Ebrahimi     vixl::Test::set_trace_write(true);
127*f5c631daSSadaf Ebrahimi     vixl::Test::set_trace_branch(true);
128*f5c631daSSadaf Ebrahimi     vixl::Test::set_trace_sim(true);
129*f5c631daSSadaf Ebrahimi     vixl::Test::set_coloured_trace(true);
130*f5c631daSSadaf Ebrahimi   }
131*f5c631daSSadaf Ebrahimi 
132*f5c631daSSadaf Ebrahimi   if (IsInArgs("--coloured-trace", argc, argv)) {
133*f5c631daSSadaf Ebrahimi     vixl::Test::set_coloured_trace(true);
134*f5c631daSSadaf Ebrahimi   }
135*f5c631daSSadaf Ebrahimi 
136*f5c631daSSadaf Ebrahimi   if (IsInArgs("--verbose", argc, argv)) {
137*f5c631daSSadaf Ebrahimi     vixl::Test::set_verbose(true);
138*f5c631daSSadaf Ebrahimi   }
139*f5c631daSSadaf Ebrahimi 
140*f5c631daSSadaf Ebrahimi   if (IsInArgs("--trace-write", argc, argv)) {
141*f5c631daSSadaf Ebrahimi     vixl::Test::set_trace_write(true);
142*f5c631daSSadaf Ebrahimi   }
143*f5c631daSSadaf Ebrahimi 
144*f5c631daSSadaf Ebrahimi   if (IsInArgs("--trace-branch", argc, argv)) {
145*f5c631daSSadaf Ebrahimi     vixl::Test::set_trace_branch(true);
146*f5c631daSSadaf Ebrahimi   }
147*f5c631daSSadaf Ebrahimi 
148*f5c631daSSadaf Ebrahimi   if (IsInArgs("--trace-reg", argc, argv)) {
149*f5c631daSSadaf Ebrahimi     vixl::Test::set_trace_reg(true);
150*f5c631daSSadaf Ebrahimi   }
151*f5c631daSSadaf Ebrahimi 
152*f5c631daSSadaf Ebrahimi   if (IsInArgs("--trace-sim", argc, argv)) {
153*f5c631daSSadaf Ebrahimi     vixl::Test::set_trace_sim(true);
154*f5c631daSSadaf Ebrahimi   }
155*f5c631daSSadaf Ebrahimi 
156*f5c631daSSadaf Ebrahimi   if (IsInArgs("--disassemble", argc, argv)) {
157*f5c631daSSadaf Ebrahimi     vixl::Test::set_disassemble(true);
158*f5c631daSSadaf Ebrahimi     vixl::Test::set_disassemble_infrastructure(true);
159*f5c631daSSadaf Ebrahimi   } else if (IsInArgs("--disassemble-test-code", argc, argv)) {
160*f5c631daSSadaf Ebrahimi     vixl::Test::set_disassemble(true);
161*f5c631daSSadaf Ebrahimi     vixl::Test::set_disassemble_infrastructure(false);
162*f5c631daSSadaf Ebrahimi   }
163*f5c631daSSadaf Ebrahimi 
164*f5c631daSSadaf Ebrahimi   if (IsInArgs("--generate-test-trace", argc, argv)) {
165*f5c631daSSadaf Ebrahimi     vixl::Test::set_generate_test_trace(true);
166*f5c631daSSadaf Ebrahimi   }
167*f5c631daSSadaf Ebrahimi 
168*f5c631daSSadaf Ebrahimi   // Basic (mutually-exclusive) operations.
169*f5c631daSSadaf Ebrahimi 
170*f5c631daSSadaf Ebrahimi   if (IsInArgs("--help", argc, argv)) {
171*f5c631daSSadaf Ebrahimi     PrintHelpMessage();
172*f5c631daSSadaf Ebrahimi 
173*f5c631daSSadaf Ebrahimi   } else if (IsInArgs("--list", argc, argv)) {
174*f5c631daSSadaf Ebrahimi     // List all registered tests, then exit.
175*f5c631daSSadaf Ebrahimi     for (vixl::Test* c = vixl::Test::first(); c != NULL; c = c->next()) {
176*f5c631daSSadaf Ebrahimi       printf("%s\n", c->name());
177*f5c631daSSadaf Ebrahimi     }
178*f5c631daSSadaf Ebrahimi 
179*f5c631daSSadaf Ebrahimi   } else if (IsInArgs("--run-all", argc, argv)) {
180*f5c631daSSadaf Ebrahimi     // Run all registered tests.
181*f5c631daSSadaf Ebrahimi     for (vixl::Test* c = vixl::Test::first(); c != NULL; c = c->next()) {
182*f5c631daSSadaf Ebrahimi       printf("Running %s\n", c->name());
183*f5c631daSSadaf Ebrahimi       c->run();
184*f5c631daSSadaf Ebrahimi     }
185*f5c631daSSadaf Ebrahimi 
186*f5c631daSSadaf Ebrahimi   } else {
187*f5c631daSSadaf Ebrahimi     // Run the specified tests.
188*f5c631daSSadaf Ebrahimi     if (test_specifiers == 0) {
189*f5c631daSSadaf Ebrahimi       printf("No tests specified.\n");
190*f5c631daSSadaf Ebrahimi       PrintHelpMessage();
191*f5c631daSSadaf Ebrahimi       return EXIT_FAILURE;
192*f5c631daSSadaf Ebrahimi     }
193*f5c631daSSadaf Ebrahimi 
194*f5c631daSSadaf Ebrahimi     for (int i = 1; i < argc; i++) {
195*f5c631daSSadaf Ebrahimi       if (!IsOption(argv[i])) {
196*f5c631daSSadaf Ebrahimi         vixl::Test* c;
197*f5c631daSSadaf Ebrahimi         for (c = vixl::Test::first(); c != NULL; c = c->next()) {
198*f5c631daSSadaf Ebrahimi           if (strcmp(c->name(), argv[i]) == 0) {
199*f5c631daSSadaf Ebrahimi             c->run();
200*f5c631daSSadaf Ebrahimi             break;
201*f5c631daSSadaf Ebrahimi           }
202*f5c631daSSadaf Ebrahimi         }
203*f5c631daSSadaf Ebrahimi         // Fail if we have not found a matching test to run.
204*f5c631daSSadaf Ebrahimi         if (c == NULL) {
205*f5c631daSSadaf Ebrahimi           printf("Test '%s' does not exist. Aborting...\n", argv[i]);
206*f5c631daSSadaf Ebrahimi           abort();
207*f5c631daSSadaf Ebrahimi         }
208*f5c631daSSadaf Ebrahimi       }
209*f5c631daSSadaf Ebrahimi     }
210*f5c631daSSadaf Ebrahimi   }
211*f5c631daSSadaf Ebrahimi 
212*f5c631daSSadaf Ebrahimi   return EXIT_SUCCESS;
213*f5c631daSSadaf Ebrahimi }
214*f5c631daSSadaf Ebrahimi 
set_callback(TestFunction * callback)215*f5c631daSSadaf Ebrahimi void vixl::Test::set_callback(TestFunction* callback) {
216*f5c631daSSadaf Ebrahimi   callback_ = callback;
217*f5c631daSSadaf Ebrahimi   callback_with_config_ = NULL;
218*f5c631daSSadaf Ebrahimi }
219*f5c631daSSadaf Ebrahimi 
set_callback(TestFunctionWithConfig * callback)220*f5c631daSSadaf Ebrahimi void vixl::Test::set_callback(TestFunctionWithConfig* callback) {
221*f5c631daSSadaf Ebrahimi   callback_ = NULL;
222*f5c631daSSadaf Ebrahimi   callback_with_config_ = callback;
223*f5c631daSSadaf Ebrahimi }
224*f5c631daSSadaf Ebrahimi 
run()225*f5c631daSSadaf Ebrahimi void vixl::Test::run() {
226*f5c631daSSadaf Ebrahimi   if (callback_ == NULL) {
227*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(callback_with_config_ != NULL);
228*f5c631daSSadaf Ebrahimi     callback_with_config_(this);
229*f5c631daSSadaf Ebrahimi   } else {
230*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(callback_with_config_ == NULL);
231*f5c631daSSadaf Ebrahimi     callback_();
232*f5c631daSSadaf Ebrahimi   }
233*f5c631daSSadaf Ebrahimi }
234