1 /*
2 * Copyright (c) 2017 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 <deque>
12 #include <limits>
13 #include <memory>
14 #include <string>
15 #include <tuple>
16
17 #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.h"
18 #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.h"
19 #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_v3.h"
20 #include "logging/rtc_event_log/events/rtc_event_alr_state.h"
21 #include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
22 #include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
23 #include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h"
24 #include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
25 #include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
26 #include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
27 #include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
28 #include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
29 #include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
30 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h"
31 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h"
32 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
33 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h"
34 #include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h"
35 #include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h"
36 #include "logging/rtc_event_log/rtc_event_log_parser.h"
37 #include "logging/rtc_event_log/rtc_event_log_unittest_helper.h"
38 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
39 #include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
40 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
41 #include "rtc_base/fake_clock.h"
42 #include "rtc_base/random.h"
43 #include "test/gtest.h"
44
45 namespace webrtc {
46 class RtcEventLogEncoderTest
47 : public ::testing::TestWithParam<
48 std::tuple<int, RtcEventLog::EncodingType, size_t, bool>> {
49 protected:
RtcEventLogEncoderTest()50 RtcEventLogEncoderTest()
51 : seed_(std::get<0>(GetParam())),
52 prng_(seed_),
53 encoding_type_(std::get<1>(GetParam())),
54 event_count_(std::get<2>(GetParam())),
55 force_repeated_fields_(std::get<3>(GetParam())),
56 gen_(seed_ * 880001UL),
57 verifier_(encoding_type_) {
58 switch (encoding_type_) {
59 case RtcEventLog::EncodingType::Legacy:
60 encoder_ = std::make_unique<RtcEventLogEncoderLegacy>();
61 break;
62 case RtcEventLog::EncodingType::NewFormat:
63 encoder_ = std::make_unique<RtcEventLogEncoderNewFormat>();
64 break;
65 case RtcEventLog::EncodingType::ProtoFree:
66 encoder_ = std::make_unique<RtcEventLogEncoderV3>();
67 break;
68 }
69 encoded_ =
70 encoder_->EncodeLogStart(rtc::TimeMillis(), rtc::TimeUTCMillis());
71 }
72 ~RtcEventLogEncoderTest() override = default;
73
74 // ANA events have some optional fields, so we want to make sure that we get
75 // correct behavior both when all of the values are there, as well as when
76 // only some.
77 void TestRtcEventAudioNetworkAdaptation(
78 const std::vector<std::unique_ptr<RtcEventAudioNetworkAdaptation>>&);
79
80 template <typename EventType>
81 std::unique_ptr<EventType> NewRtpPacket(
82 uint32_t ssrc,
83 const RtpHeaderExtensionMap& extension_map);
84
85 template <typename ParsedType>
86 const std::vector<ParsedType>* GetRtpPacketsBySsrc(
87 const ParsedRtcEventLog* parsed_log,
88 uint32_t ssrc);
89
90 template <typename EventType, typename ParsedType>
91 void TestRtpPackets();
92
93 std::deque<std::unique_ptr<RtcEvent>> history_;
94 std::unique_ptr<RtcEventLogEncoder> encoder_;
95 ParsedRtcEventLog parsed_log_;
96 const uint64_t seed_;
97 Random prng_;
98 const RtcEventLog::EncodingType encoding_type_;
99 const size_t event_count_;
100 const bool force_repeated_fields_;
101 test::EventGenerator gen_;
102 test::EventVerifier verifier_;
103 std::string encoded_;
104 };
105
TestRtcEventAudioNetworkAdaptation(const std::vector<std::unique_ptr<RtcEventAudioNetworkAdaptation>> & events)106 void RtcEventLogEncoderTest::TestRtcEventAudioNetworkAdaptation(
107 const std::vector<std::unique_ptr<RtcEventAudioNetworkAdaptation>>&
108 events) {
109 ASSERT_TRUE(history_.empty()) << "Function should be called once per test.";
110
111 for (auto& event : events) {
112 history_.push_back(event->Copy());
113 }
114
115 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
116 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
117 const auto& ana_configs = parsed_log_.audio_network_adaptation_events();
118
119 ASSERT_EQ(ana_configs.size(), events.size());
120 for (size_t i = 0; i < events.size(); ++i) {
121 verifier_.VerifyLoggedAudioNetworkAdaptationEvent(*events[i],
122 ana_configs[i]);
123 }
124 }
125
126 template <>
NewRtpPacket(uint32_t ssrc,const RtpHeaderExtensionMap & extension_map)127 std::unique_ptr<RtcEventRtpPacketIncoming> RtcEventLogEncoderTest::NewRtpPacket(
128 uint32_t ssrc,
129 const RtpHeaderExtensionMap& extension_map) {
130 return gen_.NewRtpPacketIncoming(ssrc, extension_map, false);
131 }
132
133 template <>
NewRtpPacket(uint32_t ssrc,const RtpHeaderExtensionMap & extension_map)134 std::unique_ptr<RtcEventRtpPacketOutgoing> RtcEventLogEncoderTest::NewRtpPacket(
135 uint32_t ssrc,
136 const RtpHeaderExtensionMap& extension_map) {
137 return gen_.NewRtpPacketOutgoing(ssrc, extension_map, false);
138 }
139
140 template <>
141 const std::vector<LoggedRtpPacketIncoming>*
GetRtpPacketsBySsrc(const ParsedRtcEventLog * parsed_log,uint32_t ssrc)142 RtcEventLogEncoderTest::GetRtpPacketsBySsrc(const ParsedRtcEventLog* parsed_log,
143 uint32_t ssrc) {
144 const auto& incoming_streams = parsed_log->incoming_rtp_packets_by_ssrc();
145 for (const auto& stream : incoming_streams) {
146 if (stream.ssrc == ssrc) {
147 return &stream.incoming_packets;
148 }
149 }
150 return nullptr;
151 }
152
153 template <>
154 const std::vector<LoggedRtpPacketOutgoing>*
GetRtpPacketsBySsrc(const ParsedRtcEventLog * parsed_log,uint32_t ssrc)155 RtcEventLogEncoderTest::GetRtpPacketsBySsrc(const ParsedRtcEventLog* parsed_log,
156 uint32_t ssrc) {
157 const auto& outgoing_streams = parsed_log->outgoing_rtp_packets_by_ssrc();
158 for (const auto& stream : outgoing_streams) {
159 if (stream.ssrc == ssrc) {
160 return &stream.outgoing_packets;
161 }
162 }
163 return nullptr;
164 }
165
166 template <typename EventType, typename ParsedType>
TestRtpPackets()167 void RtcEventLogEncoderTest::TestRtpPackets() {
168 // SSRCs will be randomly assigned out of this small pool, significant only
169 // in that it also covers such edge cases as SSRC = 0 and SSRC = 0xffffffff.
170 // The pool is intentionally small, so as to produce collisions.
171 const std::vector<uint32_t> kSsrcPool = {0x00000000, 0x12345678, 0xabcdef01,
172 0xffffffff, 0x20171024, 0x19840730,
173 0x19831230};
174
175 // TODO(terelius): Test extensions for legacy encoding, too.
176 RtpHeaderExtensionMap extension_map;
177 if (encoding_type_ != RtcEventLog::EncodingType::Legacy) {
178 extension_map = gen_.NewRtpHeaderExtensionMap(true);
179 }
180
181 // Simulate `event_count_` RTP packets, with SSRCs assigned randomly
182 // out of the small pool above.
183 std::map<uint32_t, std::vector<std::unique_ptr<EventType>>> events_by_ssrc;
184 for (size_t i = 0; i < event_count_; ++i) {
185 const uint32_t ssrc = kSsrcPool[prng_.Rand(kSsrcPool.size() - 1)];
186 std::unique_ptr<EventType> event =
187 (events_by_ssrc[ssrc].empty() || !force_repeated_fields_)
188 ? NewRtpPacket<EventType>(ssrc, extension_map)
189 : events_by_ssrc[ssrc][0]->Copy();
190 history_.push_back(event->Copy());
191 events_by_ssrc[ssrc].emplace_back(std::move(event));
192 }
193
194 // Encode and parse.
195 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
196 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
197
198 // For each SSRC, make sure the RTP packets associated with it to have been
199 // correctly encoded and parsed.
200 for (auto it = events_by_ssrc.begin(); it != events_by_ssrc.end(); ++it) {
201 const uint32_t ssrc = it->first;
202 const auto& original_packets = it->second;
203 const std::vector<ParsedType>* parsed_rtp_packets =
204 GetRtpPacketsBySsrc<ParsedType>(&parsed_log_, ssrc);
205 ASSERT_NE(parsed_rtp_packets, nullptr);
206 ASSERT_EQ(original_packets.size(), parsed_rtp_packets->size());
207 for (size_t i = 0; i < original_packets.size(); ++i) {
208 verifier_.VerifyLoggedRtpPacket<EventType, ParsedType>(
209 *original_packets[i], (*parsed_rtp_packets)[i]);
210 }
211 }
212 }
213
TEST_P(RtcEventLogEncoderTest,RtcEventAlrState)214 TEST_P(RtcEventLogEncoderTest, RtcEventAlrState) {
215 std::vector<std::unique_ptr<RtcEventAlrState>> events(event_count_);
216 for (size_t i = 0; i < event_count_; ++i) {
217 events[i] = (i == 0 || !force_repeated_fields_) ? gen_.NewAlrState()
218 : events[0]->Copy();
219 history_.push_back(events[i]->Copy());
220 }
221
222 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
223 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
224 const auto& alr_state_events = parsed_log_.alr_state_events();
225
226 ASSERT_EQ(alr_state_events.size(), event_count_);
227 for (size_t i = 0; i < event_count_; ++i) {
228 verifier_.VerifyLoggedAlrStateEvent(*events[i], alr_state_events[i]);
229 }
230 }
231
TEST_P(RtcEventLogEncoderTest,RtcEventRouteChange)232 TEST_P(RtcEventLogEncoderTest, RtcEventRouteChange) {
233 if (encoding_type_ == RtcEventLog::EncodingType::Legacy) {
234 return;
235 }
236 std::vector<std::unique_ptr<RtcEventRouteChange>> events(event_count_);
237 for (size_t i = 0; i < event_count_; ++i) {
238 events[i] = (i == 0 || !force_repeated_fields_) ? gen_.NewRouteChange()
239 : events[0]->Copy();
240 history_.push_back(events[i]->Copy());
241 }
242
243 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
244 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
245 const auto& route_change_events = parsed_log_.route_change_events();
246
247 ASSERT_EQ(route_change_events.size(), event_count_);
248 for (size_t i = 0; i < event_count_; ++i) {
249 verifier_.VerifyLoggedRouteChangeEvent(*events[i], route_change_events[i]);
250 }
251 }
252
TEST_P(RtcEventLogEncoderTest,RtcEventRemoteEstimate)253 TEST_P(RtcEventLogEncoderTest, RtcEventRemoteEstimate) {
254 std::vector<std::unique_ptr<RtcEventRemoteEstimate>> events(event_count_);
255 for (size_t i = 0; i < event_count_; ++i) {
256 events[i] = (i == 0 || !force_repeated_fields_)
257 ? gen_.NewRemoteEstimate()
258 : std::make_unique<RtcEventRemoteEstimate>(*events[0]);
259 history_.push_back(std::make_unique<RtcEventRemoteEstimate>(*events[i]));
260 }
261
262 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
263 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
264 const auto& parsed_events = parsed_log_.remote_estimate_events();
265
266 ASSERT_EQ(parsed_events.size(), event_count_);
267 for (size_t i = 0; i < event_count_; ++i) {
268 verifier_.VerifyLoggedRemoteEstimateEvent(*events[i], parsed_events[i]);
269 }
270 }
271
TEST_P(RtcEventLogEncoderTest,RtcEventAudioNetworkAdaptationBitrate)272 TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationBitrate) {
273 std::vector<std::unique_ptr<RtcEventAudioNetworkAdaptation>> events(
274 event_count_);
275 for (size_t i = 0; i < event_count_; ++i) {
276 if (i == 0 || !force_repeated_fields_) {
277 auto runtime_config = std::make_unique<AudioEncoderRuntimeConfig>();
278 const int bitrate_bps = rtc::checked_cast<int>(
279 prng_.Rand(0, std::numeric_limits<int32_t>::max()));
280 runtime_config->bitrate_bps = bitrate_bps;
281 events[i] = std::make_unique<RtcEventAudioNetworkAdaptation>(
282 std::move(runtime_config));
283 } else {
284 events[i] = events[0]->Copy();
285 }
286 }
287 TestRtcEventAudioNetworkAdaptation(events);
288 }
289
TEST_P(RtcEventLogEncoderTest,RtcEventAudioNetworkAdaptationFrameLength)290 TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationFrameLength) {
291 std::vector<std::unique_ptr<RtcEventAudioNetworkAdaptation>> events(
292 event_count_);
293 for (size_t i = 0; i < event_count_; ++i) {
294 if (i == 0 || !force_repeated_fields_) {
295 auto runtime_config = std::make_unique<AudioEncoderRuntimeConfig>();
296 const int frame_length_ms = prng_.Rand(1, 1000);
297 runtime_config->frame_length_ms = frame_length_ms;
298 events[i] = std::make_unique<RtcEventAudioNetworkAdaptation>(
299 std::move(runtime_config));
300 } else {
301 events[i] = events[0]->Copy();
302 }
303 }
304 TestRtcEventAudioNetworkAdaptation(events);
305 }
306
TEST_P(RtcEventLogEncoderTest,RtcEventAudioNetworkAdaptationPacketLoss)307 TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationPacketLoss) {
308 std::vector<std::unique_ptr<RtcEventAudioNetworkAdaptation>> events(
309 event_count_);
310 for (size_t i = 0; i < event_count_; ++i) {
311 if (i == 0 || !force_repeated_fields_) {
312 // To simplify the test, we just check powers of two.
313 const float plr = std::pow(0.5f, prng_.Rand(1, 8));
314 auto runtime_config = std::make_unique<AudioEncoderRuntimeConfig>();
315 runtime_config->uplink_packet_loss_fraction = plr;
316 events[i] = std::make_unique<RtcEventAudioNetworkAdaptation>(
317 std::move(runtime_config));
318 } else {
319 events[i] = events[0]->Copy();
320 }
321 }
322 TestRtcEventAudioNetworkAdaptation(events);
323 }
324
TEST_P(RtcEventLogEncoderTest,RtcEventAudioNetworkAdaptationFec)325 TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationFec) {
326 std::vector<std::unique_ptr<RtcEventAudioNetworkAdaptation>> events(
327 event_count_);
328 for (size_t i = 0; i < event_count_; ++i) {
329 if (i == 0 || !force_repeated_fields_) {
330 auto runtime_config = std::make_unique<AudioEncoderRuntimeConfig>();
331 runtime_config->enable_fec = prng_.Rand<bool>();
332 events[i] = std::make_unique<RtcEventAudioNetworkAdaptation>(
333 std::move(runtime_config));
334 } else {
335 events[i] = events[0]->Copy();
336 }
337 }
338 TestRtcEventAudioNetworkAdaptation(events);
339 }
340
TEST_P(RtcEventLogEncoderTest,RtcEventAudioNetworkAdaptationDtx)341 TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationDtx) {
342 std::vector<std::unique_ptr<RtcEventAudioNetworkAdaptation>> events(
343 event_count_);
344 for (size_t i = 0; i < event_count_; ++i) {
345 if (i == 0 || !force_repeated_fields_) {
346 auto runtime_config = std::make_unique<AudioEncoderRuntimeConfig>();
347 runtime_config->enable_dtx = prng_.Rand<bool>();
348 events[i] = std::make_unique<RtcEventAudioNetworkAdaptation>(
349 std::move(runtime_config));
350 } else {
351 events[i] = events[0]->Copy();
352 }
353 }
354 TestRtcEventAudioNetworkAdaptation(events);
355 }
356
TEST_P(RtcEventLogEncoderTest,RtcEventAudioNetworkAdaptationChannels)357 TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationChannels) {
358 std::vector<std::unique_ptr<RtcEventAudioNetworkAdaptation>> events(
359 event_count_);
360 for (size_t i = 0; i < event_count_; ++i) {
361 if (i == 0 || !force_repeated_fields_) {
362 auto runtime_config = std::make_unique<AudioEncoderRuntimeConfig>();
363 runtime_config->num_channels = prng_.Rand(1, 2);
364 events[i] = std::make_unique<RtcEventAudioNetworkAdaptation>(
365 std::move(runtime_config));
366 } else {
367 events[i] = events[0]->Copy();
368 }
369 }
370 TestRtcEventAudioNetworkAdaptation(events);
371 }
372
TEST_P(RtcEventLogEncoderTest,RtcEventAudioNetworkAdaptationAll)373 TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationAll) {
374 std::vector<std::unique_ptr<RtcEventAudioNetworkAdaptation>> events(
375 event_count_);
376 for (size_t i = 0; i < event_count_; ++i) {
377 if (i == 0 || !force_repeated_fields_) {
378 auto runtime_config = std::make_unique<AudioEncoderRuntimeConfig>();
379 runtime_config->bitrate_bps = rtc::checked_cast<int>(
380 prng_.Rand(0, std::numeric_limits<int32_t>::max()));
381 runtime_config->frame_length_ms = prng_.Rand(1, 1000);
382 runtime_config->uplink_packet_loss_fraction =
383 std::pow(0.5f, prng_.Rand(1, 8));
384 runtime_config->enable_fec = prng_.Rand<bool>();
385 runtime_config->enable_dtx = prng_.Rand<bool>();
386 runtime_config->num_channels = prng_.Rand(1, 2);
387 events[i] = std::make_unique<RtcEventAudioNetworkAdaptation>(
388 std::move(runtime_config));
389 } else {
390 events[i] = events[0]->Copy();
391 }
392 }
393 TestRtcEventAudioNetworkAdaptation(events);
394 }
395
TEST_P(RtcEventLogEncoderTest,RtcEventAudioPlayout)396 TEST_P(RtcEventLogEncoderTest, RtcEventAudioPlayout) {
397 // SSRCs will be randomly assigned out of this small pool, significant only
398 // in that it also covers such edge cases as SSRC = 0 and SSRC = 0xffffffff.
399 // The pool is intentionally small, so as to produce collisions.
400 const std::vector<uint32_t> kSsrcPool = {0x00000000, 0x12345678, 0xabcdef01,
401 0xffffffff, 0x20171024, 0x19840730,
402 0x19831230};
403
404 std::map<uint32_t, std::vector<std::unique_ptr<RtcEventAudioPlayout>>>
405 original_events_by_ssrc;
406 for (size_t i = 0; i < event_count_; ++i) {
407 const uint32_t ssrc = kSsrcPool[prng_.Rand(kSsrcPool.size() - 1)];
408 std::unique_ptr<RtcEventAudioPlayout> event =
409 (original_events_by_ssrc[ssrc].empty() || !force_repeated_fields_)
410 ? gen_.NewAudioPlayout(ssrc)
411 : original_events_by_ssrc[ssrc][0]->Copy();
412 history_.push_back(event->Copy());
413 original_events_by_ssrc[ssrc].push_back(std::move(event));
414 }
415
416 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
417 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
418
419 const auto& parsed_playout_events_by_ssrc =
420 parsed_log_.audio_playout_events();
421
422 // Same number of distinct SSRCs.
423 ASSERT_EQ(parsed_playout_events_by_ssrc.size(),
424 original_events_by_ssrc.size());
425
426 for (auto& original_event_it : original_events_by_ssrc) {
427 const uint32_t ssrc = original_event_it.first;
428 const auto& original_playout_events = original_event_it.second;
429
430 const auto& parsed_event_it = parsed_playout_events_by_ssrc.find(ssrc);
431 ASSERT_TRUE(parsed_event_it != parsed_playout_events_by_ssrc.end());
432 const auto& parsed_playout_events = parsed_event_it->second;
433
434 // Same number playout events for the SSRC under examination.
435 ASSERT_EQ(original_playout_events.size(), parsed_playout_events.size());
436
437 for (size_t i = 0; i < original_playout_events.size(); ++i) {
438 verifier_.VerifyLoggedAudioPlayoutEvent(*original_playout_events[i],
439 parsed_playout_events[i]);
440 }
441 }
442 }
443
444 // TODO(eladalon/terelius): Test with multiple events in the batch.
TEST_P(RtcEventLogEncoderTest,RtcEventAudioReceiveStreamConfig)445 TEST_P(RtcEventLogEncoderTest, RtcEventAudioReceiveStreamConfig) {
446 uint32_t ssrc = prng_.Rand<uint32_t>();
447 RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap();
448 std::unique_ptr<RtcEventAudioReceiveStreamConfig> event =
449 gen_.NewAudioReceiveStreamConfig(ssrc, extensions);
450 history_.push_back(event->Copy());
451
452 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
453 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
454 const auto& audio_recv_configs = parsed_log_.audio_recv_configs();
455
456 ASSERT_EQ(audio_recv_configs.size(), 1u);
457 verifier_.VerifyLoggedAudioRecvConfig(*event, audio_recv_configs[0]);
458 }
459
460 // TODO(eladalon/terelius): Test with multiple events in the batch.
TEST_P(RtcEventLogEncoderTest,RtcEventAudioSendStreamConfig)461 TEST_P(RtcEventLogEncoderTest, RtcEventAudioSendStreamConfig) {
462 uint32_t ssrc = prng_.Rand<uint32_t>();
463 RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap();
464 std::unique_ptr<RtcEventAudioSendStreamConfig> event =
465 gen_.NewAudioSendStreamConfig(ssrc, extensions);
466 history_.push_back(event->Copy());
467
468 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
469 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
470 const auto& audio_send_configs = parsed_log_.audio_send_configs();
471
472 ASSERT_EQ(audio_send_configs.size(), 1u);
473 verifier_.VerifyLoggedAudioSendConfig(*event, audio_send_configs[0]);
474 }
475
TEST_P(RtcEventLogEncoderTest,RtcEventBweUpdateDelayBased)476 TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateDelayBased) {
477 std::vector<std::unique_ptr<RtcEventBweUpdateDelayBased>> events(
478 event_count_);
479 for (size_t i = 0; i < event_count_; ++i) {
480 events[i] = (i == 0 || !force_repeated_fields_)
481 ? gen_.NewBweUpdateDelayBased()
482 : events[0]->Copy();
483 history_.push_back(events[i]->Copy());
484 }
485
486 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
487 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
488
489 const auto& bwe_delay_updates = parsed_log_.bwe_delay_updates();
490 ASSERT_EQ(bwe_delay_updates.size(), event_count_);
491
492 for (size_t i = 0; i < event_count_; ++i) {
493 verifier_.VerifyLoggedBweDelayBasedUpdate(*events[i], bwe_delay_updates[i]);
494 }
495 }
496
TEST_P(RtcEventLogEncoderTest,RtcEventBweUpdateLossBased)497 TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateLossBased) {
498 std::vector<std::unique_ptr<RtcEventBweUpdateLossBased>> events(event_count_);
499 for (size_t i = 0; i < event_count_; ++i) {
500 events[i] = (i == 0 || !force_repeated_fields_)
501 ? gen_.NewBweUpdateLossBased()
502 : events[0]->Copy();
503 history_.push_back(events[i]->Copy());
504 }
505
506 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
507 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
508
509 const auto& bwe_loss_updates = parsed_log_.bwe_loss_updates();
510 ASSERT_EQ(bwe_loss_updates.size(), event_count_);
511
512 for (size_t i = 0; i < event_count_; ++i) {
513 verifier_.VerifyLoggedBweLossBasedUpdate(*events[i], bwe_loss_updates[i]);
514 }
515 }
516
TEST_P(RtcEventLogEncoderTest,RtcEventGenericPacketReceived)517 TEST_P(RtcEventLogEncoderTest, RtcEventGenericPacketReceived) {
518 if (encoding_type_ == RtcEventLog::EncodingType::Legacy) {
519 return;
520 }
521 std::vector<std::unique_ptr<RtcEventGenericPacketReceived>> events(
522 event_count_);
523 for (size_t i = 0; i < event_count_; ++i) {
524 events[i] = (i == 0 || !force_repeated_fields_)
525 ? gen_.NewGenericPacketReceived()
526 : events[0]->Copy();
527 history_.push_back(events[i]->Copy());
528 }
529
530 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
531 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
532
533 const auto& packets_received = parsed_log_.generic_packets_received();
534 ASSERT_EQ(packets_received.size(), event_count_);
535
536 for (size_t i = 0; i < event_count_; ++i) {
537 verifier_.VerifyLoggedGenericPacketReceived(*events[i],
538 packets_received[i]);
539 }
540 }
541
TEST_P(RtcEventLogEncoderTest,RtcEventGenericPacketSent)542 TEST_P(RtcEventLogEncoderTest, RtcEventGenericPacketSent) {
543 if (encoding_type_ == RtcEventLog::EncodingType::Legacy) {
544 return;
545 }
546 std::vector<std::unique_ptr<RtcEventGenericPacketSent>> events(event_count_);
547 for (size_t i = 0; i < event_count_; ++i) {
548 events[i] = (i == 0 || !force_repeated_fields_)
549 ? gen_.NewGenericPacketSent()
550 : events[0]->Copy();
551 history_.push_back(events[i]->Copy());
552 }
553
554 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
555 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
556
557 const auto& packets_sent = parsed_log_.generic_packets_sent();
558 ASSERT_EQ(packets_sent.size(), event_count_);
559
560 for (size_t i = 0; i < event_count_; ++i) {
561 verifier_.VerifyLoggedGenericPacketSent(*events[i], packets_sent[i]);
562 }
563 }
564
TEST_P(RtcEventLogEncoderTest,RtcEventGenericAcksReceived)565 TEST_P(RtcEventLogEncoderTest, RtcEventGenericAcksReceived) {
566 if (encoding_type_ == RtcEventLog::EncodingType::Legacy) {
567 return;
568 }
569 std::vector<std::unique_ptr<RtcEventGenericAckReceived>> events(event_count_);
570 for (size_t i = 0; i < event_count_; ++i) {
571 events[i] = (i == 0 || !force_repeated_fields_)
572 ? gen_.NewGenericAckReceived()
573 : events[0]->Copy();
574 history_.push_back(events[i]->Copy());
575 }
576
577 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
578 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
579
580 const auto& decoded_events = parsed_log_.generic_acks_received();
581 ASSERT_EQ(decoded_events.size(), event_count_);
582
583 for (size_t i = 0; i < event_count_; ++i) {
584 verifier_.VerifyLoggedGenericAckReceived(*events[i], decoded_events[i]);
585 }
586 }
587
TEST_P(RtcEventLogEncoderTest,RtcEventDtlsTransportState)588 TEST_P(RtcEventLogEncoderTest, RtcEventDtlsTransportState) {
589 std::vector<std::unique_ptr<RtcEventDtlsTransportState>> events(event_count_);
590 for (size_t i = 0; i < event_count_; ++i) {
591 events[i] = (i == 0 || !force_repeated_fields_)
592 ? gen_.NewDtlsTransportState()
593 : events[0]->Copy();
594 history_.push_back(events[i]->Copy());
595 }
596
597 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
598 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
599
600 const auto& dtls_transport_states = parsed_log_.dtls_transport_states();
601 if (encoding_type_ == RtcEventLog::EncodingType::Legacy) {
602 ASSERT_EQ(dtls_transport_states.size(), 0u);
603 return;
604 }
605
606 ASSERT_EQ(dtls_transport_states.size(), event_count_);
607 for (size_t i = 0; i < event_count_; ++i) {
608 verifier_.VerifyLoggedDtlsTransportState(*events[i],
609 dtls_transport_states[i]);
610 }
611 }
612
TEST_P(RtcEventLogEncoderTest,RtcEventDtlsWritableState)613 TEST_P(RtcEventLogEncoderTest, RtcEventDtlsWritableState) {
614 std::vector<std::unique_ptr<RtcEventDtlsWritableState>> events(event_count_);
615 for (size_t i = 0; i < event_count_; ++i) {
616 events[i] = (i == 0 || !force_repeated_fields_)
617 ? gen_.NewDtlsWritableState()
618 : events[0]->Copy();
619 history_.push_back(events[i]->Copy());
620 }
621
622 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
623 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
624
625 const auto& dtls_writable_states = parsed_log_.dtls_writable_states();
626 if (encoding_type_ == RtcEventLog::EncodingType::Legacy) {
627 ASSERT_EQ(dtls_writable_states.size(), 0u);
628 return;
629 }
630
631 ASSERT_EQ(dtls_writable_states.size(), event_count_);
632
633 for (size_t i = 0; i < event_count_; ++i) {
634 verifier_.VerifyLoggedDtlsWritableState(*events[i],
635 dtls_writable_states[i]);
636 }
637 }
638
TEST_P(RtcEventLogEncoderTest,RtcEventFrameDecoded)639 TEST_P(RtcEventLogEncoderTest, RtcEventFrameDecoded) {
640 // SSRCs will be randomly assigned out of this small pool, significant only
641 // in that it also covers such edge cases as SSRC = 0 and SSRC = 0xffffffff.
642 // The pool is intentionally small, so as to produce collisions.
643 const std::vector<uint32_t> kSsrcPool = {0x00000000, 0x12345678, 0xabcdef01,
644 0xffffffff, 0x20171024, 0x19840730,
645 0x19831230};
646
647 std::map<uint32_t, std::vector<std::unique_ptr<RtcEventFrameDecoded>>>
648 original_events_by_ssrc;
649 for (size_t i = 0; i < event_count_; ++i) {
650 const uint32_t ssrc = kSsrcPool[prng_.Rand(kSsrcPool.size() - 1)];
651 std::unique_ptr<RtcEventFrameDecoded> event =
652 (original_events_by_ssrc[ssrc].empty() || !force_repeated_fields_)
653 ? gen_.NewFrameDecodedEvent(ssrc)
654 : original_events_by_ssrc[ssrc][0]->Copy();
655 history_.push_back(event->Copy());
656 original_events_by_ssrc[ssrc].push_back(std::move(event));
657 }
658
659 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
660 auto status = parsed_log_.ParseString(encoded_);
661 if (!status.ok())
662 RTC_LOG(LS_ERROR) << status.message();
663 ASSERT_TRUE(status.ok());
664
665 const auto& decoded_frames_by_ssrc = parsed_log_.decoded_frames();
666 if (encoding_type_ == RtcEventLog::EncodingType::Legacy) {
667 ASSERT_EQ(decoded_frames_by_ssrc.size(), 0u);
668 return;
669 }
670
671 // Same number of distinct SSRCs.
672 ASSERT_EQ(decoded_frames_by_ssrc.size(), original_events_by_ssrc.size());
673
674 for (const auto& original_event_it : original_events_by_ssrc) {
675 const uint32_t ssrc = original_event_it.first;
676 const std::vector<std::unique_ptr<RtcEventFrameDecoded>>& original_frames =
677 original_event_it.second;
678
679 const auto& parsed_event_it = decoded_frames_by_ssrc.find(ssrc);
680 ASSERT_TRUE(parsed_event_it != decoded_frames_by_ssrc.end());
681 const std::vector<LoggedFrameDecoded>& parsed_frames =
682 parsed_event_it->second;
683
684 // Same number events for the SSRC under examination.
685 ASSERT_EQ(original_frames.size(), parsed_frames.size());
686
687 for (size_t i = 0; i < original_frames.size(); ++i) {
688 verifier_.VerifyLoggedFrameDecoded(*original_frames[i], parsed_frames[i]);
689 }
690 }
691 }
692
693 // TODO(eladalon/terelius): Test with multiple events in the batch.
TEST_P(RtcEventLogEncoderTest,RtcEventIceCandidatePairConfig)694 TEST_P(RtcEventLogEncoderTest, RtcEventIceCandidatePairConfig) {
695 std::unique_ptr<RtcEventIceCandidatePairConfig> event =
696 gen_.NewIceCandidatePairConfig();
697 history_.push_back(event->Copy());
698
699 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
700 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
701 const auto& ice_candidate_pair_configs =
702 parsed_log_.ice_candidate_pair_configs();
703
704 ASSERT_EQ(ice_candidate_pair_configs.size(), 1u);
705 verifier_.VerifyLoggedIceCandidatePairConfig(*event,
706 ice_candidate_pair_configs[0]);
707 }
708
709 // TODO(eladalon/terelius): Test with multiple events in the batch.
TEST_P(RtcEventLogEncoderTest,RtcEventIceCandidatePair)710 TEST_P(RtcEventLogEncoderTest, RtcEventIceCandidatePair) {
711 std::unique_ptr<RtcEventIceCandidatePair> event = gen_.NewIceCandidatePair();
712 history_.push_back(event->Copy());
713
714 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
715 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
716 const auto& ice_candidate_pair_events =
717 parsed_log_.ice_candidate_pair_events();
718
719 ASSERT_EQ(ice_candidate_pair_events.size(), 1u);
720 verifier_.VerifyLoggedIceCandidatePairEvent(*event,
721 ice_candidate_pair_events[0]);
722 }
723
TEST_P(RtcEventLogEncoderTest,RtcEventLoggingStarted)724 TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStarted) {
725 const int64_t timestamp_ms = prng_.Rand(1'000'000'000);
726 const int64_t utc_time_ms = prng_.Rand(1'000'000'000);
727
728 // Overwrite the previously encoded LogStart event.
729 encoded_ = encoder_->EncodeLogStart(timestamp_ms * 1000, utc_time_ms * 1000);
730 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
731 const auto& start_log_events = parsed_log_.start_log_events();
732
733 ASSERT_EQ(start_log_events.size(), 1u);
734 verifier_.VerifyLoggedStartEvent(timestamp_ms * 1000, utc_time_ms * 1000,
735 start_log_events[0]);
736 }
737
TEST_P(RtcEventLogEncoderTest,RtcEventLoggingStopped)738 TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStopped) {
739 const int64_t start_timestamp_ms = prng_.Rand(1'000'000'000);
740 const int64_t start_utc_time_ms = prng_.Rand(1'000'000'000);
741
742 // Overwrite the previously encoded LogStart event.
743 encoded_ = encoder_->EncodeLogStart(start_timestamp_ms * 1000,
744 start_utc_time_ms * 1000);
745
746 const int64_t stop_timestamp_ms =
747 prng_.Rand(start_timestamp_ms, 2'000'000'000);
748 encoded_ += encoder_->EncodeLogEnd(stop_timestamp_ms * 1000);
749 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
750 const auto& stop_log_events = parsed_log_.stop_log_events();
751
752 ASSERT_EQ(stop_log_events.size(), 1u);
753 verifier_.VerifyLoggedStopEvent(stop_timestamp_ms * 1000, stop_log_events[0]);
754 }
755
756 // TODO(eladalon/terelius): Test with multiple events in the batch.
TEST_P(RtcEventLogEncoderTest,RtcEventProbeClusterCreated)757 TEST_P(RtcEventLogEncoderTest, RtcEventProbeClusterCreated) {
758 std::unique_ptr<RtcEventProbeClusterCreated> event =
759 gen_.NewProbeClusterCreated();
760 history_.push_back(event->Copy());
761
762 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
763 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
764 const auto& bwe_probe_cluster_created_events =
765 parsed_log_.bwe_probe_cluster_created_events();
766
767 ASSERT_EQ(bwe_probe_cluster_created_events.size(), 1u);
768 verifier_.VerifyLoggedBweProbeClusterCreatedEvent(
769 *event, bwe_probe_cluster_created_events[0]);
770 }
771
772 // TODO(eladalon/terelius): Test with multiple events in the batch.
TEST_P(RtcEventLogEncoderTest,RtcEventProbeResultFailure)773 TEST_P(RtcEventLogEncoderTest, RtcEventProbeResultFailure) {
774 std::unique_ptr<RtcEventProbeResultFailure> event =
775 gen_.NewProbeResultFailure();
776 history_.push_back(event->Copy());
777
778 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
779 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
780 const auto& bwe_probe_failure_events = parsed_log_.bwe_probe_failure_events();
781
782 ASSERT_EQ(bwe_probe_failure_events.size(), 1u);
783 verifier_.VerifyLoggedBweProbeFailureEvent(*event,
784 bwe_probe_failure_events[0]);
785 }
786
787 // TODO(eladalon/terelius): Test with multiple events in the batch.
TEST_P(RtcEventLogEncoderTest,RtcEventProbeResultSuccess)788 TEST_P(RtcEventLogEncoderTest, RtcEventProbeResultSuccess) {
789 std::unique_ptr<RtcEventProbeResultSuccess> event =
790 gen_.NewProbeResultSuccess();
791 history_.push_back(event->Copy());
792
793 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
794 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
795 const auto& bwe_probe_success_events = parsed_log_.bwe_probe_success_events();
796
797 ASSERT_EQ(bwe_probe_success_events.size(), 1u);
798 verifier_.VerifyLoggedBweProbeSuccessEvent(*event,
799 bwe_probe_success_events[0]);
800 }
801
TEST_P(RtcEventLogEncoderTest,RtcEventRtcpPacketIncoming)802 TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPacketIncoming) {
803 if (force_repeated_fields_) {
804 // RTCP packets maybe delivered twice (once for audio and once for video).
805 // As a work around, we're removing duplicates in the parser.
806 return;
807 }
808
809 std::vector<std::unique_ptr<RtcEventRtcpPacketIncoming>> events(event_count_);
810 for (size_t i = 0; i < event_count_; ++i) {
811 events[i] = (i == 0 || !force_repeated_fields_)
812 ? gen_.NewRtcpPacketIncoming()
813 : events[0]->Copy();
814 history_.push_back(events[i]->Copy());
815 }
816
817 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
818 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
819
820 const auto& incoming_rtcp_packets = parsed_log_.incoming_rtcp_packets();
821 ASSERT_EQ(incoming_rtcp_packets.size(), event_count_);
822
823 for (size_t i = 0; i < event_count_; ++i) {
824 verifier_.VerifyLoggedRtcpPacketIncoming(*events[i],
825 incoming_rtcp_packets[i]);
826 }
827 }
828
TEST_P(RtcEventLogEncoderTest,RtcEventRtcpPacketOutgoing)829 TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPacketOutgoing) {
830 std::vector<std::unique_ptr<RtcEventRtcpPacketOutgoing>> events(event_count_);
831 for (size_t i = 0; i < event_count_; ++i) {
832 events[i] = (i == 0 || !force_repeated_fields_)
833 ? gen_.NewRtcpPacketOutgoing()
834 : events[0]->Copy();
835 history_.push_back(events[i]->Copy());
836 }
837
838 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
839 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
840
841 const auto& outgoing_rtcp_packets = parsed_log_.outgoing_rtcp_packets();
842 ASSERT_EQ(outgoing_rtcp_packets.size(), event_count_);
843
844 for (size_t i = 0; i < event_count_; ++i) {
845 verifier_.VerifyLoggedRtcpPacketOutgoing(*events[i],
846 outgoing_rtcp_packets[i]);
847 }
848 }
849
TEST_P(RtcEventLogEncoderTest,RtcEventRtcpReceiverReport)850 TEST_P(RtcEventLogEncoderTest, RtcEventRtcpReceiverReport) {
851 if (force_repeated_fields_) {
852 return;
853 }
854
855 rtc::ScopedFakeClock fake_clock;
856 fake_clock.SetTime(Timestamp::Millis(prng_.Rand<uint32_t>()));
857
858 for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
859 std::vector<rtcp::ReceiverReport> events(event_count_);
860 std::vector<int64_t> timestamps_ms(event_count_);
861 for (size_t i = 0; i < event_count_; ++i) {
862 timestamps_ms[i] = rtc::TimeMillis();
863 events[i] = gen_.NewReceiverReport();
864 rtc::Buffer buffer = events[i].Build();
865 if (direction == kIncomingPacket) {
866 history_.push_back(
867 std::make_unique<RtcEventRtcpPacketIncoming>(buffer));
868 } else {
869 history_.push_back(
870 std::make_unique<RtcEventRtcpPacketOutgoing>(buffer));
871 }
872 fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000)));
873 }
874
875 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
876 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
877
878 const auto& receiver_reports = parsed_log_.receiver_reports(direction);
879 ASSERT_EQ(receiver_reports.size(), event_count_);
880
881 for (size_t i = 0; i < event_count_; ++i) {
882 verifier_.VerifyLoggedReceiverReport(timestamps_ms[i], events[i],
883 receiver_reports[i]);
884 }
885 }
886 }
887
TEST_P(RtcEventLogEncoderTest,RtcEventRtcpSenderReport)888 TEST_P(RtcEventLogEncoderTest, RtcEventRtcpSenderReport) {
889 if (force_repeated_fields_) {
890 return;
891 }
892
893 rtc::ScopedFakeClock fake_clock;
894 fake_clock.SetTime(Timestamp::Millis(prng_.Rand<uint32_t>()));
895
896 for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
897 std::vector<rtcp::SenderReport> events(event_count_);
898 std::vector<int64_t> timestamps_ms(event_count_);
899 for (size_t i = 0; i < event_count_; ++i) {
900 timestamps_ms[i] = rtc::TimeMillis();
901 events[i] = gen_.NewSenderReport();
902 rtc::Buffer buffer = events[i].Build();
903 if (direction == kIncomingPacket) {
904 history_.push_back(
905 std::make_unique<RtcEventRtcpPacketIncoming>(buffer));
906 } else {
907 history_.push_back(
908 std::make_unique<RtcEventRtcpPacketOutgoing>(buffer));
909 }
910 fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000)));
911 }
912
913 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
914 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
915
916 const auto& sender_reports = parsed_log_.sender_reports(direction);
917 ASSERT_EQ(sender_reports.size(), event_count_);
918
919 for (size_t i = 0; i < event_count_; ++i) {
920 verifier_.VerifyLoggedSenderReport(timestamps_ms[i], events[i],
921 sender_reports[i]);
922 }
923 }
924 }
925
TEST_P(RtcEventLogEncoderTest,RtcEventRtcpExtendedReports)926 TEST_P(RtcEventLogEncoderTest, RtcEventRtcpExtendedReports) {
927 if (force_repeated_fields_) {
928 return;
929 }
930
931 rtc::ScopedFakeClock fake_clock;
932 fake_clock.SetTime(Timestamp::Millis(prng_.Rand<uint32_t>()));
933
934 for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
935 std::vector<rtcp::ExtendedReports> events(event_count_);
936 std::vector<int64_t> timestamps_ms(event_count_);
937 for (size_t i = 0; i < event_count_; ++i) {
938 timestamps_ms[i] = rtc::TimeMillis();
939 events[i] = gen_.NewExtendedReports();
940 rtc::Buffer buffer = events[i].Build();
941 if (direction == kIncomingPacket) {
942 history_.push_back(
943 std::make_unique<RtcEventRtcpPacketIncoming>(buffer));
944 } else {
945 history_.push_back(
946 std::make_unique<RtcEventRtcpPacketOutgoing>(buffer));
947 }
948 fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000)));
949 }
950
951 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
952 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
953
954 const auto& extended_reports = parsed_log_.extended_reports(direction);
955 ASSERT_EQ(extended_reports.size(), event_count_);
956
957 for (size_t i = 0; i < event_count_; ++i) {
958 verifier_.VerifyLoggedExtendedReports(timestamps_ms[i], events[i],
959 extended_reports[i]);
960 }
961 }
962 }
963
TEST_P(RtcEventLogEncoderTest,RtcEventRtcpFir)964 TEST_P(RtcEventLogEncoderTest, RtcEventRtcpFir) {
965 if (force_repeated_fields_) {
966 return;
967 }
968
969 rtc::ScopedFakeClock fake_clock;
970 fake_clock.SetTime(Timestamp::Millis(prng_.Rand<uint32_t>()));
971
972 for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
973 std::vector<rtcp::Fir> events(event_count_);
974 std::vector<int64_t> timestamps_ms(event_count_);
975 for (size_t i = 0; i < event_count_; ++i) {
976 timestamps_ms[i] = rtc::TimeMillis();
977 events[i] = gen_.NewFir();
978 rtc::Buffer buffer = events[i].Build();
979 if (direction == kIncomingPacket) {
980 history_.push_back(
981 std::make_unique<RtcEventRtcpPacketIncoming>(buffer));
982 } else {
983 history_.push_back(
984 std::make_unique<RtcEventRtcpPacketOutgoing>(buffer));
985 }
986 fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000)));
987 }
988
989 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
990 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
991
992 const auto& firs = parsed_log_.firs(direction);
993 ASSERT_EQ(firs.size(), event_count_);
994
995 for (size_t i = 0; i < event_count_; ++i) {
996 verifier_.VerifyLoggedFir(timestamps_ms[i], events[i], firs[i]);
997 }
998 }
999 }
1000
TEST_P(RtcEventLogEncoderTest,RtcEventRtcpPli)1001 TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPli) {
1002 if (force_repeated_fields_) {
1003 return;
1004 }
1005
1006 rtc::ScopedFakeClock fake_clock;
1007 fake_clock.SetTime(Timestamp::Millis(prng_.Rand<uint32_t>()));
1008
1009 for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
1010 std::vector<rtcp::Pli> events(event_count_);
1011 std::vector<int64_t> timestamps_ms(event_count_);
1012 for (size_t i = 0; i < event_count_; ++i) {
1013 timestamps_ms[i] = rtc::TimeMillis();
1014 events[i] = gen_.NewPli();
1015 rtc::Buffer buffer = events[i].Build();
1016 if (direction == kIncomingPacket) {
1017 history_.push_back(
1018 std::make_unique<RtcEventRtcpPacketIncoming>(buffer));
1019 } else {
1020 history_.push_back(
1021 std::make_unique<RtcEventRtcpPacketOutgoing>(buffer));
1022 }
1023 fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000)));
1024 }
1025
1026 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
1027 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
1028
1029 const auto& plis = parsed_log_.plis(direction);
1030 ASSERT_EQ(plis.size(), event_count_);
1031
1032 for (size_t i = 0; i < event_count_; ++i) {
1033 verifier_.VerifyLoggedPli(timestamps_ms[i], events[i], plis[i]);
1034 }
1035 }
1036 }
1037
TEST_P(RtcEventLogEncoderTest,RtcEventRtcpBye)1038 TEST_P(RtcEventLogEncoderTest, RtcEventRtcpBye) {
1039 if (force_repeated_fields_) {
1040 return;
1041 }
1042
1043 rtc::ScopedFakeClock fake_clock;
1044 fake_clock.SetTime(Timestamp::Millis(prng_.Rand<uint32_t>()));
1045
1046 for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
1047 std::vector<rtcp::Bye> events(event_count_);
1048 std::vector<int64_t> timestamps_ms(event_count_);
1049 for (size_t i = 0; i < event_count_; ++i) {
1050 timestamps_ms[i] = rtc::TimeMillis();
1051 events[i] = gen_.NewBye();
1052 rtc::Buffer buffer = events[i].Build();
1053 if (direction == kIncomingPacket) {
1054 history_.push_back(
1055 std::make_unique<RtcEventRtcpPacketIncoming>(buffer));
1056 } else {
1057 history_.push_back(
1058 std::make_unique<RtcEventRtcpPacketOutgoing>(buffer));
1059 }
1060 fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000)));
1061 }
1062
1063 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
1064 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
1065
1066 const auto& byes = parsed_log_.byes(direction);
1067 ASSERT_EQ(byes.size(), event_count_);
1068
1069 for (size_t i = 0; i < event_count_; ++i) {
1070 verifier_.VerifyLoggedBye(timestamps_ms[i], events[i], byes[i]);
1071 }
1072 }
1073 }
1074
TEST_P(RtcEventLogEncoderTest,RtcEventRtcpNack)1075 TEST_P(RtcEventLogEncoderTest, RtcEventRtcpNack) {
1076 if (force_repeated_fields_) {
1077 return;
1078 }
1079
1080 rtc::ScopedFakeClock fake_clock;
1081 fake_clock.SetTime(Timestamp::Millis(prng_.Rand<uint32_t>()));
1082
1083 for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
1084 std::vector<rtcp::Nack> events(event_count_);
1085 std::vector<int64_t> timestamps_ms(event_count_);
1086 for (size_t i = 0; i < event_count_; ++i) {
1087 timestamps_ms[i] = rtc::TimeMillis();
1088 events[i] = gen_.NewNack();
1089 rtc::Buffer buffer = events[i].Build();
1090 if (direction == kIncomingPacket) {
1091 history_.push_back(
1092 std::make_unique<RtcEventRtcpPacketIncoming>(buffer));
1093 } else {
1094 history_.push_back(
1095 std::make_unique<RtcEventRtcpPacketOutgoing>(buffer));
1096 }
1097 fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000)));
1098 }
1099
1100 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
1101 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
1102
1103 const auto& nacks = parsed_log_.nacks(direction);
1104 ASSERT_EQ(nacks.size(), event_count_);
1105
1106 for (size_t i = 0; i < event_count_; ++i) {
1107 verifier_.VerifyLoggedNack(timestamps_ms[i], events[i], nacks[i]);
1108 }
1109 }
1110 }
1111
TEST_P(RtcEventLogEncoderTest,RtcEventRtcpRemb)1112 TEST_P(RtcEventLogEncoderTest, RtcEventRtcpRemb) {
1113 if (force_repeated_fields_) {
1114 return;
1115 }
1116
1117 rtc::ScopedFakeClock fake_clock;
1118 fake_clock.SetTime(Timestamp::Millis(prng_.Rand<uint32_t>()));
1119
1120 for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
1121 std::vector<rtcp::Remb> events(event_count_);
1122 std::vector<int64_t> timestamps_ms(event_count_);
1123 for (size_t i = 0; i < event_count_; ++i) {
1124 timestamps_ms[i] = rtc::TimeMillis();
1125 events[i] = gen_.NewRemb();
1126 rtc::Buffer buffer = events[i].Build();
1127 if (direction == kIncomingPacket) {
1128 history_.push_back(
1129 std::make_unique<RtcEventRtcpPacketIncoming>(buffer));
1130 } else {
1131 history_.push_back(
1132 std::make_unique<RtcEventRtcpPacketOutgoing>(buffer));
1133 }
1134 fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000)));
1135 }
1136
1137 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
1138 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
1139
1140 const auto& rembs = parsed_log_.rembs(direction);
1141 ASSERT_EQ(rembs.size(), event_count_);
1142
1143 for (size_t i = 0; i < event_count_; ++i) {
1144 verifier_.VerifyLoggedRemb(timestamps_ms[i], events[i], rembs[i]);
1145 }
1146 }
1147 }
1148
TEST_P(RtcEventLogEncoderTest,RtcEventRtcpTransportFeedback)1149 TEST_P(RtcEventLogEncoderTest, RtcEventRtcpTransportFeedback) {
1150 if (force_repeated_fields_) {
1151 return;
1152 }
1153
1154 rtc::ScopedFakeClock fake_clock;
1155 fake_clock.SetTime(Timestamp::Millis(prng_.Rand<uint32_t>()));
1156
1157 for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
1158 std::vector<rtcp::TransportFeedback> events;
1159 events.reserve(event_count_);
1160 std::vector<int64_t> timestamps_ms(event_count_);
1161 for (size_t i = 0; i < event_count_; ++i) {
1162 timestamps_ms[i] = rtc::TimeMillis();
1163 events.emplace_back(gen_.NewTransportFeedback());
1164 rtc::Buffer buffer = events[i].Build();
1165 if (direction == kIncomingPacket) {
1166 history_.push_back(
1167 std::make_unique<RtcEventRtcpPacketIncoming>(buffer));
1168 } else {
1169 history_.push_back(
1170 std::make_unique<RtcEventRtcpPacketOutgoing>(buffer));
1171 }
1172 fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000)));
1173 }
1174
1175 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
1176 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
1177
1178 const auto& transport_feedbacks =
1179 parsed_log_.transport_feedbacks(direction);
1180 ASSERT_EQ(transport_feedbacks.size(), event_count_);
1181
1182 for (size_t i = 0; i < event_count_; ++i) {
1183 verifier_.VerifyLoggedTransportFeedback(timestamps_ms[i], events[i],
1184 transport_feedbacks[i]);
1185 }
1186 }
1187 }
1188
TEST_P(RtcEventLogEncoderTest,RtcEventRtcpLossNotification)1189 TEST_P(RtcEventLogEncoderTest, RtcEventRtcpLossNotification) {
1190 if (force_repeated_fields_) {
1191 return;
1192 }
1193
1194 rtc::ScopedFakeClock fake_clock;
1195 fake_clock.SetTime(Timestamp::Millis(prng_.Rand<uint32_t>()));
1196
1197 for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
1198 std::vector<rtcp::LossNotification> events;
1199 events.reserve(event_count_);
1200 std::vector<int64_t> timestamps_ms(event_count_);
1201 for (size_t i = 0; i < event_count_; ++i) {
1202 timestamps_ms[i] = rtc::TimeMillis();
1203 events.emplace_back(gen_.NewLossNotification());
1204 rtc::Buffer buffer = events[i].Build();
1205 if (direction == kIncomingPacket) {
1206 history_.push_back(
1207 std::make_unique<RtcEventRtcpPacketIncoming>(buffer));
1208 } else {
1209 history_.push_back(
1210 std::make_unique<RtcEventRtcpPacketOutgoing>(buffer));
1211 }
1212 fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000)));
1213 }
1214
1215 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
1216 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
1217
1218 const auto& loss_notifications = parsed_log_.loss_notifications(direction);
1219 ASSERT_EQ(loss_notifications.size(), event_count_);
1220
1221 for (size_t i = 0; i < event_count_; ++i) {
1222 verifier_.VerifyLoggedLossNotification(timestamps_ms[i], events[i],
1223 loss_notifications[i]);
1224 }
1225 }
1226 }
1227
TEST_P(RtcEventLogEncoderTest,RtcEventRtpPacketIncoming)1228 TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketIncoming) {
1229 TestRtpPackets<RtcEventRtpPacketIncoming, LoggedRtpPacketIncoming>();
1230 }
1231
TEST_P(RtcEventLogEncoderTest,RtcEventRtpPacketOutgoing)1232 TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketOutgoing) {
1233 TestRtpPackets<RtcEventRtpPacketOutgoing, LoggedRtpPacketOutgoing>();
1234 }
1235
1236 // TODO(eladalon/terelius): Test with multiple events in the batch.
TEST_P(RtcEventLogEncoderTest,RtcEventVideoReceiveStreamConfig)1237 TEST_P(RtcEventLogEncoderTest, RtcEventVideoReceiveStreamConfig) {
1238 uint32_t ssrc = prng_.Rand<uint32_t>();
1239 RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap();
1240 std::unique_ptr<RtcEventVideoReceiveStreamConfig> event =
1241 gen_.NewVideoReceiveStreamConfig(ssrc, extensions);
1242 history_.push_back(event->Copy());
1243
1244 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
1245 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
1246 const auto& video_recv_configs = parsed_log_.video_recv_configs();
1247
1248 ASSERT_EQ(video_recv_configs.size(), 1u);
1249 verifier_.VerifyLoggedVideoRecvConfig(*event, video_recv_configs[0]);
1250 }
1251
1252 // TODO(eladalon/terelius): Test with multiple events in the batch.
TEST_P(RtcEventLogEncoderTest,RtcEventVideoSendStreamConfig)1253 TEST_P(RtcEventLogEncoderTest, RtcEventVideoSendStreamConfig) {
1254 uint32_t ssrc = prng_.Rand<uint32_t>();
1255 RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap();
1256 std::unique_ptr<RtcEventVideoSendStreamConfig> event =
1257 gen_.NewVideoSendStreamConfig(ssrc, extensions);
1258 history_.push_back(event->Copy());
1259
1260 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
1261 ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
1262 const auto& video_send_configs = parsed_log_.video_send_configs();
1263
1264 ASSERT_EQ(video_send_configs.size(), 1u);
1265 verifier_.VerifyLoggedVideoSendConfig(*event, video_send_configs[0]);
1266 }
1267
1268 INSTANTIATE_TEST_SUITE_P(
1269 RandomSeeds,
1270 RtcEventLogEncoderTest,
1271 ::testing::Combine(/* Random seed*: */ ::testing::Values(1, 2, 3, 4, 5),
1272 /* Encoding: */
1273 ::testing::Values(RtcEventLog::EncodingType::Legacy,
1274 RtcEventLog::EncodingType::NewFormat),
1275 /* Event count: */ ::testing::Values(1, 2, 10, 100),
1276 /* Repeated fields: */ ::testing::Bool()));
1277
1278 class RtcEventLogEncoderSimpleTest
1279 : public ::testing::TestWithParam<RtcEventLog::EncodingType> {
1280 protected:
RtcEventLogEncoderSimpleTest()1281 RtcEventLogEncoderSimpleTest() : encoding_type_(GetParam()) {
1282 switch (encoding_type_) {
1283 case RtcEventLog::EncodingType::Legacy:
1284 encoder_ = std::make_unique<RtcEventLogEncoderLegacy>();
1285 break;
1286 case RtcEventLog::EncodingType::NewFormat:
1287 encoder_ = std::make_unique<RtcEventLogEncoderNewFormat>();
1288 break;
1289 case RtcEventLog::EncodingType::ProtoFree:
1290 encoder_ = std::make_unique<RtcEventLogEncoderV3>();
1291 break;
1292 }
1293 encoded_ =
1294 encoder_->EncodeLogStart(rtc::TimeMillis(), rtc::TimeUTCMillis());
1295 }
1296 ~RtcEventLogEncoderSimpleTest() override = default;
1297
1298 std::deque<std::unique_ptr<RtcEvent>> history_;
1299 std::unique_ptr<RtcEventLogEncoder> encoder_;
1300 ParsedRtcEventLog parsed_log_;
1301 const RtcEventLog::EncodingType encoding_type_;
1302 std::string encoded_;
1303 };
1304
TEST_P(RtcEventLogEncoderSimpleTest,RtcEventLargeCompoundRtcpPacketIncoming)1305 TEST_P(RtcEventLogEncoderSimpleTest, RtcEventLargeCompoundRtcpPacketIncoming) {
1306 // Create a compound packet containing multiple Bye messages.
1307 rtc::Buffer packet;
1308 size_t index = 0;
1309 for (int i = 0; i < 8; i++) {
1310 rtcp::Bye bye;
1311 std::string reason(255, 'a'); // Add some arbitrary data.
1312 bye.SetReason(reason);
1313 bye.SetSenderSsrc(0x12345678);
1314 packet.SetSize(packet.size() + bye.BlockLength());
1315 bool created =
1316 bye.Create(packet.data(), &index, packet.capacity(), nullptr);
1317 ASSERT_TRUE(created);
1318 ASSERT_EQ(index, packet.size());
1319 }
1320
1321 EXPECT_GT(packet.size(), static_cast<size_t>(IP_PACKET_SIZE));
1322 auto event = std::make_unique<RtcEventRtcpPacketIncoming>(packet);
1323 history_.push_back(event->Copy());
1324 encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end());
1325
1326 ParsedRtcEventLog::ParseStatus status = parsed_log_.ParseString(encoded_);
1327 ASSERT_TRUE(status.ok()) << status.message();
1328
1329 const auto& incoming_rtcp_packets = parsed_log_.incoming_rtcp_packets();
1330 ASSERT_EQ(incoming_rtcp_packets.size(), 1u);
1331 ASSERT_EQ(incoming_rtcp_packets[0].rtcp.raw_data.size(), packet.size());
1332 EXPECT_EQ(memcmp(incoming_rtcp_packets[0].rtcp.raw_data.data(), packet.data(),
1333 packet.size()),
1334 0);
1335 }
1336
1337 INSTANTIATE_TEST_SUITE_P(
1338 LargeCompoundRtcp,
1339 RtcEventLogEncoderSimpleTest,
1340 ::testing::Values(RtcEventLog::EncodingType::Legacy,
1341 RtcEventLog::EncodingType::NewFormat));
1342
1343 } // namespace webrtc
1344