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