FuseBufferTest.cc 6.2 KB

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