blob: c9c9e62749f9f582f2ed451c25f411f88b6c5f96 [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>
Jerry Zhangbc1d4b42018-03-27 15:25:03 -070026#include <log/log.h>
Jerry Zhang487be612016-10-24 12:10:41 -070027
Jerry Zhang69b74502017-10-02 16:26:37 -070028#include "MtpDescriptors.h"
Jerry Zhang487be612016-10-24 12:10:41 -070029#include "MtpFfsHandle.h"
Jerry Zhangdf69dd32017-05-03 17:17:49 -070030#include "MtpFfsCompatHandle.h"
Jerry Zhang487be612016-10-24 12:10:41 -070031
32namespace android {
33
Jerry Zhangdf69dd32017-05-03 17:17:49 -070034constexpr int TEST_PACKET_SIZE = 500;
Jerry Zhang487be612016-10-24 12:10:41 -070035constexpr int SMALL_MULT = 30;
36constexpr int MED_MULT = 510;
37
38static const std::string dummyDataStr =
39 "/*\n * Copyright 2015 The Android Open Source Project\n *\n * Licensed un"
40 "der the Apache License, Version 2.0 (the \"License\");\n * you may not us"
41 "e this file except in compliance with the License.\n * You may obtain a c"
42 "opy of the License at\n *\n * http://www.apache.org/licenses/LICENSE"
43 "-2.0\n *\n * Unless required by applicable law or agreed to in writing, s"
44 "oftware\n * distributed under the License is distributed on an \"AS IS\" "
45 "BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express o"
Jerry Zhangdf69dd32017-05-03 17:17:49 -070046 "r im";
Jerry Zhang487be612016-10-24 12:10:41 -070047
Jerry Zhang8542fee2017-02-06 15:12:17 -080048/**
49 * Functional tests for the MtpFfsHandle class. Ensures header and data integrity
50 * by mocking ffs endpoints as pipes to capture input / output.
51 */
Jerry Zhangdf69dd32017-05-03 17:17:49 -070052template <class T>
Jerry Zhang487be612016-10-24 12:10:41 -070053class MtpFfsHandleTest : public ::testing::Test {
54protected:
Jerry Zhangdf69dd32017-05-03 17:17:49 -070055 std::unique_ptr<MtpFfsHandle> handle;
Jerry Zhang487be612016-10-24 12:10:41 -070056
57 // Pipes for reading endpoint data
Jerry Zhangdf69dd32017-05-03 17:17:49 -070058 android::base::unique_fd control;
Jerry Zhang487be612016-10-24 12:10:41 -070059 android::base::unique_fd bulk_in;
60 android::base::unique_fd bulk_out;
61 android::base::unique_fd intr;
62
63 TemporaryFile dummy_file;
64
65 MtpFfsHandleTest() {
66 int fd[2];
Jerry Zhang63dac452017-12-06 15:19:36 -080067 handle = std::make_unique<T>(-1);
Jerry Zhangdf69dd32017-05-03 17:17:49 -070068
69 EXPECT_EQ(pipe(fd), 0);
Jerry Zhang69b74502017-10-02 16:26:37 -070070 control.reset(fd[0]);
71 handle->mControl.reset(fd[1]);
Jerry Zhang487be612016-10-24 12:10:41 -070072
73 EXPECT_EQ(pipe(fd), 0);
74 EXPECT_EQ(fcntl(fd[0], F_SETPIPE_SZ, 1048576), 1048576);
75 bulk_in.reset(fd[0]);
Jerry Zhangdf69dd32017-05-03 17:17:49 -070076 handle->mBulkIn.reset(fd[1]);
Jerry Zhang487be612016-10-24 12:10:41 -070077
78 EXPECT_EQ(pipe(fd), 0);
79 EXPECT_EQ(fcntl(fd[0], F_SETPIPE_SZ, 1048576), 1048576);
80 bulk_out.reset(fd[1]);
Jerry Zhangdf69dd32017-05-03 17:17:49 -070081 handle->mBulkOut.reset(fd[0]);
Jerry Zhang487be612016-10-24 12:10:41 -070082
83 EXPECT_EQ(pipe(fd), 0);
84 intr.reset(fd[0]);
Jerry Zhangdf69dd32017-05-03 17:17:49 -070085 handle->mIntr.reset(fd[1]);
Jerry Zhang8542fee2017-02-06 15:12:17 -080086
Jerry Zhang63dac452017-12-06 15:19:36 -080087 EXPECT_EQ(handle->start(false), 0);
Jerry Zhang487be612016-10-24 12:10:41 -070088 }
89
Jerry Zhangdf69dd32017-05-03 17:17:49 -070090 ~MtpFfsHandleTest() {
91 handle->close();
92 }
Jerry Zhang487be612016-10-24 12:10:41 -070093};
94
Jerry Zhangdf69dd32017-05-03 17:17:49 -070095typedef ::testing::Types<MtpFfsHandle, MtpFfsCompatHandle> mtpHandles;
96TYPED_TEST_CASE(MtpFfsHandleTest, mtpHandles);
97
Jerry Zhang63dac452017-12-06 15:19:36 -080098TYPED_TEST(MtpFfsHandleTest, testMtpControl) {
99 EXPECT_TRUE(this->handle->writeDescriptors(false));
Jerry Zhang69b74502017-10-02 16:26:37 -0700100 struct desc_v2 desc;
101 struct functionfs_strings strings;
102 EXPECT_EQ(read(this->control, &desc, sizeof(desc)), (long)sizeof(desc));
103 EXPECT_EQ(read(this->control, &strings, sizeof(strings)), (long)sizeof(strings));
104 EXPECT_TRUE(std::memcmp(&desc, &mtp_desc_v2, sizeof(desc)) == 0);
105 EXPECT_TRUE(std::memcmp(&strings, &mtp_strings, sizeof(strings)) == 0);
106}
107
Jerry Zhang63dac452017-12-06 15:19:36 -0800108TYPED_TEST(MtpFfsHandleTest, testPtpControl) {
109 EXPECT_TRUE(this->handle->writeDescriptors(true));
110 struct desc_v2 desc;
111 struct functionfs_strings strings;
112 EXPECT_EQ(read(this->control, &desc, sizeof(desc)), (long)sizeof(desc));
113 EXPECT_EQ(read(this->control, &strings, sizeof(strings)), (long)sizeof(strings));
114 EXPECT_TRUE(std::memcmp(&desc, &ptp_desc_v2, sizeof(desc)) == 0);
115 EXPECT_TRUE(std::memcmp(&strings, &mtp_strings, sizeof(strings)) == 0);
116}
117
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700118TYPED_TEST(MtpFfsHandleTest, testRead) {
119 EXPECT_EQ(write(this->bulk_out, dummyDataStr.c_str(), TEST_PACKET_SIZE), TEST_PACKET_SIZE);
Jerry Zhang487be612016-10-24 12:10:41 -0700120 char buf[TEST_PACKET_SIZE + 1];
121 buf[TEST_PACKET_SIZE] = '\0';
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700122 EXPECT_EQ(this->handle->read(buf, TEST_PACKET_SIZE), TEST_PACKET_SIZE);
Jerry Zhang487be612016-10-24 12:10:41 -0700123 EXPECT_STREQ(buf, dummyDataStr.c_str());
124}
125
Jerry Zhang297912b2018-05-11 11:29:54 -0700126TYPED_TEST(MtpFfsHandleTest, testReadLarge) {
127 std::stringstream ss;
128 int size = TEST_PACKET_SIZE * MED_MULT;
129 char buf[size + 1];
130 buf[size] = '\0';
131
132 for (int i = 0; i < MED_MULT; i++)
133 ss << dummyDataStr;
134
135 EXPECT_EQ(write(this->bulk_out, ss.str().c_str(), size), size);
136 EXPECT_EQ(this->handle->read(buf, size), size);
137
138 EXPECT_STREQ(buf, ss.str().c_str());
139}
140
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700141TYPED_TEST(MtpFfsHandleTest, testWrite) {
Jerry Zhang487be612016-10-24 12:10:41 -0700142 char buf[TEST_PACKET_SIZE + 1];
143 buf[TEST_PACKET_SIZE] = '\0';
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700144 EXPECT_EQ(this->handle->write(dummyDataStr.c_str(), TEST_PACKET_SIZE), TEST_PACKET_SIZE);
145 EXPECT_EQ(read(this->bulk_in, buf, TEST_PACKET_SIZE), TEST_PACKET_SIZE);
Jerry Zhang487be612016-10-24 12:10:41 -0700146 EXPECT_STREQ(buf, dummyDataStr.c_str());
147}
148
Jerry Zhang297912b2018-05-11 11:29:54 -0700149TYPED_TEST(MtpFfsHandleTest, testWriteLarge) {
150 std::stringstream ss;
151 int size = TEST_PACKET_SIZE * MED_MULT;
152 char buf[size + 1];
153 buf[size] = '\0';
154
155 for (int i = 0; i < MED_MULT; i++)
156 ss << dummyDataStr;
157
158 EXPECT_EQ(this->handle->write(ss.str().c_str(), size), size);
159 EXPECT_EQ(read(this->bulk_in, buf, size), size);
160
161 EXPECT_STREQ(buf, ss.str().c_str());
162}
163
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700164TYPED_TEST(MtpFfsHandleTest, testReceiveFileEmpty) {
165 std::stringstream ss;
166 mtp_file_range mfr;
167 int size = 0;
168 char buf[size + 1];
169 buf[size] = '\0';
170
171 mfr.offset = 0;
172 mfr.length = size;
173 mfr.fd = this->dummy_file.fd;
174
175 EXPECT_EQ(write(this->bulk_out, ss.str().c_str(), size), size);
176 EXPECT_EQ(this->handle->receiveFile(mfr, false), 0);
177
178 EXPECT_EQ(read(this->dummy_file.fd, buf, size), size);
179}
180
181TYPED_TEST(MtpFfsHandleTest, testReceiveFileSmall) {
Jerry Zhang487be612016-10-24 12:10:41 -0700182 std::stringstream ss;
183 mtp_file_range mfr;
184 int size = TEST_PACKET_SIZE * SMALL_MULT;
185 char buf[size + 1];
186 buf[size] = '\0';
187
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700188 mfr.offset = 0;
Jerry Zhang487be612016-10-24 12:10:41 -0700189 mfr.length = size;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700190 mfr.fd = this->dummy_file.fd;
Jerry Zhang487be612016-10-24 12:10:41 -0700191 for (int i = 0; i < SMALL_MULT; i++)
192 ss << dummyDataStr;
193
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700194 EXPECT_EQ(write(this->bulk_out, ss.str().c_str(), size), size);
195 EXPECT_EQ(this->handle->receiveFile(mfr, false), 0);
Jerry Zhang487be612016-10-24 12:10:41 -0700196
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700197 EXPECT_EQ(read(this->dummy_file.fd, buf, size), size);
Jerry Zhang487be612016-10-24 12:10:41 -0700198
199 EXPECT_STREQ(buf, ss.str().c_str());
200}
201
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700202TYPED_TEST(MtpFfsHandleTest, testReceiveFileMed) {
Jerry Zhang487be612016-10-24 12:10:41 -0700203 std::stringstream ss;
204 mtp_file_range mfr;
205 int size = TEST_PACKET_SIZE * MED_MULT;
206 char buf[size + 1];
207 buf[size] = '\0';
208
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700209 mfr.offset = 0;
Jerry Zhang487be612016-10-24 12:10:41 -0700210 mfr.length = size;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700211 mfr.fd = this->dummy_file.fd;
Jerry Zhang487be612016-10-24 12:10:41 -0700212 for (int i = 0; i < MED_MULT; i++)
213 ss << dummyDataStr;
214
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700215 EXPECT_EQ(write(this->bulk_out, ss.str().c_str(), size), size);
216 EXPECT_EQ(this->handle->receiveFile(mfr, false), 0);
Jerry Zhang487be612016-10-24 12:10:41 -0700217
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700218 EXPECT_EQ(read(this->dummy_file.fd, buf, size), size);
Jerry Zhang487be612016-10-24 12:10:41 -0700219
220 EXPECT_STREQ(buf, ss.str().c_str());
221}
222
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700223TYPED_TEST(MtpFfsHandleTest, testReceiveFileMedPartial) {
224 std::stringstream ss;
225 mtp_file_range mfr;
226 int size = TEST_PACKET_SIZE * MED_MULT;
227 char buf[size + 1];
228 buf[size] = '\0';
229
230 mfr.fd = this->dummy_file.fd;
231 for (int i = 0; i < MED_MULT; i++)
232 ss << dummyDataStr;
233
234 EXPECT_EQ(write(this->bulk_out, ss.str().c_str(), size), size);
235
236 std::random_device rd;
237 std::mt19937 gen(rd());
238 std::uniform_int_distribution<> dis(1, TEST_PACKET_SIZE);
239 int offset = 0;
240 while (offset != size) {
241 mfr.offset = offset;
242 int length = std::min(size - offset, dis(gen));
243 mfr.length = length;
244
245 EXPECT_EQ(this->handle->receiveFile(mfr, false), 0);
246 offset += length;
247 }
248
249 EXPECT_EQ(read(this->dummy_file.fd, buf, size), size);
250
251 EXPECT_STREQ(buf, ss.str().c_str());
252}
253
254TYPED_TEST(MtpFfsHandleTest, testSendFileSmall) {
Jerry Zhang487be612016-10-24 12:10:41 -0700255 std::stringstream ss;
256 mtp_file_range mfr;
257 mfr.command = 42;
258 mfr.transaction_id = 1337;
Jerry Zhang8542fee2017-02-06 15:12:17 -0800259 mfr.offset = 0;
Jerry Zhang487be612016-10-24 12:10:41 -0700260 int size = TEST_PACKET_SIZE * SMALL_MULT;
261 char buf[size + sizeof(mtp_data_header) + 1];
262 buf[size + sizeof(mtp_data_header)] = '\0';
263
264 mfr.length = size;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700265 mfr.fd = this->dummy_file.fd;
Jerry Zhang487be612016-10-24 12:10:41 -0700266 for (int i = 0; i < SMALL_MULT; i++)
267 ss << dummyDataStr;
268
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700269 EXPECT_EQ(write(this->dummy_file.fd, ss.str().c_str(), size), size);
270 EXPECT_EQ(this->handle->sendFile(mfr), 0);
Jerry Zhang487be612016-10-24 12:10:41 -0700271
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700272 EXPECT_EQ(read(this->bulk_in, buf, size + sizeof(mtp_data_header)),
Jerry Zhang487be612016-10-24 12:10:41 -0700273 static_cast<long>(size + sizeof(mtp_data_header)));
274
275 struct mtp_data_header *header = reinterpret_cast<struct mtp_data_header*>(buf);
276 EXPECT_STREQ(buf + sizeof(mtp_data_header), ss.str().c_str());
277 EXPECT_EQ(header->length, static_cast<unsigned int>(size + sizeof(mtp_data_header)));
278 EXPECT_EQ(header->type, static_cast<unsigned int>(2));
279 EXPECT_EQ(header->command, static_cast<unsigned int>(42));
280 EXPECT_EQ(header->transaction_id, static_cast<unsigned int>(1337));
281}
282
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700283TYPED_TEST(MtpFfsHandleTest, testSendFileMed) {
Jerry Zhang487be612016-10-24 12:10:41 -0700284 std::stringstream ss;
285 mtp_file_range mfr;
286 mfr.command = 42;
287 mfr.transaction_id = 1337;
Jerry Zhang8542fee2017-02-06 15:12:17 -0800288 mfr.offset = 0;
Jerry Zhang487be612016-10-24 12:10:41 -0700289 int size = TEST_PACKET_SIZE * MED_MULT;
290 char buf[size + sizeof(mtp_data_header) + 1];
291 buf[size + sizeof(mtp_data_header)] = '\0';
292
293 mfr.length = size;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700294 mfr.fd = this->dummy_file.fd;
Jerry Zhang487be612016-10-24 12:10:41 -0700295 for (int i = 0; i < MED_MULT; i++)
296 ss << dummyDataStr;
297
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700298 EXPECT_EQ(write(this->dummy_file.fd, ss.str().c_str(), size), size);
299 EXPECT_EQ(this->handle->sendFile(mfr), 0);
Jerry Zhang487be612016-10-24 12:10:41 -0700300
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700301 EXPECT_EQ(read(this->bulk_in, buf, size + sizeof(mtp_data_header)),
Jerry Zhang487be612016-10-24 12:10:41 -0700302 static_cast<long>(size + sizeof(mtp_data_header)));
303
304 struct mtp_data_header *header = reinterpret_cast<struct mtp_data_header*>(buf);
305 EXPECT_STREQ(buf + sizeof(mtp_data_header), ss.str().c_str());
306 EXPECT_EQ(header->length, static_cast<unsigned int>(size + sizeof(mtp_data_header)));
307 EXPECT_EQ(header->type, static_cast<unsigned int>(2));
308 EXPECT_EQ(header->command, static_cast<unsigned int>(42));
309 EXPECT_EQ(header->transaction_id, static_cast<unsigned int>(1337));
310}
311
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700312TYPED_TEST(MtpFfsHandleTest, testSendFileMedPartial) {
Jerry Zhang8542fee2017-02-06 15:12:17 -0800313 std::stringstream ss;
314 mtp_file_range mfr;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700315 mfr.fd = this->dummy_file.fd;
Jerry Zhang8542fee2017-02-06 15:12:17 -0800316 mfr.command = 42;
317 mfr.transaction_id = 1337;
318 int size = TEST_PACKET_SIZE * MED_MULT;
319 char buf[size + 1];
320 buf[size] = '\0';
321
322 for (int i = 0; i < MED_MULT; i++)
323 ss << dummyDataStr;
324
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700325 EXPECT_EQ(write(this->dummy_file.fd, ss.str().c_str(), size), size);
Jerry Zhang8542fee2017-02-06 15:12:17 -0800326
327 std::random_device rd;
328 std::mt19937 gen(rd());
329 std::uniform_int_distribution<> dis(1, TEST_PACKET_SIZE);
330 int offset = 0;
331 while (offset != size) {
332 mfr.offset = offset;
333 int length = std::min(size - offset, dis(gen));
334 mfr.length = length;
335 char temp_buf[length + sizeof(mtp_data_header)];
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700336 EXPECT_EQ(this->handle->sendFile(mfr), 0);
Jerry Zhang8542fee2017-02-06 15:12:17 -0800337
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700338 EXPECT_EQ(read(this->bulk_in, temp_buf, length + sizeof(mtp_data_header)),
Jerry Zhang8542fee2017-02-06 15:12:17 -0800339 static_cast<long>(length + sizeof(mtp_data_header)));
340
341 struct mtp_data_header *header = reinterpret_cast<struct mtp_data_header*>(temp_buf);
342 EXPECT_EQ(header->length, static_cast<unsigned int>(length + sizeof(mtp_data_header)));
343 EXPECT_EQ(header->type, static_cast<unsigned int>(2));
344 EXPECT_EQ(header->command, static_cast<unsigned int>(42));
345 EXPECT_EQ(header->transaction_id, static_cast<unsigned int>(1337));
346 memcpy(buf + offset, temp_buf + sizeof(mtp_data_header), length);
347 offset += length;
348 }
349 EXPECT_STREQ(buf, ss.str().c_str());
350}
351
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700352TYPED_TEST(MtpFfsHandleTest, testSendFileEmpty) {
Jerry Zhang8542fee2017-02-06 15:12:17 -0800353 mtp_file_range mfr;
354 mfr.command = 42;
355 mfr.transaction_id = 1337;
356 mfr.offset = 0;
357 int size = 0;
358 char buf[size + sizeof(mtp_data_header) + 1];
359 buf[size + sizeof(mtp_data_header)] = '\0';
360
361 mfr.length = size;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700362 mfr.fd = this->dummy_file.fd;
Jerry Zhang8542fee2017-02-06 15:12:17 -0800363
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700364 EXPECT_EQ(this->handle->sendFile(mfr), 0);
Jerry Zhang8542fee2017-02-06 15:12:17 -0800365
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700366 EXPECT_EQ(read(this->bulk_in, buf, size + sizeof(mtp_data_header)),
Jerry Zhang8542fee2017-02-06 15:12:17 -0800367 static_cast<long>(size + sizeof(mtp_data_header)));
368
369 struct mtp_data_header *header = reinterpret_cast<struct mtp_data_header*>(buf);
370 EXPECT_EQ(header->length, static_cast<unsigned int>(size + sizeof(mtp_data_header)));
371 EXPECT_EQ(header->type, static_cast<unsigned int>(2));
372 EXPECT_EQ(header->command, static_cast<unsigned int>(42));
373 EXPECT_EQ(header->transaction_id, static_cast<unsigned int>(1337));
374}
375
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700376TYPED_TEST(MtpFfsHandleTest, testSendEvent) {
Jerry Zhang487be612016-10-24 12:10:41 -0700377 struct mtp_event event;
378 event.length = TEST_PACKET_SIZE;
379 event.data = const_cast<char*>(dummyDataStr.c_str());
380 char buf[TEST_PACKET_SIZE + 1];
381 buf[TEST_PACKET_SIZE] = '\0';
382
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700383 this->handle->sendEvent(event);
384 read(this->intr, buf, TEST_PACKET_SIZE);
Jerry Zhang487be612016-10-24 12:10:41 -0700385 EXPECT_STREQ(buf, dummyDataStr.c_str());
386}
387
388} // namespace android