1a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono/*
2a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono * Copyright (C) 2016 The Android Open Source Project
3a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono *
4a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono * Licensed under the Apache License, Version 2.0 (the "License");
5a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono * you may not use this file except in compliance with the License.
6a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono * You may obtain a copy of the License at
7a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono *
8a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono *      http://www.apache.org/licenses/LICENSE-2.0
9a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono *
10a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono * Unless required by applicable law or agreed to in writing, software
11a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono * distributed under the License is distributed on an "AS IS" BASIS,
12a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono * See the License for the specic language governing permissions and
14a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono * limitations under the License.
15a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono */
16a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
17a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono#include "libappfuse/FuseAppLoop.h"
18a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
19a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono#include <sys/socket.h>
20a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
21a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono#include <android-base/logging.h>
22a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono#include <android-base/unique_fd.h>
23a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono#include <gtest/gtest.h>
24a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono#include <thread>
25a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
26f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono#include "libappfuse/EpollController.h"
27f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono#include "libappfuse/FuseBridgeLoop.h"
28f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono
29a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirononamespace android {
30a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirononamespace fuse {
31a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirononamespace {
32a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
33a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hironoconstexpr unsigned int kTestFileSize = 1024;
34a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
35a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hironostruct CallbackRequest {
36a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  uint32_t code;
37a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  uint64_t inode;
38a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono};
39a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
40a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hironoclass Callback : public FuseAppLoopCallback {
41a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono public:
42a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  std::vector<CallbackRequest> requests;
43f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono  FuseAppLoop* loop;
44a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
45f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono  void OnGetAttr(uint64_t seq, uint64_t inode) override {
46f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono      EXPECT_NE(FUSE_ROOT_ID, static_cast<int>(inode));
47f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono      EXPECT_TRUE(loop->ReplyGetAttr(seq, inode, kTestFileSize, S_IFREG | 0777));
48a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  }
49a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
50f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono  void OnLookup(uint64_t unique, uint64_t inode) override {
51f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono      EXPECT_NE(FUSE_ROOT_ID, static_cast<int>(inode));
52f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono      EXPECT_TRUE(loop->ReplyLookup(unique, inode, kTestFileSize));
53a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  }
54a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
55f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono  void OnFsync(uint64_t seq, uint64_t inode) override {
56f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono      requests.push_back({.code = FUSE_FSYNC, .inode = inode});
57f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono      loop->ReplySimple(seq, 0);
58a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  }
59a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
60f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono  void OnWrite(uint64_t seq, uint64_t inode, uint64_t offset ATTRIBUTE_UNUSED,
61f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono               uint32_t size ATTRIBUTE_UNUSED, const void* data ATTRIBUTE_UNUSED) override {
62f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono      requests.push_back({.code = FUSE_WRITE, .inode = inode});
63f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono      loop->ReplyWrite(seq, 0);
64a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  }
65a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
66f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono  void OnRead(uint64_t seq, uint64_t inode, uint64_t offset ATTRIBUTE_UNUSED,
67f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono              uint32_t size ATTRIBUTE_UNUSED) override {
68f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono      requests.push_back({.code = FUSE_READ, .inode = inode});
69f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono      loop->ReplySimple(seq, 0);
70a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  }
71a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
72f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono  void OnOpen(uint64_t seq, uint64_t inode) override {
73f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono      requests.push_back({.code = FUSE_OPEN, .inode = inode});
74f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono      loop->ReplyOpen(seq, inode);
75a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  }
76a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
77f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono  void OnRelease(uint64_t seq, uint64_t inode) override {
78f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono      requests.push_back({.code = FUSE_RELEASE, .inode = inode});
79f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono      loop->ReplySimple(seq, 0);
80a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  }
81a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono};
82a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
83a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hironoclass FuseAppLoopTest : public ::testing::Test {
84a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono protected:
85f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono   std::thread thread_;
86f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono   base::unique_fd sockets_[2];
87f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono   Callback callback_;
88f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono   FuseRequest request_;
89f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono   FuseResponse response_;
90f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono   std::unique_ptr<FuseAppLoop> loop_;
91f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono
92f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono   void SetUp() override {
93f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono       base::SetMinimumLogSeverity(base::VERBOSE);
94f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono       ASSERT_TRUE(SetupMessageSockets(&sockets_));
95f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono       loop_.reset(new FuseAppLoop(std::move(sockets_[1])));
96f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono       callback_.loop = loop_.get();
97f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono       thread_ = std::thread([this] { loop_->Start(&callback_); });
98a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  }
99a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
100a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  void CheckCallback(
101a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono      size_t data_size, uint32_t code, size_t expected_out_size) {
102a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    request_.Reset(data_size, code, 1);
103a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    request_.header.nodeid = 10;
104a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
105a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    ASSERT_TRUE(request_.Write(sockets_[0]));
106a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    ASSERT_TRUE(response_.Read(sockets_[0]));
107a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
108a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    Close();
109a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
110a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    EXPECT_EQ(kFuseSuccess, response_.header.error);
111a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    EXPECT_EQ(sizeof(fuse_out_header) + expected_out_size,
112a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono              response_.header.len);
113a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    EXPECT_EQ(1u, response_.header.unique);
114a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
115a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    ASSERT_EQ(1u, callback_.requests.size());
116a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    EXPECT_EQ(code, callback_.requests[0].code);
117a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    EXPECT_EQ(10u, callback_.requests[0].inode);
118a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  }
119a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
120a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  void Close() {
121a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    sockets_[0].reset();
122a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    sockets_[1].reset();
123a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    if (thread_.joinable()) {
124a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono      thread_.join();
125a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    }
126a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  }
127a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
128a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  void TearDown() override {
129a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono    Close();
130a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  }
131a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono};
132a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
133a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono}  // namespace
134a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
135a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi HironoTEST_F(FuseAppLoopTest, LookUp) {
136a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  request_.Reset(3u, FUSE_LOOKUP, 1);
137a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  request_.header.nodeid = FUSE_ROOT_ID;
138a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  strcpy(request_.lookup_name, "10");
139a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
140a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  ASSERT_TRUE(request_.Write(sockets_[0].get()));
141a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  ASSERT_TRUE(response_.Read(sockets_[0].get()));
142a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
143a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(kFuseSuccess, response_.header.error);
144a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(sizeof(fuse_out_header) + sizeof(fuse_entry_out),
145a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono            response_.header.len);
146a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(1u, response_.header.unique);
147a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
148a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(10u, response_.entry_out.nodeid);
149a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.generation);
150a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(10u, response_.entry_out.entry_valid);
151a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(10u, response_.entry_out.attr_valid);
152a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.entry_valid_nsec);
153a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.attr_valid_nsec);
154a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
155a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(10u, response_.entry_out.attr.ino);
156a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(kTestFileSize, response_.entry_out.attr.size);
157a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.attr.blocks);
158a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.attr.atime);
159a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.attr.mtime);
160a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.attr.ctime);
161a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.attr.atimensec);
162a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.attr.mtimensec);
163a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.attr.ctimensec);
164a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(S_IFREG | 0777u, response_.entry_out.attr.mode);
165a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.attr.nlink);
166a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.attr.uid);
167a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.attr.gid);
168a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.attr.rdev);
169a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.attr.blksize);
170a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.entry_out.attr.padding);
171a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono}
172a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
173a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi HironoTEST_F(FuseAppLoopTest, LookUp_InvalidName) {
174a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  request_.Reset(3u, FUSE_LOOKUP, 1);
175a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  request_.header.nodeid = FUSE_ROOT_ID;
176a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  strcpy(request_.lookup_name, "aa");
177a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
178a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  ASSERT_TRUE(request_.Write(sockets_[0].get()));
179a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  ASSERT_TRUE(response_.Read(sockets_[0].get()));
180a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
181a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(sizeof(fuse_out_header), response_.header.len);
182a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(-ENOENT, response_.header.error);
183a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(1u, response_.header.unique);
184a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono}
185a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
186a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi HironoTEST_F(FuseAppLoopTest, LookUp_TooLargeName) {
187a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  request_.Reset(21u, FUSE_LOOKUP, 1);
188a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  request_.header.nodeid = FUSE_ROOT_ID;
189a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  strcpy(request_.lookup_name, "18446744073709551616");
190a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
191a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  ASSERT_TRUE(request_.Write(sockets_[0].get()));
192a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  ASSERT_TRUE(response_.Read(sockets_[0].get()));
193a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
194a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(sizeof(fuse_out_header), response_.header.len);
195a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(-ENOENT, response_.header.error);
196a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(1u, response_.header.unique);
197a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono}
198a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
199a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi HironoTEST_F(FuseAppLoopTest, GetAttr) {
200a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  request_.Reset(sizeof(fuse_getattr_in), FUSE_GETATTR, 1);
201a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  request_.header.nodeid = 10;
202a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
203a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  ASSERT_TRUE(request_.Write(sockets_[0].get()));
204a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  ASSERT_TRUE(response_.Read(sockets_[0].get()));
205a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
206a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(kFuseSuccess, response_.header.error);
207a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(sizeof(fuse_out_header) + sizeof(fuse_attr_out),
208a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono            response_.header.len);
209a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(1u, response_.header.unique);
210a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
211a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(10u, response_.attr_out.attr_valid);
212a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr_valid_nsec);
213a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
214a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(10u, response_.attr_out.attr.ino);
215a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(kTestFileSize, response_.attr_out.attr.size);
216a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.blocks);
217a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.atime);
218a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.mtime);
219a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.ctime);
220a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.atimensec);
221a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.mtimensec);
222a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.ctimensec);
223a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(S_IFREG | 0777u, response_.attr_out.attr.mode);
224a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.nlink);
225a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.uid);
226a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.gid);
227a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.rdev);
228a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.blksize);
229a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.padding);
230a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono}
231a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
232a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi HironoTEST_F(FuseAppLoopTest, GetAttr_Root) {
233a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  request_.Reset(sizeof(fuse_getattr_in), FUSE_GETATTR, 1);
234a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  request_.header.nodeid = FUSE_ROOT_ID;
235a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
236a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  ASSERT_TRUE(request_.Write(sockets_[0].get()));
237a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  ASSERT_TRUE(response_.Read(sockets_[0].get()));
238a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
239a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(kFuseSuccess, response_.header.error);
240a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(sizeof(fuse_out_header) + sizeof(fuse_attr_out),
241a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono            response_.header.len);
242a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(1u, response_.header.unique);
243a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
244a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(10u, response_.attr_out.attr_valid);
245a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr_valid_nsec);
246a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
247a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(static_cast<unsigned>(FUSE_ROOT_ID), response_.attr_out.attr.ino);
248a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.size);
249a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.blocks);
250a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.atime);
251a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.mtime);
252a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.ctime);
253a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.atimensec);
254a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.mtimensec);
255a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.ctimensec);
256a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(S_IFDIR | 0777u, response_.attr_out.attr.mode);
257a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.nlink);
258a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.uid);
259a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.gid);
260a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.rdev);
261a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.blksize);
262a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  EXPECT_EQ(0u, response_.attr_out.attr.padding);
263a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono}
264a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
265a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi HironoTEST_F(FuseAppLoopTest, Open) {
266a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  CheckCallback(sizeof(fuse_open_in), FUSE_OPEN, sizeof(fuse_open_out));
267a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono}
268a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
269a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi HironoTEST_F(FuseAppLoopTest, Fsync) {
270a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  CheckCallback(0u, FUSE_FSYNC, 0u);
271a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono}
272a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
273a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi HironoTEST_F(FuseAppLoopTest, Release) {
274a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  CheckCallback(0u, FUSE_RELEASE, 0u);
275a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono}
276a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
277a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi HironoTEST_F(FuseAppLoopTest, Read) {
278a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  CheckCallback(sizeof(fuse_read_in), FUSE_READ, 0u);
279a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono}
280a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
281a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi HironoTEST_F(FuseAppLoopTest, Write) {
282a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono  CheckCallback(sizeof(fuse_write_in), FUSE_WRITE, sizeof(fuse_write_out));
283a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono}
284a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono
285f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi HironoTEST_F(FuseAppLoopTest, Break) {
286f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono    // Ensure that the loop started.
287f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono    request_.Reset(sizeof(fuse_open_in), FUSE_OPEN, 1);
288f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono    request_.header.nodeid = 10;
289f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono    ASSERT_TRUE(request_.Write(sockets_[0]));
290f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono    ASSERT_TRUE(response_.Read(sockets_[0]));
291f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono
292f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono    loop_->Break();
293f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono    if (thread_.joinable()) {
294f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono        thread_.join();
295f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono    }
296f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono}
297f5d15f9fc4b8bd7a866660fe208bf857dea839baDaichi Hirono
298a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono}  // namespace fuse
299a0aecda12b9a76aa15a8c5175e15538574a05af7Daichi Hirono}  // namespace android
300