2 * Copyright (c) 2019 The FreeBSD Foundation
5 * This software was developed by BFF Storage Systems, LLC under sponsorship
6 * from the FreeBSD Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #include <sys/types.h>
35 #include "fuse_kernel.h"
38 #include <gmock/gmock.h>
40 #define SET_OUT_HEADER_LEN(out, variant) { \
41 (out)->header.len = (sizeof((out)->header) + \
42 sizeof((out)->body.variant)); \
47 /* This struct isn't defined by fuse_kernel.h or libfuse, but it should be */
48 struct fuse_create_out {
49 struct fuse_entry_out entry;
50 struct fuse_open_out open;
53 union fuse_payloads_in {
54 /* value is from fuse_kern_chan.c in fusefs-libs */
55 uint8_t bytes[0x21000 - sizeof(struct fuse_in_header)];
56 fuse_forget_in forget;
60 fuse_setattr_in setattr;
63 struct mockfs_buf_in {
64 fuse_in_header header;
65 union fuse_payloads_in body;
68 union fuse_payloads_out {
70 fuse_create_out create;
75 * The protocol places no limits on the length of the string. This is
76 * merely convenient for testing.
81 struct mockfs_buf_out {
82 fuse_out_header header;
83 union fuse_payloads_out body;
87 * Fake FUSE filesystem
89 * "Mounts" a filesystem to a temporary directory and services requests
90 * according to the programmed expectations.
92 * Operates directly on the fuse(4) kernel API, not the libfuse(3) user api.
96 /* thread id of the fuse daemon thread */
97 pthread_t m_daemon_id;
100 /* file descriptor of /dev/fuse control device */
103 /* pid of the test process */
107 * Thread that's running the mockfs daemon.
109 * It must run in a separate thread so it doesn't deadlock with the
114 /* Initialize a session after mounting */
117 /* Default request handler */
118 void process_default(const mockfs_buf_in*, mockfs_buf_out*);
120 /* Entry point for the daemon thread */
121 static void* service(void*);
123 /* Read, but do not process, a single request from the kernel */
124 void read_request(mockfs_buf_in*);
127 /* Create a new mockfs and mount it to a tempdir */
131 /* Process FUSE requests endlessly */
137 * This method is expected to provide the response to each FUSE
138 * operation. Responses must be immediate (so this method can't be used
139 * for testing a daemon with queue depth > 1). Test cases must define
140 * each response using Googlemock expectations
142 MOCK_METHOD2(process, void(const mockfs_buf_in*, mockfs_buf_out*));
144 /* Gracefully unmount */