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