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