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

Side by Side Diff: media/base/composite_filter_unittest.cc

Issue 5744002: Refactor PipelineImpl to use CompositeFilter to manage Filter state transitions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add explicit MessageLoop usage to make sure code is running on the expected threads. Created 10 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 (c) 2010 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/base/composite_filter.h"
6 #include "media/base/mock_filter_host.h"
7 #include "media/base/mock_filters.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9
10 using ::testing::_;
11 using ::testing::InSequence;
12 using ::testing::Return;
13 using ::testing::SaveArg;
14 using ::testing::StrictMock;
15
16 namespace media {
17
18 class CompositeFilterTest : public testing::Test {
19 public:
20 CompositeFilterTest();
21 virtual ~CompositeFilterTest();
22
23 // Sets up a new CompositeFilter in |composite_|, creates |filter_1_| and
24 // |filter_2_|, and adds these filters to |composite_|.
25 void SetupAndAdd2Filters();
26
27 // Helper enum that indicates what filter method to call.
28 enum MethodToCall {
29 PLAY,
30 PAUSE,
31 FLUSH,
32 STOP,
33 SEEK
scherkus (not reviewing) 2010/12/15 16:44:02 nit: add trailing ,
acolwell GONE FROM CHROMIUM 2010/12/15 18:20:11 Done.
34 };
35
36 // Helper method that adds a filter method call expectation based on the value
37 // of |method_to_call|.
38 //
39 // |method_to_call| - Indicates which method we expect a call for.
40 // |filter| - The MockFilter to add the expectation to.
41 // |seek_time| - The time to pass to the Seek() call if |method_to_call|
42 // equals SEEK.
43 void ExpectFilterCall(MethodToCall method_to_call, MockFilter* filter,
44 base::TimeDelta seek_time);
45
46 // Helper method that calls a filter method based on the value of
47 // |method_to_call|.
48 //
49 // |method_to_call| - Indicates which method to call.
50 // |filter| - The Filter to make the method call on.
51 // |seek_time| - The time to pass to the Seek() call if |method_to_call|
52 // equals SEEK.
53 // |callback| - The callback object to pass to the method.
54 void DoFilterCall(MethodToCall method_to_call, Filter* filter,
55 base::TimeDelta seek_time,
56 FilterCallback* callback);
57
58 // Creates an expectation sequence based on the value of method_to_call.
59 //
60 // |method_to_call| - Indicates which method we want a success sequence for.
61 // |seek_time| - The time to pass in the Seek() call if |method_to_call|
62 // equals SEEK.
63 void ExpectSuccess(MethodToCall method_to_call,
64 base::TimeDelta seek_time = base::TimeDelta());
65
66 // Issue a Play(), Pause(), Flush(), Stop(), or Seek() on the composite and
67 // verify all the expected calls on the filters.
68 void DoPlay();
69 void DoPause();
70 void DoFlush();
71 void DoStop();
72 void DoSeek(base::TimeDelta time);
73
74 // Issue a Play(), Pause(), Flush(), or Seek() and expect the calls to fail
75 // with a PIPELINE_ERROR_INVALID_STATE error.
76 //
77 // |method_to_call| - Indicates whick method to call.
78 // |seek_time| - The time to pass to the Seek() call if |method_to_call|
79 // equals SEEK.
80 void ExpectInvalidStateFail(MethodToCall method_to_call,
81 base::TimeDelta seek_time = base::TimeDelta());
82
83 protected:
84 MessageLoop message_loop_;
85
86 // The composite object being tested.
87 scoped_refptr<CompositeFilter> composite_;
88
89 // First filter added to the composite.
90 scoped_refptr<StrictMock<MockFilter> > filter_1_;
91
92 // Callback passed to |filter_1_| during last Play(), Pause(), Flush(),
93 // Stop(), or Seek() call.
94 FilterCallback* filter_1_callback_;
95
96 // Second filter added to the composite.
97 scoped_refptr<StrictMock<MockFilter> > filter_2_;
98
99 // Callback passed to |filter_2_| during last Play(), Pause(), Flush(),
100 // Stop(), or Seek() call.
101 FilterCallback* filter_2_callback_;
102
103 // FilterHost implementation passed to |composite_| via set_host().
104 scoped_ptr<StrictMock<MockFilterHost> > mock_filter_host_;
105
106 DISALLOW_COPY_AND_ASSIGN(CompositeFilterTest);
107 };
108
109 CompositeFilterTest::CompositeFilterTest() :
110 composite_(new CompositeFilter(&message_loop_)),
111 filter_1_callback_(NULL),
112 filter_2_callback_(NULL),
113 mock_filter_host_(new StrictMock<MockFilterHost>())
114 {}
scherkus (not reviewing) 2010/12/15 16:44:02 move { to previous line
acolwell GONE FROM CHROMIUM 2010/12/15 18:20:11 Done.
115
116 CompositeFilterTest::~CompositeFilterTest()
scherkus (not reviewing) 2010/12/15 16:44:02 one-liner w/ {} at end
acolwell GONE FROM CHROMIUM 2010/12/15 18:20:11 Done.
117 {}
118
119 void CompositeFilterTest::SetupAndAdd2Filters() {
120 mock_filter_host_.reset(new StrictMock<MockFilterHost>());
121 composite_ = new CompositeFilter(&message_loop_);
122 composite_->set_host(mock_filter_host_.get());
123
124 // Setup |filter_1_| and arrange for methods to set
125 // |filter_1_callback_| when they are called.
126 filter_1_ = new StrictMock<MockFilter>();
127 filter_1_callback_ = NULL;
128 ON_CALL(*filter_1_, Play(_))
129 .WillByDefault(SaveArg<0>(&filter_1_callback_));
130 ON_CALL(*filter_1_, Pause(_))
131 .WillByDefault(SaveArg<0>(&filter_1_callback_));
132 ON_CALL(*filter_1_, Flush(_))
133 .WillByDefault(SaveArg<0>(&filter_1_callback_));
134 ON_CALL(*filter_1_, Stop(_))
135 .WillByDefault(SaveArg<0>(&filter_1_callback_));
136 ON_CALL(*filter_1_, Seek(_,_))
137 .WillByDefault(SaveArg<1>(&filter_1_callback_));
138
139 // Setup |filter_2_| and arrange for methods to set
140 // |filter_2_callback_| when they are called.
141 filter_2_ = new StrictMock<MockFilter>();
142 filter_2_callback_ = NULL;
143 ON_CALL(*filter_2_, Play(_))
144 .WillByDefault(SaveArg<0>(&filter_2_callback_));
145 ON_CALL(*filter_2_, Pause(_))
146 .WillByDefault(SaveArg<0>(&filter_2_callback_));
147 ON_CALL(*filter_2_, Flush(_))
148 .WillByDefault(SaveArg<0>(&filter_2_callback_));
149 ON_CALL(*filter_2_, Stop(_))
150 .WillByDefault(SaveArg<0>(&filter_2_callback_));
151 ON_CALL(*filter_2_, Seek(_,_))
152 .WillByDefault(SaveArg<1>(&filter_2_callback_));
153
154 composite_->AddFilter(filter_1_);
155 composite_->AddFilter(filter_2_);
156 }
157
158 void CompositeFilterTest::ExpectFilterCall(MethodToCall method_to_call,
159 MockFilter* filter,
160 base::TimeDelta seek_time) {
161 switch(method_to_call) {
162 case PLAY:
163 EXPECT_CALL(*filter, Play(_));
164 break;
165 case PAUSE:
166 EXPECT_CALL(*filter, Pause(_));
167 break;
168 case FLUSH:
169 EXPECT_CALL(*filter, Flush(_));
170 break;
171 case STOP:
172 EXPECT_CALL(*filter, Stop(_));
173 break;
174 case SEEK:
175 EXPECT_CALL(*filter, Seek(seek_time, _));
176 break;
177 };
178 }
179
180 void CompositeFilterTest::DoFilterCall(MethodToCall method_to_call,
181 Filter* filter,
182 base::TimeDelta seek_time,
183 FilterCallback* callback) {
184 switch(method_to_call) {
185 case PLAY:
186 filter->Play(callback);
187 break;
188 case PAUSE:
189 filter->Pause(callback);
190 break;
191 case FLUSH:
192 filter->Flush(callback);
193 break;
194 case STOP:
195 filter->Stop(callback);
196 break;
197 case SEEK:
198 filter->Seek(seek_time, callback);
199 break;
200 };
201 }
202
203 void CompositeFilterTest::ExpectSuccess(MethodToCall method_to_call,
204 base::TimeDelta seek_time) {
205 InSequence seq;
scherkus (not reviewing) 2010/12/15 16:44:02 warning: combination of InSequence + StrictMock ca
acolwell GONE FROM CHROMIUM 2010/12/15 18:20:11 This is intentional. I'm trying to ensure a strict
206
207 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
208 new StrictMock<MockFilterCallback>());
209
210 bool is_parallel_call = (method_to_call == FLUSH);
211
212 ExpectFilterCall(method_to_call, filter_1_.get(), seek_time);
213
214 if (is_parallel_call) {
215 ExpectFilterCall(method_to_call, filter_2_.get(), seek_time);
216 }
217
218 // Make method call on the composite.
219 DoFilterCall(method_to_call, composite_.get(), seek_time,
220 mock_callback->NewCallback());
221
222 if (is_parallel_call) {
223 // Make sure both filters have their callbacks set.
224 EXPECT_NE((FilterCallback*)NULL, filter_1_callback_);
scherkus (not reviewing) 2010/12/15 16:44:02 does compiler complain when comparing to plain NUL
acolwell GONE FROM CHROMIUM 2010/12/15 18:20:11 Yes. I get this error if I don't have the cast. t
225 EXPECT_NE((FilterCallback*)NULL, filter_2_callback_);
226
227 // Run |filter_1_callback_| to simulate |filter_1_| completing its request.
228 filter_1_callback_->Run();
229 delete filter_1_callback_;
scherkus (not reviewing) 2010/12/15 16:44:02 seems like you have these three lines of code dupl
acolwell GONE FROM CHROMIUM 2010/12/15 18:20:11 I'll look into reducing this duplicate code. I agr
230 filter_1_callback_ = NULL;
231 } else {
232 // Make sure that only |filter_1_| has its callback set.
233 EXPECT_NE((FilterCallback*)NULL, filter_1_callback_);
234 EXPECT_EQ((FilterCallback*)NULL, filter_2_callback_);
235
236 ExpectFilterCall(method_to_call, filter_2_.get(), seek_time);
237
238 // Run |filter_1_callback_| to simulate |filter_1_| completing its request.
239 filter_1_callback_->Run();
240 delete filter_1_callback_;
241 filter_1_callback_ = NULL;
242
243 // Verify that |filter_2_| was called by checking the callback pointer.
244 EXPECT_NE((FilterCallback*)NULL, filter_2_callback_);
245 }
246
247 EXPECT_CALL(*mock_callback, OnFilterCallback());
248 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
249
250 // Run |filter_2_callback_| to simulate |filter_2_| completing its request.
251 filter_2_callback_->Run();
252 delete filter_2_callback_;
253 filter_2_callback_ = NULL;
254 }
255
256 void CompositeFilterTest::DoPlay() {
257 ExpectSuccess(PLAY);
258 }
259
260 void CompositeFilterTest::DoPause() {
261 ExpectSuccess(PAUSE);
262 }
263
264 void CompositeFilterTest::DoFlush() {
265 ExpectSuccess(FLUSH);
266 }
267
268 void CompositeFilterTest::DoStop() {
269 ExpectSuccess(STOP);
270 }
271
272 void CompositeFilterTest::DoSeek(base::TimeDelta time) {
273 ExpectSuccess(SEEK, time);
274 }
275
276 void CompositeFilterTest::ExpectInvalidStateFail(MethodToCall method_to_call,
277 base::TimeDelta seek_time) {
278 InSequence seq;
279 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
280 new StrictMock<MockFilterCallback>());
281
282 EXPECT_CALL(*mock_filter_host_, SetError(PIPELINE_ERROR_INVALID_STATE))
283 .WillOnce(Return());
284 EXPECT_CALL(*mock_callback, OnFilterCallback());
285 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
286
287 DoFilterCall(method_to_call, composite_, seek_time,
288 mock_callback->NewCallback());
289
290 // Make sure that neither of the filters were called by
291 // verifying that the callback pointers weren't set.
292 EXPECT_EQ((FilterCallback*)NULL, filter_1_callback_);
293 EXPECT_EQ((FilterCallback*)NULL, filter_2_callback_);
294 }
295
296 static base::Thread* NullThreadFactory(const char* thread_name) {
297 return NULL;
298 }
299
300 // Test AddFilter() failure cases.
301 TEST_F(CompositeFilterTest, TestAddFilterFailCases) {
302 // Test adding a null pointer.
303 EXPECT_FALSE(composite_->AddFilter(NULL));
304
305 scoped_refptr<StrictMock<MockFilter> > filter = new StrictMock<MockFilter>();
306 filter->set_requires_message_loop(true);
307 EXPECT_EQ(NULL, filter->host());
308 EXPECT_EQ(NULL, filter->message_loop());
309
310 // Test failing because set_host() hasn't been called yet.
311 EXPECT_FALSE(composite_->AddFilter(filter));
312
313 // Test thread creation failure.
314 composite_ = new CompositeFilter(&message_loop_, &NullThreadFactory);
315 composite_->set_host(mock_filter_host_.get());
316 EXPECT_FALSE(composite_->AddFilter(filter));
317 EXPECT_EQ(NULL, filter->host());
318 EXPECT_EQ(NULL, filter->message_loop());
319 }
320
321 // Test successful AddFilter() cases.
322 TEST_F(CompositeFilterTest, TestAddFilter) {
323 composite_->set_host(mock_filter_host_.get());
324
325 // Add a filter that doesn't require a message loop.
326 scoped_refptr<StrictMock<MockFilter> > filter = new StrictMock<MockFilter>();
327 EXPECT_EQ(NULL, filter->host());
328 EXPECT_EQ(NULL, filter->message_loop());
329
330 EXPECT_TRUE(composite_->AddFilter(filter));
331
332 EXPECT_NE((FilterHost*)NULL, filter->host());
333 EXPECT_EQ(NULL, filter->message_loop());
334
335 // Add a filter that requires a message loop.
336 scoped_refptr<StrictMock<MockFilter> > filter_2 =
337 new StrictMock<MockFilter>();
338 filter_2->set_requires_message_loop(true);
339
340 EXPECT_EQ(NULL, filter_2->host());
341 EXPECT_EQ(NULL, filter_2->message_loop());
342
343 EXPECT_TRUE(composite_->AddFilter(filter_2));
344
345 EXPECT_NE((FilterHost*)NULL, filter_2->host());
346 EXPECT_NE((MessageLoop*)NULL, filter_2->message_loop());
347 }
348
349 static bool g_thread_cleanup_called_ = false;
350 class CompositeFilterThread : public base::Thread {
351 public:
352 CompositeFilterThread(const char* name) : base::Thread(name) {}
353 virtual ~CompositeFilterThread() { Stop(); }
354 virtual void CleanUp() {
scherkus (not reviewing) 2010/12/15 16:44:02 are you using this to make sure the thread was sto
acolwell GONE FROM CHROMIUM 2010/12/15 18:20:11 Yes.
355 g_thread_cleanup_called_ = true;
356 base::Thread::CleanUp();
357 }
358 };
359
360 static base::Thread* g_thread_created_by_factory = NULL;
361 static base::Thread* TestableThreadFactory(const char* thread_name) {
362 g_thread_created_by_factory = new CompositeFilterThread(thread_name);
363 return g_thread_created_by_factory;
364 }
365
366 // Verify that thread termination works as expected.
367 TEST_F(CompositeFilterTest, TestThreadTermination) {
368 composite_ = new CompositeFilter(&message_loop_, &TestableThreadFactory);
369 composite_->set_host(mock_filter_host_.get());
370
371 // Add a filter that requires a message loop.
372 scoped_refptr<StrictMock<MockFilter> > filter = new StrictMock<MockFilter>();
373 filter->set_requires_message_loop(true);
374
375 EXPECT_EQ(NULL, g_thread_created_by_factory);
376 EXPECT_TRUE(composite_->AddFilter(filter));
377 EXPECT_NE((base::Thread*)NULL, g_thread_created_by_factory);
378 EXPECT_NE((MessageLoop*)NULL, filter->message_loop());
379
380 // Verify that the filter has a message loop and it matches the
381 // thread's message loop.
382 base::Thread* filter_thread = g_thread_created_by_factory;
383 EXPECT_NE((MessageLoop*)NULL, filter_thread->message_loop());
384 EXPECT_EQ(filter_thread->message_loop(), filter->message_loop());
385
386 EXPECT_TRUE(filter_thread->IsRunning());
387 EXPECT_FALSE(g_thread_cleanup_called_);
388
389 composite_ = NULL;
390
391 // Verify that the thread stops running when the composite is
392 // destroyed.
393 EXPECT_TRUE(g_thread_cleanup_called_);
394 }
395
396 TEST_F(CompositeFilterTest, TestPlay) {
397 InSequence sequence;
398
399 SetupAndAdd2Filters();
400
401 // Verify successful call to Play().
402 DoPlay();
403
404 // At this point we are now in the kPlaying state.
405 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
406 new StrictMock<MockFilterCallback>());
407
408 // Try calling Play() again to make sure that we simply get a callback.
409 // We are already in the Play() state so there is no point calling the
410 // filters.
411 EXPECT_CALL(*mock_callback, OnFilterCallback());
412 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
scherkus (not reviewing) 2010/12/15 16:44:02 I think MockCallback is something I need to kill f
acolwell GONE FROM CHROMIUM 2010/12/15 18:20:11 In most cases I agree, but sometimes it is handy t
scherkus (not reviewing) 2010/12/16 18:43:39 If you give it a new callback you can assert that
413
414 composite_->Play(mock_callback->NewCallback());
415
416 // Verify that neither of the filter callbacks were set.
417 EXPECT_EQ((FilterCallback*)NULL, filter_1_callback_);
418 EXPECT_EQ((FilterCallback*)NULL, filter_2_callback_);
419
420 // Stop playback.
421 DoStop();
422
423 // At this point we should be in the kStopped state.
424
425 // Try calling Stop() again to make sure neither filter is called.
426 EXPECT_CALL(*mock_callback, OnFilterCallback());
427 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
428
429 composite_->Stop(mock_callback->NewCallback());
430
431 // Verify that neither of the filter callbacks were set.
432 EXPECT_EQ((FilterCallback*)NULL, filter_1_callback_);
433 EXPECT_EQ((FilterCallback*)NULL, filter_2_callback_);
434
435 // Try calling Play() again to make sure we get an error.
436 ExpectInvalidStateFail(PLAY);
437 }
438
439 // Test errors in the middle of a serial call sequence like Play().
440 TEST_F(CompositeFilterTest, TestPlayErrors) {
441 InSequence sequence;
442
443 SetupAndAdd2Filters();
444
445 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
446 new StrictMock<MockFilterCallback>());
447
448 EXPECT_CALL(*filter_1_, Play(_));
449
450 // Call Play() on the composite.
451 composite_->Play(mock_callback->NewCallback());
452
453 EXPECT_CALL(*filter_2_, Play(_));
454
455 // Run |filter_1_callback_| to simulate success on |filter_1_|.
456 filter_1_callback_->Run();
457 delete filter_1_callback_;
458 filter_1_callback_ = NULL;
459
460 // At this point Play() has been called on |filter_2_|. Simulate an
461 // error by calling SetError() on its FilterHost interface.
462 filter_2_->host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY);
463
464 // Expect error to be reported and "play done" callback to be called.
465 EXPECT_CALL(*mock_filter_host_, SetError(PIPELINE_ERROR_OUT_OF_MEMORY));
466 EXPECT_CALL(*mock_callback, OnFilterCallback());
467 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
468
469 // Run |filter_2_callback_| to simulate |filter_2_| completing the Play()
470 // request.
471 filter_2_callback_->Run();
472 delete filter_2_callback_;
473 filter_2_callback_ = NULL;
474
475 // Verify that Play/Pause/Flush/Seek fail now that an error occured.
476 ExpectInvalidStateFail(PLAY);
477 ExpectInvalidStateFail(PAUSE);
478 ExpectInvalidStateFail(FLUSH);
479 ExpectInvalidStateFail(SEEK);
480
481 // Make sure you can still Stop().
482 DoStop();
483 }
484
485 TEST_F(CompositeFilterTest, TestPause) {
486 InSequence sequence;
487
488 SetupAndAdd2Filters();
489
490 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
491 new StrictMock<MockFilterCallback>());
492
493 // Try calling Pause() to make sure we get an error because we aren't in
494 // the playing state.
495 ExpectInvalidStateFail(PAUSE);
496
497 // Transition to playing state.
498 DoPlay();
499
500 // Issue a successful Pause().
501 DoPause();
502
503 // At this point we are paused.
504
505 // Try calling Pause() again to make sure that the filters aren't called
506 // because we are already in the paused state.
507 EXPECT_CALL(*mock_callback, OnFilterCallback());
508 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
509
510 composite_->Pause(mock_callback->NewCallback());
511
512 // Verify that neither of the filter callbacks were set.
513 EXPECT_EQ((FilterCallback*)NULL, filter_1_callback_);
514 EXPECT_EQ((FilterCallback*)NULL, filter_2_callback_);
515
516 // Verify that we can transition pack to the play state.
517 DoPlay();
518
519 // Go back to the pause state.
520 DoPause();
521
522 // Transition to the stop state.
523 DoStop();
524
525 // Try calling Pause() to make sure we get an error because we aren't in
526 // the playing state.
527 ExpectInvalidStateFail(PAUSE);
528 }
529
530 // Test errors in the middle of a serial call sequence like Pause().
531 TEST_F(CompositeFilterTest, TestPauseErrors) {
532 InSequence sequence;
533
534 SetupAndAdd2Filters();
535
536 DoPlay();
537
538 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
539 new StrictMock<MockFilterCallback>());
540
541 EXPECT_CALL(*filter_1_, Pause(_));
542
543 // Call Pause() on the composite.
544 composite_->Pause(mock_callback->NewCallback());
545
546 // Simulate an error by calling SetError() on |filter_1_|'s FilterHost
547 // interface.
548 filter_1_->host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY);
549
550 // Expect error to be reported and "pause done" callback to be called.
551 EXPECT_CALL(*mock_filter_host_, SetError(PIPELINE_ERROR_OUT_OF_MEMORY));
552 EXPECT_CALL(*mock_callback, OnFilterCallback());
553 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
554
555 // Run |filter_1_callback_| to simulate success on |filter_1_|.
556 filter_1_callback_->Run();
557 delete filter_1_callback_;
558 filter_1_callback_ = NULL;
559
560 // Make sure |filter_2_callback_| was not set.
561 EXPECT_EQ((FilterCallback*)NULL, filter_2_callback_);
562
563 // Verify that Play/Pause/Flush/Seek fail now that an error occured.
564 ExpectInvalidStateFail(PLAY);
565 ExpectInvalidStateFail(PAUSE);
566 ExpectInvalidStateFail(FLUSH);
567 ExpectInvalidStateFail(SEEK);
568
569 // Make sure you can still Stop().
570 DoStop();
571 }
572
573 TEST_F(CompositeFilterTest, TestFlush) {
574 InSequence sequence;
575
576 SetupAndAdd2Filters();
577
578 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
579 new StrictMock<MockFilterCallback>());
580
581 // Make sure Flush() works before calling Play().
582 DoFlush();
583
584 // Transition to playing state.
585 DoPlay();
586
587 // Call Flush() to make sure we get an error because we are in
588 // the playing state.
589 ExpectInvalidStateFail(FLUSH);
590
591 // Issue a successful Pause().
592 DoPause();
593
594 // Make sure Flush() works after pausing.
595 DoFlush();
596
597 // Verify that we can transition back to the play state.
598 DoPlay();
599
600 // Transition to the stop state.
601 DoStop();
602
603 // Try calling Flush() to make sure we get an error because we are stopped.
604 ExpectInvalidStateFail(FLUSH);
605 }
606
607 // Test errors in the middle of a parallel call sequence like Flush().
608 TEST_F(CompositeFilterTest, TestFlushErrors) {
609 InSequence sequence;
610
611 SetupAndAdd2Filters();
612
613 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
614 new StrictMock<MockFilterCallback>());
615
616 EXPECT_CALL(*filter_1_, Flush(_));
617 EXPECT_CALL(*filter_2_, Flush(_));
618
619 // Call Flush() on the composite.
620 composite_->Flush(mock_callback->NewCallback());
621
622 // Simulate an error by calling SetError() on |filter_1_|'s FilterHost
623 // interface.
624 filter_1_->host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY);
625
626 // Run |filter_1_callback_| to indicate that it is done with the request.
627 filter_1_callback_->Run();
628 delete filter_1_callback_;
629 filter_1_callback_ = NULL;
630
631 // Expect error to be reported and "pause done" callback to be called.
632 EXPECT_CALL(*mock_filter_host_, SetError(PIPELINE_ERROR_OUT_OF_MEMORY));
633 EXPECT_CALL(*mock_callback, OnFilterCallback());
634 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
635
636 // Run |filter_2_callback_| to simulate success on |filter_2_|.
637 filter_2_callback_->Run();
638 delete filter_2_callback_;
639 filter_2_callback_ = NULL;
640
641 // Verify that Play/Pause/Flush/Seek fail now that an error occured.
642 ExpectInvalidStateFail(PLAY);
643 ExpectInvalidStateFail(PAUSE);
644 ExpectInvalidStateFail(FLUSH);
645 ExpectInvalidStateFail(SEEK);
646
647 // Make sure you can still Stop().
648 DoStop();
649 }
650
651 TEST_F(CompositeFilterTest, TestSeek) {
652 InSequence sequence;
653
654 SetupAndAdd2Filters();
655
656 // Verify that seek is allowed to be called before a Play() call.
657 DoSeek(base::TimeDelta::FromSeconds(5));
658
659 // Verify we can issue a Play() after the Seek().
660 DoPlay();
661
662 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
663 new StrictMock<MockFilterCallback>());
664
665 // Try calling Seek() while playing to make sure we get an error.
666 ExpectInvalidStateFail(SEEK);
667
668 // Transition to paused state.
669 DoPause();
670
671 // Verify that seek is allowed after pausing.
672 DoSeek(base::TimeDelta::FromSeconds(5));
673
674 // Verify we can still play again.
675 DoPlay();
676
677 // Stop playback.
678 DoStop();
679
680 // Try calling Seek() to make sure we get an error.
681 ExpectInvalidStateFail(SEEK);
682 }
683
684 TEST_F(CompositeFilterTest, TestStop) {
685 InSequence sequence;
686
687 // Test Stop() before any other call.
688 SetupAndAdd2Filters();
689 DoStop();
690
691 // Test error during Stop() sequence.
692 SetupAndAdd2Filters();
693 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
694 new StrictMock<MockFilterCallback>());
695
696 EXPECT_CALL(*filter_1_, Stop(_));
697
698 composite_->Stop(mock_callback->NewCallback());
699
700 // Have |filter_1_| signal an error.
701 filter_1_->host()->SetError(PIPELINE_ERROR_READ);
702
703 EXPECT_CALL(*filter_2_, Stop(_));
704
705 filter_1_callback_->Run();
706 delete filter_1_callback_;
707 filter_1_callback_ = NULL;
708
709 EXPECT_CALL(*mock_callback, OnFilterCallback());
710 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
711
712 filter_2_callback_->Run();
713 delete filter_2_callback_;
714 filter_2_callback_ = NULL;
715 }
716
717 // Test stopping in the middle of a serial call sequence.
718 TEST_F(CompositeFilterTest, TestStopWhilePlayPending) {
719 InSequence sequence;
720
721 SetupAndAdd2Filters();
722
723 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
724 new StrictMock<MockFilterCallback>());
725
726 EXPECT_CALL(*filter_1_, Play(_));
727
728 composite_->Play(mock_callback->NewCallback());
729
730 // Note: Play() is pending on |filter_1_| right now.
731
732 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback_2(
733 new StrictMock<MockFilterCallback>());
734
735 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
736
737 composite_->Stop(mock_callback_2->NewCallback());
738
739 EXPECT_CALL(*filter_1_, Stop(_));
740
741 // Run |filter_1_|'s callback to indicate Play() has completed.
742 //
743 // Note: We need |tmp_callback| here because when the callback is
744 // run, |filter_1_| gets a stop call which resets |filter_1_callback_|
745 // to a new callback object. We don't want to miss this new callback.
746 FilterCallback* tmp_callback = filter_1_callback_;
747 tmp_callback->Run();
748 delete tmp_callback;
749 tmp_callback = NULL;
750
751 EXPECT_CALL(*filter_2_, Stop(_));
752
753 // Run |filter_1_|'s callback again to indicate Stop() has completed.
754 EXPECT_NE((FilterCallback*)NULL, filter_1_callback_);
755 filter_1_callback_->Run();
756 delete filter_1_callback_;
757 filter_1_callback_ = NULL;
758
759 EXPECT_CALL(*mock_callback_2, OnFilterCallback());
760 EXPECT_CALL(*mock_callback_2, OnCallbackDestroyed());
761
762 // Run |filter_2_|'s callback to indicate Stop() has completed.
763 EXPECT_NE((FilterCallback*)NULL, filter_2_callback_);
764 filter_2_callback_->Run();
765 delete filter_2_callback_;
766 filter_2_callback_ = NULL;
767 }
768
769 // Test stopping in the middle of a parallel call sequence.
770 TEST_F(CompositeFilterTest, TestStopWhileFlushPending) {
771 InSequence sequence;
772
773 SetupAndAdd2Filters();
774
775 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
776 new StrictMock<MockFilterCallback>());
777
778 EXPECT_CALL(*filter_1_, Flush(_));
779 EXPECT_CALL(*filter_2_, Flush(_));
780
781 composite_->Flush(mock_callback->NewCallback());
782
783 // Note: |filter_1_| and |filter_2_| have pending Flush() calls at this point.
784
785 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback_2(
786 new StrictMock<MockFilterCallback>());
787
788 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
789
790 composite_->Stop(mock_callback_2->NewCallback());
791
792 // Run |filter_1_callback_| to indicate Flush() has completed.
793 filter_1_callback_->Run();
794 delete filter_1_callback_;
795 filter_1_callback_ = NULL;
796
797 EXPECT_CALL(*filter_1_, Stop(_));
798
799 // Call |filter_2_callback_| to indicate that |filter_2_| is done with the
800 // outstanding request.
801 filter_2_callback_->Run();
802 delete filter_2_callback_;
803 filter_2_callback_ = NULL;
804
805 EXPECT_CALL(*filter_2_, Stop(_));
806
807 // Run |filter_1_callback_| to indicate that |filter_1_|'s Stop() has
808 // completed.
809 filter_1_callback_->Run();
810 delete filter_1_callback_;
811 filter_1_callback_ = NULL;
812
813
814 EXPECT_CALL(*mock_callback_2, OnFilterCallback());
815 EXPECT_CALL(*mock_callback_2, OnCallbackDestroyed());
816
817 // Run |filter_2_callback_| to indicate that |filter_2_|'s Stop() has
818 // completed.
819 filter_2_callback_->Run();
820 delete filter_2_callback_;
821 filter_2_callback_ = NULL;
822 }
823
824 TEST_F(CompositeFilterTest, TestErrorWhilePlaying) {
825 InSequence sequence;
826
827 SetupAndAdd2Filters();
828
829 // Simulate an error on |filter_2_| while in kCreated state. This
830 // can happen if an error occurs during filter initialization.
831 EXPECT_CALL(*mock_filter_host_, SetError(PIPELINE_ERROR_OUT_OF_MEMORY));
832 filter_2_->host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY);
833
834 DoPlay();
835
836 // Simulate an error on |filter_2_| while playing.
837 EXPECT_CALL(*mock_filter_host_, SetError(PIPELINE_ERROR_OUT_OF_MEMORY));
838 filter_2_->host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY);
839
840 DoPause();
841
842 // Simulate an error on |filter_2_| while paused.
843 EXPECT_CALL(*mock_filter_host_, SetError(PIPELINE_ERROR_NETWORK));
844 filter_2_->host()->SetError(PIPELINE_ERROR_NETWORK);
845
846 DoStop();
847
848 // Verify that errors are not passed to |mock_filter_host_|
849 // after Stop() has been called.
850 filter_2_->host()->SetError(PIPELINE_ERROR_NETWORK);
851 }
852
853 // Make sure that state transitions act as expected even
854 // if the composite doesn't contain any filters.
855 TEST_F(CompositeFilterTest, TestEmptyComposite) {
856 InSequence sequence;
857
858 composite_->set_host(mock_filter_host_.get());
859
860 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
861 new StrictMock<MockFilterCallback>());
862
863 // Issue a Play() and expect no errors.
864 EXPECT_CALL(*mock_callback, OnFilterCallback());
865 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
866 composite_->Play(mock_callback->NewCallback());
867
868 // Issue a Pause() and expect no errors.
869 EXPECT_CALL(*mock_callback, OnFilterCallback());
870 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
871 composite_->Pause(mock_callback->NewCallback());
872
873 // Issue a Flush() and expect no errors.
874 EXPECT_CALL(*mock_callback, OnFilterCallback());
875 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
876 composite_->Flush(mock_callback->NewCallback());
877
878 // Issue a Seek() and expect no errors.
879 EXPECT_CALL(*mock_callback, OnFilterCallback());
880 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
881 composite_->Seek(base::TimeDelta::FromSeconds(5),
882 mock_callback->NewCallback());
883
884 // Issue a Play() and expect no errors.
885 EXPECT_CALL(*mock_callback, OnFilterCallback());
886 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
887 composite_->Play(mock_callback->NewCallback());
888
889 // Issue a Stop() and expect no errors.
890 EXPECT_CALL(*mock_callback, OnFilterCallback());
891 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
892 composite_->Stop(mock_callback->NewCallback());
893 }
894
895 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698