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