diff options
Diffstat (limited to 'libappfuse/tests/AppFuseTest.cc')
-rw-r--r-- | libappfuse/tests/AppFuseTest.cc | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/libappfuse/tests/AppFuseTest.cc b/libappfuse/tests/AppFuseTest.cc new file mode 100644 index 000000000..8c2cc4712 --- /dev/null +++ b/libappfuse/tests/AppFuseTest.cc | |||
@@ -0,0 +1,187 @@ | |||
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/AppFuse.h" | ||
18 | |||
19 | #include <fcntl.h> | ||
20 | #include <string.h> | ||
21 | #include <sys/socket.h> | ||
22 | |||
23 | #include <android-base/unique_fd.h> | ||
24 | #include <gtest/gtest.h> | ||
25 | |||
26 | namespace android { | ||
27 | |||
28 | constexpr char kTempFile[] = "/data/local/tmp/appfuse_test_dump"; | ||
29 | |||
30 | void OpenTempFile(android::base::unique_fd* fd) { | ||
31 | fd->reset(open(kTempFile, O_CREAT | O_RDWR)); | ||
32 | ASSERT_NE(-1, *fd) << strerror(errno); | ||
33 | unlink(kTempFile); | ||
34 | ASSERT_NE(-1, *fd) << strerror(errno); | ||
35 | } | ||
36 | |||
37 | void TestReadInvalidLength(size_t headerSize, size_t write_size) { | ||
38 | android::base::unique_fd fd; | ||
39 | OpenTempFile(&fd); | ||
40 | |||
41 | char buffer[std::max(headerSize, sizeof(FuseRequest))]; | ||
42 | FuseRequest* const packet = reinterpret_cast<FuseRequest*>(buffer); | ||
43 | packet->header.len = headerSize; | ||
44 | ASSERT_NE(-1, write(fd, packet, write_size)) << strerror(errno); | ||
45 | |||
46 | lseek(fd, 0, SEEK_SET); | ||
47 | EXPECT_FALSE(packet->Read(fd)); | ||
48 | } | ||
49 | |||
50 | void TestWriteInvalidLength(size_t size) { | ||
51 | android::base::unique_fd fd; | ||
52 | OpenTempFile(&fd); | ||
53 | |||
54 | char buffer[std::max(size, sizeof(FuseRequest))]; | ||
55 | FuseRequest* const packet = reinterpret_cast<FuseRequest*>(buffer); | ||
56 | packet->header.len = size; | ||
57 | EXPECT_FALSE(packet->Write(fd)); | ||
58 | } | ||
59 | |||
60 | // Use FuseRequest as a template instance of FuseMessage. | ||
61 | |||
62 | TEST(FuseMessageTest, ReadAndWrite) { | ||
63 | android::base::unique_fd fd; | ||
64 | OpenTempFile(&fd); | ||
65 | |||
66 | FuseRequest request; | ||
67 | request.header.len = sizeof(FuseRequest); | ||
68 | request.header.opcode = 1; | ||
69 | request.header.unique = 2; | ||
70 | request.header.nodeid = 3; | ||
71 | request.header.uid = 4; | ||
72 | request.header.gid = 5; | ||
73 | request.header.pid = 6; | ||
74 | strcpy(request.lookup_name, "test"); | ||
75 | |||
76 | ASSERT_TRUE(request.Write(fd)); | ||
77 | |||
78 | memset(&request, 0, sizeof(FuseRequest)); | ||
79 | lseek(fd, 0, SEEK_SET); | ||
80 | |||
81 | ASSERT_TRUE(request.Read(fd)); | ||
82 | EXPECT_EQ(sizeof(FuseRequest), request.header.len); | ||
83 | EXPECT_EQ(1u, request.header.opcode); | ||
84 | EXPECT_EQ(2u, request.header.unique); | ||
85 | EXPECT_EQ(3u, request.header.nodeid); | ||
86 | EXPECT_EQ(4u, request.header.uid); | ||
87 | EXPECT_EQ(5u, request.header.gid); | ||
88 | EXPECT_EQ(6u, request.header.pid); | ||
89 | EXPECT_STREQ("test", request.lookup_name); | ||
90 | } | ||
91 | |||
92 | TEST(FuseMessageTest, Read_InconsistentLength) { | ||
93 | TestReadInvalidLength(sizeof(fuse_in_header), sizeof(fuse_in_header) + 1); | ||
94 | } | ||
95 | |||
96 | TEST(FuseMessageTest, Read_TooLong) { | ||
97 | TestReadInvalidLength(sizeof(FuseRequest) + 1, sizeof(FuseRequest) + 1); | ||
98 | } | ||
99 | |||
100 | TEST(FuseMessageTest, Read_TooShort) { | ||
101 | TestReadInvalidLength(sizeof(fuse_in_header) - 1, sizeof(fuse_in_header) - 1); | ||
102 | } | ||
103 | |||
104 | TEST(FuseMessageTest, Write_TooLong) { | ||
105 | TestWriteInvalidLength(sizeof(FuseRequest) + 1); | ||
106 | } | ||
107 | |||
108 | TEST(FuseMessageTest, Write_TooShort) { | ||
109 | TestWriteInvalidLength(sizeof(fuse_in_header) - 1); | ||
110 | } | ||
111 | |||
112 | TEST(FuseResponseTest, Reset) { | ||
113 | FuseResponse response; | ||
114 | // Write 1 to the first ten bytes. | ||
115 | memset(response.read_data, 'a', 10); | ||
116 | |||
117 | response.Reset(0, -1, 2); | ||
118 | EXPECT_EQ(sizeof(fuse_out_header), response.header.len); | ||
119 | EXPECT_EQ(-1, response.header.error); | ||
120 | EXPECT_EQ(2u, response.header.unique); | ||
121 | EXPECT_EQ('a', response.read_data[0]); | ||
122 | EXPECT_EQ('a', response.read_data[9]); | ||
123 | |||
124 | response.Reset(5, -4, 3); | ||
125 | EXPECT_EQ(sizeof(fuse_out_header) + 5, response.header.len); | ||
126 | EXPECT_EQ(-4, response.header.error); | ||
127 | EXPECT_EQ(3u, response.header.unique); | ||
128 | EXPECT_EQ(0, response.read_data[0]); | ||
129 | EXPECT_EQ(0, response.read_data[1]); | ||
130 | EXPECT_EQ(0, response.read_data[2]); | ||
131 | EXPECT_EQ(0, response.read_data[3]); | ||
132 | EXPECT_EQ(0, response.read_data[4]); | ||
133 | EXPECT_EQ('a', response.read_data[5]); | ||
134 | } | ||
135 | |||
136 | TEST(FuseResponseTest, ResetHeader) { | ||
137 | FuseResponse response; | ||
138 | // Write 1 to the first ten bytes. | ||
139 | memset(response.read_data, 'a', 10); | ||
140 | |||
141 | response.ResetHeader(0, -1, 2); | ||
142 | EXPECT_EQ(sizeof(fuse_out_header), response.header.len); | ||
143 | EXPECT_EQ(-1, response.header.error); | ||
144 | EXPECT_EQ(2u, response.header.unique); | ||
145 | EXPECT_EQ('a', response.read_data[0]); | ||
146 | EXPECT_EQ('a', response.read_data[9]); | ||
147 | |||
148 | response.ResetHeader(5, -4, 3); | ||
149 | EXPECT_EQ(sizeof(fuse_out_header) + 5, response.header.len); | ||
150 | EXPECT_EQ(-4, response.header.error); | ||
151 | EXPECT_EQ(3u, response.header.unique); | ||
152 | EXPECT_EQ('a', response.read_data[0]); | ||
153 | EXPECT_EQ('a', response.read_data[9]); | ||
154 | } | ||
155 | |||
156 | TEST(FuseBufferTest, HandleInit) { | ||
157 | FuseBuffer buffer; | ||
158 | memset(&buffer, 0, sizeof(FuseBuffer)); | ||
159 | |||
160 | buffer.request.header.opcode = FUSE_INIT; | ||
161 | buffer.request.init_in.major = FUSE_KERNEL_VERSION; | ||
162 | buffer.request.init_in.minor = FUSE_KERNEL_MINOR_VERSION; | ||
163 | |||
164 | buffer.HandleInit(); | ||
165 | |||
166 | ASSERT_EQ(sizeof(fuse_out_header) + sizeof(fuse_init_out), | ||
167 | buffer.response.header.len); | ||
168 | EXPECT_EQ(kFuseSuccess, buffer.response.header.error); | ||
169 | EXPECT_EQ(static_cast<unsigned int>(FUSE_KERNEL_VERSION), | ||
170 | buffer.response.init_out.major); | ||
171 | EXPECT_EQ(15u, buffer.response.init_out.minor); | ||
172 | EXPECT_EQ(static_cast<unsigned int>(FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES), | ||
173 | buffer.response.init_out.flags); | ||
174 | EXPECT_EQ(kFuseMaxWrite, buffer.response.init_out.max_write); | ||
175 | } | ||
176 | |||
177 | TEST(FuseBufferTest, HandleNotImpl) { | ||
178 | FuseBuffer buffer; | ||
179 | memset(&buffer, 0, sizeof(FuseBuffer)); | ||
180 | |||
181 | buffer.HandleNotImpl(); | ||
182 | |||
183 | ASSERT_EQ(sizeof(fuse_out_header), buffer.response.header.len); | ||
184 | EXPECT_EQ(-ENOSYS, buffer.response.header.error); | ||
185 | } | ||
186 | } | ||
187 | // namespace android | ||