| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // This program contains several "tests" that exercise tracing functionality. |
| // Each test is composed of two pieces: a runner and a verifier. |
| // Each test is spawned by trace_system_test twice: once to run the runner |
| // and once to run the verifier. When run as a "runner" this program is |
| // actually spawned by "trace record". When run as a "verifier", this program |
| // is invoked directly by trace_system_test. |
| // See |kUsageString| for usage instructions. |
| // |
| // The tests are currently combined into one binary because there aren't |
| // that many and they share enough code. KISS. |
| |
| #include <stdlib.h> |
| #include <iostream> |
| |
| #include <lib/fxl/command_line.h> |
| #include <lib/fxl/files/file.h> |
| #include <lib/fxl/log_settings.h> |
| #include <lib/fxl/log_settings_command_line.h> |
| #include <lib/fxl/logging.h> |
| |
| #include "garnet/bin/trace/spec.h" |
| #include "garnet/bin/trace/tests/integration_test_utils.h" |
| |
| const char kUsageString[] = { |
| "Test runner usage:\n" |
| " $program [options] run tspec-file\n" |
| "\n" |
| "Test verifier usage:\n" |
| " $program [options] verify tspec-file trace-output-file\n" |
| "\n" |
| "Options:\n" |
| " --quiet[=LEVEL] set quietness level (opposite of verbose)\n" |
| " --verbose[=LEVEL] set debug verbosity level\n" |
| " --log-file=FILE write log output to FILE\n"}; |
| |
| static int RunTest(const tracing::Spec& spec, TestRunner* run) { |
| bool success = run(spec); |
| return success ? EXIT_SUCCESS : EXIT_FAILURE; |
| } |
| |
| static int VerifyTest(const tracing::Spec& spec, TestVerifier* verify, |
| const std::string& test_output_file) { |
| if (!verify(spec, test_output_file)) |
| return EXIT_FAILURE; |
| return EXIT_SUCCESS; |
| } |
| |
| static void PrintUsageString() { std::cout << kUsageString << std::endl; } |
| |
| int main(int argc, char* argv[]) { |
| fxl::CommandLine cl = fxl::CommandLineFromArgcArgv(argc, argv); |
| |
| if (!fxl::SetLogSettingsFromCommandLine(cl)) |
| return EXIT_FAILURE; |
| |
| if (cl.HasOption("help", nullptr)) { |
| PrintUsageString(); |
| return EXIT_SUCCESS; |
| } |
| |
| auto args = cl.positional_args(); |
| |
| if (args.size() < 2) { |
| PrintUsageString(); |
| return EXIT_FAILURE; |
| } |
| |
| const std::string command = args[0]; |
| const std::string spec_file_path = args[1]; |
| |
| if (command == "run") { |
| if (args.size() != 2) { |
| FXL_LOG(ERROR) << "Wrong number of arguments to run invocation"; |
| return EXIT_FAILURE; |
| } |
| } else if (command == "verify") { |
| if (args.size() != 3) { |
| FXL_LOG(ERROR) << "Wrong number of arguments to verify invocation"; |
| return EXIT_FAILURE; |
| } |
| } else { |
| FXL_LOG(ERROR) << "Unknown command: " << command; |
| return EXIT_FAILURE; |
| } |
| |
| std::string spec_file_contents; |
| if (!files::ReadFileToString(spec_file_path, &spec_file_contents)) { |
| FXL_LOG(ERROR) << "Can't read test spec: " << spec_file_path; |
| return EXIT_FAILURE; |
| } |
| |
| tracing::Spec spec; |
| if (!tracing::DecodeSpec(spec_file_contents, &spec)) { |
| FXL_LOG(ERROR) << "Error decoding test spec: " << spec_file_path; |
| return EXIT_FAILURE; |
| } |
| |
| FXL_DCHECK(spec.test_name); |
| auto test_name = *spec.test_name; |
| |
| auto test = LookupTest(test_name); |
| if (test == nullptr) { |
| FXL_LOG(ERROR) << "Unknown test name: " << test_name; |
| return EXIT_FAILURE; |
| } |
| |
| if (command == "run") { |
| FXL_VLOG(1) << "Running subprogram for test " << spec_file_path << ":\"" |
| << test_name << "\""; |
| return RunTest(spec, test->run); |
| } else { |
| FXL_VLOG(1) << "Verifying test " << spec_file_path << ":\"" << test_name |
| << "\""; |
| const std::string& trace_output_file = args[2]; |
| return VerifyTest(spec, test->verify, trace_output_file); |
| } |
| } |