|
21 | 21 | #include <iostream> |
22 | 22 | #include <string> |
23 | 23 | #include <string.h> |
| 24 | +#include <thread> |
24 | 25 | #include <type_traits> |
25 | 26 |
|
26 | 27 | #include <gtest/gtest.h> |
27 | 28 | #include <gmock/gmock.h> |
28 | 29 |
|
29 | 30 | #include "priv_aamp.h" |
30 | 31 | #include "AampProfiler.h" |
| 32 | +#include "AampUtils.h" |
31 | 33 |
|
32 | 34 | #include "MockPrivateInstanceAAMP.h" |
33 | 35 | #include "main_aamp.h" |
@@ -1716,14 +1718,118 @@ TEST_F(PrivAampTests,UpdateRefreshPlaylistIntervalTest) |
1716 | 1718 | p_aamp->UpdateRefreshPlaylistInterval(-12.43265); |
1717 | 1719 | } |
1718 | 1720 |
|
1719 | | -TEST_F(PrivAampTests,SendBufferChangeEventTest) |
| 1721 | +// --- Buffering duration tracking tests --- |
| 1722 | + |
| 1723 | +// mBufferingStartTimeMS is initialised to -1 in the constructor; no episode in flight yet. |
| 1724 | +TEST_F(PrivAampTests, SendBufferChangeEvent_InitialTimestampIsUnset) |
| 1725 | +{ |
| 1726 | + EXPECT_EQ(p_aamp->GetBufferingStartTimeMS(), -1LL); |
| 1727 | +} |
| 1728 | + |
| 1729 | +// Start event must capture a plausible steady-clock timestamp (>= before, <= after). |
| 1730 | +TEST_F(PrivAampTests, SendBufferChangeEvent_StartSetsTimestamp) |
| 1731 | +{ |
| 1732 | + long long beforeMs = NOW_STEADY_TS_MS; |
| 1733 | + p_aamp->SendBufferChangeEvent(true); |
| 1734 | + long long afterMs = NOW_STEADY_TS_MS; |
| 1735 | + |
| 1736 | + long long recorded = p_aamp->GetBufferingStartTimeMS(); |
| 1737 | + EXPECT_GE(recorded, beforeMs); |
| 1738 | + EXPECT_LE(recorded, afterMs); |
| 1739 | +} |
| 1740 | + |
| 1741 | +// End event must reset mBufferingStartTimeMS back to -1. |
| 1742 | +TEST_F(PrivAampTests, SendBufferChangeEvent_EndResetsTimestamp) |
| 1743 | +{ |
| 1744 | + p_aamp->SendBufferChangeEvent(true); |
| 1745 | + EXPECT_GE(p_aamp->GetBufferingStartTimeMS(), 0LL); |
| 1746 | + |
| 1747 | + p_aamp->SendBufferChangeEvent(false); |
| 1748 | + EXPECT_EQ(p_aamp->GetBufferingStartTimeMS(), -1LL); |
| 1749 | +} |
| 1750 | + |
| 1751 | +// End call without a preceding start is a no-op: no crash, state stays -1. |
| 1752 | +TEST_F(PrivAampTests, SendBufferChangeEvent_EndWithoutStartIsNoOp) |
| 1753 | +{ |
| 1754 | + ASSERT_EQ(p_aamp->GetBufferingStartTimeMS(), -1LL); |
| 1755 | + p_aamp->SendBufferChangeEvent(false); |
| 1756 | + EXPECT_EQ(p_aamp->GetBufferingStartTimeMS(), -1LL); |
| 1757 | +} |
| 1758 | + |
| 1759 | +// Duplicate start events must not reset the timestamp; only the first call wins. |
| 1760 | +// Verified by sleeping briefly so a second capture would produce a strictly later value. |
| 1761 | +TEST_F(PrivAampTests, SendBufferChangeEvent_DuplicateStartDoesNotResetTimestamp) |
| 1762 | +{ |
| 1763 | + p_aamp->SendBufferChangeEvent(true); |
| 1764 | + long long firstTimestamp = p_aamp->GetBufferingStartTimeMS(); |
| 1765 | + ASSERT_GE(firstTimestamp, 0LL); |
| 1766 | + |
| 1767 | + std::this_thread::sleep_for(std::chrono::milliseconds(5)); |
| 1768 | + p_aamp->SendBufferChangeEvent(true); |
| 1769 | + |
| 1770 | + EXPECT_EQ(p_aamp->GetBufferingStartTimeMS(), firstTimestamp); |
| 1771 | +} |
| 1772 | + |
| 1773 | +// The duration that would be reported to telemetry is bounded by the elapsed real time. |
| 1774 | +// We verify this indirectly: capture the steady-clock window around the end call and |
| 1775 | +// confirm it brackets (end_clock - startTime), then confirm the episode is closed out. |
| 1776 | +TEST_F(PrivAampTests, SendBufferChangeEvent_DurationBoundedByElapsedRealTime) |
| 1777 | +{ |
| 1778 | + p_aamp->SendBufferChangeEvent(true); |
| 1779 | + long long startTime = p_aamp->GetBufferingStartTimeMS(); |
| 1780 | + ASSERT_GE(startTime, 0LL); |
| 1781 | + |
| 1782 | + std::this_thread::sleep_for(std::chrono::milliseconds(5)); |
| 1783 | + |
| 1784 | + long long beforeEnd = NOW_STEADY_TS_MS; |
| 1785 | + p_aamp->SendBufferChangeEvent(false); |
| 1786 | + long long afterEnd = NOW_STEADY_TS_MS; |
| 1787 | + |
| 1788 | + // The internal duration = (steady_clock at end) - startTime. |
| 1789 | + // It must be >= (beforeEnd - startTime) and <= (afterEnd - startTime). |
| 1790 | + long long minDuration = beforeEnd - startTime; |
| 1791 | + long long maxDuration = afterEnd - startTime; |
| 1792 | + EXPECT_GE(minDuration, 0LL); |
| 1793 | + EXPECT_LE(minDuration, maxDuration); |
| 1794 | + |
| 1795 | + // Episode must be closed out. |
| 1796 | + EXPECT_EQ(p_aamp->GetBufferingStartTimeMS(), -1LL); |
| 1797 | +} |
| 1798 | + |
| 1799 | +// BufUnderFlowStatus flag must follow start/end transitions. |
| 1800 | +TEST_F(PrivAampTests, SendBufferChangeEvent_UnderflowStatusTracksTransitions) |
1720 | 1801 | { |
| 1802 | + EXPECT_FALSE(p_aamp->GetBufUnderFlowStatus()); |
| 1803 | + |
1721 | 1804 | p_aamp->SendBufferChangeEvent(true); |
| 1805 | + EXPECT_TRUE(p_aamp->GetBufUnderFlowStatus()); |
| 1806 | + |
| 1807 | + p_aamp->SendBufferChangeEvent(false); |
| 1808 | + EXPECT_FALSE(p_aamp->GetBufUnderFlowStatus()); |
1722 | 1809 | } |
1723 | 1810 |
|
1724 | | -TEST_F(PrivAampTests,SendBufferChangeEventTest_1) |
| 1811 | +// Back-to-back episodes must each be tracked independently: the second start time |
| 1812 | +// must be strictly later than the first (monotonic clock), and each episode closes cleanly. |
| 1813 | +TEST_F(PrivAampTests, SendBufferChangeEvent_SequentialEpisodesTrackedIndependently) |
1725 | 1814 | { |
| 1815 | + // First episode |
| 1816 | + p_aamp->SendBufferChangeEvent(true); |
| 1817 | + long long t1 = p_aamp->GetBufferingStartTimeMS(); |
| 1818 | + ASSERT_GE(t1, 0LL); |
| 1819 | + |
| 1820 | + std::this_thread::sleep_for(std::chrono::milliseconds(2)); |
| 1821 | + p_aamp->SendBufferChangeEvent(false); |
| 1822 | + EXPECT_EQ(p_aamp->GetBufferingStartTimeMS(), -1LL); |
| 1823 | + |
| 1824 | + // Second episode |
| 1825 | + std::this_thread::sleep_for(std::chrono::milliseconds(2)); |
| 1826 | + p_aamp->SendBufferChangeEvent(true); |
| 1827 | + long long t2 = p_aamp->GetBufferingStartTimeMS(); |
| 1828 | + ASSERT_GE(t2, 0LL); |
| 1829 | + EXPECT_GT(t2, t1); // monotonic: second start must be later than first |
| 1830 | + |
1726 | 1831 | p_aamp->SendBufferChangeEvent(false); |
| 1832 | + EXPECT_EQ(p_aamp->GetBufferingStartTimeMS(), -1LL); |
1727 | 1833 | } |
1728 | 1834 |
|
1729 | 1835 | TEST_F(PrivAampTests,PausePipelineTest) |
|
0 commit comments