blob: 2174893907222992f2f9ea20626ad23d2c4f5ed5 [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
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 Zhangdf69dd32017-05-03 17:17:49 -0700126TYPED_TEST(MtpFfsHandleTest, testWrite) {
Jerry Zhang487be612016-10-24 12:10:41 -0700127 char buf[TEST_PACKET_SIZE + 1];
128 buf[TEST_PACKET_SIZE] = '\0';
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700129 EXPECT_EQ(this->handle->write(dummyDataStr.c_str(), TEST_PACKET_SIZE), TEST_PACKET_SIZE);
130 EXPECT_EQ(read(this->bulk_in, buf, TEST_PACKET_SIZE), TEST_PACKET_SIZE);
Jerry Zhang487be612016-10-24 12:10:41 -0700131 EXPECT_STREQ(buf, dummyDataStr.c_str());
132}
133
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700134TYPED_TEST(MtpFfsHandleTest, testReceiveFileEmpty) {
135 std::stringstream ss;
136 mtp_file_range mfr;
137 int size = 0;
138 char buf[size + 1];
139 buf[size] = '\0';
140
141 mfr.offset = 0;
142 mfr.length = size;
143 mfr.fd = this->dummy_file.fd;
144
145 EXPECT_EQ(write(this->bulk_out, ss.str().c_str(), size), size);
146 EXPECT_EQ(this->handle->receiveFile(mfr, false), 0);
147
148 EXPECT_EQ(read(this->dummy_file.fd, buf, size), size);
149}
150
151TYPED_TEST(MtpFfsHandleTest, testReceiveFileSmall) {
Jerry Zhang487be612016-10-24 12:10:41 -0700152 std::stringstream ss;
153 mtp_file_range mfr;
154 int size = TEST_PACKET_SIZE * SMALL_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 < SMALL_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, testReceiveFileMed) {
Jerry Zhang487be612016-10-24 12:10:41 -0700173 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
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700179 mfr.offset = 0;
Jerry Zhang487be612016-10-24 12:10:41 -0700180 mfr.length = size;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700181 mfr.fd = this->dummy_file.fd;
Jerry Zhang487be612016-10-24 12:10:41 -0700182 for (int i = 0; i < MED_MULT; i++)
183 ss << dummyDataStr;
184
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700185 EXPECT_EQ(write(this->bulk_out, ss.str().c_str(), size), size);
186 EXPECT_EQ(this->handle->receiveFile(mfr, false), 0);
Jerry Zhang487be612016-10-24 12:10:41 -0700187
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700188 EXPECT_EQ(read(this->dummy_file.fd, buf, size), size);
Jerry Zhang487be612016-10-24 12:10:41 -0700189
190 EXPECT_STREQ(buf, ss.str().c_str());
191}
192
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700193TYPED_TEST(MtpFfsHandleTest, testReceiveFileMedPartial) {
194 std::stringstream ss;
195 mtp_file_range mfr;
196 int size = TEST_PACKET_SIZE * MED_MULT;
197 char buf[size + 1];
198 buf[size] = '\0';
199
200 mfr.fd = this->dummy_file.fd;
201 for (int i = 0; i < MED_MULT; i++)
202 ss << dummyDataStr;
203
204 EXPECT_EQ(write(this->bulk_out, ss.str().c_str(), size), size);
205
206 std::random_device rd;
207 std::mt19937 gen(rd());
208 std::uniform_int_distribution<> dis(1, TEST_PACKET_SIZE);
209 int offset = 0;
210 while (offset != size) {
211 mfr.offset = offset;
212 int length = std::min(size - offset, dis(gen));
213 mfr.length = length;
214
215 EXPECT_EQ(this->handle->receiveFile(mfr, false), 0);
216 offset += length;
217 }
218
219 EXPECT_EQ(read(this->dummy_file.fd, buf, size), size);
220
221 EXPECT_STREQ(buf, ss.str().c_str());
222}
223
224TYPED_TEST(MtpFfsHandleTest, testSendFileSmall) {
Jerry Zhang487be612016-10-24 12:10:41 -0700225 std::stringstream ss;
226 mtp_file_range mfr;
227 mfr.command = 42;
228 mfr.transaction_id = 1337;
Jerry Zhang8542fee2017-02-06 15:12:17 -0800229 mfr.offset = 0;
Jerry Zhang487be612016-10-24 12:10:41 -0700230 int size = TEST_PACKET_SIZE * SMALL_MULT;
231 char buf[size + sizeof(mtp_data_header) + 1];
232 buf[size + sizeof(mtp_data_header)] = '\0';
233
234 mfr.length = size;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700235 mfr.fd = this->dummy_file.fd;
Jerry Zhang487be612016-10-24 12:10:41 -0700236 for (int i = 0; i < SMALL_MULT; i++)
237 ss << dummyDataStr;
238
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700239 EXPECT_EQ(write(this->dummy_file.fd, ss.str().c_str(), size), size);
240 EXPECT_EQ(this->handle->sendFile(mfr), 0);
Jerry Zhang487be612016-10-24 12:10:41 -0700241
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700242 EXPECT_EQ(read(this->bulk_in, buf, size + sizeof(mtp_data_header)),
Jerry Zhang487be612016-10-24 12:10:41 -0700243 static_cast<long>(size + sizeof(mtp_data_header)));
244
245 struct mtp_data_header *header = reinterpret_cast<struct mtp_data_header*>(buf);
246 EXPECT_STREQ(buf + sizeof(mtp_data_header), ss.str().c_str());
247 EXPECT_EQ(header->length, static_cast<unsigned int>(size + sizeof(mtp_data_header)));
248 EXPECT_EQ(header->type, static_cast<unsigned int>(2));
249 EXPECT_EQ(header->command, static_cast<unsigned int>(42));
250 EXPECT_EQ(header->transaction_id, static_cast<unsigned int>(1337));
251}
252
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700253TYPED_TEST(MtpFfsHandleTest, testSendFileMed) {
Jerry Zhang487be612016-10-24 12:10:41 -0700254 std::stringstream ss;
255 mtp_file_range mfr;
256 mfr.command = 42;
257 mfr.transaction_id = 1337;
Jerry Zhang8542fee2017-02-06 15:12:17 -0800258 mfr.offset = 0;
Jerry Zhang487be612016-10-24 12:10:41 -0700259 int size = TEST_PACKET_SIZE * MED_MULT;
260 char buf[size + sizeof(mtp_data_header) + 1];
261 buf[size + sizeof(mtp_data_header)] = '\0';
262
263 mfr.length = size;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700264 mfr.fd = this->dummy_file.fd;
Jerry Zhang487be612016-10-24 12:10:41 -0700265 for (int i = 0; i < MED_MULT; i++)
266 ss << dummyDataStr;
267
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700268 EXPECT_EQ(write(this->dummy_file.fd, ss.str().c_str(), size), size);
269 EXPECT_EQ(this->handle->sendFile(mfr), 0);
Jerry Zhang487be612016-10-24 12:10:41 -0700270
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700271 EXPECT_EQ(read(this->bulk_in, buf, size + sizeof(mtp_data_header)),
Jerry Zhang487be612016-10-24 12:10:41 -0700272 static_cast<long>(size + sizeof(mtp_data_header)));
273
274 struct mtp_data_header *header = reinterpret_cast<struct mtp_data_header*>(buf);
275 EXPECT_STREQ(buf + sizeof(mtp_data_header), ss.str().c_str());
276 EXPECT_EQ(header->length, static_cast<unsigned int>(size + sizeof(mtp_data_header)));
277 EXPECT_EQ(header->type, static_cast<unsigned int>(2));
278 EXPECT_EQ(header->command, static_cast<unsigned int>(42));
279 EXPECT_EQ(header->transaction_id, static_cast<unsigned int>(1337));
280}
281
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700282TYPED_TEST(MtpFfsHandleTest, testSendFileMedPartial) {
Jerry Zhang8542fee2017-02-06 15:12:17 -0800283 std::stringstream ss;
284 mtp_file_range mfr;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700285 mfr.fd = this->dummy_file.fd;
Jerry Zhang8542fee2017-02-06 15:12:17 -0800286 mfr.command = 42;
287 mfr.transaction_id = 1337;
288 int size = TEST_PACKET_SIZE * MED_MULT;
289 char buf[size + 1];
290 buf[size] = '\0';
291
292 for (int i = 0; i < MED_MULT; i++)
293 ss << dummyDataStr;
294
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700295 EXPECT_EQ(write(this->dummy_file.fd, ss.str().c_str(), size), size);
Jerry Zhang8542fee2017-02-06 15:12:17 -0800296
297 std::random_device rd;
298 std::mt19937 gen(rd());
299 std::uniform_int_distribution<> dis(1, TEST_PACKET_SIZE);
300 int offset = 0;
301 while (offset != size) {
302 mfr.offset = offset;
303 int length = std::min(size - offset, dis(gen));
304 mfr.length = length;
305 char temp_buf[length + sizeof(mtp_data_header)];
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700306 EXPECT_EQ(this->handle->sendFile(mfr), 0);
Jerry Zhang8542fee2017-02-06 15:12:17 -0800307
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700308 EXPECT_EQ(read(this->bulk_in, temp_buf, length + sizeof(mtp_data_header)),
Jerry Zhang8542fee2017-02-06 15:12:17 -0800309 static_cast<long>(length + sizeof(mtp_data_header)));
310
311 struct mtp_data_header *header = reinterpret_cast<struct mtp_data_header*>(temp_buf);
312 EXPECT_EQ(header->length, static_cast<unsigned int>(length + sizeof(mtp_data_header)));
313 EXPECT_EQ(header->type, static_cast<unsigned int>(2));
314 EXPECT_EQ(header->command, static_cast<unsigned int>(42));
315 EXPECT_EQ(header->transaction_id, static_cast<unsigned int>(1337));
316 memcpy(buf + offset, temp_buf + sizeof(mtp_data_header), length);
317 offset += length;
318 }
319 EXPECT_STREQ(buf, ss.str().c_str());
320}
321
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700322TYPED_TEST(MtpFfsHandleTest, testSendFileEmpty) {
Jerry Zhang8542fee2017-02-06 15:12:17 -0800323 mtp_file_range mfr;
324 mfr.command = 42;
325 mfr.transaction_id = 1337;
326 mfr.offset = 0;
327 int size = 0;
328 char buf[size + sizeof(mtp_data_header) + 1];
329 buf[size + sizeof(mtp_data_header)] = '\0';
330
331 mfr.length = size;
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700332 mfr.fd = this->dummy_file.fd;
Jerry Zhang8542fee2017-02-06 15:12:17 -0800333
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700334 EXPECT_EQ(this->handle->sendFile(mfr), 0);
Jerry Zhang8542fee2017-02-06 15:12:17 -0800335
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700336 EXPECT_EQ(read(this->bulk_in, buf, size + sizeof(mtp_data_header)),
Jerry Zhang8542fee2017-02-06 15:12:17 -0800337 static_cast<long>(size + sizeof(mtp_data_header)));
338
339 struct mtp_data_header *header = reinterpret_cast<struct mtp_data_header*>(buf);
340 EXPECT_EQ(header->length, static_cast<unsigned int>(size + sizeof(mtp_data_header)));
341 EXPECT_EQ(header->type, static_cast<unsigned int>(2));
342 EXPECT_EQ(header->command, static_cast<unsigned int>(42));
343 EXPECT_EQ(header->transaction_id, static_cast<unsigned int>(1337));
344}
345
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700346TYPED_TEST(MtpFfsHandleTest, testSendEvent) {
Jerry Zhang487be612016-10-24 12:10:41 -0700347 struct mtp_event event;
348 event.length = TEST_PACKET_SIZE;
349 event.data = const_cast<char*>(dummyDataStr.c_str());
350 char buf[TEST_PACKET_SIZE + 1];
351 buf[TEST_PACKET_SIZE] = '\0';
352
Jerry Zhangdf69dd32017-05-03 17:17:49 -0700353 this->handle->sendEvent(event);
354 read(this->intr, buf, TEST_PACKET_SIZE);
Jerry Zhang487be612016-10-24 12:10:41 -0700355 EXPECT_STREQ(buf, dummyDataStr.c_str());
356}
357
358} // namespace android