1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specic language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "libappfuse/FuseBuffer.h" 18 19#include <fcntl.h> 20#include <string.h> 21#include <sys/socket.h> 22 23#include <thread> 24 25#include <android-base/unique_fd.h> 26#include <gtest/gtest.h> 27 28namespace android { 29namespace fuse { 30 31constexpr char kTempFile[] = "/data/local/tmp/appfuse_test_dump"; 32 33void OpenTempFile(android::base::unique_fd* fd) { 34 fd->reset(open(kTempFile, O_CREAT | O_RDWR, 0600)); 35 ASSERT_NE(-1, *fd) << strerror(errno); 36 unlink(kTempFile); 37 ASSERT_NE(-1, *fd) << strerror(errno); 38} 39 40void TestReadInvalidLength(size_t headerSize, size_t write_size) { 41 android::base::unique_fd fd; 42 OpenTempFile(&fd); 43 44 char buffer[std::max(headerSize, sizeof(FuseRequest))]; 45 FuseRequest* const packet = reinterpret_cast<FuseRequest*>(buffer); 46 packet->header.len = headerSize; 47 ASSERT_NE(-1, write(fd, packet, write_size)) << strerror(errno); 48 49 lseek(fd, 0, SEEK_SET); 50 EXPECT_FALSE(packet->Read(fd)); 51} 52 53void TestWriteInvalidLength(size_t size) { 54 android::base::unique_fd fd; 55 OpenTempFile(&fd); 56 57 char buffer[std::max(size, sizeof(FuseRequest))]; 58 FuseRequest* const packet = reinterpret_cast<FuseRequest*>(buffer); 59 packet->header.len = size; 60 EXPECT_FALSE(packet->Write(fd)); 61} 62 63// Use FuseRequest as a template instance of FuseMessage. 64 65TEST(FuseMessageTest, ReadAndWrite) { 66 android::base::unique_fd fd; 67 OpenTempFile(&fd); 68 69 FuseRequest request; 70 request.header.len = sizeof(FuseRequest); 71 request.header.opcode = 1; 72 request.header.unique = 2; 73 request.header.nodeid = 3; 74 request.header.uid = 4; 75 request.header.gid = 5; 76 request.header.pid = 6; 77 strcpy(request.lookup_name, "test"); 78 79 ASSERT_TRUE(request.Write(fd)); 80 81 memset(&request, 0, sizeof(FuseRequest)); 82 lseek(fd, 0, SEEK_SET); 83 84 ASSERT_TRUE(request.Read(fd)); 85 EXPECT_EQ(sizeof(FuseRequest), request.header.len); 86 EXPECT_EQ(1u, request.header.opcode); 87 EXPECT_EQ(2u, request.header.unique); 88 EXPECT_EQ(3u, request.header.nodeid); 89 EXPECT_EQ(4u, request.header.uid); 90 EXPECT_EQ(5u, request.header.gid); 91 EXPECT_EQ(6u, request.header.pid); 92 EXPECT_STREQ("test", request.lookup_name); 93} 94 95TEST(FuseMessageTest, Read_InconsistentLength) { 96 TestReadInvalidLength(sizeof(fuse_in_header), sizeof(fuse_in_header) + 1); 97} 98 99TEST(FuseMessageTest, Read_TooLong) { 100 TestReadInvalidLength(sizeof(FuseRequest) + 1, sizeof(FuseRequest) + 1); 101} 102 103TEST(FuseMessageTest, Read_TooShort) { 104 TestReadInvalidLength(sizeof(fuse_in_header) - 1, sizeof(fuse_in_header) - 1); 105} 106 107TEST(FuseMessageTest, Write_TooLong) { 108 TestWriteInvalidLength(sizeof(FuseRequest) + 1); 109} 110 111TEST(FuseMessageTest, Write_TooShort) { 112 TestWriteInvalidLength(sizeof(fuse_in_header) - 1); 113} 114 115TEST(FuseResponseTest, Reset) { 116 FuseResponse response; 117 // Write 1 to the first ten bytes. 118 memset(response.read_data, 'a', 10); 119 120 response.Reset(0, -1, 2); 121 EXPECT_EQ(sizeof(fuse_out_header), response.header.len); 122 EXPECT_EQ(-1, response.header.error); 123 EXPECT_EQ(2u, response.header.unique); 124 EXPECT_EQ('a', response.read_data[0]); 125 EXPECT_EQ('a', response.read_data[9]); 126 127 response.Reset(5, -4, 3); 128 EXPECT_EQ(sizeof(fuse_out_header) + 5, response.header.len); 129 EXPECT_EQ(-4, response.header.error); 130 EXPECT_EQ(3u, response.header.unique); 131 EXPECT_EQ(0, response.read_data[0]); 132 EXPECT_EQ(0, response.read_data[1]); 133 EXPECT_EQ(0, response.read_data[2]); 134 EXPECT_EQ(0, response.read_data[3]); 135 EXPECT_EQ(0, response.read_data[4]); 136 EXPECT_EQ('a', response.read_data[5]); 137} 138 139TEST(FuseResponseTest, ResetHeader) { 140 FuseResponse response; 141 // Write 1 to the first ten bytes. 142 memset(response.read_data, 'a', 10); 143 144 response.ResetHeader(0, -1, 2); 145 EXPECT_EQ(sizeof(fuse_out_header), response.header.len); 146 EXPECT_EQ(-1, response.header.error); 147 EXPECT_EQ(2u, response.header.unique); 148 EXPECT_EQ('a', response.read_data[0]); 149 EXPECT_EQ('a', response.read_data[9]); 150 151 response.ResetHeader(5, -4, 3); 152 EXPECT_EQ(sizeof(fuse_out_header) + 5, response.header.len); 153 EXPECT_EQ(-4, response.header.error); 154 EXPECT_EQ(3u, response.header.unique); 155 EXPECT_EQ('a', response.read_data[0]); 156 EXPECT_EQ('a', response.read_data[9]); 157} 158 159TEST(FuseBufferTest, HandleInit) { 160 FuseBuffer buffer; 161 memset(&buffer, 0, sizeof(FuseBuffer)); 162 163 buffer.request.header.opcode = FUSE_INIT; 164 buffer.request.init_in.major = FUSE_KERNEL_VERSION; 165 buffer.request.init_in.minor = FUSE_KERNEL_MINOR_VERSION; 166 167 buffer.HandleInit(); 168 169 ASSERT_EQ(sizeof(fuse_out_header) + FUSE_COMPAT_22_INIT_OUT_SIZE, 170 buffer.response.header.len); 171 EXPECT_EQ(kFuseSuccess, buffer.response.header.error); 172 EXPECT_EQ(static_cast<unsigned int>(FUSE_KERNEL_VERSION), 173 buffer.response.init_out.major); 174 EXPECT_EQ(15u, buffer.response.init_out.minor); 175 EXPECT_EQ(static_cast<unsigned int>(FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES), 176 buffer.response.init_out.flags); 177 EXPECT_EQ(kFuseMaxWrite, buffer.response.init_out.max_write); 178} 179 180TEST(FuseBufferTest, HandleNotImpl) { 181 FuseBuffer buffer; 182 memset(&buffer, 0, sizeof(FuseBuffer)); 183 184 buffer.HandleNotImpl(); 185 186 ASSERT_EQ(sizeof(fuse_out_header), buffer.response.header.len); 187 EXPECT_EQ(-ENOSYS, buffer.response.header.error); 188} 189 190TEST(SetupMessageSocketsTest, Stress) { 191 constexpr int kCount = 1000; 192 193 FuseRequest request; 194 request.header.len = sizeof(FuseRequest); 195 196 base::unique_fd fds[2]; 197 SetupMessageSockets(&fds); 198 199 std::thread thread([&fds] { 200 FuseRequest request; 201 for (int i = 0; i < kCount; ++i) { 202 ASSERT_TRUE(request.Read(fds[1])); 203 usleep(1000); 204 } 205 }); 206 207 for (int i = 0; i < kCount; ++i) { 208 ASSERT_TRUE(request.Write(fds[0])); 209 } 210 211 thread.join(); 212} 213 214} // namespace fuse 215} // namespace android 216