| Index: content/renderer/media/audio_debug_recorder_unittest.cc
|
| diff --git a/content/renderer/media/audio_debug_recorder_unittest.cc b/content/renderer/media/audio_debug_recorder_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..abe2ef4de1c3cb033030944449a8eecdc332bcb8
|
| --- /dev/null
|
| +++ b/content/renderer/media/audio_debug_recorder_unittest.cc
|
| @@ -0,0 +1,247 @@
|
| +// Copyright 2015 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 "content/renderer/media/audio_debug_recorder.h"
|
| +
|
| +#include <map>
|
| +#include <utility>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/files/file.h"
|
| +#include "base/files/scoped_temp_dir.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "base/run_loop.h"
|
| +#include "content/common/media/audio_debug_recording.mojom.h"
|
| +#include "content/test/fake_service_registry.h"
|
| +#include "mojo/public/cpp/bindings/binding.h"
|
| +#include "mojo/public/cpp/system/handle.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
|
| +
|
| +using ::testing::_;
|
| +using ::testing::Invoke;
|
| +using ::testing::InvokeWithoutArgs;
|
| +
|
| +namespace content {
|
| +namespace {
|
| +
|
| +mojo::ScopedHandle MojoHandleFromFile(base::File file) {
|
| + CHECK(file.IsValid());
|
| + mojo::embedder::PlatformHandle platform_handle_wrapper(
|
| + file.TakePlatformFile());
|
| + mojo::embedder::ScopedPlatformHandle scoped_platform_handle(
|
| + platform_handle_wrapper);
|
| + MojoHandle mojo_handle = MOJO_HANDLE_INVALID;
|
| + MojoResult create_result = mojo::embedder::CreatePlatformHandleWrapper(
|
| + std::move(scoped_platform_handle), &mojo_handle);
|
| + CHECK_EQ(MOJO_RESULT_OK, create_result);
|
| + return MakeScopedHandle(mojo::Handle(mojo_handle));
|
| +}
|
| +
|
| +class TestAudioDebugRecordingImpl : public AudioDebugRecording {
|
| + public:
|
| + TestAudioDebugRecordingImpl(
|
| + mojo::InterfaceRequest<AudioDebugRecording> request)
|
| + : binding_(this, std::move(request)) {
|
| + }
|
| +
|
| + // |AudioDebugRecording| implementation.
|
| + void RegisterObserver(int32_t id,
|
| + AudioDebugRecordingObserverPtr observer) override {
|
| + observer.set_connection_error_handler(
|
| + base::Bind(&TestAudioDebugRecordingImpl::OnConnectionError,
|
| + base::Unretained(this), id));
|
| + ASSERT_EQ(observers_.find(id), observers_.end());
|
| + observers_.insert(std::make_pair(id, make_scoped_ptr(
|
| + new AudioDebugRecordingObserverPtr(std::move(observer)))));
|
| +
|
| + if (!quit_closure_.is_null())
|
| + quit_closure_.Run();
|
| + }
|
| +
|
| + void Enable(int32_t id, const base::FilePath& file_path) {
|
| + auto it = observers_.find(id);
|
| + ASSERT_NE(it, observers_.end());
|
| + base::File log_file(file_path,
|
| + base::File::FLAG_CREATE | base::File::FLAG_WRITE);
|
| + (*it->second)->Enable(MojoHandleFromFile(std::move(log_file)));
|
| + }
|
| +
|
| + void Disable(int32_t id) {
|
| + auto it = observers_.find(id);
|
| + ASSERT_NE(it, observers_.end());
|
| + (*it->second)->Disable();
|
| + }
|
| +
|
| + size_t NumObservers() const {
|
| + return observers_.size();
|
| + }
|
| +
|
| + void WaitForObservers(size_t num_observers) {
|
| + base::RunLoop run_loop;
|
| + quit_closure_ = run_loop.QuitClosure();
|
| + while (NumObservers() != num_observers)
|
| + run_loop.Run();
|
| + quit_closure_ = base::Closure();
|
| + }
|
| +
|
| + private:
|
| + void OnConnectionError(int32_t id) {
|
| + auto it = observers_.find(id);
|
| + ASSERT_NE(it, observers_.end());
|
| + observers_.erase(it);
|
| +
|
| + if (!quit_closure_.is_null())
|
| + quit_closure_.Run();
|
| + }
|
| +
|
| + base::Closure quit_closure_;
|
| + std::map<int32_t, scoped_ptr<AudioDebugRecordingObserverPtr>>
|
| + observers_;
|
| + mojo::Binding<AudioDebugRecording> binding_;
|
| +};
|
| +
|
| +class MockDelegate : public AudioDebugRecorder::AecDumpDelegate {
|
| + public:
|
| + MockDelegate() {}
|
| +
|
| + MOCK_METHOD1(OnAecDumpFile, void(base::PlatformFile file_handle));
|
| + MOCK_METHOD0(OnDisableAecDump, void());
|
| + MOCK_METHOD0(OnIpcClosing, void());
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +class AudioDebugRecorderTest : public ::testing::Test {
|
| + public:
|
| + AudioDebugRecorderTest() {
|
| + service_registry_.AddService(
|
| + base::Bind(&AudioDebugRecorderTest::CreateService,
|
| + base::Unretained(this)));
|
| + }
|
| +
|
| + void CreateService(mojo::InterfaceRequest<AudioDebugRecording> request) {
|
| + // There can be only one!
|
| + ASSERT_EQ(nullptr, service_.get());
|
| + service_.reset(new TestAudioDebugRecordingImpl(std::move(request)));
|
| + }
|
| +
|
| + base::MessageLoop message_loop_;
|
| + FakeServiceRegistry service_registry_;
|
| + scoped_ptr<TestAudioDebugRecordingImpl> service_;
|
| +};
|
| +
|
| +TEST_F(AudioDebugRecorderTest, GetGlobal) {
|
| + EXPECT_EQ(nullptr, AudioDebugRecorder::Get());
|
| + {
|
| + scoped_refptr<AudioDebugRecorder> recorder(
|
| + new AudioDebugRecorder(&service_registry_));
|
| + EXPECT_EQ(recorder.get(), AudioDebugRecorder::Get());
|
| + }
|
| + EXPECT_EQ(nullptr, AudioDebugRecorder::Get());
|
| +}
|
| +
|
| +TEST_F(AudioDebugRecorderTest, AddRemoveDelegate) {
|
| + scoped_refptr<AudioDebugRecorder> recorder(
|
| + new AudioDebugRecorder(&service_registry_));
|
| + ASSERT_NE(nullptr, service_.get());
|
| + EXPECT_EQ(0u, service_->NumObservers());
|
| +
|
| + MockDelegate delegate1;
|
| + recorder->AddDelegate(&delegate1);
|
| + service_->WaitForObservers(1);
|
| +
|
| + MockDelegate delegate2;
|
| + recorder->AddDelegate(&delegate2);
|
| + service_->WaitForObservers(2);
|
| +
|
| + recorder->RemoveDelegate(&delegate1);
|
| + service_->WaitForObservers(1);
|
| + recorder->RemoveDelegate(&delegate2);
|
| + service_->WaitForObservers(0);
|
| +}
|
| +
|
| +TEST_F(AudioDebugRecorderTest, DeleteWithoutRemoving) {
|
| + scoped_refptr<AudioDebugRecorder> recorder(
|
| + new AudioDebugRecorder(&service_registry_));
|
| + ASSERT_NE(nullptr, service_.get());
|
| + EXPECT_EQ(0u, service_->NumObservers());
|
| +
|
| + MockDelegate delegate1;
|
| + recorder->AddDelegate(&delegate1);
|
| + service_->WaitForObservers(1);
|
| +}
|
| +
|
| +TEST_F(AudioDebugRecorderTest, EnableDisable) {
|
| + scoped_refptr<AudioDebugRecorder> recorder(
|
| + new AudioDebugRecorder(&service_registry_));
|
| + ASSERT_NE(nullptr, service_.get());
|
| + EXPECT_EQ(0u, service_->NumObservers());
|
| +
|
| + MockDelegate delegate1;
|
| + recorder->AddDelegate(&delegate1);
|
| + service_->WaitForObservers(1);
|
| +
|
| + MockDelegate delegate2;
|
| + recorder->AddDelegate(&delegate2);
|
| + service_->WaitForObservers(2);
|
| +
|
| + base::ScopedTempDir temp_dir;
|
| + ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
|
| + base::FilePath log1 = temp_dir.path().AppendASCII("log_file1");
|
| + base::FilePath log2 = temp_dir.path().AppendASCII("log_file2");
|
| +
|
| + {
|
| + base::RunLoop run_loop;
|
| + EXPECT_CALL(delegate1, OnAecDumpFile(_))
|
| + .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
|
| + service_->Enable(1, log1);
|
| + run_loop.Run();
|
| + }
|
| +
|
| + {
|
| + base::RunLoop run_loop;
|
| + EXPECT_CALL(delegate2, OnAecDumpFile(_))
|
| + .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
|
| + service_->Enable(2, log2);
|
| + run_loop.Run();
|
| + }
|
| +
|
| + {
|
| + base::RunLoop run_loop;
|
| + EXPECT_CALL(delegate1, OnDisableAecDump())
|
| + .WillOnce(Invoke(&run_loop, &base::RunLoop::Quit));
|
| + service_->Disable(1);
|
| + run_loop.Run();
|
| + }
|
| +
|
| + {
|
| + base::RunLoop run_loop;
|
| + EXPECT_CALL(delegate2, OnDisableAecDump())
|
| + .WillOnce(Invoke(&run_loop, &base::RunLoop::Quit));
|
| + service_->Disable(2);
|
| + run_loop.Run();
|
| + }
|
| +}
|
| +
|
| +TEST_F(AudioDebugRecorderTest, OnIpcClosing) {
|
| + scoped_refptr<AudioDebugRecorder> recorder(
|
| + new AudioDebugRecorder(&service_registry_));
|
| + ASSERT_NE(nullptr, service_.get());
|
| + EXPECT_EQ(0u, service_->NumObservers());
|
| +
|
| + MockDelegate delegate1;
|
| + recorder->AddDelegate(&delegate1);
|
| + service_->WaitForObservers(1);
|
| +
|
| + base::RunLoop run_loop;
|
| + EXPECT_CALL(delegate1, OnIpcClosing())
|
| + .WillOnce(Invoke(&run_loop, &base::RunLoop::Quit));
|
| + service_.reset();
|
| + run_loop.Run();
|
| +}
|
| +
|
| +} // namespace content
|
|
|