Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Side by Side Diff: media/cdm/ppapi/cdm_file_io_test.cc

Issue 93243003: Add CDM FileIO tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments addressed; adds more tests; fixes impl Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/callback_helpers.h"
8 #include "base/logging.h"
9 #include "media/base/bind_to_loop.h"
10
11 namespace media {
12
13 #define FILE_IO_DVLOG(level) DVLOG(level) << "File IO Test: "
ddorwin 2013/12/16 18:16:52 I think you'll need to replace DVLOG and probably
xhwang 2013/12/16 23:04:29 This is in ClearKeyCdm code, where it's okay to us
14
15 const uint8_t kData[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
16 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
17 const int kDataSize = arraysize(kData);
18
19 const uint8_t 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 int kBigDataSize = arraysize(kBigData);
25
26 const int kLargeDataSize = 9 * 1024 + 7; // > kReadSize in cdm_file_io_impl.cc.
27
28 // Macros to help add test cases/steps.
29 #define START_TEST_CASE(test_name) \
30 do { \
31 FileIOTest test_case(create_file_io_cb_, "FileIOTest." test_name); \
32 CREATE_FILE_IO // Create FileIO for each test case.
33
34 #define ADD_TEST_STEP(type, status, data, data_size) \
35 test_case.AddTestStep(FileIOTest::type, cdm::FileIOClient::status, \
ddorwin 2013/12/16 18:16:52 Does this really need to be a macro? Can you just
xhwang 2013/12/16 23:04:29 Using can only be used for class type. So I can't
36 (data), (data_size));
37
38 #define END_TEST_CASE \
39 tests_.push_back(test_case); \
40 } while(0);
41
42 #define CREATE_FILE_IO \
ddorwin 2013/12/16 18:16:52 Could these all be functions? (If they were functi
xhwang 2013/12/16 23:04:29 To use function, I have to use real types. So the
43 ADD_TEST_STEP(ACTION_CREATE, kSuccess, NULL, 0)
44
45 #define OPEN_FILE \
46 ADD_TEST_STEP(ACTION_OPEN, kSuccess, NULL, 0)
47
48 #define EXPECT_FILE_OPENED(status) \
49 ADD_TEST_STEP(RESULT_OPEN, status, NULL, 0)
50
51 #define READ_FILE \
52 ADD_TEST_STEP(ACTION_READ, kSuccess, NULL, 0)
53
54 #define EXPECT_FILE_READ(status, data, data_size) \
55 ADD_TEST_STEP(RESULT_READ, status, data, data_size)
56
57 #define WRITE_FILE(data, data_size) \
58 ADD_TEST_STEP(ACTION_WRITE, kSuccess, data, data_size)
59
60 #define EXPECT_FILE_WRITTEN(status) \
61 ADD_TEST_STEP(RESULT_WRITE, status, NULL, 0)
62
63 #define CLOSE_FILE \
64 ADD_TEST_STEP(ACTION_CLOSE, kSuccess, NULL, 0)
65
66 // FileIOTestRunner implementation.
67
68 FileIOTestRunner::FileIOTestRunner(const CreateFileIOCB& create_file_io_cb)
69 : create_file_io_cb_(create_file_io_cb),
70 num_tests_(0),
71 num_passed_tests_(0) {
72 // Generate |large_data_|.
73 large_data_.resize(kLargeDataSize);
74 for (size_t i = 0; i < kLargeDataSize; ++i)
75 large_data_[i] = i % kuint8max;
76
77 AddTests();
78 }
79
80 FileIOTestRunner::~FileIOTestRunner() {
81 if (tests_.empty())
82 return;
83
84 DCHECK_LT(num_passed_tests_, num_tests_);
85 FILE_IO_DVLOG(1) << "Not Finished (probably due to timeout). "
ddorwin 2013/12/16 18:16:52 Does a timeout really get here vs. killing the pro
xhwang 2013/12/16 23:04:29 It doesn't crash the process. Instead, it tears do
86 << num_passed_tests_ << " passed and "
87 << (num_tests_ - num_passed_tests_) << " failed in "
ddorwin 2013/12/16 18:16:52 failed or not run, right? Do we need to do the mat
xhwang 2013/12/16 23:04:29 Done.
88 << num_tests_ << " tests.";
89 }
90
91 // Note: Consecutive expectations (EXPECT*) can happen in any order.
92 void FileIOTestRunner::AddTests() {
93 START_TEST_CASE("ReadBeforeOpeningFile")
94 READ_FILE
95 EXPECT_FILE_READ(kError, NULL, 0)
96 END_TEST_CASE
97
98 START_TEST_CASE("WriteBeforeOpeningFile")
99 WRITE_FILE(kData, kDataSize)
100 EXPECT_FILE_WRITTEN(kError)
101 END_TEST_CASE
102
103 START_TEST_CASE("ReadBeforeFileOpened")
104 OPEN_FILE
105 READ_FILE
106 EXPECT_FILE_READ(kError, NULL, 0)
ddorwin 2013/12/16 18:16:52 This seems to contradict Note above - you will get
xhwang 2013/12/16 23:04:29 Done.
107 EXPECT_FILE_OPENED(kSuccess)
108 END_TEST_CASE
109
110 START_TEST_CASE("WriteBeforeFileOpened")
111 OPEN_FILE
112 WRITE_FILE(kData, kDataSize)
113 EXPECT_FILE_WRITTEN(kError)
114 EXPECT_FILE_OPENED(kSuccess)
115 END_TEST_CASE
116
117 START_TEST_CASE("ReadDuringPendingRead")
118 OPEN_FILE
119 EXPECT_FILE_OPENED(kSuccess)
120 WRITE_FILE(kData, kDataSize)
121 EXPECT_FILE_WRITTEN(kSuccess)
122 READ_FILE
123 READ_FILE
124 EXPECT_FILE_READ(kInUse, NULL, 0)
125 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
126 END_TEST_CASE
127
128 START_TEST_CASE("ReadDuringPendingWrite")
129 OPEN_FILE
130 EXPECT_FILE_OPENED(kSuccess)
131 WRITE_FILE(kData, kDataSize)
132 READ_FILE
133 EXPECT_FILE_READ(kInUse, NULL, 0)
134 EXPECT_FILE_WRITTEN(kSuccess)
135 END_TEST_CASE
136
137 START_TEST_CASE("WriteDuringPendingRead")
138 OPEN_FILE
139 EXPECT_FILE_OPENED(kSuccess)
140 READ_FILE
141 WRITE_FILE(kData, kDataSize)
142 EXPECT_FILE_WRITTEN(kInUse)
143 EXPECT_FILE_READ(kSuccess, NULL, 0)
144 END_TEST_CASE
145
146 START_TEST_CASE("WriteDuringPendingWrite")
147 OPEN_FILE
148 EXPECT_FILE_OPENED(kSuccess)
149 WRITE_FILE(kData, kDataSize)
150 WRITE_FILE(kBigData, kBigDataSize)
151 EXPECT_FILE_WRITTEN(kInUse)
152 EXPECT_FILE_WRITTEN(kSuccess)
153 END_TEST_CASE
154
155 START_TEST_CASE("ReadEmptyFile")
ddorwin 2013/12/16 18:16:52 Are empty and non-existent the same thing?
xhwang 2013/12/16 23:04:29 The result is the same since we specify PP_FILEOPE
ddorwin 2013/12/17 00:17:04 Okay, maybe we should note in the interface that o
156 OPEN_FILE
157 EXPECT_FILE_OPENED(kSuccess)
158 READ_FILE
159 EXPECT_FILE_READ(kSuccess, NULL, 0)
160 END_TEST_CASE
161
162 START_TEST_CASE("WriteAndRead")
163 OPEN_FILE
164 EXPECT_FILE_OPENED(kSuccess)
165 WRITE_FILE(kData, kDataSize)
166 EXPECT_FILE_WRITTEN(kSuccess)
167 READ_FILE
168 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
169 END_TEST_CASE
170
171 START_TEST_CASE("WriteZeroBytes")
172 OPEN_FILE
173 EXPECT_FILE_OPENED(kSuccess)
174 WRITE_FILE(NULL, 0)
175 EXPECT_FILE_WRITTEN(kSuccess)
176 READ_FILE
177 EXPECT_FILE_READ(kSuccess, NULL, 0)
178 END_TEST_CASE
179
180 START_TEST_CASE("WriteAndReadLargeData")
181 OPEN_FILE
182 EXPECT_FILE_OPENED(kSuccess)
183 WRITE_FILE(&large_data_[0], kLargeDataSize)
184 EXPECT_FILE_WRITTEN(kSuccess)
185 READ_FILE
186 EXPECT_FILE_READ(kSuccess, &large_data_[0], kLargeDataSize)
187 END_TEST_CASE
188
189 START_TEST_CASE("OverwriteZeroBytes")
190 OPEN_FILE
191 EXPECT_FILE_OPENED(kSuccess)
192 WRITE_FILE(kData, kDataSize)
193 EXPECT_FILE_WRITTEN(kSuccess)
194 READ_FILE
195 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
196 WRITE_FILE(NULL, 0)
197 EXPECT_FILE_WRITTEN(kSuccess)
198 READ_FILE
199 EXPECT_FILE_READ(kSuccess, NULL, 0)
200 END_TEST_CASE
201
202 START_TEST_CASE("OverwriteWithSmallerData")
203 OPEN_FILE
204 EXPECT_FILE_OPENED(kSuccess)
205 WRITE_FILE(kBigData, kBigDataSize)
206 EXPECT_FILE_WRITTEN(kSuccess)
207 WRITE_FILE(kData, kDataSize)
208 EXPECT_FILE_WRITTEN(kSuccess)
209 READ_FILE
210 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
211 END_TEST_CASE
212
213 START_TEST_CASE("OverwriteWithLargerData")
214 OPEN_FILE
215 EXPECT_FILE_OPENED(kSuccess)
216 WRITE_FILE(kData, kDataSize)
217 EXPECT_FILE_WRITTEN(kSuccess)
218 WRITE_FILE(kBigData, kBigDataSize)
219 EXPECT_FILE_WRITTEN(kSuccess)
220 READ_FILE
221 EXPECT_FILE_READ(kSuccess, kBigData, kBigDataSize)
222 END_TEST_CASE
223
224 START_TEST_CASE("ReadExistingFile")
225 OPEN_FILE
226 EXPECT_FILE_OPENED(kSuccess)
227 WRITE_FILE(kData, kDataSize)
228 EXPECT_FILE_WRITTEN(kSuccess)
229 CLOSE_FILE
230 CREATE_FILE_IO
231 OPEN_FILE
232 EXPECT_FILE_OPENED(kSuccess)
233 READ_FILE
234 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
235 END_TEST_CASE
236
237 START_TEST_CASE("ReopenFileInTheSameFileIO")
238 OPEN_FILE
239 OPEN_FILE
240 EXPECT_FILE_OPENED(kError) // The second Open() failed.
241 EXPECT_FILE_OPENED(kSuccess) // The first Open() succeeded.
242 END_TEST_CASE
243
244 // TODO(xhwang): This test should fail. But pp::FileIO doesn't support locking
245 // of opened files. We need to either workaround this or fix pp::FileIO
246 // implementation.
247 START_TEST_CASE("ReopenFileInSeparateFileIO")
248 OPEN_FILE
249 EXPECT_FILE_OPENED(kSuccess)
250 WRITE_FILE(kData, kDataSize)
251 EXPECT_FILE_WRITTEN(kSuccess)
252 CREATE_FILE_IO // Create a second FileIO without closing the first one.
253 OPEN_FILE
254 EXPECT_FILE_OPENED(kSuccess)
255 READ_FILE
256 EXPECT_FILE_READ(kSuccess, kData, kDataSize)
257 WRITE_FILE(kBigData, kBigDataSize)
258 EXPECT_FILE_WRITTEN(kSuccess)
259 END_TEST_CASE
260 }
261
262 void FileIOTestRunner::RunAllTests(const CompletionCB& completion_cb) {
263 completion_cb_ = BindToCurrentLoop(completion_cb);
264 num_tests_ = tests_.size();
265 RunNextTest();
266 }
267
268 void FileIOTestRunner::RunNextTest() {
269 if (tests_.empty()) {
270 FILE_IO_DVLOG(1) << num_passed_tests_ << " passed and "
271 << (num_tests_ - num_passed_tests_) << " failed in "
272 << num_tests_ << " tests.";
273 bool success = (num_passed_tests_ == num_tests_);
274 base::ResetAndReturn(&completion_cb_).Run(success);
275 return;
276 }
277
278 tests_.front().Run(
279 base::Bind(&FileIOTestRunner::OnTestComplete, base::Unretained(this)));
280 }
281
282 void FileIOTestRunner::OnTestComplete(bool success) {
283 if (success)
284 num_passed_tests_++;
285 tests_.pop_front();
286 RunNextTest();
287 }
288
289 // FileIOTest implementation.
290
291 FileIOTest::FileIOTest(const CreateFileIOCB& create_file_io_cb,
292 const std::string& test_name)
293 : create_file_io_cb_(create_file_io_cb),
294 test_name_(test_name),
295 file_io_(NULL),
296 old_file_io_(NULL) {}
297
298 FileIOTest::~FileIOTest() {}
299
300 void FileIOTest::AddTestStep(StepType type,
301 Status status,
302 const uint8* data,
303 uint32 data_size) {
304 test_steps_.push_back(TestStep(type, status, data, data_size));
305 }
306
307 void FileIOTest::Run(const CompletionCB& completion_cb) {
308 FILE_IO_DVLOG(3) << "Run " << test_name_;
309 completion_cb_ = BindToCurrentLoop(completion_cb);
310 RunNextStep();
311 }
312
313 void FileIOTest::OnOpenComplete(Status status) {
314 OnResult(TestStep(RESULT_OPEN, status, NULL, 0));
315 }
316
317 void FileIOTest::OnReadComplete(Status status,
318 const uint8_t* data,
319 uint32_t data_size) {
320 OnResult(TestStep(RESULT_READ, status, data, data_size));
321 }
322
323 void FileIOTest::OnWriteComplete(Status status) {
324 OnResult(TestStep(RESULT_WRITE, status, NULL, 0));
325 }
326
327 bool FileIOTest::IsResult(const TestStep& test_step) {
328 return test_step.type == RESULT_OPEN || test_step.type == RESULT_READ ||
ddorwin 2013/12/16 18:16:52 Use a switch statement instead? (Including all cas
xhwang 2013/12/16 23:04:29 Done.
329 test_step.type == RESULT_WRITE;
330 }
331
332 bool FileIOTest::MatchesResult(const TestStep& a, const TestStep& b) {
333 DCHECK(IsResult(a) && IsResult(b));
334 if (a.type != b.type || a.status != b.status)
335 return false;
336
337 if (a.type != RESULT_READ || a.status != cdm::FileIOClient::kSuccess)
338 return true;
339
340 return (a.data_size == a.data_size &&
341 std::equal(a.data, a.data + a.data_size, b.data));
342 }
343
344 void FileIOTest::RunNextStep() {
345 while (!test_steps_.empty()) {
346 if (IsResult(test_steps_.front()))
347 return;
ddorwin 2013/12/16 18:16:52 This being first seems to assume this was called f
xhwang 2013/12/16 23:04:29 Added comments.
348
349 TestStep test_step = test_steps_.front();
350 test_steps_.pop_front();
351
352 switch (test_step.type) {
353 case ACTION_CREATE:
354 if (file_io_) {
355 if (old_file_io_)
ddorwin 2013/12/16 18:16:52 Please explain. Does this retire the oldest of 3 F
xhwang 2013/12/16 23:04:29 Done.
356 old_file_io_->Close();
357 old_file_io_ = file_io_;
358 }
359 file_io_ = create_file_io_cb_.Run(this);
360 if (!file_io_) {
361 FILE_IO_DVLOG(3) << "Cannot create FileIO object.";
362 OnTestComplete(false);
363 return;
364 }
365 break;
366 case ACTION_OPEN:
367 // Use test name as the test file name.
ddorwin 2013/12/16 18:16:52 It might be good to mention this in a higher-level
xhwang 2013/12/16 23:04:29 Done.
368 file_io_->Open(test_name_.data(), test_name_.size());
369 break;
370 case ACTION_READ:
371 file_io_->Read();
372 break;
373 case ACTION_WRITE:
374 file_io_->Write(test_step.data, test_step.data_size);
375 break;
376 case ACTION_CLOSE:
377 file_io_->Close();
378 file_io_ = NULL;
379 break;
380 default:
381 NOTREACHED();
382 }
383 }
384
385 OnTestComplete(true);
386 }
387
388 void FileIOTest::OnResult(const TestStep& result) {
389 DCHECK(IsResult(result));
390 if (!CheckResult(result)) {
391 OnTestComplete(false);
392 return;
393 }
394
395 RunNextStep();
396 }
397
398 bool FileIOTest::CheckResult(const TestStep& result) {
399 if (test_steps_.empty() || !IsResult(test_steps_.front()))
400 return false;
401
402 // If there are multiple results expected, the order does not matter.
403 std::list<TestStep>::iterator iter = test_steps_.begin();
404 for (; iter != test_steps_.end(); ++iter) {
405 if (!IsResult(*iter))
406 return false;
407
408 if (!MatchesResult(*iter, result))
409 continue;
410
411 test_steps_.erase(iter);
412 return true;
413 }
414
415 return false;
416 }
417
418 void FileIOTest::OnTestComplete(bool success) {
419 FILE_IO_DVLOG(3) << test_name_ << (success ? " PASSED" : " FAILED");
420 base::ResetAndReturn(&completion_cb_).Run(success);
421 if (old_file_io_) {
422 old_file_io_->Close();
423 old_file_io_ = NULL;
424 }
425 if (file_io_) {
426 file_io_->Close();
427 file_io_ = NULL;
428 }
429 }
430
431 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698