1 /*
2 * Copyright (c) 2022 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 "test/pc/e2e/stats_based_network_quality_metrics_reporter.h"
12
13 #include <map>
14 #include <memory>
15 #include <string>
16 #include <vector>
17
18 #include "absl/strings/string_view.h"
19 #include "absl/types/optional.h"
20 #include "api/array_view.h"
21 #include "api/test/create_network_emulation_manager.h"
22 #include "api/test/create_peer_connection_quality_test_frame_generator.h"
23 #include "api/test/metrics/metrics_logger.h"
24 #include "api/test/metrics/stdout_metrics_exporter.h"
25 #include "api/test/network_emulation_manager.h"
26 #include "api/test/pclf/media_configuration.h"
27 #include "api/test/pclf/media_quality_test_params.h"
28 #include "api/test/pclf/peer_configurer.h"
29 #include "api/test/peerconnection_quality_test_fixture.h"
30 #include "api/units/time_delta.h"
31 #include "test/gmock.h"
32 #include "test/gtest.h"
33 #include "test/pc/e2e/metric_metadata_keys.h"
34 #include "test/pc/e2e/peer_connection_quality_test.h"
35
36 namespace webrtc {
37 namespace webrtc_pc_e2e {
38 namespace {
39
40 using ::testing::UnorderedElementsAre;
41
42 using ::webrtc::test::DefaultMetricsLogger;
43 using ::webrtc::test::ImprovementDirection;
44 using ::webrtc::test::Metric;
45 using ::webrtc::test::Unit;
46 using ::webrtc::webrtc_pc_e2e::PeerConfigurer;
47
48 // Adds a peer with some audio and video (the client should not care about
49 // details about audio and video configs).
AddDefaultAudioVideoPeer(absl::string_view peer_name,absl::string_view audio_stream_label,absl::string_view video_stream_label,const PeerNetworkDependencies & network_dependencies,PeerConnectionE2EQualityTestFixture & fixture)50 void AddDefaultAudioVideoPeer(
51 absl::string_view peer_name,
52 absl::string_view audio_stream_label,
53 absl::string_view video_stream_label,
54 const PeerNetworkDependencies& network_dependencies,
55 PeerConnectionE2EQualityTestFixture& fixture) {
56 AudioConfig audio{std::string(audio_stream_label)};
57 audio.sync_group = std::string(peer_name);
58 VideoConfig video(std::string(video_stream_label), 320, 180, 15);
59 video.sync_group = std::string(peer_name);
60 auto peer = std::make_unique<PeerConfigurer>(network_dependencies);
61 peer->SetName(peer_name);
62 peer->SetAudioConfig(std::move(audio));
63 peer->AddVideoConfig(std::move(video));
64 peer->SetVideoCodecs({VideoCodecConfig(cricket::kVp8CodecName)});
65 fixture.AddPeer(std::move(peer));
66 }
67
FindMeetricByName(absl::string_view name,rtc::ArrayView<const Metric> metrics)68 absl::optional<Metric> FindMeetricByName(absl::string_view name,
69 rtc::ArrayView<const Metric> metrics) {
70 for (const Metric& metric : metrics) {
71 if (metric.name == name) {
72 return metric;
73 }
74 }
75 return absl::nullopt;
76 }
77
TEST(StatsBasedNetworkQualityMetricsReporterTest,DebugStatsAreCollected)78 TEST(StatsBasedNetworkQualityMetricsReporterTest, DebugStatsAreCollected) {
79 std::unique_ptr<NetworkEmulationManager> network_emulation =
80 CreateNetworkEmulationManager(TimeMode::kSimulated,
81 EmulatedNetworkStatsGatheringMode::kDebug);
82 DefaultMetricsLogger metrics_logger(
83 network_emulation->time_controller()->GetClock());
84 PeerConnectionE2EQualityTest fixture(
85 "test_case", *network_emulation->time_controller(),
86 /*audio_quality_analyzer=*/nullptr, /*video_quality_analyzer=*/nullptr,
87 &metrics_logger);
88
89 EmulatedEndpoint* alice_endpoint =
90 network_emulation->CreateEndpoint(EmulatedEndpointConfig());
91 EmulatedEndpoint* bob_endpoint =
92 network_emulation->CreateEndpoint(EmulatedEndpointConfig());
93
94 EmulatedNetworkNode* alice_link = network_emulation->CreateEmulatedNode(
95 BuiltInNetworkBehaviorConfig{.link_capacity_kbps = 500});
96 network_emulation->CreateRoute(alice_endpoint, {alice_link}, bob_endpoint);
97 EmulatedNetworkNode* bob_link = network_emulation->CreateEmulatedNode(
98 BuiltInNetworkBehaviorConfig{.link_capacity_kbps = 500});
99 network_emulation->CreateRoute(bob_endpoint, {bob_link}, alice_endpoint);
100
101 EmulatedNetworkManagerInterface* alice_network =
102 network_emulation->CreateEmulatedNetworkManagerInterface(
103 {alice_endpoint});
104 EmulatedNetworkManagerInterface* bob_network =
105 network_emulation->CreateEmulatedNetworkManagerInterface({bob_endpoint});
106
107 AddDefaultAudioVideoPeer("alice", "alice_audio", "alice_video",
108 alice_network->network_dependencies(), fixture);
109 AddDefaultAudioVideoPeer("bob", "bob_audio", "bob_video",
110 bob_network->network_dependencies(), fixture);
111
112 auto network_stats_reporter =
113 std::make_unique<StatsBasedNetworkQualityMetricsReporter>(
114 /*peer_endpoints=*/std::map<std::string,
115 std::vector<EmulatedEndpoint*>>{},
116 network_emulation.get(), &metrics_logger);
117 network_stats_reporter->AddPeer("alice", alice_network->endpoints(),
118 /*uplink=*/{alice_link},
119 /*downlink=*/{bob_link});
120 network_stats_reporter->AddPeer("bob", bob_network->endpoints(),
121 /*uplink=*/{bob_link},
122 /*downlink=*/{alice_link});
123 fixture.AddQualityMetricsReporter(std::move(network_stats_reporter));
124
125 fixture.Run(RunParams(TimeDelta::Seconds(4)));
126
127 std::vector<Metric> metrics = metrics_logger.GetCollectedMetrics();
128 absl::optional<Metric> uplink_packet_transport_time =
129 FindMeetricByName("uplink_packet_transport_time", metrics);
130 ASSERT_TRUE(uplink_packet_transport_time.has_value());
131 ASSERT_FALSE(uplink_packet_transport_time->time_series.samples.empty());
132 absl::optional<Metric> uplink_size_to_packet_transport_time =
133 FindMeetricByName("uplink_size_to_packet_transport_time", metrics);
134 ASSERT_TRUE(uplink_size_to_packet_transport_time.has_value());
135 ASSERT_FALSE(
136 uplink_size_to_packet_transport_time->time_series.samples.empty());
137 absl::optional<Metric> downlink_packet_transport_time =
138 FindMeetricByName("downlink_packet_transport_time", metrics);
139 ASSERT_TRUE(downlink_packet_transport_time.has_value());
140 ASSERT_FALSE(downlink_packet_transport_time->time_series.samples.empty());
141 absl::optional<Metric> downlink_size_to_packet_transport_time =
142 FindMeetricByName("downlink_size_to_packet_transport_time", metrics);
143 ASSERT_TRUE(downlink_size_to_packet_transport_time.has_value());
144 ASSERT_FALSE(
145 downlink_size_to_packet_transport_time->time_series.samples.empty());
146 }
147
148 } // namespace
149 } // namespace webrtc_pc_e2e
150 } // namespace webrtc
151