cdm_file_io_test.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Copyright 2013 The Chromium Authors. All rights reserved.
288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Use of this source code is governed by a BSD-style license that can be
388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// found in the LICENSE file.
488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#include "media/cdm/ppapi/cdm_file_io_test.h"
688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#include "base/bind.h"
888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#include "base/callback_helpers.h"
988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#include "base/logging.h"
1088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
1188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgnamespace media {
1288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
1388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#define FILE_IO_DVLOG(level) DVLOG(level) << "File IO Test: "
1488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
1588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgconst uint8 kData[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
1788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgconst uint32 kDataSize = arraysize(kData);
1888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
1988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgconst uint8 kBigData[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
2088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                           0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
2188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                           0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
2288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                           0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
2388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                           0x00 };
2488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgconst uint32 kBigDataSize = arraysize(kBigData);
2588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
2688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Must be > kReadSize in cdm_file_io_impl.cc.
2788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgconst uint32 kLargeDataSize = 20 * 1024 + 7;
2888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
2988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Macros to help add test cases/steps.
3088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
3188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// |test_name| is also used as the file name. File name validity tests relies
3288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// on this to work.
3388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#define START_TEST_CASE(test_name)                                     \
3488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  do {                                                                 \
3588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    FileIOTest test_case(create_file_io_cb_, test_name);               \
3688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    CREATE_FILE_IO  // Create FileIO for each test case.
3788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
3888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#define ADD_TEST_STEP(type, status, data, data_size)                   \
3988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    test_case.AddTestStep(FileIOTest::type, cdm::FileIOClient::status, \
4088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                          (data), (data_size));
4188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
4288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#define END_TEST_CASE                 \
4388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    remaining_tests_.push_back(test_case); \
4488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  } while(0);
4588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
4688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#define CREATE_FILE_IO \
4788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  ADD_TEST_STEP(ACTION_CREATE, kSuccess, NULL, 0)
4888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
4988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#define OPEN_FILE \
5088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  ADD_TEST_STEP(ACTION_OPEN, kSuccess, NULL, 0)
5188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
5288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#define EXPECT_FILE_OPENED(status) \
5388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  ADD_TEST_STEP(RESULT_OPEN, status, NULL, 0)
5488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
5588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#define READ_FILE \
5688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  ADD_TEST_STEP(ACTION_READ, kSuccess, NULL, 0)
5788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
5888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#define EXPECT_FILE_READ(status, data, data_size) \
5988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  ADD_TEST_STEP(RESULT_READ, status, data, data_size)
6088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
6188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#define WRITE_FILE(data, data_size) \
6288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  ADD_TEST_STEP(ACTION_WRITE, kSuccess, data, data_size)
6388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
6488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#define EXPECT_FILE_WRITTEN(status) \
6588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  ADD_TEST_STEP(RESULT_WRITE, status, NULL, 0)
6688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
6788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#define CLOSE_FILE \
6888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  ADD_TEST_STEP(ACTION_CLOSE, kSuccess, NULL, 0)
6988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
7088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// FileIOTestRunner implementation.
7188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
7288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgFileIOTestRunner::FileIOTestRunner(const CreateFileIOCB& create_file_io_cb)
7388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    : create_file_io_cb_(create_file_io_cb),
7488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      total_num_tests_(0),
7588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      num_passed_tests_(0) {
7688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  // Generate |large_data_|.
7788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  large_data_.resize(kLargeDataSize);
7888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  for (size_t i = 0; i < kLargeDataSize; ++i)
7988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    large_data_[i] = i % kuint8max;
8088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
8188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  AddTests();
8288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org}
8388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
8488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgFileIOTestRunner::~FileIOTestRunner() {
8588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  if (remaining_tests_.empty())
8688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    return;
8788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
8888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  DCHECK_LT(num_passed_tests_, total_num_tests_);
8988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  FILE_IO_DVLOG(1) << "Not Finished (probably due to timeout). "
9088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                   << num_passed_tests_ << " passed in "
9188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                   << total_num_tests_ << " tests.";
9288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org}
9388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
9488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Note: Consecutive expectations (EXPECT*) can happen in any order.
9588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgvoid FileIOTestRunner::AddTests() {
9688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  START_TEST_CASE("/FileNameStartsWithForwardSlash")
9788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    OPEN_FILE
9888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    EXPECT_FILE_OPENED(kError)
9988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  END_TEST_CASE
10088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
10188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  START_TEST_CASE("FileNameContains/ForwardSlash")
10288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    OPEN_FILE
10388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    EXPECT_FILE_OPENED(kError)
10488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  END_TEST_CASE
10588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
10688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  START_TEST_CASE("\\FileNameStartsWithBackslash")
10788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    OPEN_FILE
10888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    EXPECT_FILE_OPENED(kError)
10988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  END_TEST_CASE
11088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
11188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  START_TEST_CASE("FileNameContains\\Backslash")
11288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    OPEN_FILE
11388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    EXPECT_FILE_OPENED(kError)
11488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  END_TEST_CASE
11588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
11688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  START_TEST_CASE("_FileNameStartsWithUnderscore")
11788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    OPEN_FILE
11888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    EXPECT_FILE_OPENED(kError)
11988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  END_TEST_CASE
12088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
12188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  START_TEST_CASE("FileNameContains_Underscore")
12288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    OPEN_FILE
12388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    EXPECT_FILE_OPENED(kSuccess)
12488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  END_TEST_CASE
12588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
12688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  START_TEST_CASE("ReadBeforeOpeningFile")
12788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    READ_FILE
12888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    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
439void FileIOTestRunner::RunAllTests(const CompletionCB& completion_cb) {
440  completion_cb_ = completion_cb;
441  total_num_tests_ = remaining_tests_.size();
442  RunNextTest();
443}
444
445void 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
459void FileIOTestRunner::OnTestComplete(bool success) {
460  if (success)
461    num_passed_tests_++;
462  remaining_tests_.pop_front();
463  RunNextTest();
464}
465
466// FileIOTest implementation.
467
468FileIOTest::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
473FileIOTest::~FileIOTest() {}
474
475void 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
480void 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
487void FileIOTest::OnOpenComplete(Status status) {
488  OnResult(TestStep(RESULT_OPEN, status, NULL, 0));
489}
490
491void 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
497void FileIOTest::OnWriteComplete(Status status) {
498  OnResult(TestStep(RESULT_WRITE, status, NULL, 0));
499}
500
501bool 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
518bool 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
530void 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
574void FileIOTest::OnResult(const TestStep& result) {
575  DCHECK(IsResult(result));
576  if (!CheckResult(result)) {
577    OnTestComplete(false);
578    return;
579  }
580
581  RunNextStep();
582}
583
584bool 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
604void 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
614