1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include <getopt.h> 17 18 #include "VtsCoverageProcessor.h" 19 #include "VtsTraceProcessor.h" 20 21 static constexpr const char* kDefaultMode = "noop"; 22 static constexpr const char* kDefaultOutputFile = 23 "/temp/vts_trace_processor_output"; 24 25 using namespace std; 26 27 enum mode_code { 28 // Trace related operations. 29 CLEANUP_TRACE, 30 CONVERT_TRACE, 31 DEDUPE_TRACE, 32 GET_TEST_LIST_FROM_TRACE, 33 PARSE_TRACE, 34 PROFILING_TRACE, 35 SELECT_TRACE, 36 // Coverage related operations. 37 COMPARE_COVERAGE, 38 GET_COVERGAGE_SUMMARY, 39 GET_SUBSET_COVERAGE, 40 MERGE_COVERAGE, 41 }; 42 43 mode_code getModeCode(const std::string& str) { 44 if (str == "cleanup_trace") return mode_code::CLEANUP_TRACE; 45 if (str == "convert_trace") return mode_code::CONVERT_TRACE; 46 if (str == "dedup_trace") return mode_code::DEDUPE_TRACE; 47 if (str == "get_test_list_from_trace") 48 return mode_code::GET_TEST_LIST_FROM_TRACE; 49 if (str == "parse_trace") return mode_code::PARSE_TRACE; 50 if (str == "profiling_trace") return mode_code::PROFILING_TRACE; 51 if (str == "select_trace") return mode_code::SELECT_TRACE; 52 if (str == "compare_coverage") return mode_code::COMPARE_COVERAGE; 53 if (str == "get_coverage_summary") return mode_code::GET_COVERGAGE_SUMMARY; 54 if (str == "get_subset_coverage") return mode_code::GET_SUBSET_COVERAGE; 55 if (str == "merge_coverage") return mode_code::MERGE_COVERAGE; 56 printf("Unknown operation mode: %s\n", str.c_str()); 57 exit(-1); 58 } 59 60 void ShowUsage() { 61 printf( 62 "Usage: trace_processor [options] <input>\n" 63 "--mode: The operation applied to the trace file.\n" 64 "\t cleanup_trace: cleanup trace for replay (remove duplicate events " 65 "etc.).\n" 66 "\t convert_trace: convert a text format trace file into a binary format " 67 "trace.\n" 68 "\t dedup_trace: remove duplicate trace file in the given directory. A " 69 "trace is considered duplicated if there exists a trace that contains " 70 "the " 71 "same API call sequence as the given trace and the input parameters for " 72 "each API call are all the same.\n" 73 "\t get_test_list_from_trace: parse all trace files under the given " 74 "directory and create a list of test modules for each hal@version that " 75 "access all apis covered by the whole test set. (i.e. such list should " 76 "be a subset of the whole test list that access the corresponding " 77 "hal@version)\n" 78 "\t parse_trace: parse the binary format trace file and print the text " 79 "format trace. \n" 80 "\t profiling_trace: parse the trace file to get the latency of each api " 81 "call.\n" 82 "\t select_trace: select a subset of trace files from a give trace set " 83 "based on their corresponding coverage data, the goal is to pick up the " 84 "minimal num of trace files that to maximize the total coverage.\n" 85 "\t compare_coverage: compare a coverage report with a reference " 86 "coverage report and print the additional file/lines covered.\n" 87 "\t get_coverage_summary: print the summary of the coverage file (e.g. " 88 "covered lines, total lines, coverage rate.) \n" 89 "\t get_subset_coverage: extract coverage measurement from coverage " 90 "report for files covered in the reference coverage report. It is used " 91 "in cases when we have an aggregated coverage report for all files but " 92 "are only interested in the coverage measurement of a subset of files in " 93 "that report.\n" 94 "\t merge_coverage: merge all coverage reports under the given directory " 95 "and generate a merged report.\n" 96 "--output: The file path to store the output results.\n" 97 "--help: Show help\n"); 98 exit(-1); 99 } 100 101 int main(int argc, char** argv) { 102 string mode = kDefaultMode; 103 string output = kDefaultOutputFile; 104 bool verbose_output = false; 105 106 android::vts::VtsCoverageProcessor coverage_processor; 107 android::vts::VtsTraceProcessor trace_processor(&coverage_processor); 108 109 const char* const short_opts = "hm:o:v:"; 110 const option long_opts[] = { 111 {"help", no_argument, nullptr, 'h'}, 112 {"mode", required_argument, nullptr, 'm'}, 113 {"output", required_argument, nullptr, 'o'}, 114 {"verbose", no_argument, nullptr, 'v'}, 115 {nullptr, 0, nullptr, 0}, 116 }; 117 118 while (true) { 119 int opt = getopt_long(argc, argv, short_opts, long_opts, nullptr); 120 if (opt == -1) { 121 break; 122 } 123 switch (opt) { 124 case 'h': 125 case '?': 126 ShowUsage(); 127 return 0; 128 case 'm': { 129 mode = string(optarg); 130 break; 131 } 132 case 'o': { 133 output = string(optarg); 134 break; 135 } 136 case 'v': { 137 verbose_output = true; 138 break; 139 } 140 default: 141 printf("getopt_long returned unexpected value: %d\n", opt); 142 return -1; 143 } 144 } 145 146 if (optind == argc - 1) { 147 string trace_path = argv[optind]; 148 switch (getModeCode(mode)) { 149 case mode_code::CLEANUP_TRACE: 150 trace_processor.CleanupTraces(trace_path); 151 break; 152 case mode_code::CONVERT_TRACE: 153 trace_processor.ConvertTrace(trace_path); 154 break; 155 case mode_code::DEDUPE_TRACE: 156 trace_processor.DedupTraces(trace_path); 157 break; 158 case mode_code::GET_TEST_LIST_FROM_TRACE: 159 trace_processor.GetTestListForHal(trace_path, output, verbose_output); 160 break; 161 case mode_code::PARSE_TRACE: 162 trace_processor.ParseTrace(trace_path); 163 break; 164 case mode_code::PROFILING_TRACE: 165 trace_processor.ProcessTraceForLatencyProfiling(trace_path); 166 break; 167 case mode_code::GET_COVERGAGE_SUMMARY: 168 coverage_processor.GetCoverageSummary(trace_path); 169 break; 170 case mode_code::MERGE_COVERAGE: 171 coverage_processor.MergeCoverage(trace_path, output); 172 break; 173 default: 174 printf("Invalid argument."); 175 return -1; 176 } 177 } else if (optind == argc - 2) { 178 switch (getModeCode(mode)) { 179 case mode_code::SELECT_TRACE: { 180 string coverage_dir = argv[optind]; 181 string trace_dir = argv[optind + 1]; 182 trace_processor.SelectTraces(coverage_dir, trace_dir); 183 break; 184 } 185 case mode_code::COMPARE_COVERAGE: { 186 string ref_coverage_path = argv[optind]; 187 string coverage_path = argv[optind + 1]; 188 coverage_processor.CompareCoverage(ref_coverage_path, coverage_path); 189 break; 190 } 191 case mode_code::GET_SUBSET_COVERAGE: { 192 string ref_coverage_path = argv[optind]; 193 string coverage_path = argv[optind + 1]; 194 coverage_processor.GetSubsetCoverage(ref_coverage_path, coverage_path, 195 output); 196 break; 197 } 198 default: 199 printf("Invalid argument."); 200 return -1; 201 } 202 } 203 return 0; 204 } 205