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 "base/basictypes.h"
6#include "base/macros.h"
7#include "base/message_loop/message_loop.h"
8#include "base/test/simple_test_tick_clock.h"
9#include "components/copresence/timed_map.h"
10#include "testing/gtest/include/gtest/gtest.h"
11
12namespace {
13
14struct Value {
15  Value() : value(0) {}
16  explicit Value(int new_value) : value(new_value) {}
17
18  int value;
19};
20
21}  // namespace
22
23class TimedMapTest : public testing::Test {
24 public:
25  typedef copresence::TimedMap<int, Value> Map;
26
27  TimedMapTest() {}
28
29 private:
30  // Exists since the timer needs a message loop.
31  base::MessageLoop message_loop_;
32
33  DISALLOW_COPY_AND_ASSIGN(TimedMapTest);
34};
35
36TEST_F(TimedMapTest, Basic) {
37  Map map(base::TimeDelta::FromSeconds(9999), 3);
38
39  EXPECT_FALSE(map.HasKey(0));
40  EXPECT_EQ(0, map.GetValue(0).value);
41
42  map.Add(0x1337, Value(0x7331));
43  EXPECT_TRUE(map.HasKey(0x1337));
44  EXPECT_EQ(0x7331, map.GetValue(0x1337).value);
45
46  map.Add(0xbaad, Value(0xf00d));
47  EXPECT_TRUE(map.HasKey(0xbaad));
48  EXPECT_EQ(0xf00d, map.GetValue(0xbaad).value);
49  EXPECT_EQ(0x7331, map.GetValue(0x1337).value);
50
51  map.Add(0x1234, Value(0x5678));
52  EXPECT_TRUE(map.HasKey(0x1234));
53  EXPECT_TRUE(map.HasKey(0xbaad));
54  EXPECT_TRUE(map.HasKey(0x1337));
55
56  EXPECT_EQ(0x5678, map.GetValue(0x1234).value);
57  EXPECT_EQ(0xf00d, map.GetValue(0xbaad).value);
58  EXPECT_EQ(0x7331, map.GetValue(0x1337).value);
59}
60
61TEST_F(TimedMapTest, ValueReplacement) {
62  Map map(base::TimeDelta::FromSeconds(9999), 10);
63
64  map.Add(0x1337, Value(0x7331));
65  EXPECT_TRUE(map.HasKey(0x1337));
66  EXPECT_EQ(0x7331, map.GetValue(0x1337).value);
67
68  map.Add(0xbaad, Value(0xf00d));
69  EXPECT_TRUE(map.HasKey(0xbaad));
70  EXPECT_EQ(0xf00d, map.GetValue(0xbaad).value);
71
72  map.Add(0x1337, Value(0xd00d));
73  EXPECT_TRUE(map.HasKey(0x1337));
74  EXPECT_EQ(0xd00d, map.GetValue(0x1337).value);
75}
76
77TEST_F(TimedMapTest, SizeEvict) {
78  Map two_element_map(base::TimeDelta::FromSeconds(9999), 2);
79
80  two_element_map.Add(0x1337, Value(0x7331));
81  EXPECT_TRUE(two_element_map.HasKey(0x1337));
82  EXPECT_EQ(0x7331, two_element_map.GetValue(0x1337).value);
83
84  two_element_map.Add(0xbaad, Value(0xf00d));
85  EXPECT_TRUE(two_element_map.HasKey(0xbaad));
86  EXPECT_EQ(0xf00d, two_element_map.GetValue(0xbaad).value);
87
88  two_element_map.Add(0x1234, Value(0x5678));
89  EXPECT_TRUE(two_element_map.HasKey(0x1234));
90  EXPECT_EQ(0xf00d, two_element_map.GetValue(0xbaad).value);
91
92  EXPECT_FALSE(two_element_map.HasKey(0x1337));
93  EXPECT_EQ(0, two_element_map.GetValue(0x1337).value);
94}
95
96TEST_F(TimedMapTest, TimedEvict) {
97  const int kLargeTimeValueSeconds = 9999;
98  Map map(base::TimeDelta::FromSeconds(kLargeTimeValueSeconds), 2);
99
100  // The map takes ownership of the clock, but we retain a pointer.
101  base::SimpleTestTickClock* clock = new base::SimpleTestTickClock;
102  map.set_clock_for_testing(make_scoped_ptr<base::TickClock>(clock));
103
104  // Add value at T=0.
105  map.Add(0x1337, Value(0x7331));
106  EXPECT_TRUE(map.HasKey(0x1337));
107  EXPECT_EQ(0x7331, map.GetValue(0x1337).value);
108
109  // Add value at T=kLargeTimeValueSeconds-1.
110  clock->Advance(base::TimeDelta::FromSeconds(kLargeTimeValueSeconds - 1));
111  map.Add(0xbaad, Value(0xf00d));
112
113  // Check values at T=kLargeTimeValueSeconds-1.
114  EXPECT_TRUE(map.HasKey(0xbaad));
115  EXPECT_EQ(0xf00d, map.GetValue(0xbaad).value);
116  EXPECT_TRUE(map.HasKey(0x1337));
117  EXPECT_EQ(0x7331, map.GetValue(0x1337).value);
118
119  // Check values at T=kLargeTimeValueSeconds.
120  clock->Advance(base::TimeDelta::FromSeconds(1));
121  EXPECT_FALSE(map.HasKey(0x1337));
122  EXPECT_EQ(0, map.GetValue(0x1337).value);
123  EXPECT_TRUE(map.HasKey(0xbaad));
124  EXPECT_EQ(0xf00d, map.GetValue(0xbaad).value);
125
126  // Check values at T=2*kLargeTimeValueSeconds
127  clock->Advance(base::TimeDelta::FromSeconds(kLargeTimeValueSeconds));
128  EXPECT_FALSE(map.HasKey(0xbaad));
129  EXPECT_EQ(0, map.GetValue(0xbaad).value);
130}
131