diff options
Diffstat (limited to 'media/audio/audio_controller_unittest.cc')
-rw-r--r-- | media/audio/audio_controller_unittest.cc | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/media/audio/audio_controller_unittest.cc b/media/audio/audio_controller_unittest.cc new file mode 100644 index 0000000..5c5a522 --- /dev/null +++ b/media/audio/audio_controller_unittest.cc @@ -0,0 +1,164 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/env_var.h" +#include "base/basictypes.h" +#include "base/waitable_event.h" +#include "media/audio/audio_controller.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; +using ::testing::AtLeast; +using ::testing::Exactly; +using ::testing::InvokeWithoutArgs; +using ::testing::NotNull; + +namespace media { + +class MockAudioControllerEventHandler : public AudioController::EventHandler { + public: + MockAudioControllerEventHandler() {} + + MOCK_METHOD1(OnCreated, void(AudioController* controller)); + MOCK_METHOD1(OnPlaying, void(AudioController* controller)); + MOCK_METHOD1(OnPaused, void(AudioController* controller)); + MOCK_METHOD2(OnError, void(AudioController* controller, int error_code)); + MOCK_METHOD3(OnMoreData, + void(AudioController* controller, + base::Time timestamp, uint32 pending_bytes)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockAudioControllerEventHandler); +}; + +class MockAudioControllerSyncReader : public AudioController::SyncReader { + public: + MockAudioControllerSyncReader() {} + + MOCK_METHOD1(UpdatePendingBytes, void(uint32 bytes)); + MOCK_METHOD2(Read, uint32(void* data, uint32 size)); + MOCK_METHOD0(Close, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockAudioControllerSyncReader); +}; + +static bool HasAudioDevices() { + AudioManager* audio_man = AudioManager::GetAudioManager(); + CHECK(audio_man); + return audio_man->HasAudioDevices(); +} + +static bool IsRunningHeadless() { + scoped_ptr<base::EnvVarGetter> env(base::EnvVarGetter::Create()); + if (env->HasEnv("CHROME_HEADLESS")) + return true; + return false; +} + +ACTION_P3(SignalEvent, event, count, limit) { + if (++*count >= limit) { + event->Signal(); + } +} + +TEST(AudioControllerTest, PlayAndClose) { + if (!HasAudioDevices() || IsRunningHeadless()) + return; + + MockAudioControllerEventHandler event_handler; + base::WaitableEvent event(false, false); + int count = 0; + + // If OnCreated is called then signal the event. + EXPECT_CALL(event_handler, OnCreated(NotNull())) + .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal)); + + // OnPlaying() will be called only once. + EXPECT_CALL(event_handler, OnPlaying(NotNull())) + .Times(Exactly(1)); + + // If OnMoreData is called enough then signal the event. + EXPECT_CALL(event_handler, OnMoreData(NotNull(), _, 0)) + .Times(AtLeast(10)) + .WillRepeatedly(SignalEvent(&event, &count, 10)); + + scoped_refptr<AudioController> controller = AudioController::Create( + &event_handler, AudioManager::AUDIO_PCM_LINEAR, 1, + AudioManager::kAudioCDSampleRate, 16, 4096); + ASSERT_TRUE(controller.get()); + + // Wait for OnCreated() to be called. + event.Wait(); + event.Reset(); + + // Play and then wait for the event to be signaled. + controller->Play(); + event.Wait(); + + // Now stop the controller. This should shutdown the internal + // thread and we hold the only reference to it. + controller->Close(); + + // TODO(hclam): Make sure releasing the reference to this + // object actually destruct it. + controller = NULL; +} + +TEST(AudioControllerTest, PlayPauseClose) { + if (!HasAudioDevices() || IsRunningHeadless()) + return; + + MockAudioControllerEventHandler event_handler; + base::WaitableEvent event(false, false); + int count = 0; + + // If OnCreated is called then signal the event. + EXPECT_CALL(event_handler, OnCreated(NotNull())) + .Times(Exactly(1)) + .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal)); + + // OnPlaying() will be called only once. + EXPECT_CALL(event_handler, OnPlaying(NotNull())) + .Times(Exactly(1)); + + // If OnMoreData is called enough then signal the event. + EXPECT_CALL(event_handler, OnMoreData(NotNull(), _, 0)) + .Times(AtLeast(10)) + .WillRepeatedly(SignalEvent(&event, &count, 10)); + + // And then OnPaused() will be called. + EXPECT_CALL(event_handler, OnPaused(NotNull())) + .Times(Exactly(1)) + .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal)); + + scoped_refptr<AudioController> controller = AudioController::Create( + &event_handler, AudioManager::AUDIO_PCM_LINEAR, 1, + AudioManager::kAudioCDSampleRate, 16, 4096); + ASSERT_TRUE(controller.get()); + + // Wait for OnCreated() to be called. + event.Wait(); + event.Reset(); + + // Play and then wait for the event to be signaled. + controller->Play(); + event.Wait(); + event.Reset(); + + // And then wait for pause to complete. + controller->Pause(); + event.Wait(); + + // Now stop the controller. This should shutdown the internal + // thread and we hold the only reference to it. + controller->Close(); + + // TODO(hclam): Make sure releasing the reference to this + // object actually destruct it. + controller = NULL; +} + +} // namespace media |