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