Chromium Code Reviews| Index: cc/scheduler/frame_source_unittest.cc |
| diff --git a/cc/scheduler/frame_source_unittest.cc b/cc/scheduler/frame_source_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d8c444f9b45c863f5da258543365ff94372f22c6 |
| --- /dev/null |
| +++ b/cc/scheduler/frame_source_unittest.cc |
| @@ -0,0 +1,626 @@ |
| +// Copyright 2011 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 <deque> |
| + |
| +#include "base/basictypes.h" |
| +#include "base/gtest_prod_util.h" |
| +#include "base/test/test_simple_task_runner.h" |
| +#include "cc/scheduler/frame_source.h" |
| +#include "cc/test/begin_frame_args_test.h" |
| +#include "cc/test/scheduler_test_common.h" |
| +#include "testing/gmock/include/gmock/gmock.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +#define EXPECT_BEGIN_FRAME(obs, ...) \ |
| + { \ |
| + ::testing::Expectation exp = \ |
| + EXPECT_CALL(obs, \ |
| + OnBeginFrame(CreateBeginFrameArgsForTesting(__VA_ARGS__))) \ |
| + .InSequence(obs.sequence); \ |
| + BeginFrameArgs args = CreateBeginFrameArgsForTesting(__VA_ARGS__); \ |
| + EXPECT_CALL(obs, LastBeginFrameArgs()) \ |
| + .Times(::testing::AnyNumber()) \ |
| + .After(exp) \ |
| + .WillRepeatedly(::testing::ReturnRefOfCopy(args)); \ |
| + } |
| + |
| +#define EXPECT_BEGIN_FRAME_P(obs_ptr, ...) \ |
| + EXPECT_BEGIN_FRAME((*obs_ptr), __VA_ARGS__); |
| + |
| +#define SEND_BEGIN_FRAME(source, ...) \ |
| + source.TestSendBeginFrame(CreateBeginFrameArgsForTesting(__VA_ARGS__)); |
| + |
| +#define SEND_BEGIN_FRAME_P(source, ...) \ |
| + SEND_BEGIN_FRAME((*source), __VA_ARGS__); |
| + |
| +namespace cc { |
| +namespace { |
| + |
| +class MockBeginFrameObserver : public BeginFrameObserver { |
| + public: |
| + MOCK_METHOD1(OnBeginFrame, void(const BeginFrameArgs&)); |
| + MOCK_CONST_METHOD0(LastBeginFrameArgs, const BeginFrameArgs&()); |
| + // MOCK_CONST_METHOD0(AsValueInto, void(base::debug::TracedValue*)); |
|
Sami
2014/09/18 13:55:08
Unused?
mithro-old
2014/09/19 02:45:39
Removed.
|
| + |
| + virtual void AsValueInto(base::debug::TracedValue* dict) const { |
| + dict->SetString("type", "MockBeginFrameObserver"); |
| + dict->BeginDictionary("last_begin_frame_args"); |
| + LastBeginFrameArgs().AsValueInto(dict); |
| + dict->EndDictionary(); |
| + } |
| + |
| + static const BeginFrameArgs kDefaultBeginFrameArgs; |
| + MockBeginFrameObserver() { |
| + // Set a "default" value returned by LastBeginFrameArgs so that gMock |
| + // doesn't fail an assert and instead returns useful information. |
| + EXPECT_CALL(*this, LastBeginFrameArgs()) |
| + .Times(::testing::AnyNumber()) |
| + .InSequence(sequence) |
| + .WillRepeatedly(::testing::ReturnRef(kDefaultBeginFrameArgs)); |
| + } |
| + virtual ~MockBeginFrameObserver() {} |
| + |
| + ::testing::Sequence sequence; |
| +}; |
| + |
| +TEST(MockBeginFrameObserverTest, Basic) { |
| + ::testing::NiceMock<MockBeginFrameObserver> obs; |
| + EXPECT_BEGIN_FRAME(obs, 100, 200, 300); |
| + EXPECT_BEGIN_FRAME(obs, 400, 600, 300); |
| + EXPECT_BEGIN_FRAME(obs, 700, 900, 300); |
| + |
| + EXPECT_EQ(obs.LastBeginFrameArgs(), |
| + MockBeginFrameObserver::kDefaultBeginFrameArgs); |
| + |
| + obs.OnBeginFrame(CreateBeginFrameArgsForTesting( |
| + 100, 200, 300)); // One call to LastBeginFrameArgs |
| + EXPECT_EQ(obs.LastBeginFrameArgs(), |
| + CreateBeginFrameArgsForTesting(100, 200, 300)); |
| + |
| + obs.OnBeginFrame(CreateBeginFrameArgsForTesting( |
| + 400, 600, 300)); // Multiple calls to LastBeginFrameArgs |
| + EXPECT_EQ(obs.LastBeginFrameArgs(), |
| + CreateBeginFrameArgsForTesting(400, 600, 300)); |
| + EXPECT_EQ(obs.LastBeginFrameArgs(), |
| + CreateBeginFrameArgsForTesting(400, 600, 300)); |
| + |
| + obs.OnBeginFrame(CreateBeginFrameArgsForTesting( |
| + 700, 900, 300)); // No calls to LastBeginFrameArgs |
| + |
| + ::testing::Mock::VerifyAndClearExpectations(&obs); |
| +} |
| + |
| +const BeginFrameArgs MockBeginFrameObserver::kDefaultBeginFrameArgs = |
| + CreateBeginFrameArgsForTesting(-1, -1, -1); |
| + |
| +// BeginFrameSource testing ---------------------------------------------- |
| +TEST(BeginFrameSourceTest, Observer) { |
| + MockBeginFrameObserver obs; |
| + MockBeginFrameObserver otherObs; |
| + FakeBeginFrameSource source; |
| + |
| + source.AddObserver(&obs); |
| + EXPECT_EQ(&obs, source.GetObserver()); |
| + |
| +#ifndef NDEBUG |
| + // Adding an observer when an observer already exists should DCHECK fail. |
| + EXPECT_DEATH({ source.AddObserver(&otherObs); }, ""); |
| + |
| + // Removing wrong observer should DCHECK fail. |
| + EXPECT_DEATH({ source.RemoveObserver(&otherObs); }, ""); |
| + |
| + // Removing an observer when there is no observer should DCHECK fail. |
| + EXPECT_DEATH({ |
| + source.RemoveObserver(&obs); |
| + source.RemoveObserver(&obs); |
| + }, |
| + ""); |
| +#endif |
| + source.RemoveObserver(&obs); |
| + |
| + source.AddObserver(&otherObs); |
| + EXPECT_EQ(&otherObs, source.GetObserver()); |
| + source.RemoveObserver(&otherObs); |
| +} |
| + |
| +class LoopingBeginFrameObserver : public BeginFrameObserver { |
| + public: |
| + BeginFrameArgs args_; |
| + BeginFrameSource* source_; |
| + |
| + virtual const BeginFrameArgs& LastBeginFrameArgs() const OVERRIDE { |
| + return args_; |
| + }; |
| + virtual void OnBeginFrame(const BeginFrameArgs& args) OVERRIDE{}; |
|
Sami
2014/09/18 13:55:08
nit: space before {}.
mithro-old
2014/09/19 02:45:39
Done.
|
| + |
| + virtual void AsValueInto(base::debug::TracedValue* dict) const OVERRIDE { |
| + dict->SetString("type", "LoopingBeginFrameObserver"); |
| + dict->BeginDictionary("source"); |
| + source_->AsValueInto(dict); |
| + dict->EndDictionary(); |
| + } |
| +}; |
| + |
| +TEST(BeginFrameSourceTest, DetectAsValueIntoLoop) { |
| + LoopingBeginFrameObserver obs; |
| + FakeBeginFrameSource source; |
| + |
| + obs.source_ = &source; |
| + source.AddObserver(&obs); |
| + |
| + scoped_refptr<base::debug::TracedValue> state = |
| + new base::debug::TracedValue(); |
| + source.AsValueInto(state.get()); |
| +} |
| + |
| +// BackToBackBeginFrameSource testing ----------------------------------------- |
| +class TestBackToBackBeginFrameSource : public BackToBackBeginFrameSource { |
| + public: |
| + static scoped_ptr<TestBackToBackBeginFrameSource> Create( |
| + scoped_refptr<TestNowSource> now_src, |
| + base::SingleThreadTaskRunner* task_runner) { |
| + return make_scoped_ptr( |
| + new TestBackToBackBeginFrameSource(now_src, task_runner)); |
| + } |
| + |
| + protected: |
| + TestBackToBackBeginFrameSource(scoped_refptr<TestNowSource> now_src, |
| + base::SingleThreadTaskRunner* task_runner) |
| + : BackToBackBeginFrameSource(task_runner), now_src_(now_src) {} |
| + |
| + virtual base::TimeTicks Now() OVERRIDE { return now_src_->Now(); } |
| + |
| + scoped_refptr<TestNowSource> now_src_; |
| +}; |
| + |
| +class BackToBackBeginFrameSourceTest : public ::testing::Test { |
| + public: |
| + static int64_t kDeadline; |
|
Sami
2014/09/18 13:55:08
const?
mithro-old
2014/09/19 02:45:39
Done.
|
| + static int64_t kInterval; |
| + |
| + scoped_refptr<TestNowSource> now_src_; |
| + scoped_refptr<OrderedSimpleTaskRunner> task_runner_; |
| + scoped_ptr<TestBackToBackBeginFrameSource> source_; |
| + scoped_ptr<MockBeginFrameObserver> obs_; |
| + |
| + virtual void SetUp() OVERRIDE { |
| + now_src_ = TestNowSource::Create(1000); |
| + task_runner_ = |
| + make_scoped_refptr(new OrderedSimpleTaskRunner(now_src_, false)); |
| + task_runner_->SetRunTaskLimit(1); |
| + source_ = |
| + TestBackToBackBeginFrameSource::Create(now_src_, task_runner_.get()); |
| + obs_ = make_scoped_ptr(new ::testing::StrictMock<MockBeginFrameObserver>()); |
| + source_->AddObserver(obs_.get()); |
| + } |
| + |
| + virtual void TearDown() OVERRIDE { obs_.reset(); } |
| +}; |
| + |
| +int64_t BackToBackBeginFrameSourceTest::kDeadline = |
| + BeginFrameArgs::DefaultInterval().ToInternalValue(); |
| + |
| +int64_t BackToBackBeginFrameSourceTest::kInterval = |
| + BeginFrameArgs::DefaultInterval().ToInternalValue(); |
| + |
| +TEST_F(BackToBackBeginFrameSourceTest, SetNeedsBeginFramesSendsBeginFrame) { |
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval); |
| + source_->SetNeedsBeginFrames(true); |
| + EXPECT_TRUE(task_runner_->HasPendingTasks()); |
| + task_runner_->RunUntilIdle(); |
| + |
| + EXPECT_BEGIN_FRAME_P(obs_, 1100, 1100 + kDeadline, kInterval); |
| + now_src_->AdvanceNowMicroseconds(100); |
| + source_->DidFinishFrame(0); |
| + task_runner_->RunUntilIdle(); |
| +} |
| + |
| +TEST_F(BackToBackBeginFrameSourceTest, |
| + DidFinishFrameThenSetNeedsBeginFramesProducesNoFrame) { |
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval); |
| + source_->SetNeedsBeginFrames(true); |
| + task_runner_->RunUntilIdle(); |
| + |
| + source_->SetNeedsBeginFrames(false); |
| + source_->DidFinishFrame(0); |
| + |
| + EXPECT_FALSE(task_runner_->HasPendingTasks()); |
| +} |
| + |
| +TEST_F(BackToBackBeginFrameSourceTest, |
| + SetNeedsBeginFramesThenDidFinishFrameProducesNoFrame) { |
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval); |
| + source_->SetNeedsBeginFrames(true); |
| + task_runner_->RunUntilIdle(); |
| + |
| + now_src_->AdvanceNowMicroseconds(100); |
| + source_->DidFinishFrame(0); |
| + source_->SetNeedsBeginFrames(false); |
| + |
| + EXPECT_TRUE(task_runner_->HasPendingTasks()); |
| + task_runner_->RunUntilIdle(); |
| +} |
| + |
| +TEST_F(BackToBackBeginFrameSourceTest, |
| + DidFinishFrameThenTogglingSetNeedsBeginFramesProducesCorrectFrame) { |
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval); |
| + source_->SetNeedsBeginFrames(true); |
| + task_runner_->RunUntilIdle(); |
| + |
| + now_src_->AdvanceNowMicroseconds(100); |
| + |
| + source_->SetNeedsBeginFrames(false); |
| + now_src_->AdvanceNowMicroseconds(10); |
| + source_->DidFinishFrame(0); |
| + now_src_->AdvanceNowMicroseconds(10); |
| + source_->SetNeedsBeginFrames(false); |
| + now_src_->AdvanceNowMicroseconds(10); |
| + source_->SetNeedsBeginFrames(true); |
| + |
| + EXPECT_BEGIN_FRAME_P(obs_, 1130, 1130 + kDeadline, kInterval); |
| + EXPECT_TRUE(task_runner_->HasPendingTasks()); |
| + task_runner_->RunUntilIdle(); |
| +} |
| + |
| +TEST_F(BackToBackBeginFrameSourceTest, |
| + TogglingSetNeedsBeginFramesThenDidFinishFrameProducesCorrectFrame) { |
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval); |
| + source_->SetNeedsBeginFrames(true); |
| + task_runner_->RunUntilIdle(); |
| + |
| + now_src_->AdvanceNowMicroseconds(100); |
| + source_->DidFinishFrame(0); |
| + now_src_->AdvanceNowMicroseconds(10); |
| + source_->SetNeedsBeginFrames(false); |
| + now_src_->AdvanceNowMicroseconds(10); |
| + source_->SetNeedsBeginFrames(true); |
| + now_src_->AdvanceNowMicroseconds(10); |
| + |
| + EXPECT_BEGIN_FRAME_P(obs_, 1130, 1130 + kDeadline, kInterval); |
| + EXPECT_TRUE(task_runner_->HasPendingTasks()); |
| + task_runner_->RunUntilIdle(); |
| +} |
| + |
| +TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameNeedsBeginFrameFalse) { |
| + source_->SetNeedsBeginFrames(false); |
| + source_->DidFinishFrame(0); |
| + EXPECT_FALSE(task_runner_->RunPendingTasks()); |
| +} |
| + |
| +TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameRemainingFrames) { |
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval); |
| + source_->SetNeedsBeginFrames(true); |
| + task_runner_->RunUntilIdle(); |
| + |
| + now_src_->AdvanceNowMicroseconds(100); |
| + |
| + source_->DidFinishFrame(3); |
| + EXPECT_FALSE(task_runner_->HasPendingTasks()); |
| + source_->DidFinishFrame(2); |
| + EXPECT_FALSE(task_runner_->HasPendingTasks()); |
| + source_->DidFinishFrame(1); |
| + EXPECT_FALSE(task_runner_->HasPendingTasks()); |
| + |
| + EXPECT_BEGIN_FRAME_P(obs_, 1100, 1100 + kDeadline, kInterval); |
| + source_->DidFinishFrame(0); |
| + EXPECT_EQ(base::TimeDelta(), task_runner_->DelayToNextTaskTime()); |
| + task_runner_->RunUntilIdle(); |
| +} |
| + |
| +TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameMultipleCallsIdempotent) { |
| + source_->SetNeedsBeginFrames(true); |
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval); |
| + task_runner_->RunUntilIdle(); |
| + |
| + now_src_->AdvanceNowMicroseconds(100); |
| + source_->DidFinishFrame(0); |
| + source_->DidFinishFrame(0); |
| + source_->DidFinishFrame(0); |
| + EXPECT_BEGIN_FRAME_P(obs_, 1100, 1100 + kDeadline, kInterval); |
| + task_runner_->RunUntilIdle(); |
| + |
| + now_src_->AdvanceNowMicroseconds(100); |
| + source_->DidFinishFrame(0); |
| + source_->DidFinishFrame(0); |
| + source_->DidFinishFrame(0); |
| + EXPECT_BEGIN_FRAME_P(obs_, 1200, 1200 + kDeadline, kInterval); |
| + task_runner_->RunUntilIdle(); |
| +} |
| + |
| +TEST_F(BackToBackBeginFrameSourceTest, DelayInPostedTaskProducesCorrectFrame) { |
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval); |
| + source_->SetNeedsBeginFrames(true); |
| + task_runner_->RunUntilIdle(); |
| + |
| + now_src_->AdvanceNowMicroseconds(100); |
| + source_->DidFinishFrame(0); |
| + now_src_->AdvanceNowMicroseconds(50); |
| + EXPECT_BEGIN_FRAME_P(obs_, 1150, 1150 + kDeadline, kInterval); |
| + |
| + EXPECT_TRUE(task_runner_->HasPendingTasks()); |
| + task_runner_->RunUntilIdle(); |
| +} |
| + |
| +// SyntheticBeginFrameSource testing ------------------------------------------ |
| +class SyntheticBeginFrameSourceTest : public ::testing::Test { |
| + public: |
| + scoped_refptr<TestNowSource> now_src_; |
| + scoped_refptr<OrderedSimpleTaskRunner> task_runner_; |
| + scoped_ptr<TestSyntheticBeginFrameSource> source_; |
| + scoped_ptr<MockBeginFrameObserver> obs_; |
| + |
| + virtual void SetUp() OVERRIDE { |
| + now_src_ = TestNowSource::Create(1000); |
| + task_runner_ = |
| + make_scoped_refptr(new OrderedSimpleTaskRunner(now_src_, false)); |
| + source_ = TestSyntheticBeginFrameSource::Create( |
| + now_src_, task_runner_.get(), base::TimeDelta::FromMicroseconds(10000)); |
| + obs_ = make_scoped_ptr(new MockBeginFrameObserver()); |
| + source_->AddObserver(obs_.get()); |
| + } |
| + |
| + virtual void TearDown() OVERRIDE { obs_.reset(); } |
| +}; |
| + |
| +TEST_F(SyntheticBeginFrameSourceTest, |
| + SetNeedsBeginFramesCallsOnBeginFrameWithMissedTick) { |
| + now_src_->SetNowMicroseconds(10010); |
| + EXPECT_BEGIN_FRAME_P(obs_, 10000, 20000, 10000); |
| + source_->SetNeedsBeginFrames(true); // Should cause the last tick to be sent |
| + // No tasks should need to be run for this to occur. |
| +} |
| + |
| +TEST_F(SyntheticBeginFrameSourceTest, |
| + SetNeedsBeginFramesCallsCausesOnBeginFrame) { |
| + source_->SetNeedsBeginFrames(true); |
| + EXPECT_EQ(10000, task_runner_->NextTaskTime().ToInternalValue()); |
| + |
| + EXPECT_BEGIN_FRAME_P(obs_, 10000, 20000, 10000); |
| + now_src_->SetNowMicroseconds(10010); |
| + task_runner_->RunPendingTasks(); |
| +} |
| + |
| +TEST_F(SyntheticBeginFrameSourceTest, BasicOperation) { |
| + task_runner_->SetAutoAdvanceNowToPendingTasks(true); |
| + |
| + source_->SetNeedsBeginFrames(true); |
| + EXPECT_BEGIN_FRAME_P(obs_, 10000, 20000, 10000); |
| + EXPECT_BEGIN_FRAME_P(obs_, 20000, 30000, 10000); |
| + EXPECT_BEGIN_FRAME_P(obs_, 30000, 40000, 10000); |
| + task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(30001)); |
| + |
| + source_->SetNeedsBeginFrames(false); |
| + // No new frames.... |
| + task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(60000)); |
| +} |
| + |
| +TEST_F(SyntheticBeginFrameSourceTest, VSyncChanges) { |
| + task_runner_->SetAutoAdvanceNowToPendingTasks(true); |
| + source_->SetNeedsBeginFrames(true); |
| + |
| + EXPECT_BEGIN_FRAME_P(obs_, 10000, 20000, 10000); |
| + EXPECT_BEGIN_FRAME_P(obs_, 20000, 30000, 10000); |
| + EXPECT_BEGIN_FRAME_P(obs_, 30000, 40000, 10000); |
| + task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(30001)); |
| + |
| + // Verify the initial vsync information |
| + EXPECT_EQ(1000, source_->VSyncTimebase().ToInternalValue()); |
| + EXPECT_EQ(base::TimeDelta::FromMicroseconds(10000), source_->VSyncInterval()); |
| + |
| + // Update the vsync information |
| + source_->OnUpdateVSyncParameters(base::TimeTicks::FromInternalValue(27500), |
| + base::TimeDelta::FromMicroseconds(10001)); |
| + |
| + // Verify the updated vsync information |
| + EXPECT_EQ(27500, source_->VSyncTimebase().ToInternalValue()); |
| + EXPECT_EQ(10001, source_->VSyncInterval().InMicroseconds()); |
| + |
| + EXPECT_BEGIN_FRAME_P(obs_, 40000, 47502, 10001); |
| + EXPECT_BEGIN_FRAME_P(obs_, 47502, 57503, 10001); |
| + EXPECT_BEGIN_FRAME_P(obs_, 57503, 67504, 10001); |
| + task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(60000)); |
| +} |
| + |
| +// BeginFrameSourceMultiplexer testing ----------------------------------- |
| +class BeginFrameSourceMultiplexerTest : public ::testing::Test { |
| + protected: |
| + virtual void SetUp() OVERRIDE { |
| + mux_ = BeginFrameSourceMultiplexer::Create(); |
| + |
| + source1_store_ = make_scoped_ptr(new FakeBeginFrameSource()); |
| + source2_store_ = make_scoped_ptr(new FakeBeginFrameSource()); |
| + source3_store_ = make_scoped_ptr(new FakeBeginFrameSource()); |
| + |
| + source1_ = source1_store_.get(); |
| + source2_ = source2_store_.get(); |
| + source3_ = source3_store_.get(); |
| + } |
| + |
| + virtual void TearDown() OVERRIDE { |
| + // Make sure the mux is torn down before the sources. |
| + mux_.reset(); |
| + } |
| + |
| + scoped_ptr<BeginFrameSourceMultiplexer> mux_; |
| + FakeBeginFrameSource* source1_; |
| + FakeBeginFrameSource* source2_; |
| + FakeBeginFrameSource* source3_; |
| + |
| + private: |
| + scoped_ptr<FakeBeginFrameSource> source1_store_; |
| + scoped_ptr<FakeBeginFrameSource> source2_store_; |
| + scoped_ptr<FakeBeginFrameSource> source3_store_; |
| +}; |
| + |
| +TEST_F(BeginFrameSourceMultiplexerTest, SourcesManipulation) { |
| + EXPECT_EQ(NULL, mux_->ActiveSource()); |
| + |
| + mux_->AddSource(source1_); |
| + EXPECT_EQ(source1_, mux_->ActiveSource()); |
| + |
| + mux_->SetActiveSource(NULL); |
| + EXPECT_EQ(NULL, mux_->ActiveSource()); |
| + |
| + mux_->SetActiveSource(source1_); |
| + |
| +#ifndef NDEBUG |
| + // Setting a source which isn't in the mux as active should DCHECK fail. |
| + EXPECT_DEATH({ mux_->SetActiveSource(source2_); }, ""); |
| + |
| + // Adding a source which is already added should DCHECK fail. |
| + EXPECT_DEATH({ mux_->AddSource(source1_); }, ""); |
| + |
| + // Removing a source which isn't in the mux should DCHECK fail. |
| + EXPECT_DEATH({ mux_->RemoveSource(source2_); }, ""); |
| + |
| + // Removing the active source fails |
| + EXPECT_DEATH({ mux_->RemoveSource(source1_); }, ""); |
| +#endif |
| + |
| + // Test manipulation doesn't segfault. |
| + mux_->AddSource(source2_); |
| + mux_->RemoveSource(source2_); |
| + |
| + mux_->AddSource(source2_); |
| + mux_->SetActiveSource(source2_); |
| + EXPECT_EQ(source2_, mux_->ActiveSource()); |
| + |
| + mux_->RemoveSource(source1_); |
| +} |
| + |
| +TEST_F(BeginFrameSourceMultiplexerTest, NeedsBeginFrames) { |
| + mux_->AddSource(source1_); |
| + mux_->AddSource(source2_); |
| + mux_->SetActiveSource(source1_); |
| + EXPECT_EQ(source1_->needs_begin_frames_, false); |
| + EXPECT_EQ(source2_->needs_begin_frames_, false); |
| + |
| + // Check SetNeedsFrames works |
| + mux_->SetNeedsBeginFrames(true); |
| + EXPECT_EQ(source1_->needs_begin_frames_, true); |
| + EXPECT_EQ(source2_->needs_begin_frames_, false); |
| + |
| + mux_->SetNeedsBeginFrames(false); |
| + EXPECT_EQ(source1_->needs_begin_frames_, false); |
| + EXPECT_EQ(source2_->needs_begin_frames_, false); |
| + |
| + // Checking that switching the source makes SetNeedsFrames on the |
| + // subsources correctly. |
| + mux_->SetNeedsBeginFrames(true); |
| + |
| + mux_->SetActiveSource(source1_); |
| + EXPECT_EQ(source1_->needs_begin_frames_, true); |
| + EXPECT_EQ(source2_->needs_begin_frames_, false); |
| + |
| + mux_->SetActiveSource(source2_); |
| + EXPECT_EQ(source1_->needs_begin_frames_, false); |
| + EXPECT_EQ(source2_->needs_begin_frames_, true); |
| +} |
| + |
| +TEST_F(BeginFrameSourceMultiplexerTest, BeginFramesSimple) { |
| + mux_->AddSource(source1_); |
| + mux_->AddSource(source2_); |
| + mux_->SetActiveSource(source1_); |
| + |
| + MockBeginFrameObserver obs; |
| + mux_->AddObserver(&obs); |
| + EXPECT_BEGIN_FRAME(obs, 100, 200, 300); |
| + EXPECT_BEGIN_FRAME(obs, 400, 600, 300); |
| + |
| + mux_->SetActiveSource(source1_); |
| + |
| + SEND_BEGIN_FRAME_P(source1_, 100, 200, 300); |
| + SEND_BEGIN_FRAME_P(source2_, 200, 500, 300); // Not received |
| + |
| + mux_->SetActiveSource(source2_); |
| + SEND_BEGIN_FRAME_P(source2_, 400, 600, 300); |
| + SEND_BEGIN_FRAME_P(source1_, 500, 700, 300); // Not received |
| +} |
| + |
| +TEST_F(BeginFrameSourceMultiplexerTest, BeginFramesBackwardsProtection) { |
| + mux_->AddSource(source1_); |
| + mux_->AddSource(source2_); |
| + |
| + MockBeginFrameObserver obs; |
| + mux_->AddObserver(&obs); |
| + EXPECT_BEGIN_FRAME(obs, 400, 600, 300); |
| + EXPECT_BEGIN_FRAME(obs, 700, 900, 300); |
| + EXPECT_BEGIN_FRAME(obs, 1000, 1200, 300); |
| + EXPECT_BEGIN_FRAME(obs, 1001, 1201, 301); |
| + |
| + mux_->SetActiveSource(source1_); |
| + SEND_BEGIN_FRAME_P(source1_, 400, 600, 300); |
| + SEND_BEGIN_FRAME_P(source1_, 700, 900, 300); |
| + |
| + mux_->SetActiveSource(source2_); |
| + SEND_BEGIN_FRAME_P(source2_, 699, 899, 300); // Skipped |
| + SEND_BEGIN_FRAME_P(source2_, 1000, 1200, 300); |
| + |
| + mux_->SetActiveSource(source1_); |
| + SEND_BEGIN_FRAME_P(source1_, 1001, 1201, 301); |
| +} |
| + |
| +TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalNegativeFails) { |
| +#ifndef NDEBUG |
| + EXPECT_DEATH( |
| + { mux_->SetMinimumInterval(base::TimeDelta::FromInternalValue(-100)); }, |
| + ""); |
| +#endif |
| +} |
| + |
| +TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalZero) { |
| + mux_->SetMinimumInterval(base::TimeDelta()); |
| + mux_->AddSource(source1_); |
| + |
| + MockBeginFrameObserver obs; |
| + mux_->AddObserver(&obs); |
| + EXPECT_BEGIN_FRAME(obs, 100, 200, 300); |
| + EXPECT_BEGIN_FRAME(obs, 400, 600, 300); |
| + EXPECT_BEGIN_FRAME(obs, 700, 900, 300); |
| + |
| + SEND_BEGIN_FRAME_P(source1_, 100, 200, 300); |
| + SEND_BEGIN_FRAME_P(source1_, 400, 600, 300); |
| + SEND_BEGIN_FRAME_P(source1_, 700, 900, 300); |
| +} |
| + |
| +TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalBasic) { |
| + mux_->SetMinimumInterval(base::TimeDelta::FromInternalValue(600)); |
| + mux_->AddSource(source1_); |
| + |
| + MockBeginFrameObserver obs; |
| + mux_->AddObserver(&obs); |
| + EXPECT_BEGIN_FRAME(obs, 100, 200, 300); |
| + EXPECT_BEGIN_FRAME(obs, 700, 900, 300); |
| + |
| + SEND_BEGIN_FRAME_P(source1_, 100, 200, 300); |
| + SEND_BEGIN_FRAME_P(source1_, 400, 600, 300); // Skipped |
| + SEND_BEGIN_FRAME_P(source1_, 700, 900, 300); |
| +} |
| + |
| +TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalWithMultipleSources) { |
| + mux_->SetMinimumInterval(base::TimeDelta::FromMicroseconds(150)); |
| + mux_->AddSource(source1_); |
| + mux_->AddSource(source2_); |
| + |
| + MockBeginFrameObserver obs; |
| + mux_->AddObserver(&obs); |
| + EXPECT_BEGIN_FRAME(obs, 400, 600, 300); |
| + EXPECT_BEGIN_FRAME(obs, 700, 900, 300); |
| + EXPECT_BEGIN_FRAME(obs, 1050, 1250, 300); |
| + |
| + mux_->SetActiveSource(source1_); |
| + SEND_BEGIN_FRAME_P(source1_, 400, 600, 300); |
| + SEND_BEGIN_FRAME_P(source1_, 700, 900, 300); |
| + |
| + mux_->SetActiveSource(source2_); |
| + SEND_BEGIN_FRAME_P(source2_, 750, 1050, 300); // Skipped |
| + SEND_BEGIN_FRAME_P(source2_, 1050, 1250, 300); |
| + |
| + mux_->SetActiveSource(source1_); |
| + SEND_BEGIN_FRAME_P(source2_, 1100, 1400, 300); // Skipped |
| +} |
| + |
| +} // namespace |
| +} // namespace cc |