xref: /aosp_15_r20/external/webrtc/system_wrappers/source/ntp_time_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2014 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 "system_wrappers/include/ntp_time.h"
12 
13 #include <random>
14 
15 #include "system_wrappers/include/clock.h"
16 #include "test/gtest.h"
17 
18 namespace webrtc {
19 namespace {
20 
21 constexpr uint32_t kNtpSec = 0x12345678;
22 constexpr uint32_t kNtpFrac = 0x23456789;
23 
24 constexpr int64_t kOneSecQ32x32 = uint64_t{1} << 32;
25 constexpr int64_t kOneMsQ32x32 = 4294967;
26 
TEST(NtpTimeTest,NoValueMeansInvalid)27 TEST(NtpTimeTest, NoValueMeansInvalid) {
28   NtpTime ntp;
29   EXPECT_FALSE(ntp.Valid());
30 }
31 
TEST(NtpTimeTest,CanResetValue)32 TEST(NtpTimeTest, CanResetValue) {
33   NtpTime ntp(kNtpSec, kNtpFrac);
34   EXPECT_TRUE(ntp.Valid());
35   ntp.Reset();
36   EXPECT_FALSE(ntp.Valid());
37 }
38 
TEST(NtpTimeTest,CanGetWhatIsSet)39 TEST(NtpTimeTest, CanGetWhatIsSet) {
40   NtpTime ntp;
41   ntp.Set(kNtpSec, kNtpFrac);
42   EXPECT_EQ(kNtpSec, ntp.seconds());
43   EXPECT_EQ(kNtpFrac, ntp.fractions());
44 }
45 
TEST(NtpTimeTest,SetIsSameAs2ParameterConstructor)46 TEST(NtpTimeTest, SetIsSameAs2ParameterConstructor) {
47   NtpTime ntp1(kNtpSec, kNtpFrac);
48   NtpTime ntp2;
49   EXPECT_NE(ntp1, ntp2);
50 
51   ntp2.Set(kNtpSec, kNtpFrac);
52   EXPECT_EQ(ntp1, ntp2);
53 }
54 
TEST(NtpTimeTest,ToMsMeansToNtpMilliseconds)55 TEST(NtpTimeTest, ToMsMeansToNtpMilliseconds) {
56   SimulatedClock clock(0x123456789abc);
57 
58   NtpTime ntp = clock.CurrentNtpTime();
59   EXPECT_EQ(ntp.ToMs(), clock.CurrentNtpInMilliseconds());
60 }
61 
TEST(NtpTimeTest,CanExplicitlyConvertToAndFromUint64)62 TEST(NtpTimeTest, CanExplicitlyConvertToAndFromUint64) {
63   uint64_t untyped_time = 0x123456789;
64   NtpTime time(untyped_time);
65   EXPECT_EQ(untyped_time, static_cast<uint64_t>(time));
66   EXPECT_EQ(NtpTime(0x12345678, 0x90abcdef), NtpTime(0x1234567890abcdef));
67 }
68 
TEST(NtpTimeTest,VerifyInt64MsToQ32x32NearZero)69 TEST(NtpTimeTest, VerifyInt64MsToQ32x32NearZero) {
70   // Zero
71   EXPECT_EQ(Int64MsToQ32x32(0), 0);
72 
73   // Zero + 1 millisecond
74   EXPECT_EQ(Int64MsToQ32x32(1), kOneMsQ32x32);
75 
76   // Zero - 1 millisecond
77   EXPECT_EQ(Int64MsToQ32x32(-1), -kOneMsQ32x32);
78 
79   // Zero + 1 second
80   EXPECT_EQ(Int64MsToQ32x32(1000), kOneSecQ32x32);
81 
82   // Zero - 1 second
83   EXPECT_EQ(Int64MsToQ32x32(-1000), -kOneSecQ32x32);
84 }
85 
TEST(NtpTimeTest,VerifyInt64MsToUQ32x32NearZero)86 TEST(NtpTimeTest, VerifyInt64MsToUQ32x32NearZero) {
87   // Zero
88   EXPECT_EQ(Int64MsToUQ32x32(0), uint64_t{0});
89 
90   // Zero + 1 millisecond
91   EXPECT_EQ(Int64MsToUQ32x32(1), uint64_t{kOneMsQ32x32});
92 
93   // Zero - 1 millisecond
94   EXPECT_EQ(Int64MsToUQ32x32(-1), uint64_t{0});  // Clamped
95 
96   // Zero + 1 second
97   EXPECT_EQ(Int64MsToUQ32x32(1000), uint64_t{kOneSecQ32x32});
98 
99   // Zero - 1 second
100   EXPECT_EQ(Int64MsToUQ32x32(-1000), uint64_t{0});  // Clamped
101 }
102 
TEST(NtpTimeTest,VerifyQ32x32ToInt64MsNearZero)103 TEST(NtpTimeTest, VerifyQ32x32ToInt64MsNearZero) {
104   // Zero
105   EXPECT_EQ(Q32x32ToInt64Ms(0), 0);
106 
107   // Zero + 1 millisecond
108   EXPECT_EQ(Q32x32ToInt64Ms(kOneMsQ32x32), 1);
109 
110   // Zero - 1 millisecond
111   EXPECT_EQ(Q32x32ToInt64Ms(-kOneMsQ32x32), -1);
112 
113   // Zero + 1 second
114   EXPECT_EQ(Q32x32ToInt64Ms(kOneSecQ32x32), 1000);
115 
116   // Zero - 1 second
117   EXPECT_EQ(Q32x32ToInt64Ms(-kOneSecQ32x32), -1000);
118 }
119 
TEST(NtpTimeTest,VerifyUQ32x32ToInt64MsNearZero)120 TEST(NtpTimeTest, VerifyUQ32x32ToInt64MsNearZero) {
121   // Zero
122   EXPECT_EQ(UQ32x32ToInt64Ms(0), 0);
123 
124   // Zero + 1 millisecond
125   EXPECT_EQ(UQ32x32ToInt64Ms(kOneMsQ32x32), 1);
126 
127   // Zero + 1 second
128   EXPECT_EQ(UQ32x32ToInt64Ms(kOneSecQ32x32), 1000);
129 }
130 
TEST(NtpTimeTest,VerifyInt64MsToQ32x32NearMax)131 TEST(NtpTimeTest, VerifyInt64MsToQ32x32NearMax) {
132   constexpr int64_t kMaxQ32x32 = std::numeric_limits<int64_t>::max();
133   constexpr int64_t kBoundaryMs = (kMaxQ32x32 >> 32) * 1000 + 999;
134 
135   // Max
136   const int64_t boundary_q32x32 = Int64MsToQ32x32(kBoundaryMs);
137   EXPECT_LE(boundary_q32x32, kMaxQ32x32);
138   EXPECT_GT(boundary_q32x32, kMaxQ32x32 - kOneMsQ32x32);
139 
140   // Max + 1 millisecond
141   EXPECT_EQ(Int64MsToQ32x32(kBoundaryMs + 1), kMaxQ32x32);  // Clamped
142 
143   // Max - 1 millisecond
144   EXPECT_LE(Int64MsToQ32x32(kBoundaryMs - 1), kMaxQ32x32 - kOneMsQ32x32);
145 
146   // Max + 1 second
147   EXPECT_EQ(Int64MsToQ32x32(kBoundaryMs + 1000), kMaxQ32x32);  // Clamped
148 
149   // Max - 1 second
150   EXPECT_LE(Int64MsToQ32x32(kBoundaryMs - 1000), kMaxQ32x32 - kOneSecQ32x32);
151 }
152 
TEST(NtpTimeTest,VerifyInt64MsToUQ32x32NearMax)153 TEST(NtpTimeTest, VerifyInt64MsToUQ32x32NearMax) {
154   constexpr uint64_t kMaxUQ32x32 = std::numeric_limits<uint64_t>::max();
155   constexpr int64_t kBoundaryMs = (kMaxUQ32x32 >> 32) * 1000 + 999;
156 
157   // Max
158   const uint64_t boundary_uq32x32 = Int64MsToUQ32x32(kBoundaryMs);
159   EXPECT_LE(boundary_uq32x32, kMaxUQ32x32);
160   EXPECT_GT(boundary_uq32x32, kMaxUQ32x32 - kOneMsQ32x32);
161 
162   // Max + 1 millisecond
163   EXPECT_EQ(Int64MsToUQ32x32(kBoundaryMs + 1), kMaxUQ32x32);  // Clamped
164 
165   // Max - 1 millisecond
166   EXPECT_LE(Int64MsToUQ32x32(kBoundaryMs - 1), kMaxUQ32x32 - kOneMsQ32x32);
167 
168   // Max + 1 second
169   EXPECT_EQ(Int64MsToUQ32x32(kBoundaryMs + 1000), kMaxUQ32x32);  // Clamped
170 
171   // Max - 1 second
172   EXPECT_LE(Int64MsToUQ32x32(kBoundaryMs - 1000), kMaxUQ32x32 - kOneSecQ32x32);
173 }
174 
TEST(NtpTimeTest,VerifyQ32x32ToInt64MsNearMax)175 TEST(NtpTimeTest, VerifyQ32x32ToInt64MsNearMax) {
176   constexpr int64_t kMaxQ32x32 = std::numeric_limits<int64_t>::max();
177   constexpr int64_t kBoundaryMs = (kMaxQ32x32 >> 32) * 1000 + 1000;
178 
179   // Max
180   EXPECT_EQ(Q32x32ToInt64Ms(kMaxQ32x32), kBoundaryMs);
181 
182   // Max - 1 millisecond
183   EXPECT_EQ(Q32x32ToInt64Ms(kMaxQ32x32 - kOneMsQ32x32), kBoundaryMs - 1);
184 
185   // Max - 1 second
186   EXPECT_EQ(Q32x32ToInt64Ms(kMaxQ32x32 - kOneSecQ32x32), kBoundaryMs - 1000);
187 }
188 
TEST(NtpTimeTest,VerifyUQ32x32ToInt64MsNearMax)189 TEST(NtpTimeTest, VerifyUQ32x32ToInt64MsNearMax) {
190   constexpr uint64_t kMaxUQ32x32 = std::numeric_limits<uint64_t>::max();
191   constexpr int64_t kBoundaryMs = (kMaxUQ32x32 >> 32) * 1000 + 1000;
192 
193   // Max
194   EXPECT_EQ(UQ32x32ToInt64Ms(kMaxUQ32x32), kBoundaryMs);
195 
196   // Max - 1 millisecond
197   EXPECT_EQ(UQ32x32ToInt64Ms(kMaxUQ32x32 - kOneMsQ32x32), kBoundaryMs - 1);
198 
199   // Max - 1 second
200   EXPECT_EQ(UQ32x32ToInt64Ms(kMaxUQ32x32 - kOneSecQ32x32), kBoundaryMs - 1000);
201 }
202 
TEST(NtpTimeTest,VerifyInt64MsToQ32x32NearMin)203 TEST(NtpTimeTest, VerifyInt64MsToQ32x32NearMin) {
204   constexpr int64_t kBoundaryQ32x32 = 0x8000000000000000;
205   constexpr int64_t kBoundaryMs = -int64_t{0x80000000} * 1000;
206 
207   // Min
208   EXPECT_EQ(Int64MsToQ32x32(kBoundaryMs), kBoundaryQ32x32);
209 
210   // Min + 1 millisecond
211   EXPECT_EQ(Q32x32ToInt64Ms(Int64MsToQ32x32(kBoundaryMs + 1)), kBoundaryMs + 1);
212 
213   // Min - 1 millisecond
214   EXPECT_EQ(Int64MsToQ32x32(kBoundaryMs - 1), kBoundaryQ32x32);  // Clamped
215 
216   // Min + 1 second
217   EXPECT_EQ(Int64MsToQ32x32(kBoundaryMs + 1000),
218             kBoundaryQ32x32 + kOneSecQ32x32);
219 
220   // Min - 1 second
221   EXPECT_EQ(Int64MsToQ32x32(kBoundaryMs - 1000), kBoundaryQ32x32);  // Clamped
222 }
223 
TEST(NtpTimeTest,VerifyQ32x32ToInt64MsNearMin)224 TEST(NtpTimeTest, VerifyQ32x32ToInt64MsNearMin) {
225   constexpr int64_t kBoundaryQ32x32 = 0x8000000000000000;
226   constexpr int64_t kBoundaryMs = -int64_t{0x80000000} * 1000;
227 
228   // Min
229   EXPECT_EQ(Q32x32ToInt64Ms(kBoundaryQ32x32), kBoundaryMs);
230 
231   // Min + 1 millisecond
232   EXPECT_EQ(Q32x32ToInt64Ms(kBoundaryQ32x32 + kOneMsQ32x32), kBoundaryMs + 1);
233 
234   // Min + 1 second
235   EXPECT_EQ(Q32x32ToInt64Ms(kBoundaryQ32x32 + kOneSecQ32x32),
236             kBoundaryMs + 1000);
237 }
238 
TEST(NtpTimeTest,VerifyInt64MsToQ32x32RoundTrip)239 TEST(NtpTimeTest, VerifyInt64MsToQ32x32RoundTrip) {
240   constexpr int kIterations = 50000;
241 
242   std::mt19937 generator(123456789);
243   std::uniform_int_distribution<int64_t> distribution(
244       Q32x32ToInt64Ms(std::numeric_limits<int64_t>::min()),
245       Q32x32ToInt64Ms(std::numeric_limits<int64_t>::max()));
246 
247   for (int iteration = 0; iteration < kIterations; ++iteration) {
248     int64_t input_ms = distribution(generator);
249     int64_t transit_q32x32 = Int64MsToQ32x32(input_ms);
250     int64_t output_ms = Q32x32ToInt64Ms(transit_q32x32);
251 
252     ASSERT_EQ(input_ms, output_ms)
253         << "iteration = " << iteration << ", input_ms = " << input_ms
254         << ", transit_q32x32 = " << transit_q32x32
255         << ", output_ms = " << output_ms;
256   }
257 }
258 
TEST(NtpTimeTest,VerifyInt64MsToUQ32x32RoundTrip)259 TEST(NtpTimeTest, VerifyInt64MsToUQ32x32RoundTrip) {
260   constexpr int kIterations = 50000;
261 
262   std::mt19937 generator(123456789);
263   std::uniform_int_distribution<uint64_t> distribution(
264       UQ32x32ToInt64Ms(std::numeric_limits<uint64_t>::min()),
265       UQ32x32ToInt64Ms(std::numeric_limits<uint64_t>::max()));
266 
267   for (int iteration = 0; iteration < kIterations; ++iteration) {
268     uint64_t input_ms = distribution(generator);
269     uint64_t transit_uq32x32 = Int64MsToUQ32x32(input_ms);
270     uint64_t output_ms = UQ32x32ToInt64Ms(transit_uq32x32);
271 
272     ASSERT_EQ(input_ms, output_ms)
273         << "iteration = " << iteration << ", input_ms = " << input_ms
274         << ", transit_uq32x32 = " << transit_uq32x32
275         << ", output_ms = " << output_ms;
276   }
277 }
278 
279 }  // namespace
280 }  // namespace webrtc
281