1 // Copyright 2018 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 <dirent.h>
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <sys/stat.h>
9 #include <sys/types.h>
10 #include <threads.h>
11 #include <unistd.h>
12 
13 #include <fbl/unique_fd.h>
14 #include <fuchsia/io/c/fidl.h>
15 #include <lib/async-loop/cpp/loop.h>
16 #include <lib/fdio/util.h>
17 #include <lib/memfs/cpp/vnode.h>
18 #include <lib/memfs/memfs.h>
19 #include <lib/zx/channel.h>
20 #include <lib/zx/vmo.h>
21 #include <unittest/unittest.h>
22 #include <zircon/processargs.h>
23 #include <zircon/syscalls.h>
24 
25 namespace {
26 
test_vmofile_basic()27 bool test_vmofile_basic() {
28     BEGIN_TEST;
29 
30     async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
31     ASSERT_EQ(loop.StartThread(), ZX_OK);
32     async_dispatcher_t* dispatcher = loop.dispatcher();
33 
34     zx::channel client, server;
35     ASSERT_EQ(zx::channel::create(0, &client, &server), ZX_OK);
36 
37     memfs::Vfs vfs;
38     vfs.SetDispatcher(dispatcher);
39 
40     fbl::RefPtr<memfs::VnodeDir> root;
41     ASSERT_EQ(memfs::CreateFilesystem("<tmp>", &vfs, &root), ZX_OK);
42 
43     zx::vmo backing_vmo;
44     ASSERT_EQ(zx::vmo::create(64, 0, &backing_vmo), ZX_OK);
45     ASSERT_EQ(backing_vmo.write("hello, world!", 0, 13), ZX_OK);
46     ASSERT_EQ(vfs.CreateFromVmo(root.get(), "greeting", backing_vmo.get(), 0, 13),
47               ZX_OK);
48     ASSERT_EQ(vfs.ServeDirectory(std::move(root), std::move(server)), ZX_OK);
49 
50     zx::channel h, request;
51     ASSERT_EQ(zx::channel::create(0, &h, &request), ZX_OK);
52     ASSERT_EQ(fuchsia_io_DirectoryOpen(client.get(), ZX_FS_RIGHT_READABLE, 0,
53                                        "greeting", 8, request.release()),
54               ZX_OK);
55 
56     fuchsia_io_NodeInfo info = {};
57     ASSERT_EQ(fuchsia_io_FileDescribe(h.get(), &info), ZX_OK);
58     ASSERT_EQ(info.tag, fuchsia_io_NodeInfoTag_vmofile);
59     ASSERT_EQ(info.vmofile.offset, 0u);
60     ASSERT_EQ(info.vmofile.length, 13u);
61     zx_handle_close(info.vmofile.vmo);
62 
63     zx_status_t status = ZX_OK;
64     uint64_t seek = 0u;
65     ASSERT_EQ(fuchsia_io_FileSeek(h.get(), 7u, fuchsia_io_SeekOrigin_START,
66                                   &status, &seek),
67               ZX_OK);
68     ASSERT_EQ(status, ZX_OK);
69     ASSERT_EQ(seek, 7u);
70     memset(&info, 0, sizeof(info));
71     ASSERT_EQ(fuchsia_io_FileDescribe(h.get(), &info), ZX_OK);
72     ASSERT_EQ(info.tag, fuchsia_io_NodeInfoTag_vmofile);
73     ASSERT_EQ(info.vmofile.offset, 0u);
74     ASSERT_EQ(info.vmofile.length, 13u);
75     zx_handle_close(info.vmofile.vmo);
76 
77     h.reset();
78 
79     vfs.Shutdown([](zx_status_t status) {
80         EXPECT_EQ(status, ZX_OK);
81     });
82 
83     loop.Shutdown();
84 
85     END_TEST;
86 }
87 
88 } // namespace
89 
90 BEGIN_TEST_CASE(vmofile_tests)
91 RUN_TEST(test_vmofile_basic)
92 END_TEST_CASE(vmofile_tests)
93