blob: 8d7301d0bb0447a2a1a088ffc043ba4b9485a932 [file] [log] [blame]
Jerry Zhang487be612016-10-24 12:10:41 -07001/*
2 * Copyright 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 specific language governing permissions and
14 * limitations under the License.
15 */
16#define LOG_TAG "MtpFfsHandle_test.cpp"
17
18#include <android-base/unique_fd.h>
19#include <android-base/test_utils.h>
20#include <fcntl.h>
21#include <gtest/gtest.h>
22#include <memory>
Jerry Zhang8542fee2017-02-06 15:12:17 -080023#include <random>
Jerry Zhang487be612016-10-24 12:10:41 -070024#include <string>
25#include <unistd.h>
26#include <utils/Log.h>
27
28#include "MtpFfsHandle.h"
Jerry Zhangdf69dd32017-05-03 17:17:49 -070029#include "MtpFfsCompatHandle.h"
Jerry Zhang487be612016-10-24 12:10:41 -070030
31namespace android {
32
Jerry Zhangdf69dd32017-05-03 17:17:49 -070033constexpr int TEST_PACKET_SIZE = 500;
Jerry Zhang487be612016-10-24 12:10:41 -070034constexpr int SMALL_MULT = 30;
35constexpr int MED_MULT = 510;
36
37static const std::string dummyDataStr =
38 "/*\n * Copyright 2015 The Android Open Source Project\n *\n * Licensed un"
39 "der the Apache License, Version 2.0 (the \"License\");\n * you may not us"
40 "e this file except in compliance with the License.\n * You may obtain a c"
41 "opy of the License at\n *\n * http://www.apache.org/licenses/LICENSE"
42 "-2.0\n *\n * Unless required by applicable law or agreed to in writing, s"
43 "oftware\n * distributed under the License is distributed on an \"AS IS\" "
44 "BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express o"
Jerry Zhangdf69dd32017-05-03 17:17:49 -070045 "r im";
Jerry Zhang487be612016-10-24 12:10:41 -070046
Jerry Zhang8542fee2017-02-06 15:12:17 -080047/**
48 * Functional tests for the MtpFfsHandle class. Ensures header and data integrity
49 * by mocking ffs endpoints as pipes to capture input / output.
50 */
Jerry Zhangdf69dd32017-05-03 17:17:49 -070051template <class T>
Jerry Zhang487be612016-10-24 12:10:41 -070052class MtpFfsHandleTest : public ::testing::Test {
53protected:
Jerry Zhangdf69dd32017-05-03 17:17:49 -070054 std::unique_ptr<MtpFfsHandle> handle;
Jerry Zhang487be612016-10-24 12:10:41 -070055
56 // Pipes for reading endpoint data
Jerry Zhangdf69dd32017-05-03 17:17:49 -070057 android::base::unique_fd control;
Jerry Zhang487be612016-10-24 12:10:41 -070058 android::base::unique_fd bulk_in;
59 android::base::unique_fd bulk_out;
60 android::base::unique_fd intr;
61
62 TemporaryFile dummy_file;
63
64 MtpFfsHandleTest() {
65 int fd[2];
Jerry Zhangdf69dd32017-05-03 17:17:49 -070066 handle = std::make_unique<T>();
67
68 EXPECT_EQ(pipe(fd), 0);
69 handle->mControl.reset(fd[0]);
70 control.reset(fd[1]);
Jerry Zhang487be612016-10-24 12:10:41 -070071
72 EXPECT_EQ(pipe(fd), 0);
73 EXPECT_EQ(fcntl(fd[0], F_SETPIPE_SZ, 1048576), 1048576);
74 bulk_in.reset(fd[0]);
Jerry Zhangdf69dd32017-05-03 17:17:49 -070075 handle->mBulkIn.reset(fd[1]);
Jerry Zhang487be612016-10-24 12:10:41 -070076
77 EXPECT_EQ(pipe(fd), 0);
78 EXPECT_EQ(fcntl(fd[0], F_SETPIPE_SZ, 1048576), 1048576);
79 bulk_out.reset(fd[1]);
Jerry Zhangdf69dd32017-05-03 17:17:49 -070080 handle->mBulkOut.reset(fd[0]);
Jerry Zhang487be612016-10-24 12:10:41 -070081
82 EXPECT_EQ(pipe(fd), 0);
83 intr.reset(fd[0]);
Jerry Zhangdf69dd32017-05-03 17:17:49 -070084 handle->mIntr.reset(fd[1]);
Jerry Zhang8542fee2017-02-06 15:12:17 -080085
Jerry Zhangdf69dd32017-05-03 17:17:49 -070086 handle->start();
Jerry Zhang487be612016-10-24 12:10:41 -070087 }
88
Jerry Zhangdf69dd32017-05-03 17:17:49 -070089 ~MtpFfsHandleTest() {
90 handle->close();
91 }
Jerry Zhang487be612016-10-24 12:10:41 -070092};
93
Jerry Zhangdf69dd32017-05-03 17:17:49 -070094typedef ::testing::Types<MtpFfsHandle, MtpFfsCompatHandle> mtpHandles;
95TYPED_TEST_CASE(MtpFfsHandleTest, mtpHandles);
96
97TYPED_TEST(MtpFfsHandleTest, testRead) {
98 EXPECT_EQ(write(this->bulk_out, dummyDataStr.c_str(), TEST_PACKET_SIZE), TEST_PACKET_SIZE);
Jerry Zhang487be612016-10-24 12:10:41 -070099 char buf[TEST_PACKET_SIZE + 1];
100 buf[TEST_PACKET_SIZE] = '\0';
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700101 EXPECT_EQ(this->handle->read(buf, TEST_PACKET_SIZE), TEST_PACKET_SIZE);
Jerry Zhang487be612016-10-24 12:10:41 -0700102 EXPECT_STREQ(buf, dummyDataStr.c_str());
103}
104
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700105TYPED_TEST(MtpFfsHandleTest, testWrite) {
Jerry Zhang487be612016-10-24 12:10:41 -0700106 char buf[TEST_PACKET_SIZE + 1];
107 buf[TEST_PACKET_SIZE] = '\0';
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700108 EXPECT_EQ(this->handle->write(dummyDataStr.c_str(), TEST_PACKET_SIZE), TEST_PACKET_SIZE);
109 EXPECT_EQ(read(this->bulk_in, buf, TEST_PACKET_SIZE), TEST_PACKET_SIZE);
Jerry Zhang487be612016-10-24 12:10:41 -0700110 EXPECT_STREQ(buf, dummyDataStr.c_str());
111}
112
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700113TYPED_TEST(MtpFfsHandleTest, testReceiveFileEmpty) {
114 std::stringstream ss;
115 mtp_file_range mfr;
116 int size = 0;
117 char buf[size + 1];
118 buf[size] = '\0';
119
120 mfr.offset = 0;
121 mfr.length = size;
122 mfr.fd = this->dummy_file.fd;
123
124 EXPECT_EQ(write(this->bulk_out, ss.str().c_str(), size), size);
125 EXPECT_EQ(this->handle->receiveFile(mfr, false), 0);
126
127 EXPECT_EQ(read(this->dummy_file.fd, buf, size), size);
128}
129
130TYPED_TEST(MtpFfsHandleTest, testReceiveFileSmall) {
Jerry Zhang487be612016-10-24 12:10:41 -0700131 std::stringstream ss;
132 mtp_file_range mfr;
133 int size = TEST_PACKET_SIZE * SMALL_MULT;
134 char buf[size + 1];
135 buf[size] = '\0';
136
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700137 mfr.offset = 0;
Jerry Zhang487be612016-10-24 12:10:41 -0700138 mfr.length = size;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700139 mfr.fd = this->dummy_file.fd;
Jerry Zhang487be612016-10-24 12:10:41 -0700140 for (int i = 0; i < SMALL_MULT; i++)
141 ss << dummyDataStr;
142
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700143 EXPECT_EQ(write(this->bulk_out, ss.str().c_str(), size), size);
144 EXPECT_EQ(this->handle->receiveFile(mfr, false), 0);
Jerry Zhang487be612016-10-24 12:10:41 -0700145
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700146 EXPECT_EQ(read(this->dummy_file.fd, buf, size), size);
Jerry Zhang487be612016-10-24 12:10:41 -0700147
148 EXPECT_STREQ(buf, ss.str().c_str());
149}
150
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700151TYPED_TEST(MtpFfsHandleTest, testReceiveFileMed) {
Jerry Zhang487be612016-10-24 12:10:41 -0700152 std::stringstream ss;
153 mtp_file_range mfr;
154 int size = TEST_PACKET_SIZE * MED_MULT;
155 char buf[size + 1];
156 buf[size] = '\0';
157
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700158 mfr.offset = 0;
Jerry Zhang487be612016-10-24 12:10:41 -0700159 mfr.length = size;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700160 mfr.fd = this->dummy_file.fd;
Jerry Zhang487be612016-10-24 12:10:41 -0700161 for (int i = 0; i < MED_MULT; i++)
162 ss << dummyDataStr;
163
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700164 EXPECT_EQ(write(this->bulk_out, ss.str().c_str(), size), size);
165 EXPECT_EQ(this->handle->receiveFile(mfr, false), 0);
Jerry Zhang487be612016-10-24 12:10:41 -0700166
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700167 EXPECT_EQ(read(this->dummy_file.fd, buf, size), size);
Jerry Zhang487be612016-10-24 12:10:41 -0700168
169 EXPECT_STREQ(buf, ss.str().c_str());
170}
171
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700172TYPED_TEST(MtpFfsHandleTest, testReceiveFileMedPartial) {
173 std::stringstream ss;
174 mtp_file_range mfr;
175 int size = TEST_PACKET_SIZE * MED_MULT;
176 char buf[size + 1];
177 buf[size] = '\0';
178
179 mfr.fd = this->dummy_file.fd;
180 for (int i = 0; i < MED_MULT; i++)
181 ss << dummyDataStr;
182
183 EXPECT_EQ(write(this->bulk_out, ss.str().c_str(), size), size);
184
185 std::random_device rd;
186 std::mt19937 gen(rd());
187 std::uniform_int_distribution<> dis(1, TEST_PACKET_SIZE);
188 int offset = 0;
189 while (offset != size) {
190 mfr.offset = offset;
191 int length = std::min(size - offset, dis(gen));
192 mfr.length = length;
193
194 EXPECT_EQ(this->handle->receiveFile(mfr, false), 0);
195 offset += length;
196 }
197
198 EXPECT_EQ(read(this->dummy_file.fd, buf, size), size);
199
200 EXPECT_STREQ(buf, ss.str().c_str());
201}
202
203TYPED_TEST(MtpFfsHandleTest, testSendFileSmall) {
Jerry Zhang487be612016-10-24 12:10:41 -0700204 std::stringstream ss;
205 mtp_file_range mfr;
206 mfr.command = 42;
207 mfr.transaction_id = 1337;
Jerry Zhang8542fee2017-02-06 15:12:17 -0800208 mfr.offset = 0;
Jerry Zhang487be612016-10-24 12:10:41 -0700209 int size = TEST_PACKET_SIZE * SMALL_MULT;
210 char buf[size + sizeof(mtp_data_header) + 1];
211 buf[size + sizeof(mtp_data_header)] = '\0';
212
213 mfr.length = size;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700214 mfr.fd = this->dummy_file.fd;
Jerry Zhang487be612016-10-24 12:10:41 -0700215 for (int i = 0; i < SMALL_MULT; i++)
216 ss << dummyDataStr;
217
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700218 EXPECT_EQ(write(this->dummy_file.fd, ss.str().c_str(), size), size);
219 EXPECT_EQ(this->handle->sendFile(mfr), 0);
Jerry Zhang487be612016-10-24 12:10:41 -0700220
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700221 EXPECT_EQ(read(this->bulk_in, buf, size + sizeof(mtp_data_header)),
Jerry Zhang487be612016-10-24 12:10:41 -0700222 static_cast<long>(size + sizeof(mtp_data_header)));
223
224 struct mtp_data_header *header = reinterpret_cast<struct mtp_data_header*>(buf);
225 EXPECT_STREQ(buf + sizeof(mtp_data_header), ss.str().c_str());
226 EXPECT_EQ(header->length, static_cast<unsigned int>(size + sizeof(mtp_data_header)));
227 EXPECT_EQ(header->type, static_cast<unsigned int>(2));
228 EXPECT_EQ(header->command, static_cast<unsigned int>(42));
229 EXPECT_EQ(header->transaction_id, static_cast<unsigned int>(1337));
230}
231
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700232TYPED_TEST(MtpFfsHandleTest, testSendFileMed) {
Jerry Zhang487be612016-10-24 12:10:41 -0700233 std::stringstream ss;
234 mtp_file_range mfr;
235 mfr.command = 42;
236 mfr.transaction_id = 1337;
Jerry Zhang8542fee2017-02-06 15:12:17 -0800237 mfr.offset = 0;
Jerry Zhang487be612016-10-24 12:10:41 -0700238 int size = TEST_PACKET_SIZE * MED_MULT;
239 char buf[size + sizeof(mtp_data_header) + 1];
240 buf[size + sizeof(mtp_data_header)] = '\0';
241
242 mfr.length = size;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700243 mfr.fd = this->dummy_file.fd;
Jerry Zhang487be612016-10-24 12:10:41 -0700244 for (int i = 0; i < MED_MULT; i++)
245 ss << dummyDataStr;
246
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700247 EXPECT_EQ(write(this->dummy_file.fd, ss.str().c_str(), size), size);
248 EXPECT_EQ(this->handle->sendFile(mfr), 0);
Jerry Zhang487be612016-10-24 12:10:41 -0700249
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700250 EXPECT_EQ(read(this->bulk_in, buf, size + sizeof(mtp_data_header)),
Jerry Zhang487be612016-10-24 12:10:41 -0700251 static_cast<long>(size + sizeof(mtp_data_header)));
252
253 struct mtp_data_header *header = reinterpret_cast<struct mtp_data_header*>(buf);
254 EXPECT_STREQ(buf + sizeof(mtp_data_header), ss.str().c_str());
255 EXPECT_EQ(header->length, static_cast<unsigned int>(size + sizeof(mtp_data_header)));
256 EXPECT_EQ(header->type, static_cast<unsigned int>(2));
257 EXPECT_EQ(header->command, static_cast<unsigned int>(42));
258 EXPECT_EQ(header->transaction_id, static_cast<unsigned int>(1337));
259}
260
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700261TYPED_TEST(MtpFfsHandleTest, testSendFileMedPartial) {
Jerry Zhang8542fee2017-02-06 15:12:17 -0800262 std::stringstream ss;
263 mtp_file_range mfr;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700264 mfr.fd = this->dummy_file.fd;
Jerry Zhang8542fee2017-02-06 15:12:17 -0800265 mfr.command = 42;
266 mfr.transaction_id = 1337;
267 int size = TEST_PACKET_SIZE * MED_MULT;
268 char buf[size + 1];
269 buf[size] = '\0';
270
271 for (int i = 0; i < MED_MULT; i++)
272 ss << dummyDataStr;
273
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700274 EXPECT_EQ(write(this->dummy_file.fd, ss.str().c_str(), size), size);
Jerry Zhang8542fee2017-02-06 15:12:17 -0800275
276 std::random_device rd;
277 std::mt19937 gen(rd());
278 std::uniform_int_distribution<> dis(1, TEST_PACKET_SIZE);
279 int offset = 0;
280 while (offset != size) {
281 mfr.offset = offset;
282 int length = std::min(size - offset, dis(gen));
283 mfr.length = length;
284 char temp_buf[length + sizeof(mtp_data_header)];
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700285 EXPECT_EQ(this->handle->sendFile(mfr), 0);
Jerry Zhang8542fee2017-02-06 15:12:17 -0800286
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700287 EXPECT_EQ(read(this->bulk_in, temp_buf, length + sizeof(mtp_data_header)),
Jerry Zhang8542fee2017-02-06 15:12:17 -0800288 static_cast<long>(length + sizeof(mtp_data_header)));
289
290 struct mtp_data_header *header = reinterpret_cast<struct mtp_data_header*>(temp_buf);
291 EXPECT_EQ(header->length, static_cast<unsigned int>(length + sizeof(mtp_data_header)));
292 EXPECT_EQ(header->type, static_cast<unsigned int>(2));
293 EXPECT_EQ(header->command, static_cast<unsigned int>(42));
294 EXPECT_EQ(header->transaction_id, static_cast<unsigned int>(1337));
295 memcpy(buf + offset, temp_buf + sizeof(mtp_data_header), length);
296 offset += length;
297 }
298 EXPECT_STREQ(buf, ss.str().c_str());
299}
300
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700301TYPED_TEST(MtpFfsHandleTest, testSendFileEmpty) {
Jerry Zhang8542fee2017-02-06 15:12:17 -0800302 mtp_file_range mfr;
303 mfr.command = 42;
304 mfr.transaction_id = 1337;
305 mfr.offset = 0;
306 int size = 0;
307 char buf[size + sizeof(mtp_data_header) + 1];
308 buf[size + sizeof(mtp_data_header)] = '\0';
309
310 mfr.length = size;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700311 mfr.fd = this->dummy_file.fd;
Jerry Zhang8542fee2017-02-06 15:12:17 -0800312
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700313 EXPECT_EQ(this->handle->sendFile(mfr), 0);
Jerry Zhang8542fee2017-02-06 15:12:17 -0800314
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700315 EXPECT_EQ(read(this->bulk_in, buf, size + sizeof(mtp_data_header)),
Jerry Zhang8542fee2017-02-06 15:12:17 -0800316 static_cast<long>(size + sizeof(mtp_data_header)));
317
318 struct mtp_data_header *header = reinterpret_cast<struct mtp_data_header*>(buf);
319 EXPECT_EQ(header->length, static_cast<unsigned int>(size + sizeof(mtp_data_header)));
320 EXPECT_EQ(header->type, static_cast<unsigned int>(2));
321 EXPECT_EQ(header->command, static_cast<unsigned int>(42));
322 EXPECT_EQ(header->transaction_id, static_cast<unsigned int>(1337));
323}
324
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700325TYPED_TEST(MtpFfsHandleTest, testSendEvent) {
Jerry Zhang487be612016-10-24 12:10:41 -0700326 struct mtp_event event;
327 event.length = TEST_PACKET_SIZE;
328 event.data = const_cast<char*>(dummyDataStr.c_str());
329 char buf[TEST_PACKET_SIZE + 1];
330 buf[TEST_PACKET_SIZE] = '\0';
331
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700332 this->handle->sendEvent(event);
333 read(this->intr, buf, TEST_PACKET_SIZE);
Jerry Zhang487be612016-10-24 12:10:41 -0700334 EXPECT_STREQ(buf, dummyDataStr.c_str());
335}
336
337} // namespace android