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