OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "content/browser/media/webrtc/webrtc_eventlog_host.h" |
| 6 |
| 7 #include <tuple> |
| 8 |
| 9 #include "base/files/file.h" |
| 10 #include "base/files/file_util.h" |
| 11 #include "base/run_loop.h" |
| 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "content/browser/renderer_host/render_process_host_impl.h" |
| 14 #include "content/common/media/peer_connection_tracker_messages.h" |
| 15 #include "content/public/browser/browser_context.h" |
| 16 #include "content/public/test/mock_render_process_host.h" |
| 17 #include "content/public/test/test_browser_context.h" |
| 18 #include "content/public/test/test_browser_thread_bundle.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" |
| 20 |
| 21 #if defined(OS_WIN) |
| 22 #define IntToStringType base::IntToString16 |
| 23 #else |
| 24 #define IntToStringType base::IntToString |
| 25 #endif |
| 26 |
| 27 namespace content { |
| 28 |
| 29 namespace { |
| 30 |
| 31 // Get the expected Rtc eventlog file name. The name will be |
| 32 // <temporary path>.<render process id>.<peer connection local id> |
| 33 base::FilePath GetExpectedEventLogFileName(const base::FilePath& base_file, |
| 34 int render_process_id, |
| 35 int peer_connection_local_id) { |
| 36 return base_file.AddExtension(IntToStringType(render_process_id)) |
| 37 .AddExtension(IntToStringType(peer_connection_local_id)); |
| 38 } |
| 39 |
| 40 } // namespace |
| 41 |
| 42 class WebRtcEventlogHostTest : public testing::Test { |
| 43 public: |
| 44 WebRtcEventlogHostTest() |
| 45 : mock_render_process_host_(static_cast<MockRenderProcessHost*>( |
| 46 mock_render_process_factory_.CreateRenderProcessHost( |
| 47 &test_browser_context_, |
| 48 nullptr))), |
| 49 render_id_(mock_render_process_host_->GetID()), |
| 50 event_log_host_(render_id_) {} |
| 51 TestBrowserThreadBundle thread_bundle_; |
| 52 MockRenderProcessHostFactory mock_render_process_factory_; |
| 53 TestBrowserContext test_browser_context_; |
| 54 std::unique_ptr<MockRenderProcessHost> mock_render_process_host_; |
| 55 const int render_id_; |
| 56 WebRTCEventLogHost event_log_host_; |
| 57 base::FilePath base_file_; |
| 58 |
| 59 void StartLogging() { |
| 60 ASSERT_TRUE(base::CreateTemporaryFile(&base_file_)); |
| 61 EXPECT_TRUE(base::DeleteFile(base_file_, false)); |
| 62 EXPECT_FALSE(base::PathExists(base_file_)); |
| 63 EXPECT_TRUE(event_log_host_.StartWebRTCEventLog(base_file_)); |
| 64 base::RunLoop().RunUntilIdle(); |
| 65 } |
| 66 |
| 67 void StopLogging() { |
| 68 EXPECT_TRUE(event_log_host_.StopWebRTCEventLog()); |
| 69 base::RunLoop().RunUntilIdle(); |
| 70 } |
| 71 |
| 72 void ValidateStartIPCMessageAndCloseFile(const IPC::Message* msg, |
| 73 const int peer_connection_id) { |
| 74 ASSERT_TRUE(msg); |
| 75 std::tuple<int, IPC::PlatformFileForTransit> start_params; |
| 76 PeerConnectionTracker_StartEventLog::Read(msg, &start_params); |
| 77 EXPECT_EQ(peer_connection_id, std::get<0>(start_params)); |
| 78 ASSERT_NE(IPC::InvalidPlatformFileForTransit(), std::get<1>(start_params)); |
| 79 IPC::PlatformFileForTransitToFile(std::get<1>(start_params)).Close(); |
| 80 } |
| 81 |
| 82 void ValidateStopIPCMessage(const IPC::Message* msg, |
| 83 const int peer_connection_id) { |
| 84 ASSERT_TRUE(msg); |
| 85 std::tuple<int> stop_params; |
| 86 PeerConnectionTracker_StopEventLog::Read(msg, &stop_params); |
| 87 EXPECT_EQ(peer_connection_id, std::get<0>(stop_params)); |
| 88 } |
| 89 }; |
| 90 |
| 91 // This test calls StartWebRTCEventLog() and StopWebRTCEventLog() without having |
| 92 // added any PeerConnections. It is expected that no IPC messages will be sent. |
| 93 TEST_F(WebRtcEventlogHostTest, NoPeerConnectionTest) { |
| 94 mock_render_process_host_->sink().ClearMessages(); |
| 95 |
| 96 // Start logging and check that no IPC messages were sent. |
| 97 StartLogging(); |
| 98 EXPECT_EQ(size_t(0), mock_render_process_host_->sink().message_count()); |
| 99 |
| 100 // Stop logging and check that no IPC messages were sent. |
| 101 StopLogging(); |
| 102 EXPECT_EQ(size_t(0), mock_render_process_host_->sink().message_count()); |
| 103 } |
| 104 |
| 105 // This test calls StartWebRTCEventLog() and StopWebRTCEventLog() after adding a |
| 106 // single PeerConnection. It is expected that one IPC message will be sent for |
| 107 // each of the Start and Stop calls, and that a logfile is created. |
| 108 TEST_F(WebRtcEventlogHostTest, OnePeerConnectionTest) { |
| 109 const int kTestPeerConnectionId = 123; |
| 110 mock_render_process_host_->sink().ClearMessages(); |
| 111 |
| 112 // Add a PeerConnection and start logging. |
| 113 event_log_host_.PeerConnectionAdded(kTestPeerConnectionId); |
| 114 StartLogging(); |
| 115 |
| 116 // Check that the correct IPC message was sent. |
| 117 EXPECT_EQ(size_t(1), mock_render_process_host_->sink().message_count()); |
| 118 const IPC::Message* start_msg = |
| 119 mock_render_process_host_->sink().GetMessageAt(0); |
| 120 ValidateStartIPCMessageAndCloseFile(start_msg, kTestPeerConnectionId); |
| 121 |
| 122 // Stop logging. |
| 123 mock_render_process_host_->sink().ClearMessages(); |
| 124 StopLogging(); |
| 125 |
| 126 // Check that the correct IPC message was sent. |
| 127 EXPECT_EQ(size_t(1), mock_render_process_host_->sink().message_count()); |
| 128 const IPC::Message* stop_msg = |
| 129 mock_render_process_host_->sink().GetMessageAt(0); |
| 130 ValidateStopIPCMessage(stop_msg, kTestPeerConnectionId); |
| 131 |
| 132 // Clean up the logfile. |
| 133 base::FilePath expected_file = GetExpectedEventLogFileName( |
| 134 base_file_, render_id_, kTestPeerConnectionId); |
| 135 ASSERT_TRUE(base::PathExists(expected_file)); |
| 136 EXPECT_TRUE(base::DeleteFile(expected_file, false)); |
| 137 } |
| 138 |
| 139 // This test calls StartWebRTCEventLog() and StopWebRTCEventLog() after adding |
| 140 // two PeerConnections. It is expected that two IPC messages will be sent for |
| 141 // each of the Start and Stop calls, and that a file is created for both |
| 142 // PeerConnections. |
| 143 TEST_F(WebRtcEventlogHostTest, TwoPeerConnectionsTest) { |
| 144 const int kTestPeerConnectionId1 = 123; |
| 145 const int kTestPeerConnectionId2 = 321; |
| 146 mock_render_process_host_->sink().ClearMessages(); |
| 147 |
| 148 // Add two PeerConnections and start logging. |
| 149 event_log_host_.PeerConnectionAdded(kTestPeerConnectionId1); |
| 150 event_log_host_.PeerConnectionAdded(kTestPeerConnectionId2); |
| 151 StartLogging(); |
| 152 |
| 153 // Check that the correct IPC messages were sent. |
| 154 EXPECT_EQ(size_t(2), mock_render_process_host_->sink().message_count()); |
| 155 const IPC::Message* start_msg1 = |
| 156 mock_render_process_host_->sink().GetMessageAt(0); |
| 157 ValidateStartIPCMessageAndCloseFile(start_msg1, kTestPeerConnectionId1); |
| 158 const IPC::Message* start_msg2 = |
| 159 mock_render_process_host_->sink().GetMessageAt(1); |
| 160 ValidateStartIPCMessageAndCloseFile(start_msg2, kTestPeerConnectionId2); |
| 161 |
| 162 // Stop logging. |
| 163 mock_render_process_host_->sink().ClearMessages(); |
| 164 StopLogging(); |
| 165 |
| 166 // Check that the correct IPC messages were sent. |
| 167 EXPECT_EQ(size_t(2), mock_render_process_host_->sink().message_count()); |
| 168 const IPC::Message* stop_msg1 = |
| 169 mock_render_process_host_->sink().GetMessageAt(0); |
| 170 ValidateStopIPCMessage(stop_msg1, kTestPeerConnectionId1); |
| 171 const IPC::Message* stop_msg2 = |
| 172 mock_render_process_host_->sink().GetMessageAt(1); |
| 173 ValidateStopIPCMessage(stop_msg2, kTestPeerConnectionId2); |
| 174 |
| 175 // Clean up the logfiles. |
| 176 base::FilePath expected_file1 = GetExpectedEventLogFileName( |
| 177 base_file_, render_id_, kTestPeerConnectionId1); |
| 178 base::FilePath expected_file2 = GetExpectedEventLogFileName( |
| 179 base_file_, render_id_, kTestPeerConnectionId2); |
| 180 ASSERT_TRUE(base::PathExists(expected_file1)); |
| 181 EXPECT_TRUE(base::DeleteFile(expected_file1, false)); |
| 182 ASSERT_TRUE(base::PathExists(expected_file2)); |
| 183 EXPECT_TRUE(base::DeleteFile(expected_file2, false)); |
| 184 } |
| 185 |
| 186 // This test calls StartWebRTCEventLog() and StopWebRTCEventLog() after adding |
| 187 // more PeerConnections than the maximum allowed. It is expected that only the |
| 188 // maximum allowed number of IPC messages and log files will be opened, but we |
| 189 // expect the number of stop IPC messages to be equal to the actual number of |
| 190 // PeerConnections. |
| 191 TEST_F(WebRtcEventlogHostTest, ExceedMaxPeerConnectionsTest) { |
| 192 #if defined(OS_ANDROID) |
| 193 const int kMaxNumberLogFiles = 3; |
| 194 #else |
| 195 const int kMaxNumberLogFiles = 5; |
| 196 #endif |
| 197 const int kNumberOfPeerConnections = kMaxNumberLogFiles + 1; |
| 198 mock_render_process_host_->sink().ClearMessages(); |
| 199 |
| 200 // Add the maximum number + 1 PeerConnections and start logging. |
| 201 for (int i = 0; i < kNumberOfPeerConnections; ++i) |
| 202 event_log_host_.PeerConnectionAdded(i); |
| 203 StartLogging(); |
| 204 |
| 205 // Check that the correct IPC messages were sent. |
| 206 ASSERT_EQ(size_t(kMaxNumberLogFiles), |
| 207 mock_render_process_host_->sink().message_count()); |
| 208 for (int i = 0; i < kMaxNumberLogFiles; ++i) { |
| 209 const IPC::Message* start_msg = |
| 210 mock_render_process_host_->sink().GetMessageAt(i); |
| 211 ValidateStartIPCMessageAndCloseFile(start_msg, i); |
| 212 } |
| 213 |
| 214 // Stop logging. |
| 215 mock_render_process_host_->sink().ClearMessages(); |
| 216 StopLogging(); |
| 217 |
| 218 // Check that the correct IPC messages were sent. |
| 219 ASSERT_EQ(size_t(kNumberOfPeerConnections), |
| 220 mock_render_process_host_->sink().message_count()); |
| 221 for (int i = 0; i < kNumberOfPeerConnections; ++i) { |
| 222 const IPC::Message* stop_msg = |
| 223 mock_render_process_host_->sink().GetMessageAt(i); |
| 224 ValidateStopIPCMessage(stop_msg, i); |
| 225 } |
| 226 |
| 227 // Clean up the logfiles. |
| 228 for (int i = 0; i < kMaxNumberLogFiles; ++i) { |
| 229 base::FilePath expected_file = |
| 230 GetExpectedEventLogFileName(base_file_, render_id_, i); |
| 231 ASSERT_TRUE(base::PathExists(expected_file)); |
| 232 EXPECT_TRUE(base::DeleteFile(expected_file, false)); |
| 233 } |
| 234 |
| 235 // Check that not too many files were created. |
| 236 for (int i = kMaxNumberLogFiles; i < kNumberOfPeerConnections; ++i) { |
| 237 base::FilePath expected_file = |
| 238 GetExpectedEventLogFileName(base_file_, render_id_, i); |
| 239 EXPECT_FALSE(base::PathExists(expected_file)); |
| 240 } |
| 241 } |
| 242 |
| 243 // This test calls StartWebRTCEventLog() and StopWebRTCEventLog() after first |
| 244 // adding and then removing a single PeerConnection. It is expected that no IPC |
| 245 // message will be sent. |
| 246 TEST_F(WebRtcEventlogHostTest, AddRemovePeerConnectionTest) { |
| 247 const int kTestPeerConnectionId = 123; |
| 248 mock_render_process_host_->sink().ClearMessages(); |
| 249 |
| 250 // Add and immediately remove a PeerConnection. |
| 251 event_log_host_.PeerConnectionAdded(kTestPeerConnectionId); |
| 252 event_log_host_.PeerConnectionRemoved(kTestPeerConnectionId); |
| 253 |
| 254 // Start logging and check that no IPC messages were sent. |
| 255 StartLogging(); |
| 256 EXPECT_EQ(size_t(0), mock_render_process_host_->sink().message_count()); |
| 257 |
| 258 // Stop logging and check that no IPC messages were sent. |
| 259 StopLogging(); |
| 260 EXPECT_EQ(size_t(0), mock_render_process_host_->sink().message_count()); |
| 261 |
| 262 // Check that no logfile was created. |
| 263 base::FilePath expected_file = GetExpectedEventLogFileName( |
| 264 base_file_, render_id_, kTestPeerConnectionId); |
| 265 ASSERT_FALSE(base::PathExists(expected_file)); |
| 266 } |
| 267 |
| 268 } // namespace content |
OLD | NEW |