1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright 2018 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include "pc/rtc_stats_traversal.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include <memory>
14*d9f75844SAndroid Build Coastguard Worker #include <vector>
15*d9f75844SAndroid Build Coastguard Worker
16*d9f75844SAndroid Build Coastguard Worker #include "api/stats/rtcstats_objects.h"
17*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
18*d9f75844SAndroid Build Coastguard Worker
19*d9f75844SAndroid Build Coastguard Worker // This file contains tests for TakeReferencedStats().
20*d9f75844SAndroid Build Coastguard Worker // GetStatsNeighborIds() is tested in rtcstats_integrationtest.cc.
21*d9f75844SAndroid Build Coastguard Worker
22*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
23*d9f75844SAndroid Build Coastguard Worker
24*d9f75844SAndroid Build Coastguard Worker class RTCStatsTraversalTest : public ::testing::Test {
25*d9f75844SAndroid Build Coastguard Worker public:
RTCStatsTraversalTest()26*d9f75844SAndroid Build Coastguard Worker RTCStatsTraversalTest() {
27*d9f75844SAndroid Build Coastguard Worker transport_ = new RTCTransportStats("transport", 0);
28*d9f75844SAndroid Build Coastguard Worker candidate_pair_ = new RTCIceCandidatePairStats("candidate-pair", 0);
29*d9f75844SAndroid Build Coastguard Worker local_candidate_ = new RTCLocalIceCandidateStats("local-candidate", 0);
30*d9f75844SAndroid Build Coastguard Worker remote_candidate_ = new RTCRemoteIceCandidateStats("remote-candidate", 0);
31*d9f75844SAndroid Build Coastguard Worker initial_report_ = RTCStatsReport::Create(Timestamp::Zero());
32*d9f75844SAndroid Build Coastguard Worker initial_report_->AddStats(std::unique_ptr<const RTCStats>(transport_));
33*d9f75844SAndroid Build Coastguard Worker initial_report_->AddStats(std::unique_ptr<const RTCStats>(candidate_pair_));
34*d9f75844SAndroid Build Coastguard Worker initial_report_->AddStats(
35*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<const RTCStats>(local_candidate_));
36*d9f75844SAndroid Build Coastguard Worker initial_report_->AddStats(
37*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<const RTCStats>(remote_candidate_));
38*d9f75844SAndroid Build Coastguard Worker result_ = RTCStatsReport::Create(Timestamp::Zero());
39*d9f75844SAndroid Build Coastguard Worker }
40*d9f75844SAndroid Build Coastguard Worker
TakeReferencedStats(std::vector<const RTCStats * > start_nodes)41*d9f75844SAndroid Build Coastguard Worker void TakeReferencedStats(std::vector<const RTCStats*> start_nodes) {
42*d9f75844SAndroid Build Coastguard Worker std::vector<std::string> start_ids;
43*d9f75844SAndroid Build Coastguard Worker start_ids.reserve(start_nodes.size());
44*d9f75844SAndroid Build Coastguard Worker for (const RTCStats* start_node : start_nodes) {
45*d9f75844SAndroid Build Coastguard Worker start_ids.push_back(start_node->id());
46*d9f75844SAndroid Build Coastguard Worker }
47*d9f75844SAndroid Build Coastguard Worker result_ = webrtc::TakeReferencedStats(initial_report_, start_ids);
48*d9f75844SAndroid Build Coastguard Worker }
49*d9f75844SAndroid Build Coastguard Worker
EXPECT_VISITED(const RTCStats * stats)50*d9f75844SAndroid Build Coastguard Worker void EXPECT_VISITED(const RTCStats* stats) {
51*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(initial_report_->Get(stats->id()))
52*d9f75844SAndroid Build Coastguard Worker << '"' << stats->id()
53*d9f75844SAndroid Build Coastguard Worker << "\" should be visited but it was not removed from initial report.";
54*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(result_->Get(stats->id()))
55*d9f75844SAndroid Build Coastguard Worker << '"' << stats->id()
56*d9f75844SAndroid Build Coastguard Worker << "\" should be visited but it was not added to the resulting report.";
57*d9f75844SAndroid Build Coastguard Worker }
58*d9f75844SAndroid Build Coastguard Worker
EXPECT_UNVISITED(const RTCStats * stats)59*d9f75844SAndroid Build Coastguard Worker void EXPECT_UNVISITED(const RTCStats* stats) {
60*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(initial_report_->Get(stats->id()))
61*d9f75844SAndroid Build Coastguard Worker << '"' << stats->id()
62*d9f75844SAndroid Build Coastguard Worker << "\" should not be visited but it was removed from initial report.";
63*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(result_->Get(stats->id()))
64*d9f75844SAndroid Build Coastguard Worker << '"' << stats->id()
65*d9f75844SAndroid Build Coastguard Worker << "\" should not be visited but it was added to the resulting report.";
66*d9f75844SAndroid Build Coastguard Worker }
67*d9f75844SAndroid Build Coastguard Worker
68*d9f75844SAndroid Build Coastguard Worker protected:
69*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<RTCStatsReport> initial_report_;
70*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<RTCStatsReport> result_;
71*d9f75844SAndroid Build Coastguard Worker // Raw pointers to stats owned by the reports.
72*d9f75844SAndroid Build Coastguard Worker RTCTransportStats* transport_;
73*d9f75844SAndroid Build Coastguard Worker RTCIceCandidatePairStats* candidate_pair_;
74*d9f75844SAndroid Build Coastguard Worker RTCIceCandidateStats* local_candidate_;
75*d9f75844SAndroid Build Coastguard Worker RTCIceCandidateStats* remote_candidate_;
76*d9f75844SAndroid Build Coastguard Worker };
77*d9f75844SAndroid Build Coastguard Worker
TEST_F(RTCStatsTraversalTest,NoReachableConnections)78*d9f75844SAndroid Build Coastguard Worker TEST_F(RTCStatsTraversalTest, NoReachableConnections) {
79*d9f75844SAndroid Build Coastguard Worker // Everything references transport but transport doesn't reference anything.
80*d9f75844SAndroid Build Coastguard Worker //
81*d9f75844SAndroid Build Coastguard Worker // candidate-pair
82*d9f75844SAndroid Build Coastguard Worker // | | |
83*d9f75844SAndroid Build Coastguard Worker // v | v
84*d9f75844SAndroid Build Coastguard Worker // local-candidate | remote-candidate
85*d9f75844SAndroid Build Coastguard Worker // | | |
86*d9f75844SAndroid Build Coastguard Worker // v v v
87*d9f75844SAndroid Build Coastguard Worker // start:transport
88*d9f75844SAndroid Build Coastguard Worker candidate_pair_->transport_id = "transport";
89*d9f75844SAndroid Build Coastguard Worker candidate_pair_->local_candidate_id = "local-candidate";
90*d9f75844SAndroid Build Coastguard Worker candidate_pair_->remote_candidate_id = "remote-candidate";
91*d9f75844SAndroid Build Coastguard Worker local_candidate_->transport_id = "transport";
92*d9f75844SAndroid Build Coastguard Worker remote_candidate_->transport_id = "transport";
93*d9f75844SAndroid Build Coastguard Worker TakeReferencedStats({transport_});
94*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(transport_);
95*d9f75844SAndroid Build Coastguard Worker EXPECT_UNVISITED(candidate_pair_);
96*d9f75844SAndroid Build Coastguard Worker EXPECT_UNVISITED(local_candidate_);
97*d9f75844SAndroid Build Coastguard Worker EXPECT_UNVISITED(remote_candidate_);
98*d9f75844SAndroid Build Coastguard Worker }
99*d9f75844SAndroid Build Coastguard Worker
TEST_F(RTCStatsTraversalTest,SelfReference)100*d9f75844SAndroid Build Coastguard Worker TEST_F(RTCStatsTraversalTest, SelfReference) {
101*d9f75844SAndroid Build Coastguard Worker transport_->rtcp_transport_stats_id = "transport";
102*d9f75844SAndroid Build Coastguard Worker TakeReferencedStats({transport_});
103*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(transport_);
104*d9f75844SAndroid Build Coastguard Worker EXPECT_UNVISITED(candidate_pair_);
105*d9f75844SAndroid Build Coastguard Worker EXPECT_UNVISITED(local_candidate_);
106*d9f75844SAndroid Build Coastguard Worker EXPECT_UNVISITED(remote_candidate_);
107*d9f75844SAndroid Build Coastguard Worker }
108*d9f75844SAndroid Build Coastguard Worker
TEST_F(RTCStatsTraversalTest,BogusReference)109*d9f75844SAndroid Build Coastguard Worker TEST_F(RTCStatsTraversalTest, BogusReference) {
110*d9f75844SAndroid Build Coastguard Worker transport_->rtcp_transport_stats_id = "bogus-reference";
111*d9f75844SAndroid Build Coastguard Worker TakeReferencedStats({transport_});
112*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(transport_);
113*d9f75844SAndroid Build Coastguard Worker EXPECT_UNVISITED(candidate_pair_);
114*d9f75844SAndroid Build Coastguard Worker EXPECT_UNVISITED(local_candidate_);
115*d9f75844SAndroid Build Coastguard Worker EXPECT_UNVISITED(remote_candidate_);
116*d9f75844SAndroid Build Coastguard Worker }
117*d9f75844SAndroid Build Coastguard Worker
TEST_F(RTCStatsTraversalTest,Tree)118*d9f75844SAndroid Build Coastguard Worker TEST_F(RTCStatsTraversalTest, Tree) {
119*d9f75844SAndroid Build Coastguard Worker // start:candidate-pair
120*d9f75844SAndroid Build Coastguard Worker // | |
121*d9f75844SAndroid Build Coastguard Worker // v v
122*d9f75844SAndroid Build Coastguard Worker // local-candidate remote-candidate
123*d9f75844SAndroid Build Coastguard Worker // |
124*d9f75844SAndroid Build Coastguard Worker // v
125*d9f75844SAndroid Build Coastguard Worker // transport
126*d9f75844SAndroid Build Coastguard Worker candidate_pair_->local_candidate_id = "local-candidate";
127*d9f75844SAndroid Build Coastguard Worker candidate_pair_->remote_candidate_id = "remote-candidate";
128*d9f75844SAndroid Build Coastguard Worker local_candidate_->transport_id = "transport";
129*d9f75844SAndroid Build Coastguard Worker TakeReferencedStats({candidate_pair_});
130*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(transport_);
131*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(candidate_pair_);
132*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(local_candidate_);
133*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(remote_candidate_);
134*d9f75844SAndroid Build Coastguard Worker }
135*d9f75844SAndroid Build Coastguard Worker
TEST_F(RTCStatsTraversalTest,MultiplePathsToSameNode)136*d9f75844SAndroid Build Coastguard Worker TEST_F(RTCStatsTraversalTest, MultiplePathsToSameNode) {
137*d9f75844SAndroid Build Coastguard Worker // start:candidate-pair
138*d9f75844SAndroid Build Coastguard Worker // | |
139*d9f75844SAndroid Build Coastguard Worker // v v
140*d9f75844SAndroid Build Coastguard Worker // local-candidate remote-candidate
141*d9f75844SAndroid Build Coastguard Worker // | |
142*d9f75844SAndroid Build Coastguard Worker // v v
143*d9f75844SAndroid Build Coastguard Worker // transport
144*d9f75844SAndroid Build Coastguard Worker candidate_pair_->local_candidate_id = "local-candidate";
145*d9f75844SAndroid Build Coastguard Worker candidate_pair_->remote_candidate_id = "remote-candidate";
146*d9f75844SAndroid Build Coastguard Worker local_candidate_->transport_id = "transport";
147*d9f75844SAndroid Build Coastguard Worker remote_candidate_->transport_id = "transport";
148*d9f75844SAndroid Build Coastguard Worker TakeReferencedStats({candidate_pair_});
149*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(transport_);
150*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(candidate_pair_);
151*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(local_candidate_);
152*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(remote_candidate_);
153*d9f75844SAndroid Build Coastguard Worker }
154*d9f75844SAndroid Build Coastguard Worker
TEST_F(RTCStatsTraversalTest,CyclicGraph)155*d9f75844SAndroid Build Coastguard Worker TEST_F(RTCStatsTraversalTest, CyclicGraph) {
156*d9f75844SAndroid Build Coastguard Worker // candidate-pair
157*d9f75844SAndroid Build Coastguard Worker // | ^
158*d9f75844SAndroid Build Coastguard Worker // v |
159*d9f75844SAndroid Build Coastguard Worker // start:local-candidate | remote-candidate
160*d9f75844SAndroid Build Coastguard Worker // | |
161*d9f75844SAndroid Build Coastguard Worker // v |
162*d9f75844SAndroid Build Coastguard Worker // transport
163*d9f75844SAndroid Build Coastguard Worker local_candidate_->transport_id = "transport";
164*d9f75844SAndroid Build Coastguard Worker transport_->selected_candidate_pair_id = "candidate-pair";
165*d9f75844SAndroid Build Coastguard Worker candidate_pair_->local_candidate_id = "local-candidate";
166*d9f75844SAndroid Build Coastguard Worker TakeReferencedStats({local_candidate_});
167*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(transport_);
168*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(candidate_pair_);
169*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(local_candidate_);
170*d9f75844SAndroid Build Coastguard Worker EXPECT_UNVISITED(remote_candidate_);
171*d9f75844SAndroid Build Coastguard Worker }
172*d9f75844SAndroid Build Coastguard Worker
TEST_F(RTCStatsTraversalTest,MultipleStarts)173*d9f75844SAndroid Build Coastguard Worker TEST_F(RTCStatsTraversalTest, MultipleStarts) {
174*d9f75844SAndroid Build Coastguard Worker // start:candidate-pair
175*d9f75844SAndroid Build Coastguard Worker // |
176*d9f75844SAndroid Build Coastguard Worker // v
177*d9f75844SAndroid Build Coastguard Worker // local-candidate remote-candidate
178*d9f75844SAndroid Build Coastguard Worker // |
179*d9f75844SAndroid Build Coastguard Worker // v
180*d9f75844SAndroid Build Coastguard Worker // start:transport
181*d9f75844SAndroid Build Coastguard Worker candidate_pair_->remote_candidate_id = "remote-candidate";
182*d9f75844SAndroid Build Coastguard Worker local_candidate_->transport_id = "transport";
183*d9f75844SAndroid Build Coastguard Worker TakeReferencedStats({candidate_pair_, transport_});
184*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(transport_);
185*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(candidate_pair_);
186*d9f75844SAndroid Build Coastguard Worker EXPECT_UNVISITED(local_candidate_);
187*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(remote_candidate_);
188*d9f75844SAndroid Build Coastguard Worker }
189*d9f75844SAndroid Build Coastguard Worker
TEST_F(RTCStatsTraversalTest,MultipleStartsLeadingToSameNode)190*d9f75844SAndroid Build Coastguard Worker TEST_F(RTCStatsTraversalTest, MultipleStartsLeadingToSameNode) {
191*d9f75844SAndroid Build Coastguard Worker // candidate-pair
192*d9f75844SAndroid Build Coastguard Worker //
193*d9f75844SAndroid Build Coastguard Worker //
194*d9f75844SAndroid Build Coastguard Worker // start:local-candidate start:remote-candidate
195*d9f75844SAndroid Build Coastguard Worker // | |
196*d9f75844SAndroid Build Coastguard Worker // v v
197*d9f75844SAndroid Build Coastguard Worker // transport
198*d9f75844SAndroid Build Coastguard Worker local_candidate_->transport_id = "transport";
199*d9f75844SAndroid Build Coastguard Worker remote_candidate_->transport_id = "transport";
200*d9f75844SAndroid Build Coastguard Worker TakeReferencedStats({local_candidate_, remote_candidate_});
201*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(transport_);
202*d9f75844SAndroid Build Coastguard Worker EXPECT_UNVISITED(candidate_pair_);
203*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(local_candidate_);
204*d9f75844SAndroid Build Coastguard Worker EXPECT_VISITED(remote_candidate_);
205*d9f75844SAndroid Build Coastguard Worker }
206*d9f75844SAndroid Build Coastguard Worker
207*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
208