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

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: Applied code review suggestions. 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,
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 // Run the callback stored in |filter_1_callback_|,
scherkus (not reviewing) 2010/12/16 18:43:39 nit: , -> .
acolwell GONE FROM CHROMIUM 2010/12/20 17:43:22 Done.
84 void RunFilter1Callback();
85
86 // Run the callback stored in |filter_2_callback_|,
scherkus (not reviewing) 2010/12/16 18:43:39 nit: , -> .
acolwell GONE FROM CHROMIUM 2010/12/20 17:43:22 Done.
87 void RunFilter2Callback();
88
89 protected:
90 MessageLoop message_loop_;
91
92 // The composite object being tested.
93 scoped_refptr<CompositeFilter> composite_;
94
95 // First filter added to the composite.
96 scoped_refptr<StrictMock<MockFilter> > filter_1_;
97
98 // Callback passed to |filter_1_| during last Play(), Pause(), Flush(),
99 // Stop(), or Seek() call.
100 FilterCallback* filter_1_callback_;
101
102 // Second filter added to the composite.
103 scoped_refptr<StrictMock<MockFilter> > filter_2_;
104
105 // Callback passed to |filter_2_| during last Play(), Pause(), Flush(),
106 // Stop(), or Seek() call.
107 FilterCallback* filter_2_callback_;
108
109 // FilterHost implementation passed to |composite_| via set_host().
110 scoped_ptr<StrictMock<MockFilterHost> > mock_filter_host_;
111
112 DISALLOW_COPY_AND_ASSIGN(CompositeFilterTest);
113 };
114
115 CompositeFilterTest::CompositeFilterTest() :
116 composite_(new CompositeFilter(&message_loop_)),
117 filter_1_callback_(NULL),
118 filter_2_callback_(NULL),
119 mock_filter_host_(new StrictMock<MockFilterHost>()){
scherkus (not reviewing) 2010/12/16 18:43:39 nit: space between ) and {
acolwell GONE FROM CHROMIUM 2010/12/20 17:43:22 Done.
120 }
121
122 CompositeFilterTest::~CompositeFilterTest() {}
123
124 void CompositeFilterTest::SetupAndAdd2Filters() {
125 mock_filter_host_.reset(new StrictMock<MockFilterHost>());
126 composite_ = new CompositeFilter(&message_loop_);
127 composite_->set_host(mock_filter_host_.get());
128
129 // Setup |filter_1_| and arrange for methods to set
130 // |filter_1_callback_| when they are called.
131 filter_1_ = new StrictMock<MockFilter>();
132 filter_1_callback_ = NULL;
133 ON_CALL(*filter_1_, Play(_))
134 .WillByDefault(SaveArg<0>(&filter_1_callback_));
135 ON_CALL(*filter_1_, Pause(_))
136 .WillByDefault(SaveArg<0>(&filter_1_callback_));
137 ON_CALL(*filter_1_, Flush(_))
138 .WillByDefault(SaveArg<0>(&filter_1_callback_));
139 ON_CALL(*filter_1_, Stop(_))
140 .WillByDefault(SaveArg<0>(&filter_1_callback_));
141 ON_CALL(*filter_1_, Seek(_,_))
142 .WillByDefault(SaveArg<1>(&filter_1_callback_));
143
144 // Setup |filter_2_| and arrange for methods to set
145 // |filter_2_callback_| when they are called.
146 filter_2_ = new StrictMock<MockFilter>();
147 filter_2_callback_ = NULL;
148 ON_CALL(*filter_2_, Play(_))
149 .WillByDefault(SaveArg<0>(&filter_2_callback_));
150 ON_CALL(*filter_2_, Pause(_))
151 .WillByDefault(SaveArg<0>(&filter_2_callback_));
152 ON_CALL(*filter_2_, Flush(_))
153 .WillByDefault(SaveArg<0>(&filter_2_callback_));
154 ON_CALL(*filter_2_, Stop(_))
155 .WillByDefault(SaveArg<0>(&filter_2_callback_));
156 ON_CALL(*filter_2_, Seek(_,_))
157 .WillByDefault(SaveArg<1>(&filter_2_callback_));
158
159 composite_->AddFilter(filter_1_);
160 composite_->AddFilter(filter_2_);
161 }
162
163 void CompositeFilterTest::ExpectFilterCall(MethodToCall method_to_call,
164 MockFilter* filter,
165 base::TimeDelta seek_time) {
166 switch(method_to_call) {
167 case PLAY:
168 EXPECT_CALL(*filter, Play(_));
169 break;
170 case PAUSE:
171 EXPECT_CALL(*filter, Pause(_));
172 break;
173 case FLUSH:
174 EXPECT_CALL(*filter, Flush(_));
175 break;
176 case STOP:
177 EXPECT_CALL(*filter, Stop(_));
178 break;
179 case SEEK:
180 EXPECT_CALL(*filter, Seek(seek_time, _));
181 break;
182 };
183 }
184
185 void CompositeFilterTest::DoFilterCall(MethodToCall method_to_call,
186 Filter* filter,
187 base::TimeDelta seek_time,
188 FilterCallback* callback) {
189 switch(method_to_call) {
190 case PLAY:
191 filter->Play(callback);
192 break;
193 case PAUSE:
194 filter->Pause(callback);
195 break;
196 case FLUSH:
197 filter->Flush(callback);
198 break;
199 case STOP:
200 filter->Stop(callback);
201 break;
202 case SEEK:
203 filter->Seek(seek_time, callback);
204 break;
205 };
206 }
207
208 void CompositeFilterTest::ExpectSuccess(MethodToCall method_to_call,
209 base::TimeDelta seek_time) {
210 InSequence seq;
211
212 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
213 new StrictMock<MockFilterCallback>(false));
214
215 bool is_parallel_call = (method_to_call == FLUSH);
216
217 ExpectFilterCall(method_to_call, filter_1_.get(), seek_time);
218
219 if (is_parallel_call) {
220 ExpectFilterCall(method_to_call, filter_2_.get(), seek_time);
221 }
222
223 // Make method call on the composite.
224 DoFilterCall(method_to_call, composite_.get(), seek_time,
225 mock_callback->NewCallback());
226
227 if (is_parallel_call) {
228 // Make sure both filters have their callbacks set.
229 EXPECT_NE((FilterCallback*)NULL, filter_1_callback_);
scherkus (not reviewing) 2010/12/16 18:43:39 ok I debugged this a bit because that's strange...
acolwell GONE FROM CHROMIUM 2010/12/20 17:43:22 Done. I just changed the EXPECT_NE()s to EXPECT_TR
230 EXPECT_NE((FilterCallback*)NULL, filter_2_callback_);
231
232 RunFilter1Callback();
233 } else {
234 // Make sure that only |filter_1_| has its callback set.
235 EXPECT_NE((FilterCallback*)NULL, filter_1_callback_);
236 EXPECT_EQ((FilterCallback*)NULL, filter_2_callback_);
237
238 ExpectFilterCall(method_to_call, filter_2_.get(), seek_time);
239
240 RunFilter1Callback();
241
242 // Verify that |filter_2_| was called by checking the callback pointer.
243 EXPECT_NE((FilterCallback*)NULL, filter_2_callback_);
244 }
245
246 EXPECT_CALL(*mock_callback, OnFilterCallback());
247
248 RunFilter2Callback();
249 }
250
251 void CompositeFilterTest::DoPlay() {
252 ExpectSuccess(PLAY);
253 }
254
255 void CompositeFilterTest::DoPause() {
256 ExpectSuccess(PAUSE);
257 }
258
259 void CompositeFilterTest::DoFlush() {
260 ExpectSuccess(FLUSH);
261 }
262
263 void CompositeFilterTest::DoStop() {
264 ExpectSuccess(STOP);
265 }
266
267 void CompositeFilterTest::DoSeek(base::TimeDelta time) {
268 ExpectSuccess(SEEK, time);
269 }
270
271 void CompositeFilterTest::ExpectInvalidStateFail(MethodToCall method_to_call,
272 base::TimeDelta seek_time) {
273 InSequence seq;
274 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
275 new StrictMock<MockFilterCallback>(false));
276
277 EXPECT_CALL(*mock_filter_host_, SetError(PIPELINE_ERROR_INVALID_STATE))
278 .WillOnce(Return());
279 EXPECT_CALL(*mock_callback, OnFilterCallback());
280
281 DoFilterCall(method_to_call, composite_, seek_time,
282 mock_callback->NewCallback());
283
284 // Make sure that neither of the filters were called by
285 // verifying that the callback pointers weren't set.
286 EXPECT_EQ((FilterCallback*)NULL, filter_1_callback_);
287 EXPECT_EQ((FilterCallback*)NULL, filter_2_callback_);
288 }
289
290 void CompositeFilterTest::RunFilter1Callback() {
291 EXPECT_NE((FilterCallback*)NULL, filter_1_callback_);
292 FilterCallback* callback = filter_1_callback_;
293 filter_1_callback_ = NULL;
294 callback->Run();
295 delete callback;
296 }
297
298 void CompositeFilterTest::RunFilter2Callback() {
299 EXPECT_NE((FilterCallback*)NULL, filter_2_callback_);
300 FilterCallback* callback = filter_2_callback_;
301 filter_2_callback_ = NULL;
302 callback->Run();
303 delete callback;
304 }
305
306 static base::Thread* NullThreadFactory(const char* thread_name) {
307 return NULL;
308 }
309
310 // Test AddFilter() failure cases.
311 TEST_F(CompositeFilterTest, TestAddFilterFailCases) {
312 // Test adding a null pointer.
313 EXPECT_FALSE(composite_->AddFilter(NULL));
314
315 scoped_refptr<StrictMock<MockFilter> > filter =
316 new StrictMock<MockFilter>(true);
317 EXPECT_EQ(NULL, filter->host());
318 EXPECT_EQ(NULL, filter->message_loop());
319
320 // Test failing because set_host() hasn't been called yet.
321 EXPECT_FALSE(composite_->AddFilter(filter));
322
323 // Test thread creation failure.
324 composite_ = new CompositeFilter(&message_loop_, &NullThreadFactory);
325 composite_->set_host(mock_filter_host_.get());
326 EXPECT_FALSE(composite_->AddFilter(filter));
327 EXPECT_EQ(NULL, filter->host());
328 EXPECT_EQ(NULL, filter->message_loop());
329 }
330
331 // Test successful AddFilter() cases.
332 TEST_F(CompositeFilterTest, TestAddFilter) {
333 composite_->set_host(mock_filter_host_.get());
334
335 // Add a filter that doesn't require a message loop.
336 scoped_refptr<StrictMock<MockFilter> > filter = new StrictMock<MockFilter>();
337 EXPECT_EQ(NULL, filter->host());
338 EXPECT_EQ(NULL, filter->message_loop());
339
340 EXPECT_TRUE(composite_->AddFilter(filter));
341
342 EXPECT_NE((FilterHost*)NULL, filter->host());
343 EXPECT_EQ(NULL, filter->message_loop());
344
345 // Add a filter that requires a message loop.
346 scoped_refptr<StrictMock<MockFilter> > filter_2 =
347 new StrictMock<MockFilter>(true);
348
349 EXPECT_EQ(NULL, filter_2->host());
350 EXPECT_EQ(NULL, filter_2->message_loop());
351
352 EXPECT_TRUE(composite_->AddFilter(filter_2));
353
354 EXPECT_NE((FilterHost*)NULL, filter_2->host());
355 EXPECT_NE((MessageLoop*)NULL, filter_2->message_loop());
356 }
357
358 static bool g_thread_cleanup_called_ = false;
359 class CompositeFilterThread : public base::Thread {
360 public:
361 CompositeFilterThread(const char* name) : base::Thread(name) {}
362 virtual void CleanUp() {
363 g_thread_cleanup_called_ = true;
364 base::Thread::CleanUp();
365 }
366 };
367
368 static base::Thread* g_thread_created_by_factory = NULL;
369 static base::Thread* TestableThreadFactory(const char* thread_name) {
370 g_thread_created_by_factory = new CompositeFilterThread(thread_name);
371 return g_thread_created_by_factory;
372 }
373
374 // Verify that thread termination works as expected.
375 TEST_F(CompositeFilterTest, TestThreadTermination) {
scherkus (not reviewing) 2010/12/16 18:43:39 I still don't think we need (most of) this test si
acolwell GONE FROM CHROMIUM 2010/12/20 17:43:22 Removed the test case. Agree that thread managemen
376 composite_ = new CompositeFilter(&message_loop_, &TestableThreadFactory);
377 composite_->set_host(mock_filter_host_.get());
378
379 // Add a filter that requires a message loop.
380 scoped_refptr<StrictMock<MockFilter> > filter =
381 new StrictMock<MockFilter>(true);
382
383 EXPECT_EQ(NULL, g_thread_created_by_factory);
384 EXPECT_TRUE(composite_->AddFilter(filter));
385 EXPECT_NE((base::Thread*)NULL, g_thread_created_by_factory);
386 EXPECT_NE((MessageLoop*)NULL, filter->message_loop());
387
388 // Verify that the filter has a message loop and it matches the
389 // thread's message loop.
390 base::Thread* filter_thread = g_thread_created_by_factory;
391 EXPECT_NE((MessageLoop*)NULL, filter_thread->message_loop());
392 EXPECT_EQ(filter_thread->message_loop(), filter->message_loop());
393
394 EXPECT_TRUE(filter_thread->IsRunning());
395 EXPECT_FALSE(g_thread_cleanup_called_);
396
397 composite_ = NULL;
398
399 // Verify that the thread stops running when the composite is
400 // destroyed.
401 EXPECT_TRUE(g_thread_cleanup_called_);
402 }
403
404 TEST_F(CompositeFilterTest, TestPlay) {
405 InSequence sequence;
406
407 SetupAndAdd2Filters();
408
409 // Verify successful call to Play().
410 DoPlay();
411
412 // At this point we are now in the kPlaying state.
413 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
414 new StrictMock<MockFilterCallback>(false));
415
416 // Try calling Play() again to make sure that we simply get a callback.
417 // We are already in the Play() state so there is no point calling the
418 // filters.
419 EXPECT_CALL(*mock_callback, OnFilterCallback());
420
421 composite_->Play(mock_callback->NewCallback());
422
423 // Verify that neither of the filter callbacks were set.
424 EXPECT_EQ((FilterCallback*)NULL, filter_1_callback_);
425 EXPECT_EQ((FilterCallback*)NULL, filter_2_callback_);
426
427 // Stop playback.
428 DoStop();
429
430 // At this point we should be in the kStopped state.
431
432 // Try calling Stop() again to make sure neither filter is called.
433 EXPECT_CALL(*mock_callback, OnFilterCallback());
434
435 composite_->Stop(mock_callback->NewCallback());
436
437 // Verify that neither of the filter callbacks were set.
438 EXPECT_EQ((FilterCallback*)NULL, filter_1_callback_);
439 EXPECT_EQ((FilterCallback*)NULL, filter_2_callback_);
440
441 // Try calling Play() again to make sure we get an error.
442 ExpectInvalidStateFail(PLAY);
443 }
444
445 // Test errors in the middle of a serial call sequence like Play().
446 TEST_F(CompositeFilterTest, TestPlayErrors) {
447 InSequence sequence;
448
449 SetupAndAdd2Filters();
450
451 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
452 new StrictMock<MockFilterCallback>(false));
453
454 EXPECT_CALL(*filter_1_, Play(_));
455
456 // Call Play() on the composite.
457 composite_->Play(mock_callback->NewCallback());
458
459 EXPECT_CALL(*filter_2_, Play(_));
460
461 // Run callback to indicate that |filter_1_|'s Play() has completed.
462 RunFilter1Callback();
463
464 // At this point Play() has been called on |filter_2_|. Simulate an
465 // error by calling SetError() on its FilterHost interface.
466 filter_2_->host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY);
467
468 // Expect error to be reported and "play done" callback to be called.
469 EXPECT_CALL(*mock_filter_host_, SetError(PIPELINE_ERROR_OUT_OF_MEMORY));
470 EXPECT_CALL(*mock_callback, OnFilterCallback());
471
472 // Run callback to indicate that |filter_2_|'s Play() has completed.
473 RunFilter2Callback();
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>(false));
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
509 composite_->Pause(mock_callback->NewCallback());
510
511 // Verify that neither of the filter callbacks were set.
512 EXPECT_EQ((FilterCallback*)NULL, filter_1_callback_);
513 EXPECT_EQ((FilterCallback*)NULL, filter_2_callback_);
514
515 // Verify that we can transition pack to the play state.
516 DoPlay();
517
518 // Go back to the pause state.
519 DoPause();
520
521 // Transition to the stop state.
522 DoStop();
523
524 // Try calling Pause() to make sure we get an error because we aren't in
525 // the playing state.
526 ExpectInvalidStateFail(PAUSE);
527 }
528
529 // Test errors in the middle of a serial call sequence like Pause().
530 TEST_F(CompositeFilterTest, TestPauseErrors) {
531 InSequence sequence;
532
533 SetupAndAdd2Filters();
534
535 DoPlay();
536
537 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
538 new StrictMock<MockFilterCallback>(false));
539
540 EXPECT_CALL(*filter_1_, Pause(_));
541
542 // Call Pause() on the composite.
543 composite_->Pause(mock_callback->NewCallback());
544
545 // Simulate an error by calling SetError() on |filter_1_|'s FilterHost
546 // interface.
547 filter_1_->host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY);
548
549 // Expect error to be reported and "pause done" callback to be called.
550 EXPECT_CALL(*mock_filter_host_, SetError(PIPELINE_ERROR_OUT_OF_MEMORY));
551 EXPECT_CALL(*mock_callback, OnFilterCallback());
552
553 RunFilter1Callback();
554
555 // Make sure |filter_2_callback_| was not set.
556 EXPECT_EQ((FilterCallback*)NULL, filter_2_callback_);
557
558 // Verify that Play/Pause/Flush/Seek fail now that an error occured.
559 ExpectInvalidStateFail(PLAY);
560 ExpectInvalidStateFail(PAUSE);
561 ExpectInvalidStateFail(FLUSH);
562 ExpectInvalidStateFail(SEEK);
563
564 // Make sure you can still Stop().
565 DoStop();
566 }
567
568 TEST_F(CompositeFilterTest, TestFlush) {
569 InSequence sequence;
570
571 SetupAndAdd2Filters();
572
573 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
574 new StrictMock<MockFilterCallback>(false));
575
576 // Make sure Flush() works before calling Play().
577 DoFlush();
578
579 // Transition to playing state.
580 DoPlay();
581
582 // Call Flush() to make sure we get an error because we are in
583 // the playing state.
584 ExpectInvalidStateFail(FLUSH);
585
586 // Issue a successful Pause().
587 DoPause();
588
589 // Make sure Flush() works after pausing.
590 DoFlush();
591
592 // Verify that we can transition back to the play state.
593 DoPlay();
594
595 // Transition to the stop state.
596 DoStop();
597
598 // Try calling Flush() to make sure we get an error because we are stopped.
599 ExpectInvalidStateFail(FLUSH);
600 }
601
602 // Test errors in the middle of a parallel call sequence like Flush().
603 TEST_F(CompositeFilterTest, TestFlushErrors) {
604 InSequence sequence;
605
606 SetupAndAdd2Filters();
607
608 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
609 new StrictMock<MockFilterCallback>(false));
610
611 EXPECT_CALL(*filter_1_, Flush(_));
612 EXPECT_CALL(*filter_2_, Flush(_));
613
614 // Call Flush() on the composite.
615 composite_->Flush(mock_callback->NewCallback());
616
617 // Simulate an error by calling SetError() on |filter_1_|'s FilterHost
618 // interface.
619 filter_1_->host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY);
620
621 RunFilter1Callback();
622
623 // Expect error to be reported and "pause done" callback to be called.
624 EXPECT_CALL(*mock_filter_host_, SetError(PIPELINE_ERROR_OUT_OF_MEMORY));
625 EXPECT_CALL(*mock_callback, OnFilterCallback());
626
627 RunFilter2Callback();
628
629 // Verify that Play/Pause/Flush/Seek fail now that an error occured.
630 ExpectInvalidStateFail(PLAY);
631 ExpectInvalidStateFail(PAUSE);
632 ExpectInvalidStateFail(FLUSH);
633 ExpectInvalidStateFail(SEEK);
634
635 // Make sure you can still Stop().
636 DoStop();
637 }
638
639 TEST_F(CompositeFilterTest, TestSeek) {
640 InSequence sequence;
641
642 SetupAndAdd2Filters();
643
644 // Verify that seek is allowed to be called before a Play() call.
645 DoSeek(base::TimeDelta::FromSeconds(5));
646
647 // Verify we can issue a Play() after the Seek().
648 DoPlay();
649
650 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
651 new StrictMock<MockFilterCallback>(false));
652
653 // Try calling Seek() while playing to make sure we get an error.
654 ExpectInvalidStateFail(SEEK);
655
656 // Transition to paused state.
657 DoPause();
658
659 // Verify that seek is allowed after pausing.
660 DoSeek(base::TimeDelta::FromSeconds(5));
661
662 // Verify we can still play again.
663 DoPlay();
664
665 // Stop playback.
666 DoStop();
667
668 // Try calling Seek() to make sure we get an error.
669 ExpectInvalidStateFail(SEEK);
670 }
671
672 TEST_F(CompositeFilterTest, TestStop) {
673 InSequence sequence;
674
675 // Test Stop() before any other call.
676 SetupAndAdd2Filters();
677 DoStop();
678
679 // Test error during Stop() sequence.
680 SetupAndAdd2Filters();
681 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
682 new StrictMock<MockFilterCallback>(false));
683
684 EXPECT_CALL(*filter_1_, Stop(_));
685
686 composite_->Stop(mock_callback->NewCallback());
687
688 // Have |filter_1_| signal an error.
689 filter_1_->host()->SetError(PIPELINE_ERROR_READ);
690
691 EXPECT_CALL(*filter_2_, Stop(_));
692
693 RunFilter1Callback();
694
695 EXPECT_CALL(*mock_callback, OnFilterCallback());
696
697 RunFilter2Callback();
698 }
699
700 // Test stopping in the middle of a serial call sequence.
701 TEST_F(CompositeFilterTest, TestStopWhilePlayPending) {
702 InSequence sequence;
703
704 SetupAndAdd2Filters();
705
706 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
707 new StrictMock<MockFilterCallback>());
708
709 EXPECT_CALL(*filter_1_, Play(_));
710
711 composite_->Play(mock_callback->NewCallback());
712
713 // Note: Play() is pending on |filter_1_| right now.
714
715 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback_2(
716 new StrictMock<MockFilterCallback>(false));
717
718 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
719
720 composite_->Stop(mock_callback_2->NewCallback());
721
722 EXPECT_CALL(*filter_1_, Stop(_));
723
724 // Run |filter_1_|'s callback again to indicate Play() has completed.
725 RunFilter1Callback();
726
727 EXPECT_CALL(*filter_2_, Stop(_));
728
729 // Run |filter_1_|'s callback again to indicate Stop() has completed.
730 RunFilter1Callback();
731
732 EXPECT_CALL(*mock_callback_2, OnFilterCallback());
733
734 // Run |filter_2_|'s callback to indicate Stop() has completed.
735 RunFilter2Callback();
736 }
737
738 // Test stopping in the middle of a parallel call sequence.
739 TEST_F(CompositeFilterTest, TestStopWhileFlushPending) {
740 InSequence sequence;
741
742 SetupAndAdd2Filters();
743
744 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
745 new StrictMock<MockFilterCallback>());
746
747 EXPECT_CALL(*filter_1_, Flush(_));
748 EXPECT_CALL(*filter_2_, Flush(_));
749
750 composite_->Flush(mock_callback->NewCallback());
751
752 // Note: |filter_1_| and |filter_2_| have pending Flush() calls at this point.
753
754 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback_2(
755 new StrictMock<MockFilterCallback>(false));
756
757 EXPECT_CALL(*mock_callback, OnCallbackDestroyed());
758
759 composite_->Stop(mock_callback_2->NewCallback());
760
761 // Run callback to indicate that |filter_1_|'s Flush() has completed.
762 RunFilter1Callback();
763
764 EXPECT_CALL(*filter_1_, Stop(_));
765
766 // Run callback to indicate that |filter_2_|'s Flush() has completed.
767 RunFilter2Callback();
768
769 EXPECT_CALL(*filter_2_, Stop(_));
770
771 // Run callback to indicate that |filter_1_|'s Stop() has completed.
772 RunFilter1Callback();
773
774 EXPECT_CALL(*mock_callback_2, OnFilterCallback());
775
776 // Run callback to indicate that |filter_2_|'s Stop() has completed.
777 RunFilter2Callback();
778 }
779
780 TEST_F(CompositeFilterTest, TestErrorWhilePlaying) {
781 InSequence sequence;
782
783 SetupAndAdd2Filters();
784
785 // Simulate an error on |filter_2_| while in kCreated state. This
786 // can happen if an error occurs during filter initialization.
787 EXPECT_CALL(*mock_filter_host_, SetError(PIPELINE_ERROR_OUT_OF_MEMORY));
788 filter_2_->host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY);
789
790 DoPlay();
791
792 // Simulate an error on |filter_2_| while playing.
793 EXPECT_CALL(*mock_filter_host_, SetError(PIPELINE_ERROR_OUT_OF_MEMORY));
794 filter_2_->host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY);
795
796 DoPause();
797
798 // Simulate an error on |filter_2_| while paused.
799 EXPECT_CALL(*mock_filter_host_, SetError(PIPELINE_ERROR_NETWORK));
800 filter_2_->host()->SetError(PIPELINE_ERROR_NETWORK);
801
802 DoStop();
803
804 // Verify that errors are not passed to |mock_filter_host_|
805 // after Stop() has been called.
806 filter_2_->host()->SetError(PIPELINE_ERROR_NETWORK);
807 }
808
809 // Make sure that state transitions act as expected even
810 // if the composite doesn't contain any filters.
811 TEST_F(CompositeFilterTest, TestEmptyComposite) {
812 InSequence sequence;
813
814 composite_->set_host(mock_filter_host_.get());
815
816 scoped_ptr<StrictMock<MockFilterCallback> > mock_callback(
817 new StrictMock<MockFilterCallback>(false));
818
819 // Issue a Play() and expect no errors.
820 EXPECT_CALL(*mock_callback, OnFilterCallback());
821 composite_->Play(mock_callback->NewCallback());
822
823 // Issue a Pause() and expect no errors.
824 EXPECT_CALL(*mock_callback, OnFilterCallback());
825 composite_->Pause(mock_callback->NewCallback());
826
827 // Issue a Flush() and expect no errors.
828 EXPECT_CALL(*mock_callback, OnFilterCallback());
829 composite_->Flush(mock_callback->NewCallback());
830
831 // Issue a Seek() and expect no errors.
832 EXPECT_CALL(*mock_callback, OnFilterCallback());
833 composite_->Seek(base::TimeDelta::FromSeconds(5),
834 mock_callback->NewCallback());
835
836 // Issue a Play() and expect no errors.
837 EXPECT_CALL(*mock_callback, OnFilterCallback());
838 composite_->Play(mock_callback->NewCallback());
839
840 // Issue a Stop() and expect no errors.
841 EXPECT_CALL(*mock_callback, OnFilterCallback());
842 composite_->Stop(mock_callback->NewCallback());
843 }
844
845 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698