blob: f917a7580984fae4dca387e66bef21129eacb738 [file] [log] [blame]
hbosd565b732016-08-30 14:04:35 -07001/*
2 * Copyright 2016 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 "webrtc/stats/rtcstatscollector.h"
12
13#include <memory>
14#include <string>
15#include <vector>
16
17#include "webrtc/api/jsepsessiondescription.h"
18#include "webrtc/api/rtcstats_objects.h"
19#include "webrtc/api/rtcstatsreport.h"
20#include "webrtc/api/test/mock_datachannel.h"
21#include "webrtc/api/test/mock_peerconnection.h"
22#include "webrtc/api/test/mock_webrtcsession.h"
23#include "webrtc/base/checks.h"
hbos0e6758d2016-08-31 07:57:36 -070024#include "webrtc/base/fakeclock.h"
hbosd565b732016-08-30 14:04:35 -070025#include "webrtc/base/gunit.h"
26#include "webrtc/base/logging.h"
hbos0e6758d2016-08-31 07:57:36 -070027#include "webrtc/base/timedelta.h"
28#include "webrtc/base/timeutils.h"
29#include "webrtc/base/timing.h"
hbosd565b732016-08-30 14:04:35 -070030#include "webrtc/media/base/fakemediaengine.h"
31
32using testing::Return;
33using testing::ReturnRef;
34
35namespace webrtc {
36
37class RTCStatsCollectorTester : public SetSessionDescriptionObserver {
38 public:
39 RTCStatsCollectorTester()
40 : worker_thread_(rtc::Thread::Current()),
41 network_thread_(rtc::Thread::Current()),
42 channel_manager_(new cricket::ChannelManager(
43 new cricket::FakeMediaEngine(),
44 worker_thread_,
45 network_thread_)),
46 media_controller_(
47 MediaControllerInterface::Create(cricket::MediaConfig(),
48 worker_thread_,
49 channel_manager_.get())),
50 session_(media_controller_.get()),
51 pc_() {
52 EXPECT_CALL(pc_, session()).WillRepeatedly(Return(&session_));
53 EXPECT_CALL(pc_, sctp_data_channels()).WillRepeatedly(
54 ReturnRef(data_channels_));
55 }
56
57 MockWebRtcSession& session() { return session_; }
58 MockPeerConnection& pc() { return pc_; }
59 std::vector<rtc::scoped_refptr<DataChannel>>& data_channels() {
60 return data_channels_;
61 }
62
63 // SetSessionDescriptionObserver overrides.
64 void OnSuccess() override {}
65 void OnFailure(const std::string& error) override {
66 RTC_NOTREACHED() << error;
67 }
68
69 private:
70 rtc::Thread* const worker_thread_;
71 rtc::Thread* const network_thread_;
72 std::unique_ptr<cricket::ChannelManager> channel_manager_;
73 std::unique_ptr<webrtc::MediaControllerInterface> media_controller_;
74 MockWebRtcSession session_;
75 MockPeerConnection pc_;
76
77 std::vector<rtc::scoped_refptr<DataChannel>> data_channels_;
78};
79
80class RTCStatsCollectorTest : public testing::Test {
81 public:
82 RTCStatsCollectorTest()
83 : test_(new rtc::RefCountedObject<RTCStatsCollectorTester>()),
hbos0e6758d2016-08-31 07:57:36 -070084 collector_(&test_->pc(), 50 * rtc::kNumMicrosecsPerMillisec) {
hbosd565b732016-08-30 14:04:35 -070085 }
86
87 protected:
88 rtc::scoped_refptr<RTCStatsCollectorTester> test_;
hbosd565b732016-08-30 14:04:35 -070089 RTCStatsCollector collector_;
90};
91
92TEST_F(RTCStatsCollectorTest, CachedStatsReport) {
hbos0e6758d2016-08-31 07:57:36 -070093 rtc::ScopedFakeClock fake_clock;
hbosd565b732016-08-30 14:04:35 -070094 // Caching should ensure |a| and |b| are the same report.
95 rtc::scoped_refptr<const RTCStatsReport> a = collector_.GetStatsReport();
96 rtc::scoped_refptr<const RTCStatsReport> b = collector_.GetStatsReport();
97 EXPECT_TRUE(a);
98 EXPECT_EQ(a.get(), b.get());
99 // Invalidate cache by clearing it.
100 collector_.ClearCachedStatsReport();
101 rtc::scoped_refptr<const RTCStatsReport> c = collector_.GetStatsReport();
102 EXPECT_TRUE(c);
103 EXPECT_NE(b.get(), c.get());
104 // Invalidate cache by advancing time.
hbos0e6758d2016-08-31 07:57:36 -0700105 fake_clock.AdvanceTime(rtc::TimeDelta::FromMilliseconds(51));
hbosd565b732016-08-30 14:04:35 -0700106 rtc::scoped_refptr<const RTCStatsReport> d = collector_.GetStatsReport();
107 EXPECT_TRUE(d);
108 EXPECT_NE(c.get(), d.get());
109}
110
111TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) {
hbos0e6758d2016-08-31 07:57:36 -0700112 int64_t before = static_cast<int64_t>(
113 rtc::Timing::WallTimeNow() * rtc::kNumMicrosecsPerSec);
hbosd565b732016-08-30 14:04:35 -0700114 rtc::scoped_refptr<const RTCStatsReport> report = collector_.GetStatsReport();
hbos0e6758d2016-08-31 07:57:36 -0700115 int64_t after = static_cast<int64_t>(
116 rtc::Timing::WallTimeNow() * rtc::kNumMicrosecsPerSec);
hbosd565b732016-08-30 14:04:35 -0700117 EXPECT_EQ(report->GetStatsOfType<RTCPeerConnectionStats>().size(),
118 static_cast<size_t>(1)) << "Expecting 1 RTCPeerConnectionStats.";
119 const RTCStats* stats = report->Get("RTCPeerConnection");
120 EXPECT_TRUE(stats);
hbos0e6758d2016-08-31 07:57:36 -0700121 EXPECT_LE(before, stats->timestamp_us());
122 EXPECT_LE(stats->timestamp_us(), after);
hbosd565b732016-08-30 14:04:35 -0700123 {
124 // Expected stats with no data channels
125 const RTCPeerConnectionStats& pcstats =
126 stats->cast_to<RTCPeerConnectionStats>();
127 EXPECT_EQ(*pcstats.data_channels_opened, static_cast<uint32_t>(0));
128 EXPECT_EQ(*pcstats.data_channels_closed, static_cast<uint32_t>(0));
129 }
130
131 test_->data_channels().push_back(
132 new MockDataChannel(DataChannelInterface::kConnecting));
133 test_->data_channels().push_back(
134 new MockDataChannel(DataChannelInterface::kOpen));
135 test_->data_channels().push_back(
136 new MockDataChannel(DataChannelInterface::kClosing));
137 test_->data_channels().push_back(
138 new MockDataChannel(DataChannelInterface::kClosed));
139
140 collector_.ClearCachedStatsReport();
141 report = collector_.GetStatsReport();
142 EXPECT_EQ(report->GetStatsOfType<RTCPeerConnectionStats>().size(),
143 static_cast<size_t>(1)) << "Expecting 1 RTCPeerConnectionStats.";
144 stats = report->Get("RTCPeerConnection");
145 EXPECT_TRUE(stats);
146 {
147 // Expected stats with the above four data channels
148 // TODO(hbos): When the |RTCPeerConnectionStats| is the number of data
149 // channels that have been opened and closed, not the numbers currently
150 // open/closed, we would expect opened >= closed and (opened - closed) to be
151 // the number currently open. crbug.com/636818.
152 const RTCPeerConnectionStats& pcstats =
153 stats->cast_to<RTCPeerConnectionStats>();
154 EXPECT_EQ(*pcstats.data_channels_opened, static_cast<uint32_t>(1));
155 EXPECT_EQ(*pcstats.data_channels_closed, static_cast<uint32_t>(3));
156 }
157}
158
159} // namespace webrtc