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