summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/time_clamper_test.cc
blob: f519dcfb692db08bcbd0284b5cd6fda69dd274ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/platform/time_clamper.h"

#include "testing/gtest/include/gtest/gtest.h"

#include <cmath>

namespace blink {
namespace {
const double kInterval = TimeClamper::kResolutionSeconds;
}

TEST(TimeClamperTest, TimeStampsAreNonNegative) {
  TimeClamper clamper;
  EXPECT_GE(clamper.ClampTimeResolution(0), 0.f);
  EXPECT_GE(clamper.ClampTimeResolution(TimeClamper::kResolutionSeconds), 0.f);
}

TEST(TimeClamperTest, TimeStampsIncreaseByFixedAmount) {
  const double kEpsilon = 1e-10;
  TimeClamper clamper;
  double prev = clamper.ClampTimeResolution(0);
  for (double time_seconds = 0; time_seconds < kInterval * 100;
       time_seconds += kInterval * 0.1) {
    double clamped_time = clamper.ClampTimeResolution(time_seconds);
    double delta = clamped_time - prev;
    ASSERT_GE(delta, 0);
    if (delta > kEpsilon) {
      ASSERT_TRUE(std::fabs(delta - kInterval) < kEpsilon);
      prev = clamped_time;
    }
  }
}

TEST(TimeClamperTest, ClampingIsConsistent) {
  TimeClamper clamper;
  for (double time_seconds = 0; time_seconds < kInterval * 100;
       time_seconds += kInterval * 0.1) {
    double t1 = clamper.ClampTimeResolution(time_seconds);
    double t2 = clamper.ClampTimeResolution(time_seconds);
    EXPECT_EQ(t1, t2);
  }
}

TEST(TimeClamperTest, ClampingIsPerInstance) {
  const double kEpsilon = 1e-10;
  TimeClamper clamper1;
  TimeClamper clamper2;
  double time_seconds = 0;
  while (true) {
    if (std::fabs(clamper1.ClampTimeResolution(time_seconds) -
                  clamper2.ClampTimeResolution(time_seconds)) > kEpsilon) {
      break;
    }
    time_seconds += kInterval;
  }
}

TEST(TimeClamperTest, ClampingIsUniform) {
  const int kBuckets = 8;
  const int kSampleCount = 10000;
  const double kEpsilon = 1e-10;
  const double kTimeStep = kInterval / kBuckets;
  double time_seconds = 299792.458;
  int histogram[kBuckets] = {0};
  TimeClamper clamper;

  // This test ensures the jitter thresholds are approximately uniformly
  // distributed inside the clamping intervals. It samples individual intervals
  // to detect where the threshold is and counts the number of steps taken.
  for (int i = 0; i < kSampleCount; i++) {
    double start = clamper.ClampTimeResolution(time_seconds);
    for (int step = 0; step < kBuckets; step++) {
      time_seconds += kTimeStep;
      if (std::abs(clamper.ClampTimeResolution(time_seconds) - start) >
          kEpsilon) {
        histogram[step]++;
        // Skip to the next interval to make sure each measurement is
        // independent.
        time_seconds = floor(time_seconds / kInterval) * kInterval + kInterval;
        break;
      }
    }
  }

  double expected_count = kSampleCount / kBuckets;
  double chi_squared = 0;
  for (int i = 0; i < kBuckets; ++i) {
    double difference = histogram[i] - expected_count;
    chi_squared += difference * difference / expected_count;
  }
  // P-value for a 0.001 significance level with 7 degrees of freedom.
  EXPECT_LT(chi_squared, 24.322);
}

}  // namespace blink