1// Copyright 2016 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <fbl/string.h> 6#include <fbl/vector.h> 7#include <lib/zx/time.h> 8#include <runtests-utils/fuchsia-run-test.h> 9#include <runtests-utils/log-exporter.h> 10#include <runtests-utils/runtests-utils.h> 11 12namespace { 13 14// The name of the file containing the syslog. 15constexpr char kSyslogFileName[] = "syslog.txt"; 16 17const char* kDefaultTestDirs[] = { 18 // zircon builds place everything in ramdisks so tests are located in /boot 19 "/boot/test/core", 20 "/boot/test/libc", 21 "/boot/test/ddk", 22 "/boot/test/sys", 23 "/boot/test/fs", 24 // /pkgfs is where test binaries should be found in garnet and above. 25 "/pkgfs/packages/*/*/test", 26 // Moreover, for the higher layers, there are still tests using the deprecated /system image. 27 // Soon they will all be moved under /pkgfs. 28 "/system/test", 29 "/system/test/core", 30 "/system/test/libc", 31 "/system/test/ddk", 32 "/system/test/sys", 33 "/system/test/fs", 34}; 35 36class FuchsiaStopwatch final : public runtests::Stopwatch { 37public: 38 FuchsiaStopwatch() { Start(); } 39 void Start() override { start_time_ = Now(); } 40 int64_t DurationInMsecs() override { return (Now() - start_time_).to_msecs(); } 41 42private: 43 zx::time Now() const { return zx::clock::get_monotonic(); } 44 45 zx::time start_time_; 46}; 47 48// Parse |argv| for an output directory argument. 49const char* GetOutputDir(int argc, const char* const* argv) { 50 int i = 1; 51 while (i < argc - 1 && strcmp(argv[i], "-o") != 0) { 52 ++i; 53 } 54 if (i >= argc - 1) { 55 return nullptr; 56 } 57 return argv[i + 1]; 58} 59 60} // namespace 61 62int main(int argc, char** argv) { 63 const char* output_dir = GetOutputDir(argc, argv); 64 65 // Start Log Listener. 66 fbl::unique_ptr<runtests::LogExporter> log_exporter_ptr; 67 if (output_dir != nullptr) { 68 int error = runtests::MkDirAll(output_dir); 69 if (error) { 70 printf("Error: Could not create output directory: %s, %s\n", output_dir, 71 strerror(error)); 72 return -1; 73 } 74 75 runtests::ExporterLaunchError exporter_error; 76 log_exporter_ptr = runtests::LaunchLogExporter( 77 runtests::JoinPath(output_dir, kSyslogFileName), &exporter_error); 78 // Don't fail if logger service is not available because it is only 79 // available in garnet layer and above. 80 if (!log_exporter_ptr && exporter_error != runtests::CONNECT_TO_LOGGER_SERVICE) { 81 printf("Error: Failed to launch log listener: %d", exporter_error); 82 return -1; 83 } 84 } 85 86 fbl::Vector<fbl::String> default_test_dirs; 87 const int num_default_test_dirs = sizeof(kDefaultTestDirs) / sizeof(char*); 88 for (int i = 0; i < num_default_test_dirs; ++i) { 89 default_test_dirs.push_back(kDefaultTestDirs[i]); 90 } 91 92 FuchsiaStopwatch stopwatch; 93 return runtests::DiscoverAndRunTests(&runtests::FuchsiaRunTest, argc, argv, default_test_dirs, 94 &stopwatch, kSyslogFileName); 95} 96