Upstream version 10.38.220.0
[platform/framework/web/crosswalk.git] / src / media / cdm / ppapi / cdm_file_io_test.cc
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.
4
5 #include "media/cdm/ppapi/cdm_file_io_test.h"
6
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/logging.h"
10
11 namespace media {
12
13 #define FILE_IO_DVLOG(level) DVLOG(level) << "File IO Test: "
14
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);
18
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);
25
26 // Must be > kReadSize in cdm_file_io_impl.cc.
27 const uint32 kLargeDataSize = 20 * 1024 + 7;
28
29 // Macros to help add test cases/steps.
30
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.
37
38 #define ADD_TEST_STEP(type, status, data, data_size)                   \
39     test_case.AddTestStep(FileIOTest::type, cdm::FileIOClient::status, \
40                           (data), (data_size));
41
42 #define END_TEST_CASE                 \
43     remaining_tests_.push_back(test_case); \
44   } while(0);
45
46 #define CREATE_FILE_IO \
47   ADD_TEST_STEP(ACTION_CREATE, kSuccess, NULL, 0)
48
49 #define OPEN_FILE \
50   ADD_TEST_STEP(ACTION_OPEN, kSuccess, NULL, 0)
51
52 #define EXPECT_FILE_OPENED(status) \
53   ADD_TEST_STEP(RESULT_OPEN, status, NULL, 0)
54
55 #define READ_FILE \
56   ADD_TEST_STEP(ACTION_READ, kSuccess, NULL, 0)
57
58 #define EXPECT_FILE_READ(status, data, data_size) \
59   ADD_TEST_STEP(RESULT_READ, status, data, data_size)
60
61 #define WRITE_FILE(data, data_size) \
62   ADD_TEST_STEP(ACTION_WRITE, kSuccess, data, data_size)
63
64 #define EXPECT_FILE_WRITTEN(status) \
65   ADD_TEST_STEP(RESULT_WRITE, status, NULL, 0)
66
67 #define CLOSE_FILE \
68   ADD_TEST_STEP(ACTION_CLOSE, kSuccess, NULL, 0)
69
70 // FileIOTestRunner implementation.
71
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;
80
81   AddTests();
82 }
83
84 FileIOTestRunner::~FileIOTestRunner() {
85   if (remaining_tests_.empty())
86     return;
87
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.";
92 }
93
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
100
101   START_TEST_CASE("FileNameContains/ForwardSlash")
102     OPEN_FILE
103     EXPECT_FILE_OPENED(kError)
104   END_TEST_CASE
105
106   START_TEST_CASE("\\FileNameStartsWithBackslash")
107     OPEN_FILE
108     EXPECT_FILE_OPENED(kError)
109   END_TEST_CASE
110
111   START_TEST_CASE("FileNameContains\\Backslash")
112     OPEN_FILE
113     EXPECT_FILE_OPENED(kError)
114   END_TEST_CASE
115
116   START_TEST_CASE("_FileNameStartsWithUnderscore")
117     OPEN_FILE
118     EXPECT_FILE_OPENED(kError)
119   END_TEST_CASE
120
121   START_TEST_CASE("FileNameContains_Underscore")
122     OPEN_FILE
123     EXPECT_FILE_OPENED(kSuccess)
124   END_TEST_CASE
125
126   START_TEST_CASE("ReadBeforeOpeningFile")
127     READ_FILE
128     EXPECT_FILE_READ(kError, NULL, 0)
129   END_TEST_CASE
130
131   START_TEST_CASE("WriteBeforeOpeningFile")
132     WRITE_FILE(kData, kDataSize)
133     EXPECT_FILE_WRITTEN(kError)
134   END_TEST_CASE
135
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
147
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
159
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
173
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
185
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
199
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
211
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
218
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
227
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
236
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
245
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
258
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
269
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
280
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
293
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
328
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
335
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
342
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
352
353   START_TEST_CASE("CloseAfterCreation")
354     CLOSE_FILE
355   END_TEST_CASE
356
357   START_TEST_CASE("CloseDuringPendingOpen")
358     OPEN_FILE
359     CLOSE_FILE
360   END_TEST_CASE
361
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
369
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
385
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
401
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
417
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
435     }
436   END_TEST_CASE
437 }
438
439 void FileIOTestRunner::RunAllTests(const CompletionCB& completion_cb) {
440   completion_cb_ = completion_cb;
441   total_num_tests_ = remaining_tests_.size();
442   RunNextTest();
443 }
444
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;
453   }
454
455   remaining_tests_.front().Run(
456       base::Bind(&FileIOTestRunner::OnTestComplete, base::Unretained(this)));
457 }
458
459 void FileIOTestRunner::OnTestComplete(bool success) {
460   if (success)
461     num_passed_tests_++;
462   remaining_tests_.pop_front();
463   RunNextTest();
464 }
465
466 // FileIOTest implementation.
467
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) {}
472
473 FileIOTest::~FileIOTest() {}
474
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));
478 }
479
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();
485 }
486
487 void FileIOTest::OnOpenComplete(Status status) {
488   OnResult(TestStep(RESULT_OPEN, status, NULL, 0));
489 }
490
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));
495 }
496
497 void FileIOTest::OnWriteComplete(Status status) {
498   OnResult(TestStep(RESULT_WRITE, status, NULL, 0));
499 }
500
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;
513   }
514   NOTREACHED();
515   return false;
516 }
517
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;
522
523   if (a.type != RESULT_READ || a.status != cdm::FileIOClient::kSuccess)
524     return true;
525
526   return (a.data_size == b.data_size &&
527           std::equal(a.data, a.data + a.data_size, b.data));
528 }
529
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;
536
537     TestStep test_step = test_steps_.front();
538     test_steps_.pop_front();
539
540     cdm::FileIO* file_io = file_io_stack_.empty()? NULL : file_io_stack_.top();
541
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;
549         }
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();
568     }
569   }
570
571   OnTestComplete(true);
572 }
573
574 void FileIOTest::OnResult(const TestStep& result) {
575   DCHECK(IsResult(result));
576   if (!CheckResult(result)) {
577     OnTestComplete(false);
578     return;
579   }
580
581   RunNextStep();
582 }
583
584 bool FileIOTest::CheckResult(const TestStep& result) {
585   if (test_steps_.empty() || !IsResult(test_steps_.front()))
586     return false;
587
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;
593
594     if (!MatchesResult(*iter, result))
595       continue;
596
597     test_steps_.erase(iter);
598     return true;
599   }
600
601   return false;
602 }
603
604 void FileIOTest::OnTestComplete(bool success) {
605   while (!file_io_stack_.empty()) {
606     file_io_stack_.top()->Close();
607     file_io_stack_.pop();
608   }
609   FILE_IO_DVLOG(3) << test_name_ << (success ? " PASSED" : " FAILED");
610   base::ResetAndReturn(&completion_cb_).Run(success);
611 }
612
613 }  // namespace media