Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "base/test/simple_test_tick_clock.h" | 10 #include "base/test/simple_test_tick_clock.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 48 } | 48 } |
| 49 | 49 |
| 50 ACTION_P2(SetError, pipeline, status) { | 50 ACTION_P2(SetError, pipeline, status) { |
| 51 pipeline->SetErrorForTesting(status); | 51 pipeline->SetErrorForTesting(status); |
| 52 } | 52 } |
| 53 | 53 |
| 54 ACTION_P2(SetBufferingState, cb, buffering_state) { | 54 ACTION_P2(SetBufferingState, cb, buffering_state) { |
| 55 cb->Run(buffering_state); | 55 cb->Run(buffering_state); |
| 56 } | 56 } |
| 57 | 57 |
| 58 ACTION_TEMPLATE(TrampolineRunCallback, | |
|
xhwang
2015/01/16 23:09:07
How about PostCallback?
DaleCurtis
2015/01/20 21:37:43
Done.
| |
| 59 HAS_1_TEMPLATE_PARAMS(int, k), | |
| 60 AND_0_VALUE_PARAMS()) { | |
| 61 return base::MessageLoop::current()->PostTask(FROM_HERE, | |
| 62 ::std::tr1::get<k>(args)); | |
|
xhwang
2015/01/16 23:09:07
worth adding to media/base/gmock_callback_support.
DaleCurtis
2015/01/20 21:37:43
If we see this pattern elsewhere, maybe, but these
xhwang
2015/01/20 23:00:38
\o/ Acknowledged.
| |
| 63 } | |
| 64 | |
| 65 ACTION_TEMPLATE(TrampolineRunCallback, | |
| 66 HAS_1_TEMPLATE_PARAMS(int, k), | |
| 67 AND_1_VALUE_PARAMS(p0)) { | |
| 68 return base::MessageLoop::current()->PostTask( | |
| 69 FROM_HERE, base::Bind(::std::tr1::get<k>(args), p0)); | |
| 70 } | |
| 71 | |
| 58 // TODO(scherkus): even though some filters are initialized on separate | 72 // TODO(scherkus): even though some filters are initialized on separate |
| 59 // threads these test aren't flaky... why? It's because filters' Initialize() | 73 // threads these test aren't flaky... why? It's because filters' Initialize() |
| 60 // is executed on |message_loop_| and the mock filters instantly call | 74 // is executed on |message_loop_| and the mock filters instantly call |
| 61 // InitializationComplete(), which keeps the pipeline humming along. If | 75 // InitializationComplete(), which keeps the pipeline humming along. If |
| 62 // either filters don't call InitializationComplete() immediately or filter | 76 // either filters don't call InitializationComplete() immediately or filter |
| 63 // initialization is moved to a separate thread this test will become flaky. | 77 // initialization is moved to a separate thread this test will become flaky. |
| 64 class PipelineTest : public ::testing::Test { | 78 class PipelineTest : public ::testing::Test { |
| 65 public: | 79 public: |
| 66 // Used for setting expectations on pipeline callbacks. Using a StrictMock | 80 // Used for setting expectations on pipeline callbacks. Using a StrictMock |
| 67 // also lets us test for missing callbacks. | 81 // also lets us test for missing callbacks. |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 132 } | 146 } |
| 133 | 147 |
| 134 protected: | 148 protected: |
| 135 // Sets up expectations to allow the demuxer to initialize. | 149 // Sets up expectations to allow the demuxer to initialize. |
| 136 typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector; | 150 typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector; |
| 137 void SetDemuxerExpectations(MockDemuxerStreamVector* streams, | 151 void SetDemuxerExpectations(MockDemuxerStreamVector* streams, |
| 138 const base::TimeDelta& duration) { | 152 const base::TimeDelta& duration) { |
| 139 EXPECT_CALL(callbacks_, OnDurationChange()); | 153 EXPECT_CALL(callbacks_, OnDurationChange()); |
| 140 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 154 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
| 141 .WillOnce(DoAll(SetDemuxerProperties(duration), | 155 .WillOnce(DoAll(SetDemuxerProperties(duration), |
| 142 RunCallback<1>(PIPELINE_OK))); | 156 TrampolineRunCallback<1>(PIPELINE_OK))); |
| 143 | 157 |
| 144 // Configure the demuxer to return the streams. | 158 // Configure the demuxer to return the streams. |
| 145 for (size_t i = 0; i < streams->size(); ++i) { | 159 for (size_t i = 0; i < streams->size(); ++i) { |
| 146 DemuxerStream* stream = (*streams)[i]; | 160 DemuxerStream* stream = (*streams)[i]; |
| 147 EXPECT_CALL(*demuxer_, GetStream(stream->type())) | 161 EXPECT_CALL(*demuxer_, GetStream(stream->type())) |
| 148 .WillRepeatedly(Return(stream)); | 162 .WillRepeatedly(Return(stream)); |
| 149 } | 163 } |
| 150 } | 164 } |
| 151 | 165 |
| 152 void SetDemuxerExpectations(MockDemuxerStreamVector* streams) { | 166 void SetDemuxerExpectations(MockDemuxerStreamVector* streams) { |
| 153 // Initialize with a default non-zero duration. | 167 // Initialize with a default non-zero duration. |
| 154 SetDemuxerExpectations(streams, base::TimeDelta::FromSeconds(10)); | 168 SetDemuxerExpectations(streams, base::TimeDelta::FromSeconds(10)); |
| 155 } | 169 } |
| 156 | 170 |
| 157 scoped_ptr<StrictMock<MockDemuxerStream> > CreateStream( | 171 scoped_ptr<StrictMock<MockDemuxerStream> > CreateStream( |
| 158 DemuxerStream::Type type) { | 172 DemuxerStream::Type type) { |
| 159 scoped_ptr<StrictMock<MockDemuxerStream> > stream( | 173 scoped_ptr<StrictMock<MockDemuxerStream> > stream( |
| 160 new StrictMock<MockDemuxerStream>(type)); | 174 new StrictMock<MockDemuxerStream>(type)); |
| 161 return stream.Pass(); | 175 return stream.Pass(); |
| 162 } | 176 } |
| 163 | 177 |
| 164 // Sets up expectations to allow the video renderer to initialize. | 178 // Sets up expectations to allow the video renderer to initialize. |
| 165 void SetRendererExpectations() { | 179 void SetRendererExpectations() { |
| 166 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) | 180 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) |
| 167 .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_), | 181 .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_), |
| 168 SaveArg<5>(&ended_cb_), | 182 SaveArg<5>(&ended_cb_), |
| 169 RunCallback<1>())); | 183 TrampolineRunCallback<1>())); |
| 170 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(audio_stream())); | 184 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(audio_stream())); |
| 171 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(video_stream())); | 185 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(video_stream())); |
| 172 } | 186 } |
| 173 | 187 |
| 174 void AddTextStream() { | 188 void AddTextStream() { |
| 175 EXPECT_CALL(*this, OnAddTextTrack(_,_)) | 189 EXPECT_CALL(*this, OnAddTextTrack(_,_)) |
| 176 .WillOnce(Invoke(this, &PipelineTest::DoOnAddTextTrack)); | 190 .WillOnce(Invoke(this, &PipelineTest::DoOnAddTextTrack)); |
| 177 static_cast<DemuxerHost*>(pipeline_.get())->AddTextStream(text_stream(), | 191 static_cast<DemuxerHost*>(pipeline_.get())->AddTextStream(text_stream(), |
| 178 TextTrackConfig(kTextSubtitles, "", "", "")); | 192 TextTrackConfig(kTextSubtitles, "", "", "")); |
| 179 message_loop_.RunUntilIdle(); | 193 message_loop_.RunUntilIdle(); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 365 | 379 |
| 366 TEST_F(PipelineTest, StopWithoutStart) { | 380 TEST_F(PipelineTest, StopWithoutStart) { |
| 367 ExpectPipelineStopAndDestroyPipeline(); | 381 ExpectPipelineStopAndDestroyPipeline(); |
| 368 pipeline_->Stop( | 382 pipeline_->Stop( |
| 369 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | 383 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); |
| 370 message_loop_.RunUntilIdle(); | 384 message_loop_.RunUntilIdle(); |
| 371 } | 385 } |
| 372 | 386 |
| 373 TEST_F(PipelineTest, StartThenStopImmediately) { | 387 TEST_F(PipelineTest, StartThenStopImmediately) { |
| 374 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 388 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
| 375 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 389 .WillOnce(TrampolineRunCallback<1>(PIPELINE_OK)); |
| 376 EXPECT_CALL(*demuxer_, Stop()); | 390 EXPECT_CALL(*demuxer_, Stop()); |
| 377 | 391 |
| 378 EXPECT_CALL(callbacks_, OnStart(_)); | 392 EXPECT_CALL(callbacks_, OnStart(_)); |
| 379 StartPipeline(); | 393 StartPipeline(); |
| 380 | 394 |
| 381 // Expect a stop callback if we were started. | 395 // Expect a stop callback if we were started. |
| 382 ExpectPipelineStopAndDestroyPipeline(); | 396 ExpectPipelineStopAndDestroyPipeline(); |
| 383 pipeline_->Stop( | 397 pipeline_->Stop( |
| 384 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | 398 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); |
| 385 message_loop_.RunUntilIdle(); | 399 message_loop_.RunUntilIdle(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 399 .WillOnce(InvokeWithoutArgs(this, &PipelineTest::OnDemuxerError)); | 413 .WillOnce(InvokeWithoutArgs(this, &PipelineTest::OnDemuxerError)); |
| 400 ExpectPipelineStopAndDestroyPipeline(); | 414 ExpectPipelineStopAndDestroyPipeline(); |
| 401 | 415 |
| 402 pipeline_->Stop( | 416 pipeline_->Stop( |
| 403 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | 417 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); |
| 404 message_loop_.RunUntilIdle(); | 418 message_loop_.RunUntilIdle(); |
| 405 } | 419 } |
| 406 | 420 |
| 407 TEST_F(PipelineTest, URLNotFound) { | 421 TEST_F(PipelineTest, URLNotFound) { |
| 408 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 422 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
| 409 .WillOnce(RunCallback<1>(PIPELINE_ERROR_URL_NOT_FOUND)); | 423 .WillOnce(TrampolineRunCallback<1>(PIPELINE_ERROR_URL_NOT_FOUND)); |
| 410 EXPECT_CALL(*demuxer_, Stop()); | 424 EXPECT_CALL(*demuxer_, Stop()); |
| 411 | 425 |
| 412 StartPipelineAndExpect(PIPELINE_ERROR_URL_NOT_FOUND); | 426 StartPipelineAndExpect(PIPELINE_ERROR_URL_NOT_FOUND); |
| 413 } | 427 } |
| 414 | 428 |
| 415 TEST_F(PipelineTest, NoStreams) { | 429 TEST_F(PipelineTest, NoStreams) { |
| 416 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 430 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
| 417 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 431 .WillOnce(TrampolineRunCallback<1>(PIPELINE_OK)); |
| 418 EXPECT_CALL(*demuxer_, Stop()); | 432 EXPECT_CALL(*demuxer_, Stop()); |
| 419 | 433 |
| 420 StartPipelineAndExpect(PIPELINE_ERROR_COULD_NOT_RENDER); | 434 StartPipelineAndExpect(PIPELINE_ERROR_COULD_NOT_RENDER); |
| 421 } | 435 } |
| 422 | 436 |
| 423 TEST_F(PipelineTest, AudioStream) { | 437 TEST_F(PipelineTest, AudioStream) { |
| 424 CreateAudioStream(); | 438 CreateAudioStream(); |
| 425 MockDemuxerStreamVector streams; | 439 MockDemuxerStreamVector streams; |
| 426 streams.push_back(audio_stream()); | 440 streams.push_back(audio_stream()); |
| 427 | 441 |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 818 PipelineStatus SetInitializeExpectations(TeardownState state, | 832 PipelineStatus SetInitializeExpectations(TeardownState state, |
| 819 StopOrError stop_or_error) { | 833 StopOrError stop_or_error) { |
| 820 PipelineStatus status = PIPELINE_OK; | 834 PipelineStatus status = PIPELINE_OK; |
| 821 base::Closure stop_cb = base::Bind( | 835 base::Closure stop_cb = base::Bind( |
| 822 &CallbackHelper::OnStop, base::Unretained(&callbacks_)); | 836 &CallbackHelper::OnStop, base::Unretained(&callbacks_)); |
| 823 | 837 |
| 824 if (state == kInitDemuxer) { | 838 if (state == kInitDemuxer) { |
| 825 if (stop_or_error == kStop) { | 839 if (stop_or_error == kStop) { |
| 826 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 840 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
| 827 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), | 841 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), |
| 828 RunCallback<1>(PIPELINE_OK))); | 842 TrampolineRunCallback<1>(PIPELINE_OK))); |
| 829 ExpectPipelineStopAndDestroyPipeline(); | 843 ExpectPipelineStopAndDestroyPipeline(); |
| 830 } else { | 844 } else { |
| 831 status = DEMUXER_ERROR_COULD_NOT_OPEN; | 845 status = DEMUXER_ERROR_COULD_NOT_OPEN; |
| 832 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 846 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
| 833 .WillOnce(RunCallback<1>(status)); | 847 .WillOnce(TrampolineRunCallback<1>(status)); |
| 834 } | 848 } |
| 835 | 849 |
| 836 EXPECT_CALL(*demuxer_, Stop()); | 850 EXPECT_CALL(*demuxer_, Stop()); |
| 837 return status; | 851 return status; |
| 838 } | 852 } |
| 839 | 853 |
| 840 CreateAudioStream(); | 854 CreateAudioStream(); |
| 841 CreateVideoStream(); | 855 CreateVideoStream(); |
| 842 MockDemuxerStreamVector streams; | 856 MockDemuxerStreamVector streams; |
| 843 streams.push_back(audio_stream()); | 857 streams.push_back(audio_stream()); |
| 844 streams.push_back(video_stream()); | 858 streams.push_back(video_stream()); |
| 845 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); | 859 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); |
| 846 | 860 |
| 847 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(true)); | 861 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(true)); |
| 848 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(true)); | 862 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(true)); |
| 849 | 863 |
| 850 if (state == kInitRenderer) { | 864 if (state == kInitRenderer) { |
| 851 if (stop_or_error == kStop) { | 865 if (stop_or_error == kStop) { |
| 852 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) | 866 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) |
| 853 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), | 867 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), |
| 854 RunCallback<1>())); | 868 TrampolineRunCallback<1>())); |
| 855 ExpectPipelineStopAndDestroyPipeline(); | 869 ExpectPipelineStopAndDestroyPipeline(); |
| 856 } else { | 870 } else { |
| 857 status = PIPELINE_ERROR_INITIALIZATION_FAILED; | 871 status = PIPELINE_ERROR_INITIALIZATION_FAILED; |
| 858 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) | 872 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) |
| 859 .WillOnce(DoAll(RunCallback<6>(status), RunCallback<1>())); | 873 .WillOnce( |
| 874 DoAll(RunCallback<6>(status), TrampolineRunCallback<1>())); | |
| 860 } | 875 } |
| 861 | 876 |
| 862 EXPECT_CALL(*demuxer_, Stop()); | 877 EXPECT_CALL(*demuxer_, Stop()); |
| 863 return status; | 878 return status; |
| 864 } | 879 } |
| 865 | 880 |
| 866 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) | 881 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) |
| 867 .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_), | 882 .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_), |
| 868 RunCallback<1>())); | 883 TrampolineRunCallback<1>())); |
| 869 | 884 |
| 870 EXPECT_CALL(callbacks_, OnMetadata(_)); | 885 EXPECT_CALL(callbacks_, OnMetadata(_)); |
| 871 | 886 |
| 872 // If we get here it's a successful initialization. | 887 // If we get here it's a successful initialization. |
| 873 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0f)); | 888 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0f)); |
| 874 EXPECT_CALL(*renderer_, SetVolume(1.0f)); | 889 EXPECT_CALL(*renderer_, SetVolume(1.0f)); |
| 875 EXPECT_CALL(*renderer_, StartPlayingFrom(base::TimeDelta())) | 890 EXPECT_CALL(*renderer_, StartPlayingFrom(base::TimeDelta())) |
| 876 .WillOnce(SetBufferingState(&buffering_state_cb_, | 891 .WillOnce(SetBufferingState(&buffering_state_cb_, |
| 877 BUFFERING_HAVE_ENOUGH)); | 892 BUFFERING_HAVE_ENOUGH)); |
| 878 | 893 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 995 | 1010 |
| 996 INSTANTIATE_TEARDOWN_TEST(Error, InitDemuxer); | 1011 INSTANTIATE_TEARDOWN_TEST(Error, InitDemuxer); |
| 997 INSTANTIATE_TEARDOWN_TEST(Error, InitRenderer); | 1012 INSTANTIATE_TEARDOWN_TEST(Error, InitRenderer); |
| 998 INSTANTIATE_TEARDOWN_TEST(Error, Flushing); | 1013 INSTANTIATE_TEARDOWN_TEST(Error, Flushing); |
| 999 INSTANTIATE_TEARDOWN_TEST(Error, Seeking); | 1014 INSTANTIATE_TEARDOWN_TEST(Error, Seeking); |
| 1000 INSTANTIATE_TEARDOWN_TEST(Error, Playing); | 1015 INSTANTIATE_TEARDOWN_TEST(Error, Playing); |
| 1001 | 1016 |
| 1002 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing); | 1017 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing); |
| 1003 | 1018 |
| 1004 } // namespace media | 1019 } // namespace media |
| OLD | NEW |