1 // Copyright (c) 2011 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.
5 #include "content/common/inter_process_time_ticks_converter.h"
7 #include "base/time/time.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 using base::TimeTicks
;
17 int64 local_lower_bound
;
18 int64 remote_lower_bound
;
19 int64 remote_upper_bound
;
20 int64 local_upper_bound
;
28 bool is_skew_additive
;
32 TestResults
RunTest(const TestParams
& params
) {
33 TimeTicks local_lower_bound
= TimeTicks::FromInternalValue(
34 params
.local_lower_bound
);
35 TimeTicks local_upper_bound
= TimeTicks::FromInternalValue(
36 params
.local_upper_bound
);
37 TimeTicks remote_lower_bound
= TimeTicks::FromInternalValue(
38 params
.remote_lower_bound
);
39 TimeTicks remote_upper_bound
= TimeTicks::FromInternalValue(
40 params
.remote_upper_bound
);
41 TimeTicks test_time
= TimeTicks::FromInternalValue(params
.test_time
);
43 InterProcessTimeTicksConverter
converter(
44 LocalTimeTicks::FromTimeTicks(local_lower_bound
),
45 LocalTimeTicks::FromTimeTicks(local_upper_bound
),
46 RemoteTimeTicks::FromTimeTicks(remote_lower_bound
),
47 RemoteTimeTicks::FromTimeTicks(remote_upper_bound
));
50 results
.result_time
= converter
.ToLocalTimeTicks(
51 RemoteTimeTicks::FromTimeTicks(
52 test_time
)).ToTimeTicks().ToInternalValue();
53 results
.result_delta
= converter
.ToLocalTimeDelta(
54 RemoteTimeDelta::FromRawDelta(params
.test_delta
)).ToInt32();
55 results
.is_skew_additive
= converter
.IsSkewAdditiveForMetrics();
56 results
.skew
= converter
.GetSkewForMetrics().ToInternalValue();
60 TEST(InterProcessTimeTicksConverterTest
, NullTime
) {
61 // Null / zero times should remain null.
63 p
.local_lower_bound
= 1;
64 p
.remote_lower_bound
= 2;
65 p
.remote_upper_bound
= 5;
66 p
.local_upper_bound
= 6;
69 TestResults results
= RunTest(p
);
70 EXPECT_EQ(0, results
.result_time
);
71 EXPECT_EQ(0, results
.result_delta
);
74 TEST(InterProcessTimeTicksConverterTest
, NoSkew
) {
75 // All times are monotonic and centered, so no adjustment should occur.
77 p
.local_lower_bound
= 1;
78 p
.remote_lower_bound
= 2;
79 p
.remote_upper_bound
= 5;
80 p
.local_upper_bound
= 6;
83 TestResults results
= RunTest(p
);
84 EXPECT_EQ(3, results
.result_time
);
85 EXPECT_EQ(1, results
.result_delta
);
86 EXPECT_TRUE(results
.is_skew_additive
);
87 EXPECT_EQ(0, results
.skew
);
90 TEST(InterProcessTimeTicksConverterTest
, OffsetMidpoints
) {
91 // All times are monotonic, but not centered. Adjust the |remote_*| times so
92 // they are centered within the |local_*| times.
94 p
.local_lower_bound
= 1;
95 p
.remote_lower_bound
= 3;
96 p
.remote_upper_bound
= 6;
97 p
.local_upper_bound
= 6;
100 TestResults results
= RunTest(p
);
101 EXPECT_EQ(3, results
.result_time
);
102 EXPECT_EQ(1, results
.result_delta
);
103 EXPECT_TRUE(results
.is_skew_additive
);
104 EXPECT_EQ(1, results
.skew
);
107 TEST(InterProcessTimeTicksConverterTest
, DoubleEndedSkew
) {
108 // |remote_lower_bound| occurs before |local_lower_bound| and
109 // |remote_upper_bound| occurs after |local_upper_bound|. We must adjust both
110 // bounds and scale down the delta. |test_time| is on the midpoint, so it
111 // doesn't change. The ratio of local time to network time is 1:2, so we scale
112 // |test_delta| to half.
114 p
.local_lower_bound
= 3;
115 p
.remote_lower_bound
= 1;
116 p
.remote_upper_bound
= 9;
117 p
.local_upper_bound
= 7;
120 TestResults results
= RunTest(p
);
121 EXPECT_EQ(5, results
.result_time
);
122 EXPECT_EQ(1, results
.result_delta
);
123 EXPECT_FALSE(results
.is_skew_additive
);
126 TEST(InterProcessTimeTicksConverterTest
, FrontEndSkew
) {
127 // |remote_upper_bound| is coherent, but |remote_lower_bound| is not. So we
128 // adjust the lower bound and move |test_time| out. The scale factor is 2:3,
129 // but since we use integers, the numbers truncate from 3.33 to 3 and 1.33
132 p
.local_lower_bound
= 3;
133 p
.remote_lower_bound
= 1;
134 p
.remote_upper_bound
= 7;
135 p
.local_upper_bound
= 7;
138 TestResults results
= RunTest(p
);
139 EXPECT_EQ(4, results
.result_time
);
140 EXPECT_EQ(1, results
.result_delta
);
141 EXPECT_FALSE(results
.is_skew_additive
);
144 TEST(InterProcessTimeTicksConverterTest
, BackEndSkew
) {
145 // Like the previous test, but |remote_lower_bound| is coherent and
146 // |remote_upper_bound| is skewed.
148 p
.local_lower_bound
= 1;
149 p
.remote_lower_bound
= 1;
150 p
.remote_upper_bound
= 7;
151 p
.local_upper_bound
= 5;
154 TestResults results
= RunTest(p
);
155 EXPECT_EQ(2, results
.result_time
);
156 EXPECT_EQ(1, results
.result_delta
);
157 EXPECT_FALSE(results
.is_skew_additive
);
160 TEST(InterProcessTimeTicksConverterTest
, Instantaneous
) {
161 // The bounds are all okay, but the |remote_lower_bound| and
162 // |remote_upper_bound| have the same value. No adjustments should be made and
163 // no divide-by-zero errors should occur.
165 p
.local_lower_bound
= 1;
166 p
.remote_lower_bound
= 2;
167 p
.remote_upper_bound
= 2;
168 p
.local_upper_bound
= 3;
171 TestResults results
= RunTest(p
);
172 EXPECT_EQ(2, results
.result_time
);
173 EXPECT_EQ(0, results
.result_delta
);
176 TEST(InterProcessTimeTicksConverterTest
, OffsetInstantaneous
) {
177 // The bounds are all okay, but the |remote_lower_bound| and
178 // |remote_upper_bound| have the same value and are offset from the midpoint
179 // of |local_lower_bound| and |local_upper_bound|. An offset should be applied
180 // to make the midpoints line up.
182 p
.local_lower_bound
= 1;
183 p
.remote_lower_bound
= 3;
184 p
.remote_upper_bound
= 3;
185 p
.local_upper_bound
= 3;
188 TestResults results
= RunTest(p
);
189 EXPECT_EQ(2, results
.result_time
);
190 EXPECT_EQ(0, results
.result_delta
);
193 TEST(InterProcessTimeTicksConverterTest
, DisjointInstantaneous
) {
194 // |local_lower_bound| and |local_upper_bound| are the same. No matter what
195 // the other values are, they must fit within [local_lower_bound,
196 // local_upper_bound]. So, all of the values should be adjusted so they are
197 // exactly that value.
199 p
.local_lower_bound
= 1;
200 p
.remote_lower_bound
= 2;
201 p
.remote_upper_bound
= 2;
202 p
.local_upper_bound
= 1;
205 TestResults results
= RunTest(p
);
206 EXPECT_EQ(1, results
.result_time
);
207 EXPECT_EQ(0, results
.result_delta
);
210 TEST(InterProcessTimeTicksConverterTest
, RoundingNearEdges
) {
211 // Verify that rounding never causes a value to appear outside the given
213 const int kMaxRange
= 101;
214 for (int i
= 1; i
< kMaxRange
; ++i
) {
215 for (int j
= 1; j
< kMaxRange
; ++j
) {
217 p
.local_lower_bound
= 1;
218 p
.remote_lower_bound
= 1;
219 p
.remote_upper_bound
= j
;
220 p
.local_upper_bound
= i
;
224 TestResults results
= RunTest(p
);
225 EXPECT_LE(1, results
.result_time
);
226 EXPECT_EQ(0, results
.result_delta
);
229 p
.test_delta
= j
- 1;
230 results
= RunTest(p
);
231 EXPECT_GE(i
, results
.result_time
);
232 EXPECT_GE(i
- 1, results
.result_delta
);
237 TEST(InterProcessTimeTicksConverterTest
, DisjointRanges
) {
239 p
.local_lower_bound
= 10;
240 p
.remote_lower_bound
= 30;
241 p
.remote_upper_bound
= 41;
242 p
.local_upper_bound
= 20;
245 TestResults results
= RunTest(p
);
246 EXPECT_EQ(20, results
.result_time
);
247 EXPECT_EQ(0, results
.result_delta
);
250 } // anonymous namespace
252 } // namespace content