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