Commit 48d872c8 authored by rkc's avatar rkc Committed by Commit bot

Add AudioDirectiveHandler timed tests.

This CL adds tests for AudioDirectiveHandler which move time forward to verify
functionality. It also adds a ref counted tick clock proxy that can be used to
pass around a tick clock among multiple classes.

BUG=None.
R=xiyuan@chromium.org

Review URL: https://codereview.chromium.org/665353002

Cr-Commit-Position: refs/heads/master@{#301400}
parent 90bbd533
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
'copresence/handlers/audio/audio_directive_handler.h', 'copresence/handlers/audio/audio_directive_handler.h',
'copresence/handlers/audio/audio_directive_list.cc', 'copresence/handlers/audio/audio_directive_list.cc',
'copresence/handlers/audio/audio_directive_list.h', 'copresence/handlers/audio/audio_directive_list.h',
'copresence/handlers/audio/tick_clock_ref_counted.cc',
'copresence/handlers/audio/tick_clock_ref_counted.h',
'copresence/handlers/directive_handler.cc', 'copresence/handlers/directive_handler.cc',
'copresence/handlers/directive_handler.h', 'copresence/handlers/directive_handler.h',
'copresence/mediums/audio/audio_manager.h', 'copresence/mediums/audio/audio_manager.h',
......
...@@ -13,6 +13,8 @@ static_library("copresence") { ...@@ -13,6 +13,8 @@ static_library("copresence") {
"handlers/audio/audio_directive_handler.h", "handlers/audio/audio_directive_handler.h",
"handlers/audio/audio_directive_list.cc", "handlers/audio/audio_directive_list.cc",
"handlers/audio/audio_directive_list.h", "handlers/audio/audio_directive_list.h",
"handlers/audio/tick_clock_ref_counted.cc",
"handlers/audio/tick_clock_ref_counted.h",
"handlers/directive_handler.cc", "handlers/directive_handler.cc",
"handlers/directive_handler.h", "handlers/directive_handler.h",
"mediums/audio/audio_manager.h", "mediums/audio/audio_manager.h",
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/time/default_tick_clock.h" #include "base/time/default_tick_clock.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "components/copresence/handlers/audio/tick_clock_ref_counted.h"
#include "components/copresence/mediums/audio/audio_manager_impl.h" #include "components/copresence/mediums/audio/audio_manager_impl.h"
#include "components/copresence/proto/data.pb.h" #include "components/copresence/proto/data.pb.h"
#include "components/copresence/public/copresence_constants.h" #include "components/copresence/public/copresence_constants.h"
...@@ -36,7 +37,8 @@ base::TimeTicks GetEarliestEventTime(AudioDirectiveList* list, ...@@ -36,7 +37,8 @@ base::TimeTicks GetEarliestEventTime(AudioDirectiveList* list,
AudioDirectiveHandler::AudioDirectiveHandler() AudioDirectiveHandler::AudioDirectiveHandler()
: audio_event_timer_(new base::OneShotTimer<AudioDirectiveHandler>), : audio_event_timer_(new base::OneShotTimer<AudioDirectiveHandler>),
clock_(new base::DefaultTickClock) { clock_(new TickClockRefCounted(
make_scoped_ptr(new base::DefaultTickClock))) {
} }
AudioDirectiveHandler::~AudioDirectiveHandler() { AudioDirectiveHandler::~AudioDirectiveHandler() {
...@@ -107,6 +109,22 @@ void AudioDirectiveHandler::RemoveInstructions(const std::string& op_id) { ...@@ -107,6 +109,22 @@ void AudioDirectiveHandler::RemoveInstructions(const std::string& op_id) {
const std::string AudioDirectiveHandler::PlayingToken(AudioType type) const { const std::string AudioDirectiveHandler::PlayingToken(AudioType type) const {
return audio_manager_->GetToken(type); return audio_manager_->GetToken(type);
} }
void AudioDirectiveHandler::set_clock_for_testing(
const scoped_refptr<TickClockRefCounted>& clock) {
clock_ = clock;
transmits_list_[AUDIBLE].set_clock_for_testing(clock);
transmits_list_[INAUDIBLE].set_clock_for_testing(clock);
receives_list_[AUDIBLE].set_clock_for_testing(clock);
receives_list_[INAUDIBLE].set_clock_for_testing(clock);
}
void AudioDirectiveHandler::set_timer_for_testing(
scoped_ptr<base::Timer> timer) {
audio_event_timer_.swap(timer);
}
// Private methods. // Private methods.
void AudioDirectiveHandler::ProcessNextInstruction() { void AudioDirectiveHandler::ProcessNextInstruction() {
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "components/copresence/proto/data.pb.h" #include "components/copresence/proto/data.pb.h"
namespace base { namespace base {
class TickClock;
class Timer; class Timer;
} }
...@@ -27,6 +26,8 @@ class AudioBusRefCounted; ...@@ -27,6 +26,8 @@ class AudioBusRefCounted;
namespace copresence { namespace copresence {
class TickClockRefCounted;
// The AudioDirectiveHandler handles audio transmit and receive instructions. // The AudioDirectiveHandler handles audio transmit and receive instructions.
// TODO(rkc): Currently since WhispernetClient can only have one token encoded // TODO(rkc): Currently since WhispernetClient can only have one token encoded
// callback at a time, we need to have both the audible and inaudible in this // callback at a time, we need to have both the audible and inaudible in this
...@@ -60,6 +61,9 @@ class AudioDirectiveHandler final { ...@@ -60,6 +61,9 @@ class AudioDirectiveHandler final {
audio_manager_ = manager.Pass(); audio_manager_ = manager.Pass();
} }
void set_clock_for_testing(const scoped_refptr<TickClockRefCounted>& clock);
void set_timer_for_testing(scoped_ptr<base::Timer> timer);
private: private:
// Processes the next active instruction, updating our audio manager state // Processes the next active instruction, updating our audio manager state
// accordingly. // accordingly.
...@@ -80,7 +84,7 @@ class AudioDirectiveHandler final { ...@@ -80,7 +84,7 @@ class AudioDirectiveHandler final {
scoped_ptr<base::Timer> audio_event_timer_; scoped_ptr<base::Timer> audio_event_timer_;
scoped_ptr<base::TickClock> clock_; scoped_refptr<TickClockRefCounted> clock_;
DISALLOW_COPY_AND_ASSIGN(AudioDirectiveHandler); DISALLOW_COPY_AND_ASSIGN(AudioDirectiveHandler);
}; };
......
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/timer/mock_timer.h"
#include "components/copresence/handlers/audio/tick_clock_ref_counted.h"
#include "components/copresence/mediums/audio/audio_manager.h" #include "components/copresence/mediums/audio/audio_manager.h"
#include "components/copresence/test/audio_test_support.h" #include "components/copresence/test/audio_test_support.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -135,8 +138,71 @@ TEST_F(AudioDirectiveHandlerTest, Basic) { ...@@ -135,8 +138,71 @@ TEST_F(AudioDirectiveHandlerTest, Basic) {
EXPECT_FALSE(IsRecording(INAUDIBLE)); EXPECT_FALSE(IsRecording(INAUDIBLE));
} }
TEST_F(AudioDirectiveHandlerTest, Timed) {
scoped_ptr<base::SimpleTestTickClock> clock(new base::SimpleTestTickClock());
base::SimpleTestTickClock* clock_ptr = clock.get();
scoped_refptr<TickClockRefCounted> clock_proxy =
new TickClockRefCounted(clock.Pass());
directive_handler_->set_clock_for_testing(clock_proxy);
scoped_ptr<base::Timer> timer(new base::MockTimer(false, false));
base::MockTimer* timer_ptr = static_cast<base::MockTimer*>(timer.get());
directive_handler_->set_timer_for_testing(timer.Pass());
const base::TimeDelta kTtl1 = base::TimeDelta::FromMilliseconds(1337);
directive_handler_->AddInstruction(
CreateTransmitInstruction("token", true), "op_id1", kTtl1);
const base::TimeDelta kTtl2 = base::TimeDelta::FromMilliseconds(1338);
directive_handler_->AddInstruction(
CreateTransmitInstruction("token", false), "op_id1", kTtl2);
const base::TimeDelta kTtl3 = base::TimeDelta::FromMilliseconds(1336);
directive_handler_->AddInstruction(
CreateReceiveInstruction(false), "op_id3", kTtl3);
EXPECT_TRUE(IsPlaying(AUDIBLE));
EXPECT_TRUE(IsPlaying(INAUDIBLE));
EXPECT_FALSE(IsRecording(AUDIBLE));
EXPECT_TRUE(IsRecording(INAUDIBLE));
// We *have* to call an operation on the directive handler after we advance
// time to trigger the next set of operations, so ensure that after calling
// advance, we are also calling another operation.
clock_ptr->Advance(kTtl3 + base::TimeDelta::FromMilliseconds(1));
// We are now at base + 1337ms.
// This instruction expires at base + (1337 + 1337 = 2674)
directive_handler_->AddInstruction(
CreateReceiveInstruction(true), "op_id4", kTtl1);
EXPECT_TRUE(IsPlaying(AUDIBLE));
EXPECT_TRUE(IsPlaying(INAUDIBLE));
EXPECT_TRUE(IsRecording(AUDIBLE));
EXPECT_FALSE(IsRecording(INAUDIBLE));
clock_ptr->Advance(base::TimeDelta::FromMilliseconds(1));
// We are now at base + 1338ms.
timer_ptr->Fire();
EXPECT_FALSE(IsPlaying(AUDIBLE));
EXPECT_TRUE(IsPlaying(INAUDIBLE));
EXPECT_TRUE(IsRecording(AUDIBLE));
clock_ptr->Advance(base::TimeDelta::FromMilliseconds(1));
// We are now at base + 1339ms.
timer_ptr->Fire();
EXPECT_FALSE(IsPlaying(INAUDIBLE));
EXPECT_TRUE(IsRecording(AUDIBLE));
clock_ptr->Advance(kTtl3);
// We are now at base + 2676ms.
timer_ptr->Fire();
EXPECT_FALSE(IsRecording(AUDIBLE));
}
// TODO(rkc): Write more tests that check more convoluted sequences of // TODO(rkc): Write more tests that check more convoluted sequences of
// transmits/receives. // transmits/receives.
// TODO(rkc): Write tests to move time forward and test functionality.
} // namespace copresence } // namespace copresence
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/time/default_tick_clock.h" #include "base/time/default_tick_clock.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "components/copresence/handlers/audio/tick_clock_ref_counted.h"
namespace copresence { namespace copresence {
...@@ -23,7 +23,9 @@ AudioDirective::AudioDirective(const std::string& op_id, ...@@ -23,7 +23,9 @@ AudioDirective::AudioDirective(const std::string& op_id,
: op_id(op_id), end_time(end_time) { : op_id(op_id), end_time(end_time) {
} }
AudioDirectiveList::AudioDirectiveList() : clock_(new base::DefaultTickClock) { AudioDirectiveList::AudioDirectiveList()
: clock_(new TickClockRefCounted(
make_scoped_ptr(new base::DefaultTickClock))) {
} }
AudioDirectiveList::~AudioDirectiveList() { AudioDirectiveList::~AudioDirectiveList() {
...@@ -75,6 +77,13 @@ scoped_ptr<AudioDirective> AudioDirectiveList::GetActiveDirective() { ...@@ -75,6 +77,13 @@ scoped_ptr<AudioDirective> AudioDirectiveList::GetActiveDirective() {
return make_scoped_ptr(new AudioDirective(active_directives_.front())); return make_scoped_ptr(new AudioDirective(active_directives_.front()));
} }
void AudioDirectiveList::set_clock_for_testing(
const scoped_refptr<TickClockRefCounted>& clock) {
clock_ = clock;
}
// Private methods.
std::vector<AudioDirective>::iterator AudioDirectiveList::FindDirectiveByOpId( std::vector<AudioDirective>::iterator AudioDirectiveList::FindDirectiveByOpId(
const std::string& op_id) { const std::string& op_id) {
for (std::vector<AudioDirective>::iterator it = active_directives_.begin(); for (std::vector<AudioDirective>::iterator it = active_directives_.begin();
......
...@@ -10,19 +10,18 @@ ...@@ -10,19 +10,18 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/time/time.h" #include "base/time/time.h"
namespace base {
class TickClock;
}
namespace media { namespace media {
class AudioBusRefCounted; class AudioBusRefCounted;
} }
namespace copresence { namespace copresence {
class TickClockRefCounted;
struct AudioDirective final { struct AudioDirective final {
// Default ctor, required by the priority queue. // Default ctor, required by the priority queue.
AudioDirective(); AudioDirective();
...@@ -50,6 +49,8 @@ class AudioDirectiveList { ...@@ -50,6 +49,8 @@ class AudioDirectiveList {
scoped_ptr<AudioDirective> GetActiveDirective(); scoped_ptr<AudioDirective> GetActiveDirective();
void set_clock_for_testing(const scoped_refptr<TickClockRefCounted>& clock);
private: private:
// Comparator for comparing end_times on audio tokens. // Comparator for comparing end_times on audio tokens.
class LatestFirstComparator { class LatestFirstComparator {
...@@ -68,7 +69,7 @@ class AudioDirectiveList { ...@@ -68,7 +69,7 @@ class AudioDirectiveList {
// element. Only currently active directives will exist in this list. // element. Only currently active directives will exist in this list.
std::vector<AudioDirective> active_directives_; std::vector<AudioDirective> active_directives_;
scoped_ptr<base::TickClock> clock_; scoped_refptr<TickClockRefCounted> clock_;
DISALLOW_COPY_AND_ASSIGN(AudioDirectiveList); DISALLOW_COPY_AND_ASSIGN(AudioDirectiveList);
}; };
......
// Copyright 2014 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 "components/copresence/handlers/audio/tick_clock_ref_counted.h"
#include "base/time/tick_clock.h"
namespace copresence {
TickClockRefCounted::TickClockRefCounted(scoped_ptr<base::TickClock> clock)
: clock_(clock.Pass()) {
}
base::TimeTicks TickClockRefCounted::NowTicks() {
return clock_->NowTicks();
}
TickClockRefCounted::~TickClockRefCounted() {
}
} // namespace copresence
// Copyright 2014 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.
#ifndef COMPONENTS_COPRESENCE_HANDLERS_AUDIO_TICK_CLOCK_REF_COUNTED_H_
#define COMPONENTS_COPRESENCE_HANDLERS_AUDIO_TICK_CLOCK_REF_COUNTED_H_
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
namespace base {
class TickClock;
}
namespace copresence {
class TickClockRefCounted
: public base::RefCountedThreadSafe<TickClockRefCounted> {
public:
explicit TickClockRefCounted(scoped_ptr<base::TickClock> clock);
base::TimeTicks NowTicks();
private:
friend class base::RefCountedThreadSafe<TickClockRefCounted>;
virtual ~TickClockRefCounted();
scoped_ptr<base::TickClock> clock_;
DISALLOW_COPY_AND_ASSIGN(TickClockRefCounted);
};
} // namespace copresence
#endif // COMPONENTS_COPRESENCE_HANDLERS_AUDIO_TICK_CLOCK_REF_COUNTED_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment