/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <getopt.h> #include "VtsCoverageProcessor.h" #include "VtsTraceProcessor.h" static constexpr const char* kDefaultMode = "noop"; static constexpr const char* kDefaultOutputFile = "/temp/vts_trace_processor_output"; using namespace std; enum mode_code { // Trace related operations. CLEANUP_TRACE, CONVERT_TRACE, DEDUPE_TRACE, GET_TEST_LIST_FROM_TRACE, PARSE_TRACE, PROFILING_TRACE, SELECT_TRACE, // Coverage related operations. COMPARE_COVERAGE, GET_COVERGAGE_SUMMARY, GET_SUBSET_COVERAGE, MERGE_COVERAGE, }; mode_code getModeCode(const std::string& str) { if (str == "cleanup_trace") return mode_code::CLEANUP_TRACE; if (str == "convert_trace") return mode_code::CONVERT_TRACE; if (str == "dedup_trace") return mode_code::DEDUPE_TRACE; if (str == "get_test_list_from_trace") return mode_code::GET_TEST_LIST_FROM_TRACE; if (str == "parse_trace") return mode_code::PARSE_TRACE; if (str == "profiling_trace") return mode_code::PROFILING_TRACE; if (str == "select_trace") return mode_code::SELECT_TRACE; if (str == "compare_coverage") return mode_code::COMPARE_COVERAGE; if (str == "get_coverage_summary") return mode_code::GET_COVERGAGE_SUMMARY; if (str == "get_subset_coverage") return mode_code::GET_SUBSET_COVERAGE; if (str == "merge_coverage") return mode_code::MERGE_COVERAGE; printf("Unknown operation mode: %s\n", str.c_str()); exit(-1); } void ShowUsage() { printf( "Usage: trace_processor [options] <input>\n" "--mode: The operation applied to the trace file.\n" "\t cleanup_trace: cleanup trace for replay (remove duplicate events " "etc.).\n" "\t convert_trace: convert a text format trace file into a binary format " "trace.\n" "\t dedup_trace: remove duplicate trace file in the given directory. A " "trace is considered duplicated if there exists a trace that contains " "the " "same API call sequence as the given trace and the input parameters for " "each API call are all the same.\n" "\t get_test_list_from_trace: parse all trace files under the given " "directory and create a list of test modules for each hal@version that " "access all apis covered by the whole test set. (i.e. such list should " "be a subset of the whole test list that access the corresponding " "hal@version)\n" "\t parse_trace: parse the binary format trace file and print the text " "format trace. \n" "\t profiling_trace: parse the trace file to get the latency of each api " "call.\n" "\t select_trace: select a subset of trace files from a give trace set " "based on their corresponding coverage data, the goal is to pick up the " "minimal num of trace files that to maximize the total coverage.\n" "\t compare_coverage: compare a coverage report with a reference " "coverage report and print the additional file/lines covered.\n" "\t get_coverage_summary: print the summary of the coverage file (e.g. " "covered lines, total lines, coverage rate.) \n" "\t get_subset_coverage: extract coverage measurement from coverage " "report for files covered in the reference coverage report. It is used " "in cases when we have an aggregated coverage report for all files but " "are only interested in the coverage measurement of a subset of files in " "that report.\n" "\t merge_coverage: merge all coverage reports under the given directory " "and generate a merged report.\n" "--output: The file path to store the output results.\n" "--help: Show help\n"); exit(-1); } int main(int argc, char** argv) { string mode = kDefaultMode; string output = kDefaultOutputFile; bool verbose_output = false; android::vts::VtsCoverageProcessor coverage_processor; android::vts::VtsTraceProcessor trace_processor(&coverage_processor); const char* const short_opts = "hm:o:v:"; const option long_opts[] = { {"help", no_argument, nullptr, 'h'}, {"mode", required_argument, nullptr, 'm'}, {"output", required_argument, nullptr, 'o'}, {"verbose", no_argument, nullptr, 'v'}, {nullptr, 0, nullptr, 0}, }; while (true) { int opt = getopt_long(argc, argv, short_opts, long_opts, nullptr); if (opt == -1) { break; } switch (opt) { case 'h': case '?': ShowUsage(); return 0; case 'm': { mode = string(optarg); break; } case 'o': { output = string(optarg); break; } case 'v': { verbose_output = true; break; } default: printf("getopt_long returned unexpected value: %d\n", opt); return -1; } } if (optind == argc - 1) { string trace_path = argv[optind]; switch (getModeCode(mode)) { case mode_code::CLEANUP_TRACE: trace_processor.CleanupTraces(trace_path); break; case mode_code::CONVERT_TRACE: trace_processor.ConvertTrace(trace_path); break; case mode_code::DEDUPE_TRACE: trace_processor.DedupTraces(trace_path); break; case mode_code::GET_TEST_LIST_FROM_TRACE: trace_processor.GetTestListForHal(trace_path, output, verbose_output); break; case mode_code::PARSE_TRACE: trace_processor.ParseTrace(trace_path); break; case mode_code::PROFILING_TRACE: trace_processor.ProcessTraceForLatencyProfiling(trace_path); break; case mode_code::GET_COVERGAGE_SUMMARY: coverage_processor.GetCoverageSummary(trace_path); break; case mode_code::MERGE_COVERAGE: coverage_processor.MergeCoverage(trace_path, output); break; default: printf("Invalid argument."); return -1; } } else if (optind == argc - 2) { switch (getModeCode(mode)) { case mode_code::SELECT_TRACE: { string coverage_dir = argv[optind]; string trace_dir = argv[optind + 1]; trace_processor.SelectTraces(coverage_dir, trace_dir); break; } case mode_code::COMPARE_COVERAGE: { string ref_coverage_path = argv[optind]; string coverage_path = argv[optind + 1]; coverage_processor.CompareCoverage(ref_coverage_path, coverage_path); break; } case mode_code::GET_SUBSET_COVERAGE: { string ref_coverage_path = argv[optind]; string coverage_path = argv[optind + 1]; coverage_processor.GetSubsetCoverage(ref_coverage_path, coverage_path, output); break; } default: printf("Invalid argument."); return -1; } } return 0; }