base::ManualConstructor improvements
[chromium-blink-merge.git] / media / cdm / ppapi / cdm_file_io_test.cc
blob2252e2c2a1de1834ada448ff7fb0cc53b55cd803
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"
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/logging.h"
11 namespace media {
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,
23 0x00 };
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
32 // on this to work.
33 #define START_TEST_CASE(test_name) \
34 do { \
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, \
40 (data), (data_size));
42 #define END_TEST_CASE \
43 remaining_tests_.push_back(test_case); \
44 } while(0);
46 #define CREATE_FILE_IO \
47 ADD_TEST_STEP(ACTION_CREATE, kSuccess, NULL, 0)
49 #define OPEN_FILE \
50 ADD_TEST_STEP(ACTION_OPEN, kSuccess, NULL, 0)
52 #define EXPECT_FILE_OPENED(status) \
53 ADD_TEST_STEP(RESULT_OPEN, status, NULL, 0)
55 #define READ_FILE \
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)
67 #define CLOSE_FILE \
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),
74 total_num_tests_(0),
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;
81 AddTests();
84 FileIOTestRunner::~FileIOTestRunner() {
85 if (remaining_tests_.empty())
86 return;
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")
97 OPEN_FILE
98 EXPECT_FILE_OPENED(kError)
99 END_TEST_CASE
101 START_TEST_CASE("FileNameContains/ForwardSlash")
102 OPEN_FILE
103 EXPECT_FILE_OPENED(kError)
104 END_TEST_CASE
106 START_TEST_CASE("\\FileNameStartsWithBackslash")
107 OPEN_FILE
108 EXPECT_FILE_OPENED(kError)
109 END_TEST_CASE
111 START_TEST_CASE("FileNameContains\\Backslash")
112 OPEN_FILE
113 EXPECT_FILE_OPENED(kError)
114 END_TEST_CASE
116 START_TEST_CASE("_FileNameStartsWithUnderscore")
117 OPEN_FILE
118 EXPECT_FILE_OPENED(kError)
119 END_TEST_CASE
121 START_TEST_CASE("FileNameContains_Underscore")
122 OPEN_FILE
123 EXPECT_FILE_OPENED(kSuccess)
124 END_TEST_CASE
126 START_TEST_CASE("ReadBeforeOpeningFile")
127 READ_FILE
128 EXPECT_FILE_READ(kError, NULL, 0)
129 END_TEST_CASE
131 START_TEST_CASE("WriteBeforeOpeningFile")
132 WRITE_FILE(kData, kDataSize)
133 EXPECT_FILE_WRITTEN(kError)
134 END_TEST_CASE
136 START_TEST_CASE("ReadBeforeFileOpened")
137 OPEN_FILE
138 READ_FILE
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)
144 READ_FILE
145 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
146 END_TEST_CASE
148 START_TEST_CASE("WriteBeforeFileOpened")
149 OPEN_FILE
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)
156 READ_FILE
157 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
158 END_TEST_CASE
160 START_TEST_CASE("ReadDuringPendingRead")
161 OPEN_FILE
162 EXPECT_FILE_OPENED(kSuccess)
163 WRITE_FILE(kData, kDataSize)
164 EXPECT_FILE_WRITTEN(kSuccess)
165 READ_FILE
166 READ_FILE
167 EXPECT_FILE_READ(kInUse, NULL, 0)
168 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
169 // Read again.
170 READ_FILE
171 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
172 END_TEST_CASE
174 START_TEST_CASE("ReadDuringPendingWrite")
175 OPEN_FILE
176 EXPECT_FILE_OPENED(kSuccess)
177 WRITE_FILE(kData, kDataSize)
178 READ_FILE
179 EXPECT_FILE_READ(kInUse, NULL, 0)
180 EXPECT_FILE_WRITTEN(kSuccess)
181 // Read again.
182 READ_FILE
183 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
184 END_TEST_CASE
186 START_TEST_CASE("WriteDuringPendingRead")
187 OPEN_FILE
188 EXPECT_FILE_OPENED(kSuccess)
189 READ_FILE
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)
196 READ_FILE
197 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
198 END_TEST_CASE
200 START_TEST_CASE("WriteDuringPendingWrite")
201 OPEN_FILE
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.
208 READ_FILE
209 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
210 END_TEST_CASE
212 START_TEST_CASE("ReadFileThatDoesNotExist")
213 OPEN_FILE
214 EXPECT_FILE_OPENED(kSuccess)
215 READ_FILE
216 EXPECT_FILE_READ(kSuccess, NULL, 0)
217 END_TEST_CASE
219 START_TEST_CASE("WriteAndRead")
220 OPEN_FILE
221 EXPECT_FILE_OPENED(kSuccess)
222 WRITE_FILE(kData, kDataSize)
223 EXPECT_FILE_WRITTEN(kSuccess)
224 READ_FILE
225 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
226 END_TEST_CASE
228 START_TEST_CASE("WriteAndReadEmptyFile")
229 OPEN_FILE
230 EXPECT_FILE_OPENED(kSuccess)
231 WRITE_FILE(NULL, 0)
232 EXPECT_FILE_WRITTEN(kSuccess)
233 READ_FILE
234 EXPECT_FILE_READ(kSuccess, NULL, 0)
235 END_TEST_CASE
237 START_TEST_CASE("WriteAndReadLargeData")
238 OPEN_FILE
239 EXPECT_FILE_OPENED(kSuccess)
240 WRITE_FILE(&large_data_[0], kLargeDataSize)
241 EXPECT_FILE_WRITTEN(kSuccess)
242 READ_FILE
243 EXPECT_FILE_READ(kSuccess, &large_data_[0], kLargeDataSize)
244 END_TEST_CASE
246 START_TEST_CASE("OverwriteZeroBytes")
247 OPEN_FILE
248 EXPECT_FILE_OPENED(kSuccess)
249 WRITE_FILE(kData, kDataSize)
250 EXPECT_FILE_WRITTEN(kSuccess)
251 READ_FILE
252 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
253 WRITE_FILE(NULL, 0)
254 EXPECT_FILE_WRITTEN(kSuccess)
255 READ_FILE
256 EXPECT_FILE_READ(kSuccess, NULL, 0)
257 END_TEST_CASE
259 START_TEST_CASE("OverwriteWithSmallerData")
260 OPEN_FILE
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)
266 READ_FILE
267 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
268 END_TEST_CASE
270 START_TEST_CASE("OverwriteWithLargerData")
271 OPEN_FILE
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)
277 READ_FILE
278 EXPECT_FILE_READ(kSuccess, kBigData, kBigDataSize)
279 END_TEST_CASE
281 START_TEST_CASE("ReadExistingFile")
282 OPEN_FILE
283 EXPECT_FILE_OPENED(kSuccess)
284 WRITE_FILE(kData, kDataSize)
285 EXPECT_FILE_WRITTEN(kSuccess)
286 CLOSE_FILE
287 CREATE_FILE_IO
288 OPEN_FILE
289 EXPECT_FILE_OPENED(kSuccess)
290 READ_FILE
291 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
292 END_TEST_CASE
294 START_TEST_CASE("MultipleReadsAndWrites")
295 OPEN_FILE
296 EXPECT_FILE_OPENED(kSuccess)
297 // Read file which doesn't exist.
298 READ_FILE
299 EXPECT_FILE_READ(kSuccess, NULL, 0)
300 // Write kData to file.
301 WRITE_FILE(kData, kDataSize)
302 EXPECT_FILE_WRITTEN(kSuccess)
303 // Read file.
304 READ_FILE
305 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
306 // Read file again.
307 READ_FILE
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)
312 // Read file.
313 READ_FILE
314 EXPECT_FILE_READ(kSuccess, &large_data_[0], kLargeDataSize)
315 // Overwrite file with kData.
316 WRITE_FILE(kData, kDataSize)
317 EXPECT_FILE_WRITTEN(kSuccess)
318 // Read file.
319 READ_FILE
320 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
321 // Overwrite file with zero bytes.
322 WRITE_FILE(NULL, 0)
323 EXPECT_FILE_WRITTEN(kSuccess)
324 // Read file.
325 READ_FILE
326 EXPECT_FILE_READ(kSuccess, NULL, 0)
327 END_TEST_CASE
329 START_TEST_CASE("OpenAfterOpen")
330 OPEN_FILE
331 EXPECT_FILE_OPENED(kSuccess)
332 OPEN_FILE
333 EXPECT_FILE_OPENED(kError)
334 END_TEST_CASE
336 START_TEST_CASE("OpenDuringPendingOpen")
337 OPEN_FILE
338 OPEN_FILE
339 EXPECT_FILE_OPENED(kError) // The second Open() failed.
340 EXPECT_FILE_OPENED(kSuccess) // The first Open() succeeded.
341 END_TEST_CASE
343 START_TEST_CASE("ReopenFileInSeparateFileIO")
344 OPEN_FILE
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.
349 OPEN_FILE
350 EXPECT_FILE_OPENED(kInUse)
351 END_TEST_CASE
353 START_TEST_CASE("CloseAfterCreation")
354 CLOSE_FILE
355 END_TEST_CASE
357 START_TEST_CASE("CloseDuringPendingOpen")
358 OPEN_FILE
359 CLOSE_FILE
360 END_TEST_CASE
362 START_TEST_CASE("CloseDuringPendingWrite")
363 OPEN_FILE
364 EXPECT_FILE_OPENED(kSuccess)
365 // TODO(xhwang): Reenable this after http:://crbug.com/415401 is fixed.
366 // WRITE_FILE(kData, kDataSize)
367 CLOSE_FILE
368 END_TEST_CASE
370 START_TEST_CASE("CloseDuringPendingOverwriteWithLargerData")
371 OPEN_FILE
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)
377 CLOSE_FILE
378 // Write() didn't finish and the content of the file is not modified.
379 CREATE_FILE_IO
380 OPEN_FILE
381 EXPECT_FILE_OPENED(kSuccess)
382 READ_FILE
383 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
384 END_TEST_CASE
386 START_TEST_CASE("CloseDuringPendingOverwriteWithSmallerData")
387 OPEN_FILE
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)
393 CLOSE_FILE
394 // Write() didn't finish and the content of the file is not modified.
395 CREATE_FILE_IO
396 OPEN_FILE
397 EXPECT_FILE_OPENED(kSuccess)
398 READ_FILE
399 EXPECT_FILE_READ(kSuccess, kBigData, kBigDataSize)
400 END_TEST_CASE
402 START_TEST_CASE("CloseDuringPendingRead")
403 OPEN_FILE
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.
408 // READ_FILE
409 CLOSE_FILE
410 // Make sure the file is not modified.
411 CREATE_FILE_IO
412 OPEN_FILE
413 EXPECT_FILE_OPENED(kSuccess)
414 READ_FILE
415 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
416 END_TEST_CASE
418 START_TEST_CASE("StressTest")
419 for (int i = 0; i < 100; ++i) {
420 CREATE_FILE_IO
421 OPEN_FILE
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)
427 CLOSE_FILE
428 // Make sure the file is not modified.
429 CREATE_FILE_IO
430 OPEN_FILE
431 EXPECT_FILE_OPENED(kSuccess)
432 READ_FILE
433 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
434 CLOSE_FILE
436 END_TEST_CASE
439 void FileIOTestRunner::RunAllTests(const CompletionCB& completion_cb) {
440 completion_cb_ = completion_cb;
441 total_num_tests_ = remaining_tests_.size();
442 RunNextTest();
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);
452 return;
455 remaining_tests_.front().Run(
456 base::Bind(&FileIOTestRunner::OnTestComplete, base::Unretained(this)));
459 void FileIOTestRunner::OnTestComplete(bool success) {
460 if (success)
461 num_passed_tests_++;
462 remaining_tests_.pop_front();
463 RunNextTest();
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()));
484 RunNextStep();
487 void FileIOTest::OnOpenComplete(Status status) {
488 OnResult(TestStep(RESULT_OPEN, status, NULL, 0));
491 void FileIOTest::OnReadComplete(Status status,
492 const uint8_t* data,
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) {
503 case RESULT_OPEN:
504 case RESULT_READ:
505 case RESULT_WRITE:
506 return true;
507 case ACTION_CREATE:
508 case ACTION_OPEN:
509 case ACTION_READ:
510 case ACTION_WRITE:
511 case ACTION_CLOSE:
512 return false;
514 NOTREACHED();
515 return false;
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)
521 return false;
523 if (a.type != RESULT_READ || a.status != cdm::FileIOClient::kSuccess)
524 return true;
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()))
535 return;
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) {
543 case ACTION_CREATE:
544 file_io = create_file_io_cb_.Run(this);
545 if (!file_io) {
546 FILE_IO_DVLOG(3) << "Cannot create FileIO object.";
547 OnTestComplete(false);
548 return;
550 file_io_stack_.push(file_io);
551 break;
552 case ACTION_OPEN:
553 // Use test name as the test file name.
554 file_io->Open(test_name_.data(), test_name_.size());
555 break;
556 case ACTION_READ:
557 file_io->Read();
558 break;
559 case ACTION_WRITE:
560 file_io->Write(test_step.data, test_step.data_size);
561 break;
562 case ACTION_CLOSE:
563 file_io->Close();
564 file_io_stack_.pop();
565 break;
566 default:
567 NOTREACHED();
571 OnTestComplete(true);
574 void FileIOTest::OnResult(const TestStep& result) {
575 DCHECK(IsResult(result));
576 if (!CheckResult(result)) {
577 OnTestComplete(false);
578 return;
581 RunNextStep();
584 bool FileIOTest::CheckResult(const TestStep& result) {
585 if (test_steps_.empty() || !IsResult(test_steps_.front()))
586 return false;
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))
592 return false;
594 if (!MatchesResult(*iter, result))
595 continue;
597 test_steps_.erase(iter);
598 return true;
601 return false;
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);
613 } // namespace media