1c6134762975204ceebcf7949e364484833714345Daichi Hirono/*
2c6134762975204ceebcf7949e364484833714345Daichi Hirono * Copyright (C) 2016 The Android Open Source Project
3c6134762975204ceebcf7949e364484833714345Daichi Hirono *
4c6134762975204ceebcf7949e364484833714345Daichi Hirono * Licensed under the Apache License, Version 2.0 (the "License");
5c6134762975204ceebcf7949e364484833714345Daichi Hirono * you may not use this file except in compliance with the License.
6c6134762975204ceebcf7949e364484833714345Daichi Hirono * You may obtain a copy of the License at
7c6134762975204ceebcf7949e364484833714345Daichi Hirono *
8c6134762975204ceebcf7949e364484833714345Daichi Hirono *      http://www.apache.org/licenses/LICENSE-2.0
9c6134762975204ceebcf7949e364484833714345Daichi Hirono *
10c6134762975204ceebcf7949e364484833714345Daichi Hirono * Unless required by applicable law or agreed to in writing, software
11c6134762975204ceebcf7949e364484833714345Daichi Hirono * distributed under the License is distributed on an "AS IS" BASIS,
12c6134762975204ceebcf7949e364484833714345Daichi Hirono * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c6134762975204ceebcf7949e364484833714345Daichi Hirono * See the License for the specic language governing permissions and
14c6134762975204ceebcf7949e364484833714345Daichi Hirono * limitations under the License.
15c6134762975204ceebcf7949e364484833714345Daichi Hirono */
16c6134762975204ceebcf7949e364484833714345Daichi Hirono
17c6134762975204ceebcf7949e364484833714345Daichi Hirono#include "libappfuse/FuseBridgeLoop.h"
18c6134762975204ceebcf7949e364484833714345Daichi Hirono
19c6134762975204ceebcf7949e364484833714345Daichi Hirono#include <sys/socket.h>
20c6134762975204ceebcf7949e364484833714345Daichi Hirono
21c6134762975204ceebcf7949e364484833714345Daichi Hirono#include <sstream>
22c6134762975204ceebcf7949e364484833714345Daichi Hirono#include <thread>
23c6134762975204ceebcf7949e364484833714345Daichi Hirono
24a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono#include <android-base/logging.h>
25a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono#include <android-base/unique_fd.h>
26c6134762975204ceebcf7949e364484833714345Daichi Hirono#include <gtest/gtest.h>
27c6134762975204ceebcf7949e364484833714345Daichi Hirono
28c6134762975204ceebcf7949e364484833714345Daichi Hirononamespace android {
29a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirononamespace fuse {
30a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirononamespace {
31c6134762975204ceebcf7949e364484833714345Daichi Hirono
32a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hironoclass Callback : public FuseBridgeLoopCallback {
33c6134762975204ceebcf7949e364484833714345Daichi Hirono public:
34c6134762975204ceebcf7949e364484833714345Daichi Hirono  bool mounted;
3596c6aa4f20717535921a927401cbfa16b56c193bDaichi Hirono  bool closed;
3696c6aa4f20717535921a927401cbfa16b56c193bDaichi Hirono  Callback() : mounted(false), closed(false) {}
3796c6aa4f20717535921a927401cbfa16b56c193bDaichi Hirono
3896c6aa4f20717535921a927401cbfa16b56c193bDaichi Hirono  void OnMount(int /*mount_id*/) override { mounted = true; }
3996c6aa4f20717535921a927401cbfa16b56c193bDaichi Hirono
4096c6aa4f20717535921a927401cbfa16b56c193bDaichi Hirono  void OnClosed(int /* mount_id */) override { closed = true; }
41c6134762975204ceebcf7949e364484833714345Daichi Hirono};
42c6134762975204ceebcf7949e364484833714345Daichi Hirono
43c6134762975204ceebcf7949e364484833714345Daichi Hironoclass FuseBridgeLoopTest : public ::testing::Test {
44c6134762975204ceebcf7949e364484833714345Daichi Hirono protected:
45a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  base::unique_fd dev_sockets_[2];
46a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  base::unique_fd proxy_sockets_[2];
47c6134762975204ceebcf7949e364484833714345Daichi Hirono  Callback callback_;
48c6134762975204ceebcf7949e364484833714345Daichi Hirono  std::thread thread_;
49c6134762975204ceebcf7949e364484833714345Daichi Hirono
50c6134762975204ceebcf7949e364484833714345Daichi Hirono  FuseRequest request_;
51c6134762975204ceebcf7949e364484833714345Daichi Hirono  FuseResponse response_;
52c6134762975204ceebcf7949e364484833714345Daichi Hirono
53a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  void SetUp() override {
54a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    base::SetMinimumLogSeverity(base::VERBOSE);
5557b780fbc3e2c2442c2f58dcb83818e786246b35Daichi Hirono    ASSERT_TRUE(SetupMessageSockets(&dev_sockets_));
5657b780fbc3e2c2442c2f58dcb83818e786246b35Daichi Hirono    ASSERT_TRUE(SetupMessageSockets(&proxy_sockets_));
57c6134762975204ceebcf7949e364484833714345Daichi Hirono    thread_ = std::thread([this] {
5896c6aa4f20717535921a927401cbfa16b56c193bDaichi Hirono        FuseBridgeLoop loop;
5996c6aa4f20717535921a927401cbfa16b56c193bDaichi Hirono        loop.AddBridge(1, std::move(dev_sockets_[1]), std::move(proxy_sockets_[0]));
6096c6aa4f20717535921a927401cbfa16b56c193bDaichi Hirono        loop.Start(&callback_);
61c6134762975204ceebcf7949e364484833714345Daichi Hirono    });
62c6134762975204ceebcf7949e364484833714345Daichi Hirono  }
63c6134762975204ceebcf7949e364484833714345Daichi Hirono
64c6134762975204ceebcf7949e364484833714345Daichi Hirono  void CheckNotImpl(uint32_t opcode) {
65c6134762975204ceebcf7949e364484833714345Daichi Hirono    SCOPED_TRACE((std::ostringstream() << "opcode: " << opcode).str());
66c6134762975204ceebcf7949e364484833714345Daichi Hirono
67c6134762975204ceebcf7949e364484833714345Daichi Hirono    memset(&request_, 0, sizeof(FuseRequest));
68c6134762975204ceebcf7949e364484833714345Daichi Hirono    request_.header.opcode = opcode;
69c6134762975204ceebcf7949e364484833714345Daichi Hirono    request_.header.len = sizeof(fuse_in_header);
70afa345325647e66dc7add78f7100dc81bd066dbbDaichi Hirono    request_.header.unique = 1;
71c6134762975204ceebcf7949e364484833714345Daichi Hirono    ASSERT_TRUE(request_.Write(dev_sockets_[0]));
72c6134762975204ceebcf7949e364484833714345Daichi Hirono
73c6134762975204ceebcf7949e364484833714345Daichi Hirono    memset(&response_, 0, sizeof(FuseResponse));
74c6134762975204ceebcf7949e364484833714345Daichi Hirono    ASSERT_TRUE(response_.Read(dev_sockets_[0]));
75c6134762975204ceebcf7949e364484833714345Daichi Hirono    EXPECT_EQ(-ENOSYS, response_.header.error);
76c6134762975204ceebcf7949e364484833714345Daichi Hirono  }
77c6134762975204ceebcf7949e364484833714345Daichi Hirono
78c6134762975204ceebcf7949e364484833714345Daichi Hirono  void CheckProxy(uint32_t opcode) {
79c6134762975204ceebcf7949e364484833714345Daichi Hirono    SCOPED_TRACE((std::ostringstream() << "opcode: " << opcode).str());
80c6134762975204ceebcf7949e364484833714345Daichi Hirono
81c6134762975204ceebcf7949e364484833714345Daichi Hirono    memset(&request_, 0, sizeof(FuseRequest));
82c6134762975204ceebcf7949e364484833714345Daichi Hirono    request_.header.opcode = opcode;
83c6134762975204ceebcf7949e364484833714345Daichi Hirono    request_.header.unique = opcode; // Use opcode as unique.
84c6134762975204ceebcf7949e364484833714345Daichi Hirono    request_.header.len = sizeof(fuse_in_header);
85c6134762975204ceebcf7949e364484833714345Daichi Hirono    ASSERT_TRUE(request_.Write(dev_sockets_[0]));
86c6134762975204ceebcf7949e364484833714345Daichi Hirono
87c6134762975204ceebcf7949e364484833714345Daichi Hirono    memset(&request_, 0, sizeof(FuseRequest));
88c6134762975204ceebcf7949e364484833714345Daichi Hirono    ASSERT_TRUE(request_.Read(proxy_sockets_[1]));
89c6134762975204ceebcf7949e364484833714345Daichi Hirono    EXPECT_EQ(opcode, request_.header.opcode);
90c6134762975204ceebcf7949e364484833714345Daichi Hirono    EXPECT_EQ(opcode, request_.header.unique);
91c6134762975204ceebcf7949e364484833714345Daichi Hirono
92c6134762975204ceebcf7949e364484833714345Daichi Hirono    memset(&response_, 0, sizeof(FuseResponse));
93c6134762975204ceebcf7949e364484833714345Daichi Hirono    response_.header.len = sizeof(fuse_out_header);
94c6134762975204ceebcf7949e364484833714345Daichi Hirono    response_.header.unique = opcode;  // Use opcode as unique.
95c6134762975204ceebcf7949e364484833714345Daichi Hirono    response_.header.error = kFuseSuccess;
96c6134762975204ceebcf7949e364484833714345Daichi Hirono    ASSERT_TRUE(response_.Write(proxy_sockets_[1]));
97c6134762975204ceebcf7949e364484833714345Daichi Hirono
98c6134762975204ceebcf7949e364484833714345Daichi Hirono    memset(&response_, 0, sizeof(FuseResponse));
99c6134762975204ceebcf7949e364484833714345Daichi Hirono    ASSERT_TRUE(response_.Read(dev_sockets_[0]));
100c6134762975204ceebcf7949e364484833714345Daichi Hirono    EXPECT_EQ(opcode, response_.header.unique);
101c6134762975204ceebcf7949e364484833714345Daichi Hirono    EXPECT_EQ(kFuseSuccess, response_.header.error);
102c6134762975204ceebcf7949e364484833714345Daichi Hirono  }
103c6134762975204ceebcf7949e364484833714345Daichi Hirono
104c6134762975204ceebcf7949e364484833714345Daichi Hirono  void SendInitRequest(uint64_t unique) {
105c6134762975204ceebcf7949e364484833714345Daichi Hirono    memset(&request_, 0, sizeof(FuseRequest));
106c6134762975204ceebcf7949e364484833714345Daichi Hirono    request_.header.opcode = FUSE_INIT;
107c6134762975204ceebcf7949e364484833714345Daichi Hirono    request_.header.unique = unique;
108c6134762975204ceebcf7949e364484833714345Daichi Hirono    request_.header.len = sizeof(fuse_in_header) + sizeof(fuse_init_in);
109c6134762975204ceebcf7949e364484833714345Daichi Hirono    request_.init_in.major = FUSE_KERNEL_VERSION;
110c6134762975204ceebcf7949e364484833714345Daichi Hirono    request_.init_in.minor = FUSE_KERNEL_MINOR_VERSION;
111c6134762975204ceebcf7949e364484833714345Daichi Hirono    ASSERT_TRUE(request_.Write(dev_sockets_[0]));
112c6134762975204ceebcf7949e364484833714345Daichi Hirono  }
113c6134762975204ceebcf7949e364484833714345Daichi Hirono
114c6134762975204ceebcf7949e364484833714345Daichi Hirono  void Close() {
115a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    dev_sockets_[0].reset();
116a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    dev_sockets_[1].reset();
117a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    proxy_sockets_[0].reset();
118a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    proxy_sockets_[1].reset();
119c6134762975204ceebcf7949e364484833714345Daichi Hirono    if (thread_.joinable()) {
120c6134762975204ceebcf7949e364484833714345Daichi Hirono      thread_.join();
121c6134762975204ceebcf7949e364484833714345Daichi Hirono    }
12296c6aa4f20717535921a927401cbfa16b56c193bDaichi Hirono    ASSERT_TRUE(callback_.closed);
123c6134762975204ceebcf7949e364484833714345Daichi Hirono  }
124c6134762975204ceebcf7949e364484833714345Daichi Hirono
125a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  void TearDown() override {
126c6134762975204ceebcf7949e364484833714345Daichi Hirono    Close();
127c6134762975204ceebcf7949e364484833714345Daichi Hirono  }
128c6134762975204ceebcf7949e364484833714345Daichi Hirono};
129c6134762975204ceebcf7949e364484833714345Daichi Hirono
130a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono} //  namespace
131a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
132c6134762975204ceebcf7949e364484833714345Daichi HironoTEST_F(FuseBridgeLoopTest, FuseInit) {
133c6134762975204ceebcf7949e364484833714345Daichi Hirono  SendInitRequest(1u);
134c6134762975204ceebcf7949e364484833714345Daichi Hirono
135c6134762975204ceebcf7949e364484833714345Daichi Hirono  memset(&response_, 0, sizeof(FuseResponse));
136c6134762975204ceebcf7949e364484833714345Daichi Hirono  ASSERT_TRUE(response_.Read(dev_sockets_[0]));
137c6134762975204ceebcf7949e364484833714345Daichi Hirono  EXPECT_EQ(kFuseSuccess, response_.header.error);
138c6134762975204ceebcf7949e364484833714345Daichi Hirono  EXPECT_EQ(1u, response_.header.unique);
139c6134762975204ceebcf7949e364484833714345Daichi Hirono
140c6134762975204ceebcf7949e364484833714345Daichi Hirono  // Unmount.
141c6134762975204ceebcf7949e364484833714345Daichi Hirono  Close();
142c6134762975204ceebcf7949e364484833714345Daichi Hirono  EXPECT_TRUE(callback_.mounted);
143c6134762975204ceebcf7949e364484833714345Daichi Hirono}
144c6134762975204ceebcf7949e364484833714345Daichi Hirono
145c6134762975204ceebcf7949e364484833714345Daichi HironoTEST_F(FuseBridgeLoopTest, FuseForget) {
146c6134762975204ceebcf7949e364484833714345Daichi Hirono  memset(&request_, 0, sizeof(FuseRequest));
147c6134762975204ceebcf7949e364484833714345Daichi Hirono  request_.header.opcode = FUSE_FORGET;
148c6134762975204ceebcf7949e364484833714345Daichi Hirono  request_.header.unique = 1u;
149c6134762975204ceebcf7949e364484833714345Daichi Hirono  request_.header.len = sizeof(fuse_in_header) + sizeof(fuse_forget_in);
150c6134762975204ceebcf7949e364484833714345Daichi Hirono  ASSERT_TRUE(request_.Write(dev_sockets_[0]));
151c6134762975204ceebcf7949e364484833714345Daichi Hirono
152c6134762975204ceebcf7949e364484833714345Daichi Hirono  SendInitRequest(2u);
153c6134762975204ceebcf7949e364484833714345Daichi Hirono
154c6134762975204ceebcf7949e364484833714345Daichi Hirono  memset(&response_, 0, sizeof(FuseResponse));
155c6134762975204ceebcf7949e364484833714345Daichi Hirono  ASSERT_TRUE(response_.Read(dev_sockets_[0]));
156c6134762975204ceebcf7949e364484833714345Daichi Hirono  EXPECT_EQ(2u, response_.header.unique) <<
157c6134762975204ceebcf7949e364484833714345Daichi Hirono      "The loop must not respond to FUSE_FORGET";
158c6134762975204ceebcf7949e364484833714345Daichi Hirono}
159c6134762975204ceebcf7949e364484833714345Daichi Hirono
160c6134762975204ceebcf7949e364484833714345Daichi HironoTEST_F(FuseBridgeLoopTest, FuseNotImpl) {
161c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_SETATTR);
162c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_READLINK);
163c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_SYMLINK);
164c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_MKNOD);
165c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_MKDIR);
166c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_UNLINK);
167c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_RMDIR);
168c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_RENAME);
169c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_LINK);
170c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_STATFS);
171c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_SETXATTR);
172c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_GETXATTR);
173c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_LISTXATTR);
174c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_REMOVEXATTR);
175a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  CheckNotImpl(FUSE_FLUSH);
176c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_OPENDIR);
177c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_READDIR);
178c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_RELEASEDIR);
179c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_FSYNCDIR);
180c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_GETLK);
181c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_SETLK);
182c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_SETLKW);
183c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_ACCESS);
184c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_CREATE);
185c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_INTERRUPT);
186c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_BMAP);
187c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_DESTROY);
188c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_IOCTL);
189c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_POLL);
190c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_NOTIFY_REPLY);
191c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_BATCH_FORGET);
192c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_FALLOCATE);
193c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_READDIRPLUS);
194c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_RENAME2);
195c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckNotImpl(FUSE_LSEEK);
196c6134762975204ceebcf7949e364484833714345Daichi Hirono}
197c6134762975204ceebcf7949e364484833714345Daichi Hirono
198c6134762975204ceebcf7949e364484833714345Daichi HironoTEST_F(FuseBridgeLoopTest, Proxy) {
199c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckProxy(FUSE_LOOKUP);
200c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckProxy(FUSE_GETATTR);
201c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckProxy(FUSE_READ);
202c6134762975204ceebcf7949e364484833714345Daichi Hirono  CheckProxy(FUSE_WRITE);
203a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  CheckProxy(FUSE_FSYNC);
20430e68088951f17ad54c1d15576835ff4eb622c4cDaichi Hirono
20530e68088951f17ad54c1d15576835ff4eb622c4cDaichi Hirono  // Invoke FUSE_OPEN and FUSE_RELEASE at last as the loop will exit when all files are closed.
20630e68088951f17ad54c1d15576835ff4eb622c4cDaichi Hirono  CheckProxy(FUSE_OPEN);
20730e68088951f17ad54c1d15576835ff4eb622c4cDaichi Hirono  CheckProxy(FUSE_RELEASE);
20830e68088951f17ad54c1d15576835ff4eb622c4cDaichi Hirono
20930e68088951f17ad54c1d15576835ff4eb622c4cDaichi Hirono  // Ensure the loop exits.
21030e68088951f17ad54c1d15576835ff4eb622c4cDaichi Hirono  Close();
211c6134762975204ceebcf7949e364484833714345Daichi Hirono}
212c6134762975204ceebcf7949e364484833714345Daichi Hirono
213a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono}  // namespace fuse
214a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono}  // namespace android
215