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/peer_connection_quality_test.h"
12
13 #include <map>
14 #include <memory>
15 #include <string>
16 #include <utility>
17
18 #include "api/test/create_network_emulation_manager.h"
19 #include "api/test/metrics/global_metrics_logger_and_exporter.h"
20 #include "api/test/network_emulation_manager.h"
21 #include "api/test/pclf/media_configuration.h"
22 #include "api/test/pclf/media_quality_test_params.h"
23 #include "api/test/pclf/peer_configurer.h"
24 #include "api/test/peerconnection_quality_test_fixture.h"
25 #include "api/units/time_delta.h"
26 #include "rtc_base/time_utils.h"
27 #include "test/gmock.h"
28 #include "test/gtest.h"
29 #include "test/testsupport/file_utils.h"
30 #include "test/testsupport/frame_reader.h"
31
32 namespace webrtc {
33 namespace webrtc_pc_e2e {
34 namespace {
35
36 using ::testing::Eq;
37 using ::testing::Test;
38
39 using ::webrtc::webrtc_pc_e2e::PeerConfigurer;
40
41 // Remove files and directories in a directory non-recursively.
CleanDir(absl::string_view dir,size_t expected_output_files_count)42 void CleanDir(absl::string_view dir, size_t expected_output_files_count) {
43 absl::optional<std::vector<std::string>> dir_content =
44 test::ReadDirectory(dir);
45 if (expected_output_files_count == 0) {
46 ASSERT_FALSE(dir_content.has_value()) << "Empty directory is expected";
47 } else {
48 ASSERT_TRUE(dir_content.has_value()) << "Test directory is empty!";
49 EXPECT_EQ(dir_content->size(), expected_output_files_count);
50 for (const auto& entry : *dir_content) {
51 if (test::DirExists(entry)) {
52 EXPECT_TRUE(test::RemoveDir(entry))
53 << "Failed to remove sub directory: " << entry;
54 } else if (test::FileExists(entry)) {
55 EXPECT_TRUE(test::RemoveFile(entry))
56 << "Failed to remove file: " << entry;
57 } else {
58 FAIL() << "Can't remove unknown file type: " << entry;
59 }
60 }
61 }
62 EXPECT_TRUE(test::RemoveDir(dir)) << "Failed to remove directory: " << dir;
63 }
64
65 class PeerConnectionE2EQualityTestTest : public Test {
66 protected:
67 ~PeerConnectionE2EQualityTestTest() override = default;
68
SetUp()69 void SetUp() override {
70 // Create an empty temporary directory for this test.
71 test_directory_ = test::JoinFilename(
72 test::OutputPath(),
73 "TestDir_PeerConnectionE2EQualityTestTest_" +
74 std::string(
75 testing::UnitTest::GetInstance()->current_test_info()->name()));
76 test::CreateDir(test_directory_);
77 }
78
TearDown()79 void TearDown() override {
80 CleanDir(test_directory_, expected_output_files_count_);
81 }
82
ExpectOutputFilesCount(size_t count)83 void ExpectOutputFilesCount(size_t count) {
84 expected_output_files_count_ = count;
85 }
86
87 std::string test_directory_;
88 size_t expected_output_files_count_ = 0;
89 };
90
TEST_F(PeerConnectionE2EQualityTestTest,OutputVideoIsDumpedWhenRequested)91 TEST_F(PeerConnectionE2EQualityTestTest, OutputVideoIsDumpedWhenRequested) {
92 std::unique_ptr<NetworkEmulationManager> network_emulation =
93 CreateNetworkEmulationManager(TimeMode::kSimulated);
94 PeerConnectionE2EQualityTest fixture(
95 "test_case", *network_emulation->time_controller(),
96 /*audio_quality_analyzer=*/nullptr, /*video_quality_analyzer=*/nullptr,
97 test::GetGlobalMetricsLogger());
98
99 EmulatedEndpoint* alice_endpoint =
100 network_emulation->CreateEndpoint(EmulatedEndpointConfig());
101 EmulatedEndpoint* bob_endpoint =
102 network_emulation->CreateEndpoint(EmulatedEndpointConfig());
103
104 network_emulation->CreateRoute(
105 alice_endpoint, {network_emulation->CreateUnconstrainedEmulatedNode()},
106 bob_endpoint);
107 network_emulation->CreateRoute(
108 bob_endpoint, {network_emulation->CreateUnconstrainedEmulatedNode()},
109 alice_endpoint);
110
111 EmulatedNetworkManagerInterface* alice_network =
112 network_emulation->CreateEmulatedNetworkManagerInterface(
113 {alice_endpoint});
114 EmulatedNetworkManagerInterface* bob_network =
115 network_emulation->CreateEmulatedNetworkManagerInterface({bob_endpoint});
116
117 VideoConfig alice_video("alice_video", 320, 180, 15);
118 alice_video.output_dump_options = VideoDumpOptions(test_directory_);
119 PeerConfigurer alice(alice_network->network_dependencies());
120 alice.SetName("alice");
121 alice.AddVideoConfig(std::move(alice_video));
122 fixture.AddPeer(std::make_unique<PeerConfigurer>(std::move(alice)));
123
124 PeerConfigurer bob(bob_network->network_dependencies());
125 bob.SetName("bob");
126 fixture.AddPeer(std::make_unique<PeerConfigurer>(std::move(bob)));
127
128 fixture.Run(RunParams(TimeDelta::Seconds(2)));
129
130 test::Y4mFrameReaderImpl frame_reader(
131 test::JoinFilename(test_directory_, "alice_video_bob_320x180_15.y4m"),
132 /*width=*/320,
133 /*height=*/180);
134 ASSERT_TRUE(frame_reader.Init());
135 EXPECT_THAT(frame_reader.NumberOfFrames(), Eq(31)); // 2 seconds 15 fps + 1
136
137 ExpectOutputFilesCount(1);
138 }
139
140 } // namespace
141 } // namespace webrtc_pc_e2e
142 } // namespace webrtc
143