test-runner.cc revision bc01be684fe63a8a8c785f92e8aaa080cb6e87fa
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 <cstdlib> 28#include <cstring> 29#include <cstdio> 30 31#include "test-runner.h" 32 33// Initialize the list as empty. 34vixl::Test* vixl::Test::first_ = NULL; 35vixl::Test* vixl::Test::last_ = NULL; 36 37// No debugger to start with. 38bool vixl::Test::debug_ = false; 39 40// No tracing to start with. 41bool vixl::Test::trace_sim_ = false; 42bool vixl::Test::trace_reg_ = false; 43bool vixl::Test::trace_write_ = false; 44 45// Do not disassemble by default. 46bool vixl::Test::disassemble_ = false; 47 48// No colour highlight by default. 49bool vixl::Test::coloured_trace_ = false; 50 51// No instruction statistics by default. 52bool vixl::Test::instruction_stats_ = false; 53 54// Don't generate traces by default. 55bool vixl::Test::generate_test_trace_ = false; 56 57// Instantiate a Test and append it to the linked list. 58vixl::Test::Test(const char* name, TestFunction* callback) 59 : name_(name), callback_(callback), next_(NULL) { 60 // Append this test to the linked list. 61 if (first_ == NULL) { 62 VIXL_ASSERT(last_ == NULL); 63 first_ = this; 64 } else { 65 last_->next_ = this; 66 } 67 last_ = this; 68} 69 70 71// Look for 'search' in the arguments. 72static bool IsInArgs(const char* search, int argc, char* argv[]) { 73 for (int i = 1; i < argc; i++) { 74 if (strcmp(search, argv[i]) == 0) { 75 return true; 76 } 77 } 78 return false; 79} 80 81 82static bool IsOption(const char* arg) { 83 // Any argument like "--option" is an option. 84 return ((arg[0] == '-') && (arg[1] == '-')); 85} 86 87 88static void NormalizeOption(char * arg) { 89 // Squash all '_' characters in options. This allows --trace_sim and 90 // --trace-sim to be handled in the same way, for example. 91 VIXL_ASSERT(IsOption(arg)); 92 for (char * c = arg; *c != '\0'; c++) { 93 if (*c == '_') { 94 *c = '-'; 95 } 96 } 97} 98 99 100static void PrintHelpMessage() { 101 printf("Usage: ./test [options] [test names]\n" 102 "Run all tests specified on the command line.\n" 103 "--help Print this help message.\n" 104 "--list List all available tests.\n" 105 "--run_all Run all available tests.\n" 106 "--debugger Run in the debugger.\n" 107 "--trace_all " 108 "Enable all trace options, plus --coloured_trace.\n" 109 "--trace_sim Generate a trace of simulated instructions, as\n" 110 " well as disassembly from the DISASM tests.\n" 111 "--trace_reg Generate a trace of simulated registers.\n" 112 "--trace_write Generate a trace of memory writes.\n" 113 "--disassemble Disassemble and print generated instructions.\n" 114 "--coloured_trace Generate coloured trace.\n" 115 "--instruction_stats Log instruction statistics to vixl_stats.csv.\n" 116 "--generate_test_trace " 117 "Print result traces for SIM_* and TRACE_* tests.\n"); 118} 119 120int main(int argc, char* argv[]) { 121 // Parse the arguments. Option flags must appear first, followed by an 122 // optional list of tests to run. 123 124 int test_specifiers = 0; 125 for (int i = 1; i < argc; i++) { 126 if (IsOption(argv[i])) { 127 NormalizeOption(argv[i]); 128 } else { 129 // Anything that isn't an option is a test specifier. 130 test_specifiers++; 131 } 132 } 133 134 // Options controlling test conditions and debug output. 135 136 if (IsInArgs("--trace-all", argc, argv)) { 137 vixl::Test::set_trace_reg(true); 138 vixl::Test::set_trace_write(true); 139 vixl::Test::set_trace_sim(true); 140 vixl::Test::set_coloured_trace(true); 141 } 142 143 if (IsInArgs("--coloured-trace", argc, argv)) { 144 vixl::Test::set_coloured_trace(true); 145 } 146 147 if (IsInArgs("--debugger", argc, argv)) { 148 vixl::Test::set_debug(true); 149 } 150 151 if (IsInArgs("--trace-write", argc, argv)) { 152 vixl::Test::set_trace_write(true); 153 } 154 155 if (IsInArgs("--trace-reg", argc, argv)) { 156 vixl::Test::set_trace_reg(true); 157 } 158 159 if (IsInArgs("--trace-sim", argc, argv)) { 160 vixl::Test::set_trace_sim(true); 161 } 162 163 if (IsInArgs("--disassemble", argc, argv)) { 164 vixl::Test::set_disassemble(true); 165 } 166 167 if (IsInArgs("--instruction-stats", argc, argv)) { 168 vixl::Test::set_instruction_stats(true); 169 } 170 171 if (IsInArgs("--generate-test-trace", argc, argv)) { 172 vixl::Test::set_generate_test_trace(true); 173 } 174 175 // Basic (mutually-exclusive) operations. 176 177 if (IsInArgs("--help", argc, argv)) { 178 PrintHelpMessage(); 179 180 } else if (IsInArgs("--list", argc, argv)) { 181 // List all registered tests, then exit. 182 for (vixl::Test* c = vixl::Test::first(); c != NULL; c = c->next()) { 183 printf("%s\n", c->name()); 184 } 185 186 } else if (IsInArgs("--run-all", argc, argv)) { 187 // Run all registered tests. 188 for (vixl::Test* c = vixl::Test::first(); c != NULL; c = c->next()) { 189 printf("Running %s\n", c->name()); 190 c->callback()(); 191 } 192 193 } else { 194 // Run the specified tests. 195 if (test_specifiers == 0) { 196 printf("No tests specified.\n"); 197 PrintHelpMessage(); 198 return EXIT_FAILURE; 199 } 200 201 for (int i = 1; i < argc; i++) { 202 if (!IsOption(argv[i])) { 203 vixl::Test* c; 204 for (c = vixl::Test::first(); c != NULL; c = c->next()) { 205 if (strcmp(c->name(), argv[i]) == 0) { 206 c->callback()(); 207 break; 208 } 209 } 210 // Fail if we have not found a matching test to run. 211 if (c == NULL) { 212 printf("Test '%s' does not exist. Aborting...\n", argv[i]); 213 abort(); 214 } 215 } 216 } 217 } 218 219 return EXIT_SUCCESS; 220} 221 222