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
12 namespace {
13
14 // The name of the file containing the syslog.
15 constexpr char kSyslogFileName[] = "syslog.txt";
16
17 const 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
36 class FuchsiaStopwatch final : public runtests::Stopwatch {
37 public:
FuchsiaStopwatch()38 FuchsiaStopwatch() { Start(); }
Start()39 void Start() override { start_time_ = Now(); }
DurationInMsecs()40 int64_t DurationInMsecs() override { return (Now() - start_time_).to_msecs(); }
41
42 private:
Now() const43 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.
GetOutputDir(int argc,const char * const * argv)49 const 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
main(int argc,char ** argv)62 int 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