summaryrefslogtreecommitdiffhomepage
path: root/test/fuse
diff options
context:
space:
mode:
Diffstat (limited to 'test/fuse')
-rw-r--r--test/fuse/README.md211
-rw-r--r--test/fuse/linux/fuse_base.cc2
-rw-r--r--test/fuse/linux/fuse_fd_util.cc1
-rw-r--r--test/fuse/linux/readdir_test.cc15
4 files changed, 116 insertions, 113 deletions
diff --git a/test/fuse/README.md b/test/fuse/README.md
index 7a1839714..65add57e2 100644
--- a/test/fuse/README.md
+++ b/test/fuse/README.md
@@ -14,8 +14,8 @@ server. It creates a `socketpair(2)` to send and receive control commands and
data between the client and the server. Because the FUSE server runs in the
background thread, gTest cannot catch its assertion failure immediately. Thus,
`TearDown()` function sends command to the FUSE server to check if all gTest
-assertion in the server are successful and all requests and preset responses
-are consumed.
+assertion in the server are successful and all requests and preset responses are
+consumed.
## Communication Diagram
@@ -29,80 +29,80 @@ however, it is still helpful to know when the client waits for the server to
complete a command and when the server awaits the next instruction.
```
- | Client (Testing Thread) | Server (FUSE Server Thread)
- | |
- | >TEST_F() |
- | >SetUp() |
- | =MountFuse() |
- | >SetUpFuseServer() |
- | [create communication socket]|
- | =fork() | =fork()
- | [wait server complete] |
- | | =ServerConsumeFuseInit()
- | | =ServerCompleteWith()
- | <SetUpFuseServer() |
- | <SetUp() |
- | [testing main] |
- | | >ServerFuseLoop()
- | | [poll on socket and fd]
- | >SetServerResponse() |
- | [write data to socket] |
- | [wait server complete] |
- | | [socket event occurs]
- | | >ServerHandleCommand()
- | | >ServerReceiveResponse()
- | | [read data from socket]
- | | [save data to memory]
- | | <ServerReceiveResponse()
- | | =ServerCompleteWith()
- | <SetServerResponse() |
- | | <ServerHandleCommand()
- | >[Do fs operation] |
- | [wait for fs response] |
- | | [fd event occurs]
- | | >ServerProcessFuseRequest()
- | | =[read fs request]
- | | =[save fs request to memory]
- | | =[write fs response]
- | <[Do fs operation] |
- | | <ServerProcessFuseRequest()
- | |
- | =[Test fs operation result] |
- | |
- | >GetServerActualRequest() |
- | [write data to socket] |
- | [wait data from server] |
- | | [socket event occurs]
- | | >ServerHandleCommand()
- | | >ServerSendReceivedRequest()
- | | [write data to socket]
- | [read data from socket] |
- | [wait server complete] |
- | | <ServerSendReceivedRequest()
- | | =ServerCompleteWith()
- | <GetServerActualRequest() |
- | | <ServerHandleCommand()
- | |
- | =[Test actual request] |
- | |
- | >TearDown() |
- | ... |
- | >GetServerNumUnsentResponses() |
- | [write data to socket] |
- | [wait server complete] |
- | | [socket event arrive]
- | | >ServerHandleCommand()
- | | >ServerSendData()
- | | [write data to socket]
- | | <ServerSendData()
- | | =ServerCompleteWith()
- | [read data from socket] |
- | [test if all succeeded] |
- | <GetServerNumUnsentResponses() |
- | | <ServerHandleCommand()
- | =UnmountFuse() |
- | <TearDown() |
- | <TEST_F() |
+| Client (Testing Thread) | Server (FUSE Server Thread)
+| |
+| >TEST_F() |
+| >SetUp() |
+| =MountFuse() |
+| >SetUpFuseServer() |
+| [create communication socket]|
+| =fork() | =fork()
+| [wait server complete] |
+| | =ServerConsumeFuseInit()
+| | =ServerCompleteWith()
+| <SetUpFuseServer() |
+| <SetUp() |
+| [testing main] |
+| | >ServerFuseLoop()
+| | [poll on socket and fd]
+| >SetServerResponse() |
+| [write data to socket] |
+| [wait server complete] |
+| | [socket event occurs]
+| | >ServerHandleCommand()
+| | >ServerReceiveResponse()
+| | [read data from socket]
+| | [save data to memory]
+| | <ServerReceiveResponse()
+| | =ServerCompleteWith()
+| <SetServerResponse() |
+| | <ServerHandleCommand()
+| >[Do fs operation] |
+| [wait for fs response] |
+| | [fd event occurs]
+| | >ServerProcessFuseRequest()
+| | =[read fs request]
+| | =[save fs request to memory]
+| | =[write fs response]
+| <[Do fs operation] |
+| | <ServerProcessFuseRequest()
+| |
+| =[Test fs operation result] |
+| |
+| >GetServerActualRequest() |
+| [write data to socket] |
+| [wait data from server] |
+| | [socket event occurs]
+| | >ServerHandleCommand()
+| | >ServerSendReceivedRequest()
+| | [write data to socket]
+| [read data from socket] |
+| [wait server complete] |
+| | <ServerSendReceivedRequest()
+| | =ServerCompleteWith()
+| <GetServerActualRequest() |
+| | <ServerHandleCommand()
+| |
+| =[Test actual request] |
+| |
+| >TearDown() |
+| ... |
+| >GetServerNumUnsentResponses() |
+| [write data to socket] |
+| [wait server complete] |
+| | [socket event arrive]
+| | >ServerHandleCommand()
+| | >ServerSendData()
+| | [write data to socket]
+| | <ServerSendData()
+| | =ServerCompleteWith()
+| [read data from socket] |
+| [test if all succeeded] |
+| <GetServerNumUnsentResponses() |
+| | <ServerHandleCommand()
+| =UnmountFuse() |
+| <TearDown() |
+| <TEST_F() |
```
## Running the tests
@@ -124,17 +124,18 @@ $ bazel test --test_tag_filters=fuse //test/fuse/...
## Writing a new FUSE test
-1. Add test targets in `BUILD` and `linux/BUILD`.
-2. Inherit your test from `FuseTest` base class. It allows you to:
- - Fork a fake FUSE server in background during each test setup.
- - Create a pair of sockets for communication and provide utility functions.
- - Stop FUSE server and check if error occurs in it after test completes.
-3. Build the expected opcode-response pairs of your FUSE operation.
-4. Call `SetServerResponse()` to preset the next expected opcode and response.
-5. Do real filesystem operations (FUSE is mounted at `mount_point_`).
-6. Check FUSE response and/or errors.
-7. Retrieve FUSE request by `GetServerActualRequest()`.
-8. Check if the request is as expected.
+1. Add test targets in `BUILD` and `linux/BUILD`.
+2. Inherit your test from `FuseTest` base class. It allows you to:
+ - Fork a fake FUSE server in background during each test setup.
+ - Create a pair of sockets for communication and provide utility
+ functions.
+ - Stop FUSE server and check if error occurs in it after test completes.
+3. Build the expected opcode-response pairs of your FUSE operation.
+4. Call `SetServerResponse()` to preset the next expected opcode and response.
+5. Do real filesystem operations (FUSE is mounted at `mount_point_`).
+6. Check FUSE response and/or errors.
+7. Retrieve FUSE request by `GetServerActualRequest()`.
+8. Check if the request is as expected.
A few customized matchers used in syscalls test are encouraged to test the
outcome of filesystem operations. Such as:
@@ -158,11 +159,12 @@ FUSE server in response to a sequence of FUSE requests.
The lifecycle of a command contains following steps:
-1. The testing thread sends a `FuseTestCmd` via socket and waits for completion.
-2. The FUSE server receives the command and does corresponding action.
-3. (Optional) The testing thread reads data from socket.
-4. The FUSE server sends a success indicator via socket after processing.
-5. The testing thread gets the success signal and continues testing.
+1. The testing thread sends a `FuseTestCmd` via socket and waits for
+ completion.
+2. The FUSE server receives the command and does corresponding action.
+3. (Optional) The testing thread reads data from socket.
+4. The FUSE server sends a success indicator via socket after processing.
+5. The testing thread gets the success signal and continues testing.
The success indicator, i.e. `WaitServerComplete()`, is crucial at the end of
each `FuseTestCmd` sent from the testing thread. Because we don't want to begin
@@ -172,16 +174,15 @@ supported now.
To add a new `FuseTestCmd`, one must comply with following format:
-1. Add a new `FuseTestCmd` enum class item defined in `linux/fuse_base.h`
-2. Add a `SetServerXXX()` or `GetServerXXX()` public function in `FuseTest`.
- This is how the testing thread will call to send control message. Define how
- many bytes you want to send along with the command and what you will expect
- to receive. Finally it should block and wait for a success indicator from
- the FUSE server.
-3. Add a handler logic in the switch condition of `ServerHandleCommand()`. Use
- `ServerSendData()` or declare a new private function such as
- `ServerReceiveXXX()` or `ServerSendXXX()`. It is mandatory to set it private
- since only the FUSE server (forked from `FuseTest` base class) can call it.
- This is the server part of the specific `FuseTestCmd` and the format of the
- data should be consistent with what the client expects in the previous step.
-
+1. Add a new `FuseTestCmd` enum class item defined in `linux/fuse_base.h`
+2. Add a `SetServerXXX()` or `GetServerXXX()` public function in `FuseTest`.
+ This is how the testing thread will call to send control message. Define how
+ many bytes you want to send along with the command and what you will expect
+ to receive. Finally it should block and wait for a success indicator from
+ the FUSE server.
+3. Add a handler logic in the switch condition of `ServerHandleCommand()`. Use
+ `ServerSendData()` or declare a new private function such as
+ `ServerReceiveXXX()` or `ServerSendXXX()`. It is mandatory to set it private
+ since only the FUSE server (forked from `FuseTest` base class) can call it.
+ This is the server part of the specific `FuseTestCmd` and the format of the
+ data should be consistent with what the client expects in the previous step.
diff --git a/test/fuse/linux/fuse_base.cc b/test/fuse/linux/fuse_base.cc
index a033db117..5b45804e1 100644
--- a/test/fuse/linux/fuse_base.cc
+++ b/test/fuse/linux/fuse_base.cc
@@ -24,8 +24,8 @@
#include <sys/uio.h>
#include <unistd.h>
-#include "absl/strings/str_format.h"
#include "gtest/gtest.h"
+#include "absl/strings/str_format.h"
#include "test/util/fuse_util.h"
#include "test/util/posix_error.h"
#include "test/util/temp_path.h"
diff --git a/test/fuse/linux/fuse_fd_util.cc b/test/fuse/linux/fuse_fd_util.cc
index 4a2505b00..30d1157bb 100644
--- a/test/fuse/linux/fuse_fd_util.cc
+++ b/test/fuse/linux/fuse_fd_util.cc
@@ -59,4 +59,3 @@ Cleanup FuseFdTest::CloseFD(FileDescriptor &fd) {
} // namespace testing
} // namespace gvisor
-
diff --git a/test/fuse/linux/readdir_test.cc b/test/fuse/linux/readdir_test.cc
index ab61eb676..2afb4b062 100644
--- a/test/fuse/linux/readdir_test.cc
+++ b/test/fuse/linux/readdir_test.cc
@@ -127,8 +127,9 @@ TEST_F(ReaddirTest, SingleEntry) {
char *readdir_payload = readdir_payload_vec.data();
// Use fake ino for other directories.
- fill_fuse_dirent(readdir_payload, dot.c_str(), ino_dir-2);
- fill_fuse_dirent(readdir_payload + dot_file_dirent_size, dot_dot.c_str(), ino_dir-1);
+ fill_fuse_dirent(readdir_payload, dot.c_str(), ino_dir - 2);
+ fill_fuse_dirent(readdir_payload + dot_file_dirent_size, dot_dot.c_str(),
+ ino_dir - 1);
fill_fuse_dirent(
readdir_payload + dot_file_dirent_size + dot_dot_file_dirent_size,
test_file.c_str(), ino_dir);
@@ -148,8 +149,9 @@ TEST_F(ReaddirTest, SingleEntry) {
std::vector<char> buf(4090, 0);
int nread, off = 0, i = 0;
- EXPECT_THAT(nread = syscall(__NR_getdents64, fd.get(), buf.data(), buf.size()),
- SyscallSucceeds());
+ EXPECT_THAT(
+ nread = syscall(__NR_getdents64, fd.get(), buf.data(), buf.size()),
+ SyscallSucceeds());
for (; off < nread;) {
struct dirent64 *ent = (struct dirent64 *)(buf.data() + off);
off += ent->d_reclen;
@@ -166,8 +168,9 @@ TEST_F(ReaddirTest, SingleEntry) {
}
}
- EXPECT_THAT(nread = syscall(__NR_getdents64, fd.get(), buf.data(), buf.size()),
- SyscallSucceedsWithValue(0));
+ EXPECT_THAT(
+ nread = syscall(__NR_getdents64, fd.get(), buf.data(), buf.size()),
+ SyscallSucceedsWithValue(0));
SkipServerActualRequest(); // READDIR.
SkipServerActualRequest(); // READDIR with no data.