| // Copyright 2016 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. |
| |
| #include <lib/zx/clock.h> |
| |
| #include <fbl/string.h> |
| #include <fbl/vector.h> |
| #include <runtests-utils/fuchsia-run-test.h> |
| #include <runtests-utils/log-exporter.h> |
| #include <runtests-utils/runtests-utils.h> |
| |
| namespace { |
| |
| // The name of the file containing the syslog. |
| constexpr char kSyslogFileName[] = "syslog.txt"; |
| |
| const char* kDefaultTestDirs[] = { |
| // zircon builds place everything in ramdisks so tests are located in /boot |
| "/boot/test", |
| "/boot/test/c", |
| "/boot/test/core", |
| "/boot/test/libc", |
| "/boot/test/ddk", |
| "/boot/test/sys", |
| "/boot/test/fs", |
| "/boot/test/storage", |
| // /pkgfs is where test binaries should be found in garnet and above. |
| "/pkgfs/packages/*/*/test", |
| // Moreover, for the higher layers, there are still tests using the deprecated /system image. |
| // Soon they will all be moved under /pkgfs. |
| "/system/test", |
| "/system/test/c", |
| "/system/test/core", |
| "/system/test/libc", |
| "/system/test/ddk", |
| "/system/test/sys", |
| "/system/test/fs", |
| "/system/test/storage", |
| }; |
| |
| class FuchsiaStopwatch final : public runtests::Stopwatch { |
| public: |
| FuchsiaStopwatch() { Start(); } |
| void Start() override { start_time_ = Now(); } |
| int64_t DurationInMsecs() override { return (Now() - start_time_).to_msecs(); } |
| |
| private: |
| static zx::time Now() { return zx::clock::get_monotonic(); } |
| |
| zx::time start_time_; |
| }; |
| |
| // Parse |argv| for an output directory argument. |
| const char* GetOutputDir(int argc, const char* const* argv) { |
| int i = 1; |
| while (i < argc - 1 && (strcmp(argv[i], "--output") != 0 && strcmp(argv[i], "-o"))) { |
| ++i; |
| } |
| if (i >= argc - 1) { |
| return nullptr; |
| } |
| return argv[i + 1]; |
| } |
| |
| } // namespace |
| |
| int main(int argc, char** argv) { |
| const char* output_dir = GetOutputDir(argc, argv); |
| |
| // Start Log Listener. |
| std::unique_ptr<runtests::LogExporter> log_exporter_ptr; |
| if (output_dir != nullptr) { |
| int error = runtests::MkDirAll(output_dir); |
| if (error) { |
| printf("Error: Could not create output directory: %s, %s\n", output_dir, strerror(error)); |
| return -1; |
| } |
| |
| runtests::ExporterLaunchError exporter_error; |
| log_exporter_ptr = runtests::LaunchLogExporter(runtests::JoinPath(output_dir, kSyslogFileName), |
| &exporter_error); |
| // Don't fail if logger service is not available because it is only |
| // available in garnet layer and above. |
| if (!log_exporter_ptr && exporter_error != runtests::CONNECT_TO_LOGGER_SERVICE) { |
| printf("Error: Failed to launch log listener: %d", exporter_error); |
| return -1; |
| } |
| } |
| |
| fbl::Vector<fbl::String> default_test_dirs; |
| for (auto& kDefaultTestDir : kDefaultTestDirs) { |
| default_test_dirs.push_back(kDefaultTestDir); |
| } |
| |
| FuchsiaStopwatch stopwatch; |
| return runtests::DiscoverAndRunTests(argc, argv, default_test_dirs, &stopwatch, kSyslogFileName); |
| } |