Home | History | Annotate | Download | only in common
      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.
      4 
      5 #include "content/common/inter_process_time_ticks_converter.h"
      6 
      7 #include "base/time/time.h"
      8 #include "testing/gtest/include/gtest/gtest.h"
      9 
     10 using base::TimeTicks;
     11 
     12 namespace content {
     13 
     14 namespace {
     15 
     16 struct TestParams {
     17   int64 local_lower_bound;
     18   int64 remote_lower_bound;
     19   int64 remote_upper_bound;
     20   int64 local_upper_bound;
     21   int64 test_time;
     22   int64 test_delta;
     23 };
     24 
     25 struct TestResults {
     26   int64 result_time;
     27   int32 result_delta;
     28 };
     29 
     30 TestResults RunTest(const TestParams& params) {
     31   TimeTicks local_lower_bound = TimeTicks::FromInternalValue(
     32       params.local_lower_bound);
     33   TimeTicks local_upper_bound = TimeTicks::FromInternalValue(
     34       params.local_upper_bound);
     35   TimeTicks remote_lower_bound = TimeTicks::FromInternalValue(
     36       params.remote_lower_bound);
     37   TimeTicks remote_upper_bound = TimeTicks::FromInternalValue(
     38       params.remote_upper_bound);
     39   TimeTicks test_time = TimeTicks::FromInternalValue(params.test_time);
     40 
     41   InterProcessTimeTicksConverter converter(
     42       LocalTimeTicks::FromTimeTicks(local_lower_bound),
     43       LocalTimeTicks::FromTimeTicks(local_upper_bound),
     44       RemoteTimeTicks::FromTimeTicks(remote_lower_bound),
     45       RemoteTimeTicks::FromTimeTicks(remote_upper_bound));
     46 
     47   TestResults results;
     48   results.result_time = converter.ToLocalTimeTicks(
     49       RemoteTimeTicks::FromTimeTicks(
     50           test_time)).ToTimeTicks().ToInternalValue();
     51   results.result_delta = converter.ToLocalTimeDelta(
     52       RemoteTimeDelta::FromRawDelta(params.test_delta)).ToInt32();
     53   return results;
     54 }
     55 
     56 TEST(InterProcessTimeTicksConverterTest, NullTime) {
     57   // Null / zero times should remain null.
     58   TestParams p;
     59   p.local_lower_bound = 1;
     60   p.remote_lower_bound = 2;
     61   p.remote_upper_bound = 5;
     62   p.local_upper_bound = 6;
     63   p.test_time = 0;
     64   p.test_delta = 0;
     65   TestResults results = RunTest(p);
     66   EXPECT_EQ(0, results.result_time);
     67   EXPECT_EQ(0, results.result_delta);
     68 }
     69 
     70 TEST(InterProcessTimeTicksConverterTest, NoSkew) {
     71   // All times are monotonic and centered, so no adjustment should occur.
     72   TestParams p;
     73   p.local_lower_bound = 1;
     74   p.remote_lower_bound = 2;
     75   p.remote_upper_bound = 5;
     76   p.local_upper_bound = 6;
     77   p.test_time = 3;
     78   p.test_delta = 1;
     79   TestResults results = RunTest(p);
     80   EXPECT_EQ(3, results.result_time);
     81   EXPECT_EQ(1, results.result_delta);
     82 }
     83 
     84 TEST(InterProcessTimeTicksConverterTest, OffsetMidpoints) {
     85   // All times are monotonic, but not centered. Adjust the |remote_*| times so
     86   // they are centered within the |local_*| times.
     87   TestParams p;
     88   p.local_lower_bound = 1;
     89   p.remote_lower_bound = 3;
     90   p.remote_upper_bound = 6;
     91   p.local_upper_bound = 6;
     92   p.test_time = 4;
     93   p.test_delta = 1;
     94   TestResults results = RunTest(p);
     95   EXPECT_EQ(3, results.result_time);
     96   EXPECT_EQ(1, results.result_delta);
     97 }
     98 
     99 TEST(InterProcessTimeTicksConverterTest, DoubleEndedSkew) {
    100   // |remote_lower_bound| occurs before |local_lower_bound| and
    101   // |remote_upper_bound| occurs after |local_upper_bound|. We must adjust both
    102   // bounds and scale down the delta. |test_time| is on the midpoint, so it
    103   // doesn't change. The ratio of local time to network time is 1:2, so we scale
    104   // |test_delta| to half.
    105   TestParams p;
    106   p.local_lower_bound = 3;
    107   p.remote_lower_bound = 1;
    108   p.remote_upper_bound = 9;
    109   p.local_upper_bound = 7;
    110   p.test_time = 5;
    111   p.test_delta = 2;
    112   TestResults results = RunTest(p);
    113   EXPECT_EQ(5, results.result_time);
    114   EXPECT_EQ(1, results.result_delta);
    115 }
    116 
    117 TEST(InterProcessTimeTicksConverterTest, FrontEndSkew) {
    118   // |remote_upper_bound| is coherent, but |remote_lower_bound| is not. So we
    119   // adjust the lower bound and move |test_time| out. The scale factor is 2:3,
    120   // but since we use integers, the numbers truncate from 3.33 to 3 and 1.33
    121   // to 1.
    122   TestParams p;
    123   p.local_lower_bound = 3;
    124   p.remote_lower_bound = 1;
    125   p.remote_upper_bound = 7;
    126   p.local_upper_bound = 7;
    127   p.test_time = 3;
    128   p.test_delta = 2;
    129   TestResults results = RunTest(p);
    130   EXPECT_EQ(4, results.result_time);
    131   EXPECT_EQ(1, results.result_delta);
    132 }
    133 
    134 TEST(InterProcessTimeTicksConverterTest, BackEndSkew) {
    135   // Like the previous test, but |remote_lower_bound| is coherent and
    136   // |remote_upper_bound| is skewed.
    137   TestParams p;
    138   p.local_lower_bound = 1;
    139   p.remote_lower_bound = 1;
    140   p.remote_upper_bound = 7;
    141   p.local_upper_bound = 5;
    142   p.test_time = 3;
    143   p.test_delta = 2;
    144   TestResults results = RunTest(p);
    145   EXPECT_EQ(2, results.result_time);
    146   EXPECT_EQ(1, results.result_delta);
    147 }
    148 
    149 TEST(InterProcessTimeTicksConverterTest, Instantaneous) {
    150   // The bounds are all okay, but the |remote_lower_bound| and
    151   // |remote_upper_bound| have the same value. No adjustments should be made and
    152   // no divide-by-zero errors should occur.
    153   TestParams p;
    154   p.local_lower_bound = 1;
    155   p.remote_lower_bound = 2;
    156   p.remote_upper_bound = 2;
    157   p.local_upper_bound = 3;
    158   p.test_time = 2;
    159   p.test_delta = 0;
    160   TestResults results = RunTest(p);
    161   EXPECT_EQ(2, results.result_time);
    162   EXPECT_EQ(0, results.result_delta);
    163 }
    164 
    165 TEST(InterProcessTimeTicksConverterTest, OffsetInstantaneous) {
    166   // The bounds are all okay, but the |remote_lower_bound| and
    167   // |remote_upper_bound| have the same value and are offset from the midpoint
    168   // of |local_lower_bound| and |local_upper_bound|. An offset should be applied
    169   // to make the midpoints line up.
    170   TestParams p;
    171   p.local_lower_bound = 1;
    172   p.remote_lower_bound = 3;
    173   p.remote_upper_bound = 3;
    174   p.local_upper_bound = 3;
    175   p.test_time = 3;
    176   p.test_delta = 0;
    177   TestResults results = RunTest(p);
    178   EXPECT_EQ(2, results.result_time);
    179   EXPECT_EQ(0, results.result_delta);
    180 }
    181 
    182 TEST(InterProcessTimeTicksConverterTest, DisjointInstantaneous) {
    183   // |local_lower_bound| and |local_upper_bound| are the same. No matter what
    184   // the other values are, they must fit within [local_lower_bound,
    185   // local_upper_bound].  So, all of the values should be adjusted so they are
    186   // exactly that value.
    187   TestParams p;
    188   p.local_lower_bound = 1;
    189   p.remote_lower_bound = 2;
    190   p.remote_upper_bound = 2;
    191   p.local_upper_bound = 1;
    192   p.test_time = 2;
    193   p.test_delta = 0;
    194   TestResults results = RunTest(p);
    195   EXPECT_EQ(1, results.result_time);
    196   EXPECT_EQ(0, results.result_delta);
    197 }
    198 
    199 TEST(InterProcessTimeTicksConverterTest, RoundingNearEdges) {
    200   // Verify that rounding never causes a value to appear outside the given
    201   // |local_*| range.
    202   const int kMaxRange = 101;
    203   for (int i = 1; i < kMaxRange; ++i) {
    204     for (int j = 1; j < kMaxRange; ++j) {
    205       TestParams p;
    206       p.local_lower_bound = 1;
    207       p.remote_lower_bound = 1;
    208       p.remote_upper_bound = j;
    209       p.local_upper_bound = i;
    210 
    211       p.test_time = 1;
    212       p.test_delta = 0;
    213       TestResults results = RunTest(p);
    214       EXPECT_LE(1, results.result_time);
    215       EXPECT_EQ(0, results.result_delta);
    216 
    217       p.test_time = j;
    218       p.test_delta = j - 1;
    219       results = RunTest(p);
    220       EXPECT_GE(i, results.result_time);
    221       EXPECT_GE(i - 1, results.result_delta);
    222     }
    223   }
    224 }
    225 
    226 TEST(InterProcessTimeTicksConverterTest, DisjointRanges) {
    227   TestParams p;
    228   p.local_lower_bound = 10;
    229   p.remote_lower_bound = 30;
    230   p.remote_upper_bound = 41;
    231   p.local_upper_bound = 20;
    232   p.test_time = 41;
    233   p.test_delta = 0;
    234   TestResults results = RunTest(p);
    235   EXPECT_EQ(20, results.result_time);
    236   EXPECT_EQ(0, results.result_delta);
    237 }
    238 
    239 }  // anonymous namespace
    240 
    241 }  // namespace content
    242