]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/fs/fuse/statfs.cc
fuse(4): add tests for FUSE_INTERRUPT
[FreeBSD/FreeBSD.git] / tests / sys / fs / fuse / statfs.cc
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2019 The FreeBSD Foundation
5  *
6  * This software was developed by BFF Storage Systems, LLC under sponsorship
7  * from the FreeBSD Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30
31 extern "C" {
32 #include <sys/param.h>
33 #include <sys/mount.h>
34 }
35
36 #include "mockfs.hh"
37 #include "utils.hh"
38
39 using namespace testing;
40
41 class Statfs: public FuseTest {};
42
43 TEST_F(Statfs, eio)
44 {
45         struct statfs statbuf;
46
47         EXPECT_CALL(*m_mock, process(
48                 ResultOf([](auto in) {
49                         return (in->header.opcode == FUSE_STATFS);
50                 }, Eq(true)),
51                 _)
52         ).WillOnce(Invoke(ReturnErrno(EIO)));
53
54         ASSERT_NE(0, statfs("mountpoint", &statbuf));
55         ASSERT_EQ(EIO, errno);
56 }
57
58 /*
59  * When the daemon is dead but the filesystem is still mounted, fuse(4) fakes
60  * the statfs(2) response, which is necessary for unmounting.
61  */
62 TEST_F(Statfs, enotconn)
63 {
64         struct statfs statbuf;
65         char mp[PATH_MAX];
66
67         m_mock->kill_daemon();
68
69         ASSERT_NE(NULL, getcwd(mp, PATH_MAX)) << strerror(errno);
70         strlcat(mp, "/mountpoint", PATH_MAX);
71         ASSERT_EQ(0, statfs("mountpoint", &statbuf)) << strerror(errno);
72
73         EXPECT_EQ(getuid(), statbuf.f_owner);
74         EXPECT_EQ(0, strcmp("fusefs", statbuf.f_fstypename));
75         EXPECT_EQ(0, strcmp("/dev/fuse", statbuf.f_mntfromname));
76         EXPECT_EQ(0, strcmp(mp, statbuf.f_mntonname));
77 }
78
79 TEST_F(Statfs, ok)
80 {
81         struct statfs statbuf;
82         char mp[PATH_MAX];
83
84         EXPECT_CALL(*m_mock, process(
85                 ResultOf([](auto in) {
86                         return (in->header.opcode == FUSE_STATFS);
87                 }, Eq(true)),
88                 _)
89         ).WillOnce(Invoke(ReturnImmediate([=](auto in, auto out) {
90                 out->header.unique = in->header.unique;
91                 SET_OUT_HEADER_LEN(out, statfs);
92                 out->body.statfs.st.blocks = 1000;
93                 out->body.statfs.st.bfree = 100;
94                 out->body.statfs.st.bavail = 200;
95                 out->body.statfs.st.files = 5;
96                 out->body.statfs.st.ffree = 6;
97                 out->body.statfs.st.namelen = 128;
98                 out->body.statfs.st.frsize = 1024;
99         })));
100
101         ASSERT_NE(NULL, getcwd(mp, PATH_MAX)) << strerror(errno);
102         strlcat(mp, "/mountpoint", PATH_MAX);
103         ASSERT_EQ(0, statfs("mountpoint", &statbuf)) << strerror(errno);
104         EXPECT_EQ(1024ul, statbuf.f_bsize);
105         /* 
106          * fuse(4) ignores the filesystem's reported optimal transfer size, and
107          * chooses a size that works well with the rest of the system instead
108          */
109         EXPECT_EQ(1000ul, statbuf.f_blocks);
110         EXPECT_EQ(100ul, statbuf.f_bfree);
111         EXPECT_EQ(200l, statbuf.f_bavail);
112         EXPECT_EQ(5ul, statbuf.f_files);
113         EXPECT_EQ(6l, statbuf.f_ffree);
114         EXPECT_EQ(128u, statbuf.f_namemax);
115         EXPECT_EQ(getuid(), statbuf.f_owner);
116         EXPECT_EQ(0, strcmp("fusefs", statbuf.f_fstypename));
117         EXPECT_EQ(0, strcmp("/dev/fuse", statbuf.f_mntfromname));
118         EXPECT_EQ(0, strcmp(mp, statbuf.f_mntonname));
119 }