1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "third_party/blink/renderer/core/timing/time_clamper.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8
9 #include <cmath>
10
11 namespace blink {
12 namespace {
13 const double kInterval = TimeClamper::kResolutionSeconds;
14 }
15
TEST(TimeClamperTest,TimeStampsAreNonNegative)16 TEST(TimeClamperTest, TimeStampsAreNonNegative) {
17 TimeClamper clamper;
18 EXPECT_GE(clamper.ClampTimeResolution(0), 0.f);
19 EXPECT_GE(clamper.ClampTimeResolution(TimeClamper::kResolutionSeconds), 0.f);
20 }
21
TEST(TimeClamperTest,TimeStampsIncreaseByFixedAmount)22 TEST(TimeClamperTest, TimeStampsIncreaseByFixedAmount) {
23 const double kEpsilon = 1e-10;
24 TimeClamper clamper;
25 double prev = clamper.ClampTimeResolution(0);
26 for (double time_seconds = 0; time_seconds < kInterval * 100;
27 time_seconds += kInterval * 0.1) {
28 double clamped_time = clamper.ClampTimeResolution(time_seconds);
29 double delta = clamped_time - prev;
30 ASSERT_GE(delta, 0);
31 if (delta > kEpsilon) {
32 ASSERT_TRUE(std::fabs(delta - kInterval) < kEpsilon);
33 prev = clamped_time;
34 }
35 }
36 }
37
TEST(TimeClamperTest,ClampingIsConsistent)38 TEST(TimeClamperTest, ClampingIsConsistent) {
39 TimeClamper clamper;
40 for (double time_seconds = 0; time_seconds < kInterval * 100;
41 time_seconds += kInterval * 0.1) {
42 double t1 = clamper.ClampTimeResolution(time_seconds);
43 double t2 = clamper.ClampTimeResolution(time_seconds);
44 EXPECT_EQ(t1, t2);
45 }
46 }
47
TEST(TimeClamperTest,ClampingNegativeNumbersIsConsistent)48 TEST(TimeClamperTest, ClampingNegativeNumbersIsConsistent) {
49 TimeClamper clamper;
50 for (double time_seconds = -kInterval * 100; time_seconds <= 0;
51 time_seconds += kInterval * 0.1) {
52 double t1 = clamper.ClampTimeResolution(time_seconds);
53 double t2 = clamper.ClampTimeResolution(time_seconds);
54 EXPECT_EQ(t1, t2);
55 }
56 }
57
TEST(TimeClamperTest,ClampingIsPerInstance)58 TEST(TimeClamperTest, ClampingIsPerInstance) {
59 const double kEpsilon = 1e-10;
60 TimeClamper clamper1;
61 TimeClamper clamper2;
62 double time_seconds = 0;
63 while (true) {
64 if (std::fabs(clamper1.ClampTimeResolution(time_seconds) -
65 clamper2.ClampTimeResolution(time_seconds)) > kEpsilon) {
66 break;
67 }
68 time_seconds += kInterval;
69 }
70 }
71
TEST(TimeClamperTest,ClampingIsUniform)72 TEST(TimeClamperTest, ClampingIsUniform) {
73 const int kBuckets = 8;
74 const int kSampleCount = 10000;
75 const double kEpsilon = 1e-10;
76 const double kTimeStep = kInterval / kBuckets;
77 double time_seconds = 299792.458;
78 int histogram[kBuckets] = {0};
79 TimeClamper clamper;
80
81 // This test ensures the jitter thresholds are approximately uniformly
82 // distributed inside the clamping intervals. It samples individual intervals
83 // to detect where the threshold is and counts the number of steps taken.
84 for (int i = 0; i < kSampleCount; i++) {
85 double start = clamper.ClampTimeResolution(time_seconds);
86 for (int step = 0; step < kBuckets; step++) {
87 time_seconds += kTimeStep;
88 if (std::abs(clamper.ClampTimeResolution(time_seconds) - start) >
89 kEpsilon) {
90 histogram[step]++;
91 // Skip to the next interval to make sure each measurement is
92 // independent.
93 time_seconds = floor(time_seconds / kInterval) * kInterval + kInterval;
94 break;
95 }
96 }
97 }
98
99 double expected_count = kSampleCount / kBuckets;
100 double chi_squared = 0;
101 for (int i = 0; i < kBuckets; ++i) {
102 double difference = histogram[i] - expected_count;
103 chi_squared += difference * difference / expected_count;
104 }
105 // P-value for a 0.001 significance level with 7 degrees of freedom.
106 EXPECT_LT(chi_squared, 24.322);
107 }
108
109 } // namespace blink
110