blob: cd129dd50646ddd3ef2e53ad71c3bc4c4cc8d7df [file] [edit]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cast/streaming/impl/statistics_collector.h"
#include <vector>
#include "cast/streaming/impl/statistics_defines.h"
#include "gtest/gtest.h"
#include "platform/api/time.h"
#include "platform/base/span.h"
#include "platform/test/fake_clock.h"
#include "platform/test/fake_task_runner.h"
#include "util/chrono_helpers.h"
namespace openscreen::cast {
class StatisticsCollectorTest : public ::testing::Test {
public:
StatisticsCollectorTest()
: fake_clock_(Clock::now()), collector_(fake_clock_.now) {}
protected:
FakeClock fake_clock_;
StatisticsCollector collector_;
};
TEST_F(StatisticsCollectorTest, ReturnsEmptyIfNoEvents) {
EXPECT_TRUE(collector_.TakeRecentPacketEvents().empty());
EXPECT_TRUE(collector_.TakeRecentFrameEvents().empty());
}
TEST_F(StatisticsCollectorTest, CanCollectPacketEvents) {
// clang-format off
constexpr PacketEvent kEventOne(
FrameId(5000),
StatisticsEventType::kPacketSentToNetwork,
StatisticsEventMediaType::kAudio,
RtpTimeTicks(47474838),
1234u,
Clock::time_point(milliseconds(12455680)),
Clock::time_point(milliseconds(12455685)),
123u,
456u);
constexpr PacketEvent kEventTwo(
FrameId(20000),
StatisticsEventType::kPacketSentToNetwork,
StatisticsEventMediaType::kVideo,
RtpTimeTicks(4747900),
553u,
Clock::time_point(milliseconds(12455880)),
Clock::time_point(milliseconds(12455889)),
124u,
456u);
// clang-format on
collector_.CollectPacketEvent(kEventOne);
collector_.CollectPacketEvent(kEventTwo);
const std::vector<PacketEvent> events = collector_.TakeRecentPacketEvents();
ASSERT_EQ(2u, events.size());
EXPECT_EQ(kEventOne, events[0]);
EXPECT_EQ(kEventTwo, events[1]);
}
TEST_F(StatisticsCollectorTest, CanCollectPacketSentEvents) {
constexpr std::array<uint8_t, 20> kPacketOne{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
constexpr std::array<uint8_t, 21> kPacketTwo{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
collector_.CollectPacketSentEvent(
ByteView(kPacketOne),
PacketMetadata{StreamType::kAudio, RtpTimeTicks(1234)});
collector_.CollectPacketSentEvent(
ByteView(kPacketTwo),
PacketMetadata{StreamType::kVideo, RtpTimeTicks(2234)});
const std::vector<PacketEvent> events = collector_.TakeRecentPacketEvents();
ASSERT_EQ(2u, events.size());
EXPECT_EQ(3856u, events[0].packet_id);
EXPECT_EQ(4370u, events[0].max_packet_id);
EXPECT_EQ(RtpTimeTicks(84281096), events[0].rtp_timestamp);
EXPECT_EQ(FrameId(), events[0].frame_id);
EXPECT_EQ(20u, events[0].size);
EXPECT_GT(Clock::now(), events[0].timestamp);
EXPECT_EQ(StatisticsEventType::kPacketSentToNetwork, events[0].type);
EXPECT_EQ(StatisticsEventMediaType::kAudio, events[0].media_type);
EXPECT_EQ(3599u, events[1].packet_id);
EXPECT_EQ(4113u, events[1].max_packet_id);
EXPECT_EQ(RtpTimeTicks(67438087), events[1].rtp_timestamp);
EXPECT_EQ(FrameId(), events[1].frame_id);
EXPECT_EQ(21u, events[1].size);
EXPECT_GT(Clock::now(), events[1].timestamp);
EXPECT_EQ(StatisticsEventType::kPacketSentToNetwork, events[1].type);
EXPECT_EQ(StatisticsEventMediaType::kVideo, events[1].media_type);
}
TEST_F(StatisticsCollectorTest, CanCollectFrameEvents) {
// clang-format off
constexpr FrameEvent kEventOne(
FrameId(1),
StatisticsEventType::kFrameAckReceived,
StatisticsEventMediaType::kVideo,
RtpTimeTicks(1233),
/* size= */ 0,
Clock::time_point(milliseconds(12345678)),
Clock::time_point(milliseconds(12345699)),
/* width= */ 640,
/* height= */ 480,
/* delay_delta= */ std::chrono::milliseconds(20),
/* key_frame= */ false,
/* target_bitrate= */ 0);
constexpr FrameEvent kEventTwo(
FrameId(2),
StatisticsEventType::kFramePlayedOut,
StatisticsEventMediaType::kAudio,
RtpTimeTicks(1733),
/* size= */ 6000,
Clock::time_point(milliseconds(12455680)),
Clock::time_point(milliseconds(12455685)),
/* width= */ 0,
/* height= */ 0,
/* delay_delta= */ std::chrono::milliseconds(10),
/* key_frame= */ false,
/* target_bitrate = */ 5000);
// clang-format on
collector_.CollectFrameEvent(kEventOne);
collector_.CollectFrameEvent(kEventTwo);
const std::vector<FrameEvent> events = collector_.TakeRecentFrameEvents();
ASSERT_EQ(2u, events.size());
EXPECT_EQ(kEventOne, events[0]);
EXPECT_EQ(kEventTwo, events[1]);
}
} // namespace openscreen::cast