Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / base / memory / discardable_shared_memory_unittest.cc
1 // Copyright 2014 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/memory/discardable_shared_memory.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8
9 namespace base {
10 namespace {
11
12 class TestDiscardableSharedMemory : public DiscardableSharedMemory {
13  public:
14   TestDiscardableSharedMemory() {}
15
16   explicit TestDiscardableSharedMemory(SharedMemoryHandle handle)
17       : DiscardableSharedMemory(handle) {}
18
19   void SetNow(Time now) { now_ = now; }
20
21  private:
22   // Overriden from DiscardableSharedMemory:
23   virtual Time Now() const override { return now_; }
24
25   Time now_;
26 };
27
28 TEST(DiscardableSharedMemoryTest, CreateAndMap) {
29   const uint32 kDataSize = 1024;
30
31   TestDiscardableSharedMemory memory;
32   bool rv = memory.CreateAndMap(kDataSize);
33   ASSERT_TRUE(rv);
34   EXPECT_GE(memory.mapped_size(), kDataSize);
35 }
36
37 TEST(DiscardableSharedMemoryTest, CreateFromHandle) {
38   const uint32 kDataSize = 1024;
39
40   TestDiscardableSharedMemory memory1;
41   bool rv = memory1.CreateAndMap(kDataSize);
42   ASSERT_TRUE(rv);
43
44   SharedMemoryHandle shared_handle;
45   ASSERT_TRUE(
46       memory1.ShareToProcess(GetCurrentProcessHandle(), &shared_handle));
47   ASSERT_TRUE(SharedMemory::IsHandleValid(shared_handle));
48
49   TestDiscardableSharedMemory memory2(shared_handle);
50   rv = memory2.Map(kDataSize);
51   ASSERT_TRUE(rv);
52 }
53
54 TEST(DiscardableSharedMemoryTest, LockAndUnlock) {
55   const uint32 kDataSize = 1024;
56
57   TestDiscardableSharedMemory memory1;
58   bool rv = memory1.CreateAndMap(kDataSize);
59   ASSERT_TRUE(rv);
60
61   // Memory is initially locked. Unlock it.
62   memory1.SetNow(Time::FromDoubleT(1));
63   memory1.Unlock();
64
65   // Lock and unlock memory.
66   rv = memory1.Lock();
67   EXPECT_TRUE(rv);
68   memory1.SetNow(Time::FromDoubleT(2));
69   memory1.Unlock();
70
71   SharedMemoryHandle shared_handle;
72   ASSERT_TRUE(
73       memory1.ShareToProcess(GetCurrentProcessHandle(), &shared_handle));
74   ASSERT_TRUE(SharedMemory::IsHandleValid(shared_handle));
75
76   TestDiscardableSharedMemory memory2(shared_handle);
77   rv = memory2.Map(kDataSize);
78   ASSERT_TRUE(rv);
79
80   // Lock first instance again.
81   rv = memory1.Lock();
82   EXPECT_TRUE(rv);
83
84   // Unlock second instance.
85   memory2.SetNow(Time::FromDoubleT(3));
86   memory2.Unlock();
87
88   // Lock and unlock second instance.
89   rv = memory2.Lock();
90   EXPECT_TRUE(rv);
91   memory2.SetNow(Time::FromDoubleT(4));
92   memory2.Unlock();
93
94   // Try to lock first instance again. Should fail as first instance has an
95   // incorrect last know usage time.
96   rv = memory1.Lock();
97   EXPECT_FALSE(rv);
98
99   // Memory should still be resident.
100   rv = memory1.IsMemoryResident();
101   EXPECT_TRUE(rv);
102
103   // Second attempt to lock first instance should succeed as last known usage
104   // time is now correct.
105   rv = memory1.Lock();
106   EXPECT_TRUE(rv);
107   memory1.SetNow(Time::FromDoubleT(5));
108   memory1.Unlock();
109 }
110
111 TEST(DiscardableSharedMemoryTest, Purge) {
112   const uint32 kDataSize = 1024;
113
114   TestDiscardableSharedMemory memory1;
115   bool rv = memory1.CreateAndMap(kDataSize);
116   ASSERT_TRUE(rv);
117
118   SharedMemoryHandle shared_handle;
119   ASSERT_TRUE(
120       memory1.ShareToProcess(GetCurrentProcessHandle(), &shared_handle));
121   ASSERT_TRUE(SharedMemory::IsHandleValid(shared_handle));
122
123   TestDiscardableSharedMemory memory2(shared_handle);
124   rv = memory2.Map(kDataSize);
125   ASSERT_TRUE(rv);
126
127   // This should fail as memory is locked.
128   rv = memory1.Purge(Time::FromDoubleT(1));
129   EXPECT_FALSE(rv);
130
131   memory2.SetNow(Time::FromDoubleT(2));
132   memory2.Unlock();
133
134   ASSERT_TRUE(memory2.IsMemoryResident());
135
136   // Memory is unlocked, but our usage timestamp is incorrect.
137   rv = memory1.Purge(Time::FromDoubleT(3));
138   EXPECT_FALSE(rv);
139
140   ASSERT_TRUE(memory2.IsMemoryResident());
141
142   // Memory is unlocked and our usage timestamp should be correct.
143   rv = memory1.Purge(Time::FromDoubleT(4));
144   EXPECT_TRUE(rv);
145
146   // Lock should fail as memory has been purged.
147   rv = memory2.Lock();
148   EXPECT_FALSE(rv);
149
150   ASSERT_FALSE(memory2.IsMemoryResident());
151 }
152
153 TEST(DiscardableSharedMemoryTest, LastUsed) {
154   const uint32 kDataSize = 1024;
155
156   TestDiscardableSharedMemory memory1;
157   bool rv = memory1.CreateAndMap(kDataSize);
158   ASSERT_TRUE(rv);
159
160   SharedMemoryHandle shared_handle;
161   ASSERT_TRUE(
162       memory1.ShareToProcess(GetCurrentProcessHandle(), &shared_handle));
163   ASSERT_TRUE(SharedMemory::IsHandleValid(shared_handle));
164
165   TestDiscardableSharedMemory memory2(shared_handle);
166   rv = memory2.Map(kDataSize);
167   ASSERT_TRUE(rv);
168
169   memory2.SetNow(Time::FromDoubleT(1));
170   memory2.Unlock();
171
172   EXPECT_EQ(memory2.last_known_usage(), Time::FromDoubleT(1));
173
174   rv = memory2.Lock();
175   EXPECT_TRUE(rv);
176
177   // This should fail as memory is locked.
178   rv = memory1.Purge(Time::FromDoubleT(2));
179   ASSERT_FALSE(rv);
180
181   // Last usage should have been updated to timestamp passed to Purge above.
182   EXPECT_EQ(memory1.last_known_usage(), Time::FromDoubleT(2));
183
184   memory2.SetNow(Time::FromDoubleT(3));
185   memory2.Unlock();
186
187   // Usage time should be correct for |memory2| instance.
188   EXPECT_EQ(memory2.last_known_usage(), Time::FromDoubleT(3));
189
190   // However, usage time has not changed as far as |memory1| instance knows.
191   EXPECT_EQ(memory1.last_known_usage(), Time::FromDoubleT(2));
192
193   // Memory is unlocked, but our usage timestamp is incorrect.
194   rv = memory1.Purge(Time::FromDoubleT(4));
195   EXPECT_FALSE(rv);
196
197   // The failed purge attempt should have updated usage time to the correct
198   // value.
199   EXPECT_EQ(memory1.last_known_usage(), Time::FromDoubleT(3));
200
201   // Purge memory through |memory2| instance. The last usage time should be
202   // set to 0 as a result of this.
203   rv = memory2.Purge(Time::FromDoubleT(5));
204   EXPECT_TRUE(rv);
205   EXPECT_TRUE(memory2.last_known_usage().is_null());
206
207   // This should fail as memory has already been purged and |memory1|'s usage
208   // time is incorrect as a result.
209   rv = memory1.Purge(Time::FromDoubleT(6));
210   EXPECT_FALSE(rv);
211
212   // The failed purge attempt should have updated usage time to the correct
213   // value.
214   EXPECT_TRUE(memory1.last_known_usage().is_null());
215
216   // Purge should succeed now that usage time is correct.
217   rv = memory1.Purge(Time::FromDoubleT(7));
218   EXPECT_TRUE(rv);
219 }
220
221 TEST(DiscardableSharedMemoryTest, LockShouldAlwaysFailAfterSuccessfulPurge) {
222   const uint32 kDataSize = 1024;
223
224   TestDiscardableSharedMemory memory1;
225   bool rv = memory1.CreateAndMap(kDataSize);
226   ASSERT_TRUE(rv);
227
228   SharedMemoryHandle shared_handle;
229   ASSERT_TRUE(
230       memory1.ShareToProcess(GetCurrentProcessHandle(), &shared_handle));
231   ASSERT_TRUE(SharedMemory::IsHandleValid(shared_handle));
232
233   TestDiscardableSharedMemory memory2(shared_handle);
234   rv = memory2.Map(kDataSize);
235   ASSERT_TRUE(rv);
236
237   memory2.SetNow(Time::FromDoubleT(1));
238   memory2.Unlock();
239
240   rv = memory2.Purge(Time::FromDoubleT(2));
241   EXPECT_TRUE(rv);
242
243   // Lock should fail as memory has been purged.
244   rv = memory2.Lock();
245   EXPECT_FALSE(rv);
246   rv = memory1.Lock();
247   EXPECT_FALSE(rv);
248 }
249
250 }  // namespace
251 }  // namespace base