OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/multiprocess_test.h" | 5 #include "base/multiprocess_test.h" |
6 #include "base/platform_thread.h" | 6 #include "base/platform_thread.h" |
7 #include "base/simple_thread.h" | 7 #include "base/simple_thread.h" |
| 8 #include "base/shared_memory.h" |
8 #include "base/stats_table.h" | 9 #include "base/stats_table.h" |
9 #include "base/stats_counters.h" | 10 #include "base/stats_counters.h" |
10 #include "base/string_util.h" | 11 #include "base/string_util.h" |
11 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
12 #include "testing/multiprocess_func_list.h" | 13 #include "testing/multiprocess_func_list.h" |
13 | 14 |
14 #if defined(OS_WIN) | 15 #if defined(OS_WIN) |
15 #include <process.h> | 16 #include <process.h> |
16 #include <windows.h> | 17 #include <windows.h> |
17 #endif | 18 #endif |
18 | 19 |
19 namespace base { | 20 namespace base { |
20 | 21 |
21 class StatsTableTest : public MultiProcessTest { | 22 class StatsTableTest : public MultiProcessTest { |
| 23 public: |
| 24 void DeleteShmem(std::string name) { |
| 25 base::SharedMemory mem; |
| 26 mem.Delete(UTF8ToWide(name)); |
| 27 } |
22 }; | 28 }; |
23 | 29 |
24 // Open a StatsTable and verify that we can write to each of the | 30 // Open a StatsTable and verify that we can write to each of the |
25 // locations in the table. | 31 // locations in the table. |
26 TEST_F(StatsTableTest, VerifySlots) { | 32 TEST_F(StatsTableTest, VerifySlots) { |
27 const std::string kTableName = "VerifySlotsStatTable"; | 33 const std::string kTableName = "VerifySlotsStatTable"; |
28 const int kMaxThreads = 1; | 34 const int kMaxThreads = 1; |
29 const int kMaxCounter = 5; | 35 const int kMaxCounter = 5; |
| 36 DeleteShmem(kTableName); |
30 StatsTable table(kTableName, kMaxThreads, kMaxCounter); | 37 StatsTable table(kTableName, kMaxThreads, kMaxCounter); |
31 | 38 |
32 // Register a single thread. | 39 // Register a single thread. |
33 std::string thread_name = "mainThread"; | 40 std::string thread_name = "mainThread"; |
34 int slot_id = table.RegisterThread(thread_name); | 41 int slot_id = table.RegisterThread(thread_name); |
35 EXPECT_TRUE(slot_id); | 42 EXPECT_TRUE(slot_id); |
36 | 43 |
37 // Fill up the table with counters. | 44 // Fill up the table with counters. |
38 std::string counter_base_name = "counter"; | 45 std::string counter_base_name = "counter"; |
39 for (int index=0; index < kMaxCounter; index++) { | 46 for (int index=0; index < kMaxCounter; index++) { |
40 std::string counter_name = counter_base_name; | 47 std::string counter_name = counter_base_name; |
41 StringAppendF(&counter_name, "counter.ctr%d", index); | 48 StringAppendF(&counter_name, "counter.ctr%d", index); |
42 int counter_id = table.FindCounter(counter_name); | 49 int counter_id = table.FindCounter(counter_name); |
43 EXPECT_GT(counter_id, 0); | 50 EXPECT_GT(counter_id, 0); |
44 } | 51 } |
45 | 52 |
46 // Try to allocate an additional thread. Verify it fails. | 53 // Try to allocate an additional thread. Verify it fails. |
47 slot_id = table.RegisterThread("too many threads"); | 54 slot_id = table.RegisterThread("too many threads"); |
48 EXPECT_EQ(slot_id, 0); | 55 EXPECT_EQ(slot_id, 0); |
49 | 56 |
50 // Try to allocate an additional counter. Verify it fails. | 57 // Try to allocate an additional counter. Verify it fails. |
51 int counter_id = table.FindCounter(counter_base_name); | 58 int counter_id = table.FindCounter(counter_base_name); |
52 EXPECT_EQ(counter_id, 0); | 59 EXPECT_EQ(counter_id, 0); |
| 60 |
| 61 DeleteShmem(kTableName); |
53 } | 62 } |
54 | 63 |
55 // CounterZero will continually be set to 0. | 64 // CounterZero will continually be set to 0. |
56 const std::string kCounterZero = "CounterZero"; | 65 const std::string kCounterZero = "CounterZero"; |
57 // Counter1313 will continually be set to 1313. | 66 // Counter1313 will continually be set to 1313. |
58 const std::string kCounter1313 = "Counter1313"; | 67 const std::string kCounter1313 = "Counter1313"; |
59 // CounterIncrement will be incremented each time. | 68 // CounterIncrement will be incremented each time. |
60 const std::string kCounterIncrement = "CounterIncrement"; | 69 const std::string kCounterIncrement = "CounterIncrement"; |
61 // CounterDecrement will be decremented each time. | 70 // CounterDecrement will be decremented each time. |
62 const std::string kCounterDecrement = "CounterDecrement"; | 71 const std::string kCounterDecrement = "CounterDecrement"; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 PlatformThread::Sleep(index % 10); // short wait | 106 PlatformThread::Sleep(index % 10); // short wait |
98 } | 107 } |
99 } | 108 } |
100 | 109 |
101 // Create a few threads and have them poke on their counters. | 110 // Create a few threads and have them poke on their counters. |
102 TEST_F(StatsTableTest, MultipleThreads) { | 111 TEST_F(StatsTableTest, MultipleThreads) { |
103 // Create a stats table. | 112 // Create a stats table. |
104 const std::string kTableName = "MultipleThreadStatTable"; | 113 const std::string kTableName = "MultipleThreadStatTable"; |
105 const int kMaxThreads = 20; | 114 const int kMaxThreads = 20; |
106 const int kMaxCounter = 5; | 115 const int kMaxCounter = 5; |
| 116 DeleteShmem(kTableName); |
107 StatsTable table(kTableName, kMaxThreads, kMaxCounter); | 117 StatsTable table(kTableName, kMaxThreads, kMaxCounter); |
108 StatsTable::set_current(&table); | 118 StatsTable::set_current(&table); |
109 | 119 |
110 EXPECT_EQ(0, table.CountThreadsRegistered()); | 120 EXPECT_EQ(0, table.CountThreadsRegistered()); |
111 | 121 |
112 // Spin up a set of threads to go bang on the various counters. | 122 // Spin up a set of threads to go bang on the various counters. |
113 // After we join the threads, we'll make sure the counters | 123 // After we join the threads, we'll make sure the counters |
114 // contain the values we expected. | 124 // contain the values we expected. |
115 StatsTableThread* threads[kMaxThreads]; | 125 StatsTableThread* threads[kMaxThreads]; |
116 | 126 |
(...skipping 25 matching lines...) Expand all Loading... |
142 name = "c:" + kCounterIncrement; | 152 name = "c:" + kCounterIncrement; |
143 EXPECT_EQ(kMaxThreads * kThreadLoops, | 153 EXPECT_EQ(kMaxThreads * kThreadLoops, |
144 table.GetCounterValue(name)); | 154 table.GetCounterValue(name)); |
145 name = "c:" + kCounterDecrement; | 155 name = "c:" + kCounterDecrement; |
146 EXPECT_EQ(-kMaxThreads * kThreadLoops, | 156 EXPECT_EQ(-kMaxThreads * kThreadLoops, |
147 table.GetCounterValue(name)); | 157 table.GetCounterValue(name)); |
148 name = "c:" + kCounterMixed; | 158 name = "c:" + kCounterMixed; |
149 EXPECT_EQ((kMaxThreads % 2) * kThreadLoops, | 159 EXPECT_EQ((kMaxThreads % 2) * kThreadLoops, |
150 table.GetCounterValue(name)); | 160 table.GetCounterValue(name)); |
151 EXPECT_EQ(0, table.CountThreadsRegistered()); | 161 EXPECT_EQ(0, table.CountThreadsRegistered()); |
| 162 |
| 163 DeleteShmem(kTableName); |
152 } | 164 } |
153 | 165 |
154 const std::string kTableName = "MultipleProcessStatTable"; | 166 const std::string kMPTableName = "MultipleProcessStatTable"; |
155 | 167 |
156 MULTIPROCESS_TEST_MAIN(StatsTableMultipleProcessMain) { | 168 MULTIPROCESS_TEST_MAIN(StatsTableMultipleProcessMain) { |
157 // Each process will open the shared memory and set counters | 169 // Each process will open the shared memory and set counters |
158 // concurrently in a loop. We'll use some pauses to | 170 // concurrently in a loop. We'll use some pauses to |
159 // mixup the scheduling. | 171 // mixup the scheduling. |
160 | 172 |
161 StatsTable table(kTableName, 0, 0); | 173 StatsTable table(kMPTableName, 0, 0); |
162 StatsTable::set_current(&table); | 174 StatsTable::set_current(&table); |
163 StatsCounter zero_counter(kCounterZero); | 175 StatsCounter zero_counter(kCounterZero); |
164 StatsCounter lucky13_counter(kCounter1313); | 176 StatsCounter lucky13_counter(kCounter1313); |
165 StatsCounter increment_counter(kCounterIncrement); | 177 StatsCounter increment_counter(kCounterIncrement); |
166 StatsCounter decrement_counter(kCounterDecrement); | 178 StatsCounter decrement_counter(kCounterDecrement); |
167 for (int index = 0; index < kThreadLoops; index++) { | 179 for (int index = 0; index < kThreadLoops; index++) { |
168 zero_counter.Set(0); | 180 zero_counter.Set(0); |
169 lucky13_counter.Set(1313); | 181 lucky13_counter.Set(1313); |
170 increment_counter.Increment(); | 182 increment_counter.Increment(); |
171 decrement_counter.Decrement(); | 183 decrement_counter.Decrement(); |
172 PlatformThread::Sleep(index % 10); // short wait | 184 PlatformThread::Sleep(index % 10); // short wait |
173 } | 185 } |
174 return 0; | 186 return 0; |
175 } | 187 } |
176 | 188 |
177 // Create a few processes and have them poke on their counters. | 189 // Create a few processes and have them poke on their counters. |
178 TEST_F(StatsTableTest, MultipleProcesses) { | 190 TEST_F(StatsTableTest, MultipleProcesses) { |
179 // Create a stats table. | 191 // Create a stats table. |
180 const std::string kTableName = "MultipleProcessStatTable"; | |
181 const int kMaxProcs = 20; | 192 const int kMaxProcs = 20; |
182 const int kMaxCounter = 5; | 193 const int kMaxCounter = 5; |
183 StatsTable table(kTableName, kMaxProcs, kMaxCounter); | 194 DeleteShmem(kMPTableName); |
| 195 StatsTable table(kMPTableName, kMaxProcs, kMaxCounter); |
184 StatsTable::set_current(&table); | 196 StatsTable::set_current(&table); |
185 | |
186 EXPECT_EQ(0, table.CountThreadsRegistered()); | 197 EXPECT_EQ(0, table.CountThreadsRegistered()); |
187 | 198 |
188 // Spin up a set of processes to go bang on the various counters. | 199 // Spin up a set of processes to go bang on the various counters. |
189 // After we join the processes, we'll make sure the counters | 200 // After we join the processes, we'll make sure the counters |
190 // contain the values we expected. | 201 // contain the values we expected. |
191 ProcessHandle procs[kMaxProcs]; | 202 ProcessHandle procs[kMaxProcs]; |
192 | 203 |
193 // Spawn the processes. | 204 // Spawn the processes. |
194 for (int16 index = 0; index < kMaxProcs; index++) { | 205 for (int16 index = 0; index < kMaxProcs; index++) { |
195 procs[index] = this->SpawnChild(L"StatsTableMultipleProcessMain"); | 206 procs[index] = this->SpawnChild(L"StatsTableMultipleProcessMain"); |
(...skipping 17 matching lines...) Expand all Loading... |
213 name = "c:" + kCounter1313; | 224 name = "c:" + kCounter1313; |
214 EXPECT_EQ(1313 * kMaxProcs, | 225 EXPECT_EQ(1313 * kMaxProcs, |
215 table.GetCounterValue(name)); | 226 table.GetCounterValue(name)); |
216 name = "c:" + kCounterIncrement; | 227 name = "c:" + kCounterIncrement; |
217 EXPECT_EQ(kMaxProcs * kThreadLoops, | 228 EXPECT_EQ(kMaxProcs * kThreadLoops, |
218 table.GetCounterValue(name)); | 229 table.GetCounterValue(name)); |
219 name = "c:" + kCounterDecrement; | 230 name = "c:" + kCounterDecrement; |
220 EXPECT_EQ(-kMaxProcs * kThreadLoops, | 231 EXPECT_EQ(-kMaxProcs * kThreadLoops, |
221 table.GetCounterValue(name)); | 232 table.GetCounterValue(name)); |
222 EXPECT_EQ(0, table.CountThreadsRegistered()); | 233 EXPECT_EQ(0, table.CountThreadsRegistered()); |
| 234 |
| 235 DeleteShmem(kMPTableName); |
223 } | 236 } |
224 | 237 |
225 class MockStatsCounter : public StatsCounter { | 238 class MockStatsCounter : public StatsCounter { |
226 public: | 239 public: |
227 MockStatsCounter(const std::string& name) | 240 MockStatsCounter(const std::string& name) |
228 : StatsCounter(name) {} | 241 : StatsCounter(name) {} |
229 int* Pointer() { return GetPtr(); } | 242 int* Pointer() { return GetPtr(); } |
230 }; | 243 }; |
231 | 244 |
232 // Test some basic StatsCounter operations | 245 // Test some basic StatsCounter operations |
233 TEST_F(StatsTableTest, StatsCounter) { | 246 TEST_F(StatsTableTest, StatsCounter) { |
234 // Create a stats table. | 247 // Create a stats table. |
235 const std::string kTableName = "StatTable"; | 248 const std::string kTableName = "StatTable"; |
236 const int kMaxThreads = 20; | 249 const int kMaxThreads = 20; |
237 const int kMaxCounter = 5; | 250 const int kMaxCounter = 5; |
| 251 DeleteShmem(kTableName); |
238 StatsTable table(kTableName, kMaxThreads, kMaxCounter); | 252 StatsTable table(kTableName, kMaxThreads, kMaxCounter); |
239 StatsTable::set_current(&table); | 253 StatsTable::set_current(&table); |
240 | 254 |
241 MockStatsCounter foo("foo"); | 255 MockStatsCounter foo("foo"); |
242 | 256 |
243 // Test initial state. | 257 // Test initial state. |
244 EXPECT_TRUE(foo.Enabled()); | 258 EXPECT_TRUE(foo.Enabled()); |
245 EXPECT_NE(foo.Pointer(), static_cast<int*>(0)); | 259 EXPECT_NE(foo.Pointer(), static_cast<int*>(0)); |
246 EXPECT_EQ(0, table.GetCounterValue("c:foo")); | 260 EXPECT_EQ(0, table.GetCounterValue("c:foo")); |
247 EXPECT_EQ(0, *(foo.Pointer())); | 261 EXPECT_EQ(0, *(foo.Pointer())); |
(...skipping 16 matching lines...) Expand all Loading... |
264 foo.Set(0); | 278 foo.Set(0); |
265 EXPECT_EQ(0, table.GetCounterValue("c:foo")); | 279 EXPECT_EQ(0, table.GetCounterValue("c:foo")); |
266 | 280 |
267 // Test Decrement. | 281 // Test Decrement. |
268 foo.Decrement(1); | 282 foo.Decrement(1); |
269 EXPECT_EQ(-1, table.GetCounterValue("c:foo")); | 283 EXPECT_EQ(-1, table.GetCounterValue("c:foo")); |
270 foo.Decrement(0); | 284 foo.Decrement(0); |
271 EXPECT_EQ(-1, table.GetCounterValue("c:foo")); | 285 EXPECT_EQ(-1, table.GetCounterValue("c:foo")); |
272 foo.Decrement(-1); | 286 foo.Decrement(-1); |
273 EXPECT_EQ(0, table.GetCounterValue("c:foo")); | 287 EXPECT_EQ(0, table.GetCounterValue("c:foo")); |
| 288 |
| 289 DeleteShmem(kTableName); |
274 } | 290 } |
275 | 291 |
276 class MockStatsCounterTimer : public StatsCounterTimer { | 292 class MockStatsCounterTimer : public StatsCounterTimer { |
277 public: | 293 public: |
278 MockStatsCounterTimer(const std::string& name) | 294 MockStatsCounterTimer(const std::string& name) |
279 : StatsCounterTimer(name) {} | 295 : StatsCounterTimer(name) {} |
280 | 296 |
281 TimeTicks start_time() { return start_time_; } | 297 TimeTicks start_time() { return start_time_; } |
282 TimeTicks stop_time() { return stop_time_; } | 298 TimeTicks stop_time() { return stop_time_; } |
283 }; | 299 }; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 EXPECT_EQ(2, table.GetCounterValue("c:baz")); | 357 EXPECT_EQ(2, table.GetCounterValue("c:baz")); |
342 EXPECT_LE(1000, table.GetCounterValue("t:baz")); | 358 EXPECT_LE(1000, table.GetCounterValue("t:baz")); |
343 } | 359 } |
344 | 360 |
345 // Test some basic StatsScope operations | 361 // Test some basic StatsScope operations |
346 TEST_F(StatsTableTest, StatsScope) { | 362 TEST_F(StatsTableTest, StatsScope) { |
347 // Create a stats table. | 363 // Create a stats table. |
348 const std::string kTableName = "StatTable"; | 364 const std::string kTableName = "StatTable"; |
349 const int kMaxThreads = 20; | 365 const int kMaxThreads = 20; |
350 const int kMaxCounter = 5; | 366 const int kMaxCounter = 5; |
| 367 DeleteShmem(kTableName); |
351 StatsTable table(kTableName, kMaxThreads, kMaxCounter); | 368 StatsTable table(kTableName, kMaxThreads, kMaxCounter); |
352 StatsTable::set_current(&table); | 369 StatsTable::set_current(&table); |
353 | 370 |
354 StatsCounterTimer foo("foo"); | 371 StatsCounterTimer foo("foo"); |
355 StatsRate bar("bar"); | 372 StatsRate bar("bar"); |
356 | 373 |
357 // Test initial state. | 374 // Test initial state. |
358 EXPECT_EQ(0, table.GetCounterValue("t:foo")); | 375 EXPECT_EQ(0, table.GetCounterValue("t:foo")); |
359 EXPECT_EQ(0, table.GetCounterValue("t:bar")); | 376 EXPECT_EQ(0, table.GetCounterValue("t:bar")); |
360 EXPECT_EQ(0, table.GetCounterValue("c:bar")); | 377 EXPECT_EQ(0, table.GetCounterValue("c:bar")); |
(...skipping 10 matching lines...) Expand all Loading... |
371 | 388 |
372 // Try a second scope. | 389 // Try a second scope. |
373 { | 390 { |
374 StatsScope<StatsCounterTimer> timer(foo); | 391 StatsScope<StatsCounterTimer> timer(foo); |
375 StatsScope<StatsRate> timer2(bar); | 392 StatsScope<StatsRate> timer2(bar); |
376 PlatformThread::Sleep(500); | 393 PlatformThread::Sleep(500); |
377 } | 394 } |
378 EXPECT_LE(1000, table.GetCounterValue("t:foo")); | 395 EXPECT_LE(1000, table.GetCounterValue("t:foo")); |
379 EXPECT_LE(1000, table.GetCounterValue("t:bar")); | 396 EXPECT_LE(1000, table.GetCounterValue("t:bar")); |
380 EXPECT_EQ(2, table.GetCounterValue("c:bar")); | 397 EXPECT_EQ(2, table.GetCounterValue("c:bar")); |
| 398 |
| 399 DeleteShmem(kTableName); |
381 } | 400 } |
382 | 401 |
383 } // namespace base | 402 } // namespace base |
OLD | NEW |