rtc_event_log_unittest.cc (43607B)
1 /* 2 * Copyright (c) 2015 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 "api/rtc_event_log/rtc_event_log.h" 12 13 #include <algorithm> 14 #include <cstddef> 15 #include <cstdint> 16 #include <limits> 17 #include <map> 18 #include <memory> 19 #include <string> 20 #include <tuple> 21 #include <utility> 22 #include <vector> 23 24 #include "api/environment/environment_factory.h" 25 #include "api/field_trials_view.h" 26 #include "api/rtc_event_log/rtc_event_log_factory.h" 27 #include "api/units/time_delta.h" 28 #include "api/units/timestamp.h" 29 #include "logging/rtc_event_log/events/rtc_event_alr_state.h" 30 #include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h" 31 #include "logging/rtc_event_log/events/rtc_event_audio_playout.h" 32 #include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h" 33 #include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h" 34 #include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h" 35 #include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h" 36 #include "logging/rtc_event_log/events/rtc_event_dtls_transport_state.h" 37 #include "logging/rtc_event_log/events/rtc_event_dtls_writable_state.h" 38 #include "logging/rtc_event_log/events/rtc_event_frame_decoded.h" 39 #include "logging/rtc_event_log/events/rtc_event_generic_packet_received.h" 40 #include "logging/rtc_event_log/events/rtc_event_generic_packet_sent.h" 41 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h" 42 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h" 43 #include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h" 44 #include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h" 45 #include "logging/rtc_event_log/events/rtc_event_probe_result_success.h" 46 #include "logging/rtc_event_log/events/rtc_event_remote_estimate.h" 47 #include "logging/rtc_event_log/events/rtc_event_route_change.h" 48 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h" 49 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h" 50 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h" 51 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h" 52 #include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h" 53 #include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h" 54 #include "logging/rtc_event_log/rtc_event_log_parser.h" 55 #include "logging/rtc_event_log/rtc_event_log_unittest_helper.h" 56 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" 57 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" 58 #include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h" 59 #include "rtc_base/checks.h" 60 #include "rtc_base/fake_clock.h" 61 #include "rtc_base/random.h" 62 #include "rtc_base/time_utils.h" 63 #include "test/create_test_field_trials.h" 64 #include "test/gtest.h" 65 #include "test/logging/log_writer.h" 66 #include "test/logging/memory_log_writer.h" 67 #include "test/testsupport/file_utils.h" 68 69 namespace webrtc { 70 71 namespace { 72 73 struct EventCounts { 74 size_t audio_send_streams = 0; 75 size_t audio_recv_streams = 0; 76 size_t video_send_streams = 0; 77 size_t video_recv_streams = 0; 78 size_t alr_states = 0; 79 size_t route_changes = 0; 80 size_t audio_playouts = 0; 81 size_t ana_configs = 0; 82 size_t bwe_loss_events = 0; 83 size_t bwe_delay_events = 0; 84 size_t dtls_transport_states = 0; 85 size_t dtls_writable_states = 0; 86 size_t frame_decoded_events = 0; 87 size_t probe_creations = 0; 88 size_t probe_successes = 0; 89 size_t probe_failures = 0; 90 size_t ice_configs = 0; 91 size_t ice_events = 0; 92 size_t incoming_rtp_packets = 0; 93 size_t outgoing_rtp_packets = 0; 94 size_t incoming_rtcp_packets = 0; 95 size_t outgoing_rtcp_packets = 0; 96 size_t generic_packets_sent = 0; 97 size_t generic_packets_received = 0; 98 99 size_t total_nonconfig_events() const { 100 return alr_states + route_changes + audio_playouts + ana_configs + 101 bwe_loss_events + bwe_delay_events + dtls_transport_states + 102 dtls_writable_states + frame_decoded_events + probe_creations + 103 probe_successes + probe_failures + ice_configs + ice_events + 104 incoming_rtp_packets + outgoing_rtp_packets + incoming_rtcp_packets + 105 outgoing_rtcp_packets + generic_packets_sent + 106 generic_packets_received; 107 } 108 109 size_t total_config_events() const { 110 return audio_send_streams + audio_recv_streams + video_send_streams + 111 video_recv_streams; 112 } 113 114 size_t total_events() const { 115 return total_nonconfig_events() + total_config_events(); 116 } 117 }; 118 119 std::unique_ptr<FieldTrialsView> CreateFieldTrialsFor( 120 RtcEventLog::EncodingType encoding_type) { 121 switch (encoding_type) { 122 case RtcEventLog::EncodingType::Legacy: 123 return CreateTestFieldTrialsPtr("WebRTC-RtcEventLogNewFormat/Disabled/"); 124 case RtcEventLog::EncodingType::NewFormat: 125 return CreateTestFieldTrialsPtr("WebRTC-RtcEventLogNewFormat/Enabled/"); 126 case RtcEventLog::EncodingType::ProtoFree: 127 RTC_CHECK(false); 128 return nullptr; 129 } 130 } 131 132 class RtcEventLogSession 133 : public ::testing::TestWithParam< 134 std::tuple<uint64_t, int64_t, RtcEventLog::EncodingType>> { 135 public: 136 RtcEventLogSession() 137 : seed_(std::get<0>(GetParam())), 138 prng_(seed_), 139 output_period_ms_(std::get<1>(GetParam())), 140 encoding_type_(std::get<2>(GetParam())), 141 gen_(seed_ * 880001UL), 142 verifier_(encoding_type_), 143 log_storage_(), 144 log_output_factory_(log_storage_.CreateFactory()) { 145 clock_.SetTime(Timestamp::Micros(prng_.Rand<uint32_t>())); 146 // Find the name of the current test, in order to use it as a temporary 147 // filename. 148 auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); 149 std::string test_name = 150 std::string(test_info->test_case_name()) + "_" + test_info->name(); 151 std::replace(test_name.begin(), test_name.end(), '/', '_'); 152 temp_filename_ = test::OutputPath() + test_name; 153 } 154 155 // Create and buffer the config events and `num_events_before_start` 156 // randomized non-config events. Then call StartLogging and finally create and 157 // write the remaining non-config events. 158 void WriteLog(EventCounts count, size_t num_events_before_start); 159 void ReadAndVerifyLog(); 160 161 bool IsNewFormat() { 162 return encoding_type_ == RtcEventLog::EncodingType::NewFormat; 163 } 164 165 private: 166 void WriteAudioRecvConfigs(size_t audio_recv_streams, RtcEventLog* event_log); 167 void WriteAudioSendConfigs(size_t audio_send_streams, RtcEventLog* event_log); 168 void WriteVideoRecvConfigs(size_t video_recv_streams, RtcEventLog* event_log); 169 void WriteVideoSendConfigs(size_t video_send_streams, RtcEventLog* event_log); 170 171 std::vector<std::pair<uint32_t, RtpHeaderExtensionMap>> incoming_extensions_; 172 std::vector<std::pair<uint32_t, RtpHeaderExtensionMap>> outgoing_extensions_; 173 174 // Config events. 175 std::vector<std::unique_ptr<RtcEventAudioSendStreamConfig>> 176 audio_send_config_list_; 177 std::vector<std::unique_ptr<RtcEventAudioReceiveStreamConfig>> 178 audio_recv_config_list_; 179 std::vector<std::unique_ptr<RtcEventVideoSendStreamConfig>> 180 video_send_config_list_; 181 std::vector<std::unique_ptr<RtcEventVideoReceiveStreamConfig>> 182 video_recv_config_list_; 183 184 // Regular events. 185 std::vector<std::unique_ptr<RtcEventAlrState>> alr_state_list_; 186 std::map<uint32_t, std::vector<std::unique_ptr<RtcEventAudioPlayout>>> 187 audio_playout_map_; // Groups audio by SSRC. 188 std::vector<std::unique_ptr<RtcEventAudioNetworkAdaptation>> 189 ana_configs_list_; 190 std::vector<std::unique_ptr<RtcEventBweUpdateDelayBased>> bwe_delay_list_; 191 std::vector<std::unique_ptr<RtcEventBweUpdateLossBased>> bwe_loss_list_; 192 std::vector<std::unique_ptr<RtcEventDtlsTransportState>> 193 dtls_transport_state_list_; 194 std::vector<std::unique_ptr<RtcEventDtlsWritableState>> 195 dtls_writable_state_list_; 196 std::map<uint32_t, std::vector<std::unique_ptr<RtcEventFrameDecoded>>> 197 frame_decoded_event_map_; 198 std::vector<std::unique_ptr<RtcEventGenericPacketReceived>> 199 generic_packets_received_; 200 std::vector<std::unique_ptr<RtcEventGenericPacketSent>> generic_packets_sent_; 201 std::vector<std::unique_ptr<RtcEventIceCandidatePair>> ice_event_list_; 202 std::vector<std::unique_ptr<RtcEventIceCandidatePairConfig>> ice_config_list_; 203 std::vector<std::unique_ptr<RtcEventProbeClusterCreated>> 204 probe_creation_list_; 205 std::vector<std::unique_ptr<RtcEventProbeResultFailure>> probe_failure_list_; 206 std::vector<std::unique_ptr<RtcEventProbeResultSuccess>> probe_success_list_; 207 std::vector<std::unique_ptr<RtcEventRouteChange>> route_change_list_; 208 std::vector<std::unique_ptr<RtcEventRemoteEstimate>> remote_estimate_list_; 209 std::vector<std::unique_ptr<RtcEventRtcpPacketIncoming>> incoming_rtcp_list_; 210 std::vector<std::unique_ptr<RtcEventRtcpPacketOutgoing>> outgoing_rtcp_list_; 211 std::map<uint32_t, std::vector<std::unique_ptr<RtcEventRtpPacketIncoming>>> 212 incoming_rtp_map_; // Groups incoming RTP by SSRC. 213 std::map<uint32_t, std::vector<std::unique_ptr<RtcEventRtpPacketOutgoing>>> 214 outgoing_rtp_map_; // Groups outgoing RTP by SSRC. 215 216 int64_t start_time_us_; 217 int64_t utc_start_time_us_; 218 int64_t stop_time_us_; 219 220 int64_t first_timestamp_ms_ = std::numeric_limits<int64_t>::max(); 221 int64_t last_timestamp_ms_ = std::numeric_limits<int64_t>::min(); 222 223 const uint64_t seed_; 224 Random prng_; 225 const int64_t output_period_ms_; 226 const RtcEventLog::EncodingType encoding_type_; 227 test::EventGenerator gen_; 228 test::EventVerifier verifier_; 229 ScopedFakeClock clock_; 230 std::string temp_filename_; 231 MemoryLogStorage log_storage_; 232 std::unique_ptr<LogWriterFactoryInterface> log_output_factory_; 233 }; 234 235 bool SsrcUsed( 236 uint32_t ssrc, 237 const std::vector<std::pair<uint32_t, RtpHeaderExtensionMap>>& streams) { 238 for (const auto& kv : streams) { 239 if (kv.first == ssrc) 240 return true; 241 } 242 return false; 243 } 244 245 void RtcEventLogSession::WriteAudioRecvConfigs(size_t audio_recv_streams, 246 RtcEventLog* event_log) { 247 RTC_CHECK(event_log != nullptr); 248 uint32_t ssrc; 249 for (size_t i = 0; i < audio_recv_streams; i++) { 250 clock_.AdvanceTime(TimeDelta::Millis(prng_.Rand(20))); 251 do { 252 ssrc = prng_.Rand<uint32_t>(); 253 } while (SsrcUsed(ssrc, incoming_extensions_)); 254 RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap( 255 /*configure_all=*/false, 256 /*excluded_extensions=*/{RtpDependencyDescriptorExtension::kId}); 257 incoming_extensions_.emplace_back(ssrc, extensions); 258 auto event = gen_.NewAudioReceiveStreamConfig(ssrc, extensions); 259 event_log->Log(event->Copy()); 260 audio_recv_config_list_.push_back(std::move(event)); 261 } 262 } 263 264 void RtcEventLogSession::WriteAudioSendConfigs(size_t audio_send_streams, 265 RtcEventLog* event_log) { 266 RTC_CHECK(event_log != nullptr); 267 uint32_t ssrc; 268 for (size_t i = 0; i < audio_send_streams; i++) { 269 clock_.AdvanceTime(TimeDelta::Millis(prng_.Rand(20))); 270 do { 271 ssrc = prng_.Rand<uint32_t>(); 272 } while (SsrcUsed(ssrc, outgoing_extensions_)); 273 RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap( 274 /*configure_all=*/false, 275 /*excluded_extensions=*/{RtpDependencyDescriptorExtension::kId}); 276 outgoing_extensions_.emplace_back(ssrc, extensions); 277 auto event = gen_.NewAudioSendStreamConfig(ssrc, extensions); 278 event_log->Log(event->Copy()); 279 audio_send_config_list_.push_back(std::move(event)); 280 } 281 } 282 283 void RtcEventLogSession::WriteVideoRecvConfigs(size_t video_recv_streams, 284 RtcEventLog* event_log) { 285 RTC_CHECK(event_log != nullptr); 286 RTC_CHECK_GE(video_recv_streams, 1); 287 288 // Force least one stream to use all header extensions, to ensure 289 // (statistically) that every extension is tested in packet creation. 290 RtpHeaderExtensionMap all_extensions = 291 ParsedRtcEventLog::GetDefaultHeaderExtensionMap(); 292 293 if (std::get<2>(GetParam()) == RtcEventLog::EncodingType::Legacy) { 294 all_extensions.Deregister(RtpDependencyDescriptorExtension::Uri()); 295 } 296 297 clock_.AdvanceTime(TimeDelta::Millis(prng_.Rand(20))); 298 uint32_t ssrc = prng_.Rand<uint32_t>(); 299 incoming_extensions_.emplace_back(ssrc, all_extensions); 300 auto event = gen_.NewVideoReceiveStreamConfig(ssrc, all_extensions); 301 event_log->Log(event->Copy()); 302 video_recv_config_list_.push_back(std::move(event)); 303 for (size_t i = 1; i < video_recv_streams; i++) { 304 clock_.AdvanceTime(TimeDelta::Millis(prng_.Rand(20))); 305 do { 306 ssrc = prng_.Rand<uint32_t>(); 307 } while (SsrcUsed(ssrc, incoming_extensions_)); 308 std::vector<RTPExtensionType> excluded_extensions; 309 if (std::get<2>(GetParam()) == RtcEventLog::EncodingType::Legacy) { 310 excluded_extensions.push_back(RtpDependencyDescriptorExtension::kId); 311 } 312 RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap( 313 /*configure_all=*/false, excluded_extensions); 314 incoming_extensions_.emplace_back(ssrc, extensions); 315 auto new_event = gen_.NewVideoReceiveStreamConfig(ssrc, extensions); 316 event_log->Log(new_event->Copy()); 317 video_recv_config_list_.push_back(std::move(new_event)); 318 } 319 } 320 321 void RtcEventLogSession::WriteVideoSendConfigs(size_t video_send_streams, 322 RtcEventLog* event_log) { 323 RTC_CHECK(event_log != nullptr); 324 RTC_CHECK_GE(video_send_streams, 1); 325 326 // Force least one stream to use all header extensions, to ensure 327 // (statistically) that every extension is tested in packet creation. 328 RtpHeaderExtensionMap all_extensions = 329 ParsedRtcEventLog::GetDefaultHeaderExtensionMap(); 330 331 if (std::get<2>(GetParam()) == RtcEventLog::EncodingType::Legacy) { 332 all_extensions.Deregister(RtpDependencyDescriptorExtension::Uri()); 333 } 334 335 clock_.AdvanceTime(TimeDelta::Millis(prng_.Rand(20))); 336 uint32_t ssrc = prng_.Rand<uint32_t>(); 337 outgoing_extensions_.emplace_back(ssrc, all_extensions); 338 auto first_event = gen_.NewVideoSendStreamConfig(ssrc, all_extensions); 339 event_log->Log(first_event->Copy()); 340 video_send_config_list_.push_back(std::move(first_event)); 341 for (size_t i = 1; i < video_send_streams; i++) { 342 clock_.AdvanceTime(TimeDelta::Millis(prng_.Rand(20))); 343 do { 344 ssrc = prng_.Rand<uint32_t>(); 345 } while (SsrcUsed(ssrc, outgoing_extensions_)); 346 std::vector<RTPExtensionType> excluded_extensions; 347 if (std::get<2>(GetParam()) == RtcEventLog::EncodingType::Legacy) { 348 excluded_extensions.push_back(RtpDependencyDescriptorExtension::kId); 349 } 350 RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap( 351 /*configure_all=*/false, excluded_extensions); 352 outgoing_extensions_.emplace_back(ssrc, extensions); 353 auto event = gen_.NewVideoSendStreamConfig(ssrc, extensions); 354 event_log->Log(event->Copy()); 355 video_send_config_list_.push_back(std::move(event)); 356 } 357 } 358 359 void RtcEventLogSession::WriteLog(EventCounts count, 360 size_t num_events_before_start) { 361 // TODO(terelius): Allow test to run with either a real or a fake clock_ 362 // e.g. by using clock and task_queue_factory from TimeController 363 // when RtcEventLogImpl switches to use injected clock from the environment. 364 365 // The log will be flushed to output when the event_log goes out of scope. 366 std::unique_ptr<RtcEventLog> event_log = RtcEventLogFactory().Create( 367 CreateEnvironment(CreateFieldTrialsFor(encoding_type_))); 368 369 // We can't send or receive packets without configured streams. 370 RTC_CHECK_GE(count.video_recv_streams, 1); 371 RTC_CHECK_GE(count.video_send_streams, 1); 372 373 WriteAudioRecvConfigs(count.audio_recv_streams, event_log.get()); 374 WriteAudioSendConfigs(count.audio_send_streams, event_log.get()); 375 WriteVideoRecvConfigs(count.video_recv_streams, event_log.get()); 376 WriteVideoSendConfigs(count.video_send_streams, event_log.get()); 377 378 size_t remaining_events = count.total_nonconfig_events(); 379 ASSERT_LE(num_events_before_start, remaining_events); 380 size_t remaining_events_at_start = remaining_events - num_events_before_start; 381 for (; remaining_events > 0; remaining_events--) { 382 if (remaining_events == remaining_events_at_start) { 383 clock_.AdvanceTime(TimeDelta::Millis(prng_.Rand(20))); 384 event_log->StartLogging(log_output_factory_->Create(temp_filename_), 385 output_period_ms_); 386 start_time_us_ = TimeMicros(); 387 utc_start_time_us_ = TimeUTCMicros(); 388 } 389 390 clock_.AdvanceTime(TimeDelta::Millis(prng_.Rand(20))); 391 size_t selection = prng_.Rand(remaining_events - 1); 392 first_timestamp_ms_ = std::min(first_timestamp_ms_, TimeMillis()); 393 last_timestamp_ms_ = std::max(last_timestamp_ms_, TimeMillis()); 394 395 if (selection < count.alr_states) { 396 auto event = gen_.NewAlrState(); 397 event_log->Log(event->Copy()); 398 alr_state_list_.push_back(std::move(event)); 399 count.alr_states--; 400 continue; 401 } 402 selection -= count.alr_states; 403 404 if (selection < count.route_changes) { 405 auto event = gen_.NewRouteChange(); 406 event_log->Log(event->Copy()); 407 route_change_list_.push_back(std::move(event)); 408 count.route_changes--; 409 continue; 410 } 411 selection -= count.route_changes; 412 413 if (selection < count.audio_playouts) { 414 size_t stream = prng_.Rand(incoming_extensions_.size() - 1); 415 // This might be a video SSRC, but the parser does not use the config. 416 uint32_t ssrc = incoming_extensions_[stream].first; 417 auto event = gen_.NewAudioPlayout(ssrc); 418 event_log->Log(event->Copy()); 419 audio_playout_map_[ssrc].push_back(std::move(event)); 420 count.audio_playouts--; 421 continue; 422 } 423 selection -= count.audio_playouts; 424 425 if (selection < count.ana_configs) { 426 auto event = gen_.NewAudioNetworkAdaptation(); 427 event_log->Log(event->Copy()); 428 ana_configs_list_.push_back(std::move(event)); 429 count.ana_configs--; 430 continue; 431 } 432 selection -= count.ana_configs; 433 434 if (selection < count.bwe_loss_events) { 435 auto event = gen_.NewBweUpdateLossBased(); 436 event_log->Log(event->Copy()); 437 bwe_loss_list_.push_back(std::move(event)); 438 count.bwe_loss_events--; 439 continue; 440 } 441 selection -= count.bwe_loss_events; 442 443 if (selection < count.bwe_delay_events) { 444 auto event = gen_.NewBweUpdateDelayBased(); 445 event_log->Log(event->Copy()); 446 bwe_delay_list_.push_back(std::move(event)); 447 count.bwe_delay_events--; 448 continue; 449 } 450 selection -= count.bwe_delay_events; 451 452 if (selection < count.probe_creations) { 453 auto event = gen_.NewProbeClusterCreated(); 454 event_log->Log(event->Copy()); 455 probe_creation_list_.push_back(std::move(event)); 456 count.probe_creations--; 457 continue; 458 } 459 selection -= count.probe_creations; 460 461 if (selection < count.probe_successes) { 462 auto event = gen_.NewProbeResultSuccess(); 463 event_log->Log(event->Copy()); 464 probe_success_list_.push_back(std::move(event)); 465 count.probe_successes--; 466 continue; 467 } 468 selection -= count.probe_successes; 469 470 if (selection < count.probe_failures) { 471 auto event = gen_.NewProbeResultFailure(); 472 event_log->Log(event->Copy()); 473 probe_failure_list_.push_back(std::move(event)); 474 count.probe_failures--; 475 continue; 476 } 477 selection -= count.probe_failures; 478 479 if (selection < count.dtls_transport_states) { 480 auto event = gen_.NewDtlsTransportState(); 481 event_log->Log(event->Copy()); 482 dtls_transport_state_list_.push_back(std::move(event)); 483 count.dtls_transport_states--; 484 continue; 485 } 486 selection -= count.dtls_transport_states; 487 488 if (selection < count.dtls_writable_states) { 489 auto event = gen_.NewDtlsWritableState(); 490 event_log->Log(event->Copy()); 491 dtls_writable_state_list_.push_back(std::move(event)); 492 count.dtls_writable_states--; 493 continue; 494 } 495 selection -= count.dtls_writable_states; 496 497 if (selection < count.frame_decoded_events) { 498 size_t stream = prng_.Rand(incoming_extensions_.size() - 1); 499 // This might be an audio SSRC, but that won't affect the parser. 500 uint32_t ssrc = incoming_extensions_[stream].first; 501 auto event = gen_.NewFrameDecodedEvent(ssrc); 502 event_log->Log(event->Copy()); 503 frame_decoded_event_map_[ssrc].push_back(std::move(event)); 504 count.frame_decoded_events--; 505 continue; 506 } 507 selection -= count.frame_decoded_events; 508 509 if (selection < count.ice_configs) { 510 auto event = gen_.NewIceCandidatePairConfig(); 511 event_log->Log(event->Copy()); 512 ice_config_list_.push_back(std::move(event)); 513 count.ice_configs--; 514 continue; 515 } 516 selection -= count.ice_configs; 517 518 if (selection < count.ice_events) { 519 auto event = gen_.NewIceCandidatePair(); 520 event_log->Log(event->Copy()); 521 ice_event_list_.push_back(std::move(event)); 522 count.ice_events--; 523 continue; 524 } 525 selection -= count.ice_events; 526 527 if (selection < count.incoming_rtp_packets) { 528 size_t stream = prng_.Rand(incoming_extensions_.size() - 1); 529 uint32_t ssrc = incoming_extensions_[stream].first; 530 auto event = 531 gen_.NewRtpPacketIncoming(ssrc, incoming_extensions_[stream].second); 532 event_log->Log(event->Copy()); 533 incoming_rtp_map_[ssrc].push_back(std::move(event)); 534 count.incoming_rtp_packets--; 535 continue; 536 } 537 selection -= count.incoming_rtp_packets; 538 539 if (selection < count.outgoing_rtp_packets) { 540 size_t stream = prng_.Rand(outgoing_extensions_.size() - 1); 541 uint32_t ssrc = outgoing_extensions_[stream].first; 542 auto event = 543 gen_.NewRtpPacketOutgoing(ssrc, outgoing_extensions_[stream].second); 544 event_log->Log(event->Copy()); 545 outgoing_rtp_map_[ssrc].push_back(std::move(event)); 546 count.outgoing_rtp_packets--; 547 continue; 548 } 549 selection -= count.outgoing_rtp_packets; 550 551 if (selection < count.incoming_rtcp_packets) { 552 auto event = gen_.NewRtcpPacketIncoming(); 553 event_log->Log(event->Copy()); 554 incoming_rtcp_list_.push_back(std::move(event)); 555 count.incoming_rtcp_packets--; 556 continue; 557 } 558 selection -= count.incoming_rtcp_packets; 559 560 if (selection < count.outgoing_rtcp_packets) { 561 auto event = gen_.NewRtcpPacketOutgoing(); 562 event_log->Log(event->Copy()); 563 outgoing_rtcp_list_.push_back(std::move(event)); 564 count.outgoing_rtcp_packets--; 565 continue; 566 } 567 selection -= count.outgoing_rtcp_packets; 568 569 if (selection < count.generic_packets_sent) { 570 auto event = gen_.NewGenericPacketSent(); 571 generic_packets_sent_.push_back(event->Copy()); 572 event_log->Log(std::move(event)); 573 count.generic_packets_sent--; 574 continue; 575 } 576 selection -= count.generic_packets_sent; 577 578 if (selection < count.generic_packets_received) { 579 auto event = gen_.NewGenericPacketReceived(); 580 generic_packets_received_.push_back(event->Copy()); 581 event_log->Log(std::move(event)); 582 count.generic_packets_received--; 583 continue; 584 } 585 selection -= count.generic_packets_received; 586 587 RTC_DCHECK_NOTREACHED(); 588 } 589 590 event_log->StopLogging(); 591 stop_time_us_ = TimeMicros(); 592 593 ASSERT_EQ(count.total_nonconfig_events(), static_cast<size_t>(0)); 594 } 595 596 // Read the log and verify that what we read back from the event log is the 597 // same as what we wrote down. 598 void RtcEventLogSession::ReadAndVerifyLog() { 599 // Read the generated log from memory. 600 ParsedRtcEventLog parsed_log; 601 auto it = log_storage_.logs().find(temp_filename_); 602 ASSERT_TRUE(it != log_storage_.logs().end()); 603 ASSERT_TRUE(parsed_log.ParseString(it->second).ok()); 604 605 // Start and stop events. 606 auto& parsed_start_log_events = parsed_log.start_log_events(); 607 ASSERT_EQ(parsed_start_log_events.size(), static_cast<size_t>(1)); 608 verifier_.VerifyLoggedStartEvent(start_time_us_, utc_start_time_us_, 609 parsed_start_log_events[0]); 610 611 auto& parsed_stop_log_events = parsed_log.stop_log_events(); 612 ASSERT_EQ(parsed_stop_log_events.size(), static_cast<size_t>(1)); 613 verifier_.VerifyLoggedStopEvent(stop_time_us_, parsed_stop_log_events[0]); 614 615 auto& parsed_alr_state_events = parsed_log.alr_state_events(); 616 ASSERT_EQ(parsed_alr_state_events.size(), alr_state_list_.size()); 617 for (size_t i = 0; i < parsed_alr_state_events.size(); i++) { 618 verifier_.VerifyLoggedAlrStateEvent(*alr_state_list_[i], 619 parsed_alr_state_events[i]); 620 } 621 auto& parsed_route_change_events = parsed_log.route_change_events(); 622 ASSERT_EQ(parsed_route_change_events.size(), route_change_list_.size()); 623 for (size_t i = 0; i < parsed_route_change_events.size(); i++) { 624 verifier_.VerifyLoggedRouteChangeEvent(*route_change_list_[i], 625 parsed_route_change_events[i]); 626 } 627 628 const auto& parsed_audio_playout_map = parsed_log.audio_playout_events(); 629 ASSERT_EQ(parsed_audio_playout_map.size(), audio_playout_map_.size()); 630 for (const auto& kv : parsed_audio_playout_map) { 631 uint32_t ssrc = kv.first; 632 const auto& parsed_audio_playout_stream = kv.second; 633 const auto& audio_playout_stream = audio_playout_map_[ssrc]; 634 ASSERT_EQ(parsed_audio_playout_stream.size(), audio_playout_stream.size()); 635 for (size_t i = 0; i < audio_playout_stream.size(); i++) { 636 verifier_.VerifyLoggedAudioPlayoutEvent(*audio_playout_stream[i], 637 parsed_audio_playout_stream[i]); 638 } 639 } 640 641 auto& parsed_audio_network_adaptation_events = 642 parsed_log.audio_network_adaptation_events(); 643 ASSERT_EQ(parsed_audio_network_adaptation_events.size(), 644 ana_configs_list_.size()); 645 for (size_t i = 0; i < parsed_audio_network_adaptation_events.size(); i++) { 646 verifier_.VerifyLoggedAudioNetworkAdaptationEvent( 647 *ana_configs_list_[i], parsed_audio_network_adaptation_events[i]); 648 } 649 650 auto& parsed_bwe_delay_updates = parsed_log.bwe_delay_updates(); 651 ASSERT_EQ(parsed_bwe_delay_updates.size(), bwe_delay_list_.size()); 652 for (size_t i = 0; i < parsed_bwe_delay_updates.size(); i++) { 653 verifier_.VerifyLoggedBweDelayBasedUpdate(*bwe_delay_list_[i], 654 parsed_bwe_delay_updates[i]); 655 } 656 657 auto& parsed_bwe_loss_updates = parsed_log.bwe_loss_updates(); 658 ASSERT_EQ(parsed_bwe_loss_updates.size(), bwe_loss_list_.size()); 659 for (size_t i = 0; i < parsed_bwe_loss_updates.size(); i++) { 660 verifier_.VerifyLoggedBweLossBasedUpdate(*bwe_loss_list_[i], 661 parsed_bwe_loss_updates[i]); 662 } 663 664 auto& parsed_bwe_probe_cluster_created_events = 665 parsed_log.bwe_probe_cluster_created_events(); 666 ASSERT_EQ(parsed_bwe_probe_cluster_created_events.size(), 667 probe_creation_list_.size()); 668 for (size_t i = 0; i < parsed_bwe_probe_cluster_created_events.size(); i++) { 669 verifier_.VerifyLoggedBweProbeClusterCreatedEvent( 670 *probe_creation_list_[i], parsed_bwe_probe_cluster_created_events[i]); 671 } 672 673 auto& parsed_bwe_probe_failure_events = parsed_log.bwe_probe_failure_events(); 674 ASSERT_EQ(parsed_bwe_probe_failure_events.size(), probe_failure_list_.size()); 675 for (size_t i = 0; i < parsed_bwe_probe_failure_events.size(); i++) { 676 verifier_.VerifyLoggedBweProbeFailureEvent( 677 *probe_failure_list_[i], parsed_bwe_probe_failure_events[i]); 678 } 679 680 auto& parsed_bwe_probe_success_events = parsed_log.bwe_probe_success_events(); 681 ASSERT_EQ(parsed_bwe_probe_success_events.size(), probe_success_list_.size()); 682 for (size_t i = 0; i < parsed_bwe_probe_success_events.size(); i++) { 683 verifier_.VerifyLoggedBweProbeSuccessEvent( 684 *probe_success_list_[i], parsed_bwe_probe_success_events[i]); 685 } 686 687 auto& parsed_dtls_transport_states = parsed_log.dtls_transport_states(); 688 ASSERT_EQ(parsed_dtls_transport_states.size(), 689 dtls_transport_state_list_.size()); 690 for (size_t i = 0; i < parsed_dtls_transport_states.size(); i++) { 691 verifier_.VerifyLoggedDtlsTransportState(*dtls_transport_state_list_[i], 692 parsed_dtls_transport_states[i]); 693 } 694 695 auto& parsed_dtls_writable_states = parsed_log.dtls_writable_states(); 696 ASSERT_EQ(parsed_dtls_writable_states.size(), 697 dtls_writable_state_list_.size()); 698 for (size_t i = 0; i < parsed_dtls_writable_states.size(); i++) { 699 verifier_.VerifyLoggedDtlsWritableState(*dtls_writable_state_list_[i], 700 parsed_dtls_writable_states[i]); 701 } 702 703 const auto& parsed_frame_decoded_map = parsed_log.decoded_frames(); 704 ASSERT_EQ(parsed_frame_decoded_map.size(), frame_decoded_event_map_.size()); 705 for (const auto& kv : parsed_frame_decoded_map) { 706 uint32_t ssrc = kv.first; 707 const auto& parsed_decoded_frames = kv.second; 708 const auto& decoded_frames = frame_decoded_event_map_[ssrc]; 709 ASSERT_EQ(parsed_decoded_frames.size(), decoded_frames.size()); 710 for (size_t i = 0; i < decoded_frames.size(); i++) { 711 verifier_.VerifyLoggedFrameDecoded(*decoded_frames[i], 712 parsed_decoded_frames[i]); 713 } 714 } 715 716 auto& parsed_ice_candidate_pair_configs = 717 parsed_log.ice_candidate_pair_configs(); 718 ASSERT_EQ(parsed_ice_candidate_pair_configs.size(), ice_config_list_.size()); 719 for (size_t i = 0; i < parsed_ice_candidate_pair_configs.size(); i++) { 720 verifier_.VerifyLoggedIceCandidatePairConfig( 721 *ice_config_list_[i], parsed_ice_candidate_pair_configs[i]); 722 } 723 724 auto& parsed_ice_candidate_pair_events = 725 parsed_log.ice_candidate_pair_events(); 726 ASSERT_EQ(parsed_ice_candidate_pair_events.size(), 727 parsed_ice_candidate_pair_events.size()); 728 for (size_t i = 0; i < parsed_ice_candidate_pair_events.size(); i++) { 729 verifier_.VerifyLoggedIceCandidatePairEvent( 730 *ice_event_list_[i], parsed_ice_candidate_pair_events[i]); 731 } 732 733 auto& parsed_incoming_rtp_packets_by_ssrc = 734 parsed_log.incoming_rtp_packets_by_ssrc(); 735 ASSERT_EQ(parsed_incoming_rtp_packets_by_ssrc.size(), 736 incoming_rtp_map_.size()); 737 for (const auto& kv : parsed_incoming_rtp_packets_by_ssrc) { 738 uint32_t ssrc = kv.ssrc; 739 const auto& parsed_rtp_stream = kv.incoming_packets; 740 const auto& rtp_stream = incoming_rtp_map_[ssrc]; 741 ASSERT_EQ(parsed_rtp_stream.size(), rtp_stream.size()); 742 for (size_t i = 0; i < parsed_rtp_stream.size(); i++) { 743 verifier_.VerifyLoggedRtpPacketIncoming(*rtp_stream[i], 744 parsed_rtp_stream[i]); 745 } 746 } 747 748 auto& parsed_outgoing_rtp_packets_by_ssrc = 749 parsed_log.outgoing_rtp_packets_by_ssrc(); 750 ASSERT_EQ(parsed_outgoing_rtp_packets_by_ssrc.size(), 751 outgoing_rtp_map_.size()); 752 for (const auto& kv : parsed_outgoing_rtp_packets_by_ssrc) { 753 uint32_t ssrc = kv.ssrc; 754 const auto& parsed_rtp_stream = kv.outgoing_packets; 755 const auto& rtp_stream = outgoing_rtp_map_[ssrc]; 756 ASSERT_EQ(parsed_rtp_stream.size(), rtp_stream.size()); 757 for (size_t i = 0; i < parsed_rtp_stream.size(); i++) { 758 verifier_.VerifyLoggedRtpPacketOutgoing(*rtp_stream[i], 759 parsed_rtp_stream[i]); 760 } 761 } 762 763 auto& parsed_incoming_rtcp_packets = parsed_log.incoming_rtcp_packets(); 764 ASSERT_EQ(parsed_incoming_rtcp_packets.size(), incoming_rtcp_list_.size()); 765 for (size_t i = 0; i < parsed_incoming_rtcp_packets.size(); i++) { 766 verifier_.VerifyLoggedRtcpPacketIncoming(*incoming_rtcp_list_[i], 767 parsed_incoming_rtcp_packets[i]); 768 } 769 770 auto& parsed_outgoing_rtcp_packets = parsed_log.outgoing_rtcp_packets(); 771 ASSERT_EQ(parsed_outgoing_rtcp_packets.size(), outgoing_rtcp_list_.size()); 772 for (size_t i = 0; i < parsed_outgoing_rtcp_packets.size(); i++) { 773 verifier_.VerifyLoggedRtcpPacketOutgoing(*outgoing_rtcp_list_[i], 774 parsed_outgoing_rtcp_packets[i]); 775 } 776 auto& parsed_audio_recv_configs = parsed_log.audio_recv_configs(); 777 ASSERT_EQ(parsed_audio_recv_configs.size(), audio_recv_config_list_.size()); 778 for (size_t i = 0; i < parsed_audio_recv_configs.size(); i++) { 779 verifier_.VerifyLoggedAudioRecvConfig(*audio_recv_config_list_[i], 780 parsed_audio_recv_configs[i]); 781 } 782 auto& parsed_audio_send_configs = parsed_log.audio_send_configs(); 783 ASSERT_EQ(parsed_audio_send_configs.size(), audio_send_config_list_.size()); 784 for (size_t i = 0; i < parsed_audio_send_configs.size(); i++) { 785 verifier_.VerifyLoggedAudioSendConfig(*audio_send_config_list_[i], 786 parsed_audio_send_configs[i]); 787 } 788 auto& parsed_video_recv_configs = parsed_log.video_recv_configs(); 789 ASSERT_EQ(parsed_video_recv_configs.size(), video_recv_config_list_.size()); 790 for (size_t i = 0; i < parsed_video_recv_configs.size(); i++) { 791 verifier_.VerifyLoggedVideoRecvConfig(*video_recv_config_list_[i], 792 parsed_video_recv_configs[i]); 793 } 794 auto& parsed_video_send_configs = parsed_log.video_send_configs(); 795 ASSERT_EQ(parsed_video_send_configs.size(), video_send_config_list_.size()); 796 for (size_t i = 0; i < parsed_video_send_configs.size(); i++) { 797 verifier_.VerifyLoggedVideoSendConfig(*video_send_config_list_[i], 798 parsed_video_send_configs[i]); 799 } 800 801 auto& parsed_generic_packets_received = parsed_log.generic_packets_received(); 802 ASSERT_EQ(parsed_generic_packets_received.size(), 803 generic_packets_received_.size()); 804 for (size_t i = 0; i < parsed_generic_packets_received.size(); i++) { 805 verifier_.VerifyLoggedGenericPacketReceived( 806 *generic_packets_received_[i], parsed_generic_packets_received[i]); 807 } 808 809 auto& parsed_generic_packets_sent = parsed_log.generic_packets_sent(); 810 ASSERT_EQ(parsed_generic_packets_sent.size(), generic_packets_sent_.size()); 811 for (size_t i = 0; i < parsed_generic_packets_sent.size(); i++) { 812 verifier_.VerifyLoggedGenericPacketSent(*generic_packets_sent_[i], 813 parsed_generic_packets_sent[i]); 814 } 815 816 EXPECT_EQ(first_timestamp_ms_, parsed_log.first_timestamp().ms()); 817 EXPECT_EQ(last_timestamp_ms_, parsed_log.last_timestamp().ms()); 818 819 EXPECT_EQ(parsed_log.first_log_segment().start_time_ms(), 820 std::min(start_time_us_ / 1000, first_timestamp_ms_)); 821 EXPECT_EQ(parsed_log.first_log_segment().stop_time_ms(), 822 stop_time_us_ / 1000); 823 } 824 825 } // namespace 826 827 TEST_P(RtcEventLogSession, StartLoggingFromBeginning) { 828 EventCounts count; 829 count.audio_send_streams = 2; 830 count.audio_recv_streams = 2; 831 count.video_send_streams = 3; 832 count.video_recv_streams = 4; 833 count.alr_states = 4; 834 count.audio_playouts = 100; 835 count.ana_configs = 3; 836 count.bwe_loss_events = 20; 837 count.bwe_delay_events = 20; 838 count.probe_creations = 4; 839 count.probe_successes = 2; 840 count.probe_failures = 2; 841 count.ice_configs = 3; 842 count.ice_events = 10; 843 count.incoming_rtp_packets = 100; 844 count.outgoing_rtp_packets = 100; 845 count.incoming_rtcp_packets = 20; 846 count.outgoing_rtcp_packets = 20; 847 if (IsNewFormat()) { 848 count.dtls_transport_states = 4; 849 count.dtls_writable_states = 2; 850 count.frame_decoded_events = 50; 851 count.generic_packets_sent = 100; 852 count.generic_packets_received = 100; 853 count.route_changes = 4; 854 } 855 856 WriteLog(count, 0); 857 ReadAndVerifyLog(); 858 } 859 860 TEST_P(RtcEventLogSession, StartLoggingInTheMiddle) { 861 EventCounts count; 862 count.audio_send_streams = 3; 863 count.audio_recv_streams = 4; 864 count.video_send_streams = 5; 865 count.video_recv_streams = 6; 866 count.alr_states = 10; 867 count.audio_playouts = 500; 868 count.ana_configs = 10; 869 count.bwe_loss_events = 50; 870 count.bwe_delay_events = 50; 871 count.probe_creations = 10; 872 count.probe_successes = 5; 873 count.probe_failures = 5; 874 count.ice_configs = 10; 875 count.ice_events = 20; 876 count.incoming_rtp_packets = 500; 877 count.outgoing_rtp_packets = 500; 878 count.incoming_rtcp_packets = 50; 879 count.outgoing_rtcp_packets = 50; 880 if (IsNewFormat()) { 881 count.dtls_transport_states = 4; 882 count.dtls_writable_states = 5; 883 count.frame_decoded_events = 250; 884 count.generic_packets_sent = 500; 885 count.generic_packets_received = 500; 886 count.route_changes = 10; 887 } 888 889 WriteLog(count, 500); 890 ReadAndVerifyLog(); 891 } 892 893 INSTANTIATE_TEST_SUITE_P( 894 RtcEventLogTest, 895 RtcEventLogSession, 896 ::testing::Combine( 897 ::testing::Values(1234567, 7654321), 898 ::testing::Values(RtcEventLog::kImmediateOutput, 1, 5), 899 ::testing::Values(RtcEventLog::EncodingType::Legacy, 900 RtcEventLog::EncodingType::NewFormat))); 901 902 class RtcEventLogCircularBufferTest 903 : public ::testing::TestWithParam<RtcEventLog::EncodingType> { 904 public: 905 RtcEventLogCircularBufferTest() 906 : encoding_type_(GetParam()), 907 verifier_(encoding_type_), 908 log_storage_(), 909 log_output_factory_(log_storage_.CreateFactory()) {} 910 const RtcEventLog::EncodingType encoding_type_; 911 const test::EventVerifier verifier_; 912 MemoryLogStorage log_storage_; 913 std::unique_ptr<LogWriterFactoryInterface> log_output_factory_; 914 }; 915 916 TEST_P(RtcEventLogCircularBufferTest, KeepsMostRecentEvents) { 917 // TODO(terelius): Maybe make a separate RtcEventLogImplTest that can access 918 // the size of the cyclic buffer? 919 constexpr size_t kNumEvents = 20000; 920 constexpr int64_t kStartTimeSeconds = 1; 921 constexpr int32_t kStartBitrate = 1000000; 922 923 auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); 924 std::string test_name = 925 std::string(test_info->test_case_name()) + "_" + test_info->name(); 926 std::replace(test_name.begin(), test_name.end(), '/', '_'); 927 const std::string temp_filename = test::OutputPath() + test_name; 928 929 std::unique_ptr<ScopedFakeClock> fake_clock = 930 std::make_unique<ScopedFakeClock>(); 931 fake_clock->SetTime(Timestamp::Seconds(kStartTimeSeconds)); 932 933 // Create a scope for the TQ and event log factories. 934 // This way, we make sure that task queue instances that may rely on a clock 935 // have been torn down before we run the verification steps at the end of 936 // the test. 937 int64_t start_time_us, utc_start_time_us, stop_time_us; 938 939 { 940 // When `log` goes out of scope, the contents are flushed to the output. 941 std::unique_ptr<RtcEventLog> log = RtcEventLogFactory().Create( 942 CreateEnvironment(CreateFieldTrialsFor(encoding_type_))); 943 944 for (size_t i = 0; i < kNumEvents; i++) { 945 // The purpose of the test is to verify that the log can handle 946 // more events than what fits in the internal circular buffer. The exact 947 // type of events does not matter so we chose ProbeSuccess events for 948 // simplicity. 949 // We base the various values on the index. We use this for some basic 950 // consistency checks when we read back. 951 log->Log(std::make_unique<RtcEventProbeResultSuccess>( 952 i, kStartBitrate + i * 1000)); 953 fake_clock->AdvanceTime(TimeDelta::Millis(10)); 954 } 955 start_time_us = TimeMicros(); 956 utc_start_time_us = TimeUTCMicros(); 957 log->StartLogging(log_output_factory_->Create(temp_filename), 958 RtcEventLog::kImmediateOutput); 959 fake_clock->AdvanceTime(TimeDelta::Millis(10)); 960 stop_time_us = TimeMicros(); 961 log->StopLogging(); 962 } 963 964 // Read the generated log from memory. 965 ParsedRtcEventLog parsed_log; 966 auto it = log_storage_.logs().find(temp_filename); 967 ASSERT_TRUE(it != log_storage_.logs().end()); 968 ASSERT_TRUE(parsed_log.ParseString(it->second).ok()); 969 970 const auto& start_log_events = parsed_log.start_log_events(); 971 ASSERT_EQ(start_log_events.size(), 1u); 972 verifier_.VerifyLoggedStartEvent(start_time_us, utc_start_time_us, 973 start_log_events[0]); 974 975 const auto& stop_log_events = parsed_log.stop_log_events(); 976 ASSERT_EQ(stop_log_events.size(), 1u); 977 verifier_.VerifyLoggedStopEvent(stop_time_us, stop_log_events[0]); 978 979 const auto& probe_success_events = parsed_log.bwe_probe_success_events(); 980 // If the following fails, it probably means that kNumEvents isn't larger 981 // than the size of the cyclic buffer in the event log. Try increasing 982 // kNumEvents. 983 EXPECT_LT(probe_success_events.size(), kNumEvents); 984 985 ASSERT_GT(probe_success_events.size(), 1u); 986 int64_t first_timestamp_ms = probe_success_events[0].timestamp.ms(); 987 uint32_t first_id = probe_success_events[0].id; 988 int32_t first_bitrate_bps = probe_success_events[0].bitrate_bps; 989 // We want to reset the time to what we used when generating the events, but 990 // the fake clock implementation DCHECKS if time moves backwards. We therefore 991 // recreate the clock. However we must ensure that the old fake_clock is 992 // destroyed before the new one is created, so we have to reset() first. 993 fake_clock.reset(); 994 fake_clock = std::make_unique<ScopedFakeClock>(); 995 fake_clock->SetTime(Timestamp::Millis(first_timestamp_ms)); 996 for (size_t i = 1; i < probe_success_events.size(); i++) { 997 fake_clock->AdvanceTime(TimeDelta::Millis(10)); 998 verifier_.VerifyLoggedBweProbeSuccessEvent( 999 RtcEventProbeResultSuccess(first_id + i, first_bitrate_bps + i * 1000), 1000 probe_success_events[i]); 1001 } 1002 } 1003 1004 INSTANTIATE_TEST_SUITE_P( 1005 RtcEventLogTest, 1006 RtcEventLogCircularBufferTest, 1007 ::testing::Values(RtcEventLog::EncodingType::Legacy, 1008 RtcEventLog::EncodingType::NewFormat)); 1009 1010 // TODO(terelius): Verify parser behavior if the timestamps are not 1011 // monotonically increasing in the log. 1012 1013 TEST(DereferencingVectorTest, NonConstVector) { 1014 std::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 1015 DereferencingVector<int> even; 1016 EXPECT_TRUE(even.empty()); 1017 EXPECT_EQ(even.size(), 0u); 1018 EXPECT_EQ(even.begin(), even.end()); 1019 for (size_t i = 0; i < v.size(); i += 2) { 1020 even.push_back(&v[i]); 1021 } 1022 EXPECT_FALSE(even.empty()); 1023 EXPECT_EQ(even.size(), 5u); 1024 EXPECT_NE(even.begin(), even.end()); 1025 1026 // Test direct access. 1027 for (size_t i = 0; i < even.size(); i++) { 1028 EXPECT_EQ(even[i], 2 * static_cast<int>(i)); 1029 } 1030 1031 // Test iterator. 1032 for (int val : even) { 1033 EXPECT_EQ(val % 2, 0); 1034 } 1035 1036 // Test modification through iterator. 1037 for (int& val : even) { 1038 val = val * 2; 1039 EXPECT_EQ(val % 2, 0); 1040 } 1041 1042 // Backing vector should have been modified. 1043 std::vector<int> expected{0, 1, 4, 3, 8, 5, 12, 7, 16, 9}; 1044 for (size_t i = 0; i < v.size(); i++) { 1045 EXPECT_EQ(v[i], expected[i]); 1046 } 1047 } 1048 1049 TEST(DereferencingVectorTest, ConstVector) { 1050 std::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 1051 DereferencingVector<const int> odd; 1052 EXPECT_TRUE(odd.empty()); 1053 EXPECT_EQ(odd.size(), 0u); 1054 EXPECT_EQ(odd.begin(), odd.end()); 1055 for (size_t i = 1; i < v.size(); i += 2) { 1056 odd.push_back(&v[i]); 1057 } 1058 EXPECT_FALSE(odd.empty()); 1059 EXPECT_EQ(odd.size(), 5u); 1060 EXPECT_NE(odd.begin(), odd.end()); 1061 1062 // Test direct access. 1063 for (size_t i = 0; i < odd.size(); i++) { 1064 EXPECT_EQ(odd[i], 2 * static_cast<int>(i) + 1); 1065 } 1066 1067 // Test iterator. 1068 for (int val : odd) { 1069 EXPECT_EQ(val % 2, 1); 1070 } 1071 } 1072 1073 } // namespace webrtc