1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "testing/gmock/include/gmock/gmock.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 #include "webrtc/base/scoped_ptr.h" 15 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 16 #include "webrtc/system_wrappers/include/tick_util.h" 17 #include "webrtc/video/call_stats.h" 18 19 using ::testing::_; 20 using ::testing::AnyNumber; 21 using ::testing::Return; 22 23 namespace webrtc { 24 25 class MockStatsObserver : public CallStatsObserver { 26 public: 27 MockStatsObserver() {} 28 virtual ~MockStatsObserver() {} 29 30 MOCK_METHOD2(OnRttUpdate, void(int64_t, int64_t)); 31 }; 32 33 class CallStatsTest : public ::testing::Test { 34 public: 35 CallStatsTest() : fake_clock_(12345) {} 36 37 protected: 38 virtual void SetUp() { call_stats_.reset(new CallStats(&fake_clock_)); } 39 SimulatedClock fake_clock_; 40 rtc::scoped_ptr<CallStats> call_stats_; 41 }; 42 43 TEST_F(CallStatsTest, AddAndTriggerCallback) { 44 MockStatsObserver stats_observer; 45 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats(); 46 call_stats_->RegisterStatsObserver(&stats_observer); 47 fake_clock_.AdvanceTimeMilliseconds(1000); 48 EXPECT_EQ(0, rtcp_rtt_stats->LastProcessedRtt()); 49 50 const int64_t kRtt = 25; 51 rtcp_rtt_stats->OnRttUpdate(kRtt); 52 EXPECT_CALL(stats_observer, OnRttUpdate(kRtt, kRtt)).Times(1); 53 call_stats_->Process(); 54 EXPECT_EQ(kRtt, rtcp_rtt_stats->LastProcessedRtt()); 55 56 const int64_t kRttTimeOutMs = 1500 + 10; 57 fake_clock_.AdvanceTimeMilliseconds(kRttTimeOutMs); 58 EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(0); 59 call_stats_->Process(); 60 EXPECT_EQ(0, rtcp_rtt_stats->LastProcessedRtt()); 61 62 call_stats_->DeregisterStatsObserver(&stats_observer); 63 } 64 65 TEST_F(CallStatsTest, ProcessTime) { 66 MockStatsObserver stats_observer; 67 call_stats_->RegisterStatsObserver(&stats_observer); 68 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats(); 69 rtcp_rtt_stats->OnRttUpdate(100); 70 71 // Time isn't updated yet. 72 EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(0); 73 call_stats_->Process(); 74 75 // Advance clock and verify we get an update. 76 fake_clock_.AdvanceTimeMilliseconds(1000); 77 EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(1); 78 call_stats_->Process(); 79 80 // Advance clock just too little to get an update. 81 fake_clock_.AdvanceTimeMilliseconds(999); 82 rtcp_rtt_stats->OnRttUpdate(100); 83 EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(0); 84 call_stats_->Process(); 85 86 // Advance enough to trigger a new update. 87 fake_clock_.AdvanceTimeMilliseconds(1); 88 EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(1); 89 call_stats_->Process(); 90 91 call_stats_->DeregisterStatsObserver(&stats_observer); 92 } 93 94 // Verify all observers get correct estimates and observers can be added and 95 // removed. 96 TEST_F(CallStatsTest, MultipleObservers) { 97 MockStatsObserver stats_observer_1; 98 call_stats_->RegisterStatsObserver(&stats_observer_1); 99 // Add the second observer twice, there should still be only one report to the 100 // observer. 101 MockStatsObserver stats_observer_2; 102 call_stats_->RegisterStatsObserver(&stats_observer_2); 103 call_stats_->RegisterStatsObserver(&stats_observer_2); 104 105 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats(); 106 const int64_t kRtt = 100; 107 rtcp_rtt_stats->OnRttUpdate(kRtt); 108 109 // Verify both observers are updated. 110 fake_clock_.AdvanceTimeMilliseconds(1000); 111 EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(1); 112 EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(1); 113 call_stats_->Process(); 114 115 // Deregister the second observer and verify update is only sent to the first 116 // observer. 117 call_stats_->DeregisterStatsObserver(&stats_observer_2); 118 rtcp_rtt_stats->OnRttUpdate(kRtt); 119 fake_clock_.AdvanceTimeMilliseconds(1000); 120 EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(1); 121 EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(0); 122 call_stats_->Process(); 123 124 // Deregister the first observer. 125 call_stats_->DeregisterStatsObserver(&stats_observer_1); 126 rtcp_rtt_stats->OnRttUpdate(kRtt); 127 fake_clock_.AdvanceTimeMilliseconds(1000); 128 EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(0); 129 EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(0); 130 call_stats_->Process(); 131 } 132 133 // Verify increasing and decreasing rtt triggers callbacks with correct values. 134 TEST_F(CallStatsTest, ChangeRtt) { 135 MockStatsObserver stats_observer; 136 call_stats_->RegisterStatsObserver(&stats_observer); 137 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats(); 138 139 // Advance clock to be ready for an update. 140 fake_clock_.AdvanceTimeMilliseconds(1000); 141 142 // Set a first value and verify the callback is triggered. 143 const int64_t kFirstRtt = 100; 144 rtcp_rtt_stats->OnRttUpdate(kFirstRtt); 145 EXPECT_CALL(stats_observer, OnRttUpdate(kFirstRtt, kFirstRtt)).Times(1); 146 call_stats_->Process(); 147 148 // Increase rtt and verify the new value is reported. 149 fake_clock_.AdvanceTimeMilliseconds(1000); 150 const int64_t kHighRtt = kFirstRtt + 20; 151 const int64_t kAvgRtt1 = 103; 152 rtcp_rtt_stats->OnRttUpdate(kHighRtt); 153 EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt1, kHighRtt)).Times(1); 154 call_stats_->Process(); 155 156 // Increase time enough for a new update, but not too much to make the 157 // rtt invalid. Report a lower rtt and verify the old/high value still is sent 158 // in the callback. 159 fake_clock_.AdvanceTimeMilliseconds(1000); 160 const int64_t kLowRtt = kFirstRtt - 20; 161 const int64_t kAvgRtt2 = 102; 162 rtcp_rtt_stats->OnRttUpdate(kLowRtt); 163 EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt2, kHighRtt)).Times(1); 164 call_stats_->Process(); 165 166 // Advance time to make the high report invalid, the lower rtt should now be 167 // in the callback. 168 fake_clock_.AdvanceTimeMilliseconds(1000); 169 const int64_t kAvgRtt3 = 95; 170 EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt3, kLowRtt)).Times(1); 171 call_stats_->Process(); 172 173 call_stats_->DeregisterStatsObserver(&stats_observer); 174 } 175 176 TEST_F(CallStatsTest, LastProcessedRtt) { 177 MockStatsObserver stats_observer; 178 call_stats_->RegisterStatsObserver(&stats_observer); 179 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats(); 180 fake_clock_.AdvanceTimeMilliseconds(1000); 181 182 // Set a first values and verify that LastProcessedRtt initially returns the 183 // average rtt. 184 const int64_t kRttLow = 10; 185 const int64_t kRttHigh = 30; 186 const int64_t kAvgRtt = 20; 187 rtcp_rtt_stats->OnRttUpdate(kRttLow); 188 rtcp_rtt_stats->OnRttUpdate(kRttHigh); 189 EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt, kRttHigh)).Times(1); 190 call_stats_->Process(); 191 EXPECT_EQ(kAvgRtt, rtcp_rtt_stats->LastProcessedRtt()); 192 193 // Update values and verify LastProcessedRtt. 194 fake_clock_.AdvanceTimeMilliseconds(1000); 195 rtcp_rtt_stats->OnRttUpdate(kRttLow); 196 rtcp_rtt_stats->OnRttUpdate(kRttHigh); 197 EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt, kRttHigh)).Times(1); 198 call_stats_->Process(); 199 EXPECT_EQ(kAvgRtt, rtcp_rtt_stats->LastProcessedRtt()); 200 201 call_stats_->DeregisterStatsObserver(&stats_observer); 202 } 203 204 } // namespace webrtc 205