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 <fcntl.h>
6 #include <limits.h>
7 #include <unistd.h>
8
9 #include <fbl/unique_fd.h>
10 #include <fs-management/fvm.h>
11 #include <lib/async-loop/cpp/loop.h>
12 #include <lib/memfs/memfs.h>
13 #include <unittest/unittest.h>
14 #include <zircon/device/device.h>
15
16 #include "filesystems.h"
17
18 const char* filesystem_name_filter = "";
19
print_test_help(FILE * f)20 static void print_test_help(FILE* f) {
21 fprintf(f,
22 " -d <blkdev>\n"
23 " Use block device <blkdev> instead of a ramdisk\n"
24 "\n"
25 " -f <fs>\n"
26 " Test only fileystem <fs>, where <fs> is one of:\n");
27 for (int j = 0; j < NUM_FILESYSTEMS; j++) {
28 fprintf(f, "%8s%s\n", "", FILESYSTEMS[j].name);
29 }
30 }
31
main(int argc,char ** argv)32 int main(int argc, char** argv) {
33 use_real_disk = false;
34
35 unittest_register_test_help_printer(print_test_help);
36
37 int i = 1;
38 while (i < argc) {
39 if (strcmp(argv[i], "-d") == 0 && (i + 1 < argc)) {
40 fbl::unique_fd fd(open(argv[i + 1], O_RDWR));
41 if (!fd) {
42 fprintf(stderr, "[fs] Could not open block device\n");
43 return -1;
44 } else if (ioctl_device_get_topo_path(fd.get(), test_disk_path, PATH_MAX) < 0) {
45 fprintf(stderr, "[fs] Could not acquire topological path of block device\n");
46 return -1;
47 } else if (ioctl_block_get_info(fd.get(), &test_disk_info) < 0) {
48 fprintf(stderr, "[fs] Could not read disk info\n");
49 return -1;
50 }
51 // If we previously tried running tests on this disk, it may
52 // have created an FVM and failed. (Try to) clean up from previous state
53 // before re-running.
54 fvm_destroy(test_disk_path);
55 use_real_disk = true;
56 i += 2;
57 } else if (!strcmp(argv[i], "-f") && (i + 1 < argc)) {
58 bool found = false;
59 for (int j = 0; j < NUM_FILESYSTEMS; j++) {
60 if (!strcmp(argv[i + 1], FILESYSTEMS[j].name)) {
61 found = true;
62 filesystem_name_filter = argv[i + 1];
63 break;
64 }
65 }
66 if (!found) {
67 fprintf(stderr, "Error: Filesystem not found\n");
68 return -1;
69 }
70 i += 2;
71 } else {
72 // Ignore options we don't recognize. See ulib/unittest/README.md.
73 break;
74 }
75 }
76
77 // Initialize tmpfs.
78 async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
79 if (loop.StartThread() != ZX_OK) {
80 fprintf(stderr, "Error: Cannot initialize local tmpfs loop\n");
81 return -1;
82 }
83 if (memfs_install_at(loop.dispatcher(), kTmpfsPath) != ZX_OK) {
84 fprintf(stderr, "Error: Cannot install local tmpfs\n");
85 return -1;
86 }
87
88 return unittest_run_all_tests(argc, argv) ? 0 : -1;
89 }
90