1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/cdm/ppapi/cdm_file_io_test.h"
8 #include "base/callback_helpers.h"
9 #include "base/logging.h"
13 #define FILE_IO_DVLOG(level) DVLOG(level) << "File IO Test: "
15 const uint8 kData
[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
16 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
17 const uint32 kDataSize
= arraysize(kData
);
19 const uint8 kBigData
[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
20 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
21 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
22 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
24 const uint32 kBigDataSize
= arraysize(kBigData
);
26 // Must be > kReadSize in cdm_file_io_impl.cc.
27 const uint32 kLargeDataSize
= 20 * 1024 + 7;
29 // Macros to help add test cases/steps.
31 // |test_name| is also used as the file name. File name validity tests relies
33 #define START_TEST_CASE(test_name) \
35 FileIOTest test_case(create_file_io_cb_, test_name); \
36 CREATE_FILE_IO // Create FileIO for each test case.
38 #define ADD_TEST_STEP(type, status, data, data_size) \
39 test_case.AddTestStep(FileIOTest::type, cdm::FileIOClient::status, \
42 #define END_TEST_CASE \
43 remaining_tests_.push_back(test_case); \
46 #define CREATE_FILE_IO \
47 ADD_TEST_STEP(ACTION_CREATE, kSuccess, NULL, 0)
50 ADD_TEST_STEP(ACTION_OPEN, kSuccess, NULL, 0)
52 #define EXPECT_FILE_OPENED(status) \
53 ADD_TEST_STEP(RESULT_OPEN, status, NULL, 0)
56 ADD_TEST_STEP(ACTION_READ, kSuccess, NULL, 0)
58 #define EXPECT_FILE_READ(status, data, data_size) \
59 ADD_TEST_STEP(RESULT_READ, status, data, data_size)
61 #define WRITE_FILE(data, data_size) \
62 ADD_TEST_STEP(ACTION_WRITE, kSuccess, data, data_size)
64 #define EXPECT_FILE_WRITTEN(status) \
65 ADD_TEST_STEP(RESULT_WRITE, status, NULL, 0)
68 ADD_TEST_STEP(ACTION_CLOSE, kSuccess, NULL, 0)
70 // FileIOTestRunner implementation.
72 FileIOTestRunner::FileIOTestRunner(const CreateFileIOCB
& create_file_io_cb
)
73 : create_file_io_cb_(create_file_io_cb
),
75 num_passed_tests_(0) {
76 // Generate |large_data_|.
77 large_data_
.resize(kLargeDataSize
);
78 for (size_t i
= 0; i
< kLargeDataSize
; ++i
)
79 large_data_
[i
] = i
% kuint8max
;
84 FileIOTestRunner::~FileIOTestRunner() {
85 if (remaining_tests_
.empty())
88 DCHECK_LT(num_passed_tests_
, total_num_tests_
);
89 FILE_IO_DVLOG(1) << "Not Finished (probably due to timeout). "
90 << num_passed_tests_
<< " passed in "
91 << total_num_tests_
<< " tests.";
94 // Note: Consecutive expectations (EXPECT*) can happen in any order.
95 void FileIOTestRunner::AddTests() {
96 START_TEST_CASE("/FileNameStartsWithForwardSlash")
98 EXPECT_FILE_OPENED(kError
)
101 START_TEST_CASE("FileNameContains/ForwardSlash")
103 EXPECT_FILE_OPENED(kError
)
106 START_TEST_CASE("\\FileNameStartsWithBackslash")
108 EXPECT_FILE_OPENED(kError
)
111 START_TEST_CASE("FileNameContains\\Backslash")
113 EXPECT_FILE_OPENED(kError
)
116 START_TEST_CASE("_FileNameStartsWithUnderscore")
118 EXPECT_FILE_OPENED(kError
)
121 START_TEST_CASE("FileNameContains_Underscore")
123 EXPECT_FILE_OPENED(kSuccess
)
126 START_TEST_CASE("ReadBeforeOpeningFile")
128 EXPECT_FILE_READ(kError
, NULL
, 0)
131 START_TEST_CASE("WriteBeforeOpeningFile")
132 WRITE_FILE(kData
, kDataSize
)
133 EXPECT_FILE_WRITTEN(kError
)
136 START_TEST_CASE("ReadBeforeFileOpened")
139 EXPECT_FILE_OPENED(kSuccess
)
140 EXPECT_FILE_READ(kError
, NULL
, 0)
141 // After file opened, we can still do normal operations.
142 WRITE_FILE(kData
, kDataSize
)
143 EXPECT_FILE_WRITTEN(kSuccess
)
145 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
148 START_TEST_CASE("WriteBeforeFileOpened")
150 WRITE_FILE(kData
, kDataSize
)
151 EXPECT_FILE_WRITTEN(kError
)
152 EXPECT_FILE_OPENED(kSuccess
)
153 // After file opened, we can still do normal operations.
154 WRITE_FILE(kData
, kDataSize
)
155 EXPECT_FILE_WRITTEN(kSuccess
)
157 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
160 START_TEST_CASE("ReadDuringPendingRead")
162 EXPECT_FILE_OPENED(kSuccess
)
163 WRITE_FILE(kData
, kDataSize
)
164 EXPECT_FILE_WRITTEN(kSuccess
)
167 EXPECT_FILE_READ(kInUse
, NULL
, 0)
168 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
171 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
174 START_TEST_CASE("ReadDuringPendingWrite")
176 EXPECT_FILE_OPENED(kSuccess
)
177 WRITE_FILE(kData
, kDataSize
)
179 EXPECT_FILE_READ(kInUse
, NULL
, 0)
180 EXPECT_FILE_WRITTEN(kSuccess
)
183 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
186 START_TEST_CASE("WriteDuringPendingRead")
188 EXPECT_FILE_OPENED(kSuccess
)
190 WRITE_FILE(kData
, kDataSize
)
191 EXPECT_FILE_WRITTEN(kInUse
)
192 EXPECT_FILE_READ(kSuccess
, NULL
, 0)
193 // We can still do normal operations.
194 WRITE_FILE(kData
, kDataSize
)
195 EXPECT_FILE_WRITTEN(kSuccess
)
197 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
200 START_TEST_CASE("WriteDuringPendingWrite")
202 EXPECT_FILE_OPENED(kSuccess
)
203 WRITE_FILE(kData
, kDataSize
)
204 WRITE_FILE(kBigData
, kBigDataSize
)
205 EXPECT_FILE_WRITTEN(kInUse
)
206 EXPECT_FILE_WRITTEN(kSuccess
)
207 // Read to make sure original data (kData) is written.
209 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
212 START_TEST_CASE("ReadFileThatDoesNotExist")
214 EXPECT_FILE_OPENED(kSuccess
)
216 EXPECT_FILE_READ(kSuccess
, NULL
, 0)
219 START_TEST_CASE("WriteAndRead")
221 EXPECT_FILE_OPENED(kSuccess
)
222 WRITE_FILE(kData
, kDataSize
)
223 EXPECT_FILE_WRITTEN(kSuccess
)
225 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
228 START_TEST_CASE("WriteAndReadEmptyFile")
230 EXPECT_FILE_OPENED(kSuccess
)
232 EXPECT_FILE_WRITTEN(kSuccess
)
234 EXPECT_FILE_READ(kSuccess
, NULL
, 0)
237 START_TEST_CASE("WriteAndReadLargeData")
239 EXPECT_FILE_OPENED(kSuccess
)
240 WRITE_FILE(&large_data_
[0], kLargeDataSize
)
241 EXPECT_FILE_WRITTEN(kSuccess
)
243 EXPECT_FILE_READ(kSuccess
, &large_data_
[0], kLargeDataSize
)
246 START_TEST_CASE("OverwriteZeroBytes")
248 EXPECT_FILE_OPENED(kSuccess
)
249 WRITE_FILE(kData
, kDataSize
)
250 EXPECT_FILE_WRITTEN(kSuccess
)
252 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
254 EXPECT_FILE_WRITTEN(kSuccess
)
256 EXPECT_FILE_READ(kSuccess
, NULL
, 0)
259 START_TEST_CASE("OverwriteWithSmallerData")
261 EXPECT_FILE_OPENED(kSuccess
)
262 WRITE_FILE(kBigData
, kBigDataSize
)
263 EXPECT_FILE_WRITTEN(kSuccess
)
264 WRITE_FILE(kData
, kDataSize
)
265 EXPECT_FILE_WRITTEN(kSuccess
)
267 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
270 START_TEST_CASE("OverwriteWithLargerData")
272 EXPECT_FILE_OPENED(kSuccess
)
273 WRITE_FILE(kData
, kDataSize
)
274 EXPECT_FILE_WRITTEN(kSuccess
)
275 WRITE_FILE(kBigData
, kBigDataSize
)
276 EXPECT_FILE_WRITTEN(kSuccess
)
278 EXPECT_FILE_READ(kSuccess
, kBigData
, kBigDataSize
)
281 START_TEST_CASE("ReadExistingFile")
283 EXPECT_FILE_OPENED(kSuccess
)
284 WRITE_FILE(kData
, kDataSize
)
285 EXPECT_FILE_WRITTEN(kSuccess
)
289 EXPECT_FILE_OPENED(kSuccess
)
291 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
294 START_TEST_CASE("MultipleReadsAndWrites")
296 EXPECT_FILE_OPENED(kSuccess
)
297 // Read file which doesn't exist.
299 EXPECT_FILE_READ(kSuccess
, NULL
, 0)
300 // Write kData to file.
301 WRITE_FILE(kData
, kDataSize
)
302 EXPECT_FILE_WRITTEN(kSuccess
)
305 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
308 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
309 // Overwrite file with large data.
310 WRITE_FILE(&large_data_
[0], kLargeDataSize
)
311 EXPECT_FILE_WRITTEN(kSuccess
)
314 EXPECT_FILE_READ(kSuccess
, &large_data_
[0], kLargeDataSize
)
315 // Overwrite file with kData.
316 WRITE_FILE(kData
, kDataSize
)
317 EXPECT_FILE_WRITTEN(kSuccess
)
320 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
321 // Overwrite file with zero bytes.
323 EXPECT_FILE_WRITTEN(kSuccess
)
326 EXPECT_FILE_READ(kSuccess
, NULL
, 0)
329 START_TEST_CASE("OpenAfterOpen")
331 EXPECT_FILE_OPENED(kSuccess
)
333 EXPECT_FILE_OPENED(kError
)
336 START_TEST_CASE("OpenDuringPendingOpen")
339 EXPECT_FILE_OPENED(kError
) // The second Open() failed.
340 EXPECT_FILE_OPENED(kSuccess
) // The first Open() succeeded.
343 START_TEST_CASE("ReopenFileInSeparateFileIO")
345 EXPECT_FILE_OPENED(kSuccess
)
346 WRITE_FILE(kData
, kDataSize
)
347 EXPECT_FILE_WRITTEN(kSuccess
)
348 CREATE_FILE_IO
// Create a second FileIO without closing the first one.
350 EXPECT_FILE_OPENED(kInUse
)
353 START_TEST_CASE("CloseAfterCreation")
357 START_TEST_CASE("CloseDuringPendingOpen")
362 START_TEST_CASE("CloseDuringPendingWrite")
364 EXPECT_FILE_OPENED(kSuccess
)
365 // TODO(xhwang): Reenable this after http:://crbug.com/415401 is fixed.
366 // WRITE_FILE(kData, kDataSize)
370 START_TEST_CASE("CloseDuringPendingOverwriteWithLargerData")
372 EXPECT_FILE_OPENED(kSuccess
)
373 WRITE_FILE(kData
, kDataSize
)
374 EXPECT_FILE_WRITTEN(kSuccess
)
375 // TODO(xhwang): Reenable this after http:://crbug.com/415401 is fixed.
376 // WRITE_FILE(kBigData, kBigDataSize)
378 // Write() didn't finish and the content of the file is not modified.
381 EXPECT_FILE_OPENED(kSuccess
)
383 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
386 START_TEST_CASE("CloseDuringPendingOverwriteWithSmallerData")
388 EXPECT_FILE_OPENED(kSuccess
)
389 WRITE_FILE(kBigData
, kBigDataSize
)
390 EXPECT_FILE_WRITTEN(kSuccess
)
391 // TODO(xhwang): Reenable this after http:://crbug.com/415401 is fixed.
392 // WRITE_FILE(kData, kDataSize)
394 // Write() didn't finish and the content of the file is not modified.
397 EXPECT_FILE_OPENED(kSuccess
)
399 EXPECT_FILE_READ(kSuccess
, kBigData
, kBigDataSize
)
402 START_TEST_CASE("CloseDuringPendingRead")
404 EXPECT_FILE_OPENED(kSuccess
)
405 WRITE_FILE(kData
, kDataSize
)
406 EXPECT_FILE_WRITTEN(kSuccess
)
407 // TODO(xhwang): Reenable this after http:://crbug.com/415401 is fixed.
410 // Make sure the file is not modified.
413 EXPECT_FILE_OPENED(kSuccess
)
415 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
418 START_TEST_CASE("StressTest")
419 for (int i
= 0; i
< 100; ++i
) {
422 EXPECT_FILE_OPENED(kSuccess
)
423 WRITE_FILE(kData
, kDataSize
)
424 EXPECT_FILE_WRITTEN(kSuccess
)
425 // TODO(xhwang): Reenable this after http:://crbug.com/415401 is fixed.
426 // WRITE_FILE(kBigData, kBigDataSize)
428 // Make sure the file is not modified.
431 EXPECT_FILE_OPENED(kSuccess
)
433 EXPECT_FILE_READ(kSuccess
, kData
, kDataSize
)
439 void FileIOTestRunner::RunAllTests(const CompletionCB
& completion_cb
) {
440 completion_cb_
= completion_cb
;
441 total_num_tests_
= remaining_tests_
.size();
445 void FileIOTestRunner::RunNextTest() {
446 if (remaining_tests_
.empty()) {
447 FILE_IO_DVLOG(1) << num_passed_tests_
<< " passed and "
448 << (total_num_tests_
- num_passed_tests_
) << " failed in "
449 << total_num_tests_
<< " tests.";
450 bool success
= (num_passed_tests_
== total_num_tests_
);
451 base::ResetAndReturn(&completion_cb_
).Run(success
);
455 remaining_tests_
.front().Run(
456 base::Bind(&FileIOTestRunner::OnTestComplete
, base::Unretained(this)));
459 void FileIOTestRunner::OnTestComplete(bool success
) {
462 remaining_tests_
.pop_front();
466 // FileIOTest implementation.
468 FileIOTest::FileIOTest(const CreateFileIOCB
& create_file_io_cb
,
469 const std::string
& test_name
)
470 : create_file_io_cb_(create_file_io_cb
),
471 test_name_(test_name
) {}
473 FileIOTest::~FileIOTest() {}
475 void FileIOTest::AddTestStep(
476 StepType type
, Status status
, const uint8
* data
, uint32 data_size
) {
477 test_steps_
.push_back(TestStep(type
, status
, data
, data_size
));
480 void FileIOTest::Run(const CompletionCB
& completion_cb
) {
481 FILE_IO_DVLOG(3) << "Run " << test_name_
;
482 completion_cb_
= completion_cb
;
483 DCHECK(!test_steps_
.empty() && !IsResult(test_steps_
.front()));
487 void FileIOTest::OnOpenComplete(Status status
) {
488 OnResult(TestStep(RESULT_OPEN
, status
, NULL
, 0));
491 void FileIOTest::OnReadComplete(Status status
,
493 uint32_t data_size
) {
494 OnResult(TestStep(RESULT_READ
, status
, data
, data_size
));
497 void FileIOTest::OnWriteComplete(Status status
) {
498 OnResult(TestStep(RESULT_WRITE
, status
, NULL
, 0));
501 bool FileIOTest::IsResult(const TestStep
& test_step
) {
502 switch (test_step
.type
) {
518 bool FileIOTest::MatchesResult(const TestStep
& a
, const TestStep
& b
) {
519 DCHECK(IsResult(a
) && IsResult(b
));
520 if (a
.type
!= b
.type
|| a
.status
!= b
.status
)
523 if (a
.type
!= RESULT_READ
|| a
.status
!= cdm::FileIOClient::kSuccess
)
526 return (a
.data_size
== b
.data_size
&&
527 std::equal(a
.data
, a
.data
+ a
.data_size
, b
.data
));
530 void FileIOTest::RunNextStep() {
531 // Run all actions in the current action group.
532 while (!test_steps_
.empty()) {
533 // Start to wait for test results when the next step is a test result.
534 if (IsResult(test_steps_
.front()))
537 TestStep test_step
= test_steps_
.front();
538 test_steps_
.pop_front();
540 cdm::FileIO
* file_io
= file_io_stack_
.empty()? NULL
: file_io_stack_
.top();
542 switch (test_step
.type
) {
544 file_io
= create_file_io_cb_
.Run(this);
546 FILE_IO_DVLOG(3) << "Cannot create FileIO object.";
547 OnTestComplete(false);
550 file_io_stack_
.push(file_io
);
553 // Use test name as the test file name.
554 file_io
->Open(test_name_
.data(), test_name_
.size());
560 file_io
->Write(test_step
.data
, test_step
.data_size
);
564 file_io_stack_
.pop();
571 OnTestComplete(true);
574 void FileIOTest::OnResult(const TestStep
& result
) {
575 DCHECK(IsResult(result
));
576 if (!CheckResult(result
)) {
577 OnTestComplete(false);
584 bool FileIOTest::CheckResult(const TestStep
& result
) {
585 if (test_steps_
.empty() || !IsResult(test_steps_
.front()))
588 // If there are multiple results expected, the order does not matter.
589 std::list
<TestStep
>::iterator iter
= test_steps_
.begin();
590 for (; iter
!= test_steps_
.end(); ++iter
) {
591 if (!IsResult(*iter
))
594 if (!MatchesResult(*iter
, result
))
597 test_steps_
.erase(iter
);
604 void FileIOTest::OnTestComplete(bool success
) {
605 while (!file_io_stack_
.empty()) {
606 file_io_stack_
.top()->Close();
607 file_io_stack_
.pop();
609 FILE_IO_DVLOG(3) << test_name_
<< (success
? " PASSED" : " FAILED");
610 base::ResetAndReturn(&completion_cb_
).Run(success
);