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 18const char* filesystem_name_filter = ""; 19 20static 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 32int 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