[email protected] | 9fc4416 | 2012-01-23 22:56:41 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 4 | |
| 5 | // Test of classes in the tracked_objects.h classes. |
| 6 | |
| 7 | #include "base/tracked_objects.h" |
[email protected] | f539333 | 2009-06-03 15:01:29 | [diff] [blame] | 8 | |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 9 | #include "base/json/json_writer.h" |
| 10 | #include "base/memory/scoped_ptr.h" |
[email protected] | c62dd9d | 2011-09-21 18:05:41 | [diff] [blame] | 11 | #include "base/time.h" |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 12 | #include "testing/gtest/include/gtest/gtest.h" |
| 13 | |
| 14 | namespace tracked_objects { |
| 15 | |
| 16 | class TrackedObjectsTest : public testing::Test { |
[email protected] | eab79c38 | 2011-11-06 19:14:48 | [diff] [blame] | 17 | protected: |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 18 | TrackedObjectsTest() { |
| 19 | // On entry, leak any database structures in case they are still in use by |
| 20 | // prior threads. |
| 21 | ThreadData::ShutdownSingleThreadedCleanup(true); |
| 22 | } |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 23 | |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 24 | ~TrackedObjectsTest() { |
| 25 | // We should not need to leak any structures we create, since we are |
| 26 | // single threaded, and carefully accounting for items. |
| 27 | ThreadData::ShutdownSingleThreadedCleanup(false); |
| 28 | } |
[email protected] | eab79c38 | 2011-11-06 19:14:48 | [diff] [blame] | 29 | |
| 30 | // Provide access, since this class is a friend of ThreadData. |
| 31 | void ShutdownSingleThreadedCleanup(bool leak) { |
| 32 | ThreadData::ShutdownSingleThreadedCleanup(leak); |
| 33 | } |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 34 | }; |
| 35 | |
[email protected] | c7788d6 | 2008-08-26 06:44:38 | [diff] [blame] | 36 | TEST_F(TrackedObjectsTest, MinimalStartupShutdown) { |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 37 | // Minimal test doesn't even create any tasks. |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 38 | if (!ThreadData::InitializeAndSetTrackingStatus(true)) |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 39 | return; |
| 40 | |
| 41 | EXPECT_FALSE(ThreadData::first()); // No activity even on this thread. |
[email protected] | 84b5795 | 2011-10-15 23:52:45 | [diff] [blame] | 42 | ThreadData* data = ThreadData::Get(); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 43 | EXPECT_TRUE(ThreadData::first()); // Now class was constructed. |
| 44 | EXPECT_TRUE(data); |
| 45 | EXPECT_TRUE(!data->next()); |
[email protected] | 84b5795 | 2011-10-15 23:52:45 | [diff] [blame] | 46 | EXPECT_EQ(data, ThreadData::Get()); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 47 | ThreadData::BirthMap birth_map; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 48 | ThreadData::DeathMap death_map; |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 49 | ThreadData::ParentChildSet parent_child_set; |
| 50 | data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 51 | EXPECT_EQ(0u, birth_map.size()); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 52 | EXPECT_EQ(0u, death_map.size()); |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 53 | EXPECT_EQ(0u, parent_child_set.size()); |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 54 | // Cleanup with no leaking. |
[email protected] | eab79c38 | 2011-11-06 19:14:48 | [diff] [blame] | 55 | ShutdownSingleThreadedCleanup(false); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 56 | |
| 57 | // Do it again, just to be sure we reset state completely. |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 58 | ThreadData::InitializeAndSetTrackingStatus(true); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 59 | EXPECT_FALSE(ThreadData::first()); // No activity even on this thread. |
[email protected] | 84b5795 | 2011-10-15 23:52:45 | [diff] [blame] | 60 | data = ThreadData::Get(); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 61 | EXPECT_TRUE(ThreadData::first()); // Now class was constructed. |
| 62 | EXPECT_TRUE(data); |
| 63 | EXPECT_TRUE(!data->next()); |
[email protected] | 84b5795 | 2011-10-15 23:52:45 | [diff] [blame] | 64 | EXPECT_EQ(data, ThreadData::Get()); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 65 | birth_map.clear(); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 66 | death_map.clear(); |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 67 | data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 68 | EXPECT_EQ(0u, birth_map.size()); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 69 | EXPECT_EQ(0u, death_map.size()); |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 70 | EXPECT_EQ(0u, parent_child_set.size()); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 71 | } |
| 72 | |
[email protected] | c7788d6 | 2008-08-26 06:44:38 | [diff] [blame] | 73 | TEST_F(TrackedObjectsTest, TinyStartupShutdown) { |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 74 | if (!ThreadData::InitializeAndSetTrackingStatus(true)) |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 75 | return; |
| 76 | |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 77 | // Instigate tracking on a single tracked object, on our thread. |
[email protected] | 7d550fa0 | 2011-06-23 23:20:39 | [diff] [blame] | 78 | const Location& location = FROM_HERE; |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 79 | Births* first_birth = ThreadData::TallyABirthIfActive(location); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 80 | |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 81 | ThreadData* data = ThreadData::first(); |
[email protected] | 7d550fa0 | 2011-06-23 23:20:39 | [diff] [blame] | 82 | ASSERT_TRUE(data); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 83 | EXPECT_TRUE(!data->next()); |
[email protected] | 84b5795 | 2011-10-15 23:52:45 | [diff] [blame] | 84 | EXPECT_EQ(data, ThreadData::Get()); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 85 | ThreadData::BirthMap birth_map; |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 86 | ThreadData::DeathMap death_map; |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 87 | ThreadData::ParentChildSet parent_child_set; |
| 88 | data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 89 | EXPECT_EQ(1u, birth_map.size()); // 1 birth location. |
| 90 | EXPECT_EQ(1, birth_map.begin()->second->birth_count()); // 1 birth. |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 91 | EXPECT_EQ(0u, death_map.size()); // No deaths. |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 92 | EXPECT_EQ(0u, parent_child_set.size()); // No children. |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 93 | |
| 94 | |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 95 | // Now instigate another birth, while we are timing the run of the first |
| 96 | // execution. |
| 97 | TrackedTime start_time = |
| 98 | ThreadData::NowForStartOfRun(first_birth); |
| 99 | // Create a child (using the same birth location). |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 100 | // TrackingInfo will call TallyABirth() during construction. |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 101 | base::TimeTicks kBogusBirthTime; |
| 102 | base::TrackingInfo pending_task(location, kBogusBirthTime); |
| 103 | // Finally conclude the outer run. |
| 104 | TrackedTime end_time = ThreadData::NowForEndOfRun(); |
| 105 | ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, start_time, |
| 106 | end_time); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 107 | |
| 108 | birth_map.clear(); |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 109 | death_map.clear(); |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 110 | parent_child_set.clear(); |
| 111 | data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 112 | EXPECT_EQ(1u, birth_map.size()); // 1 birth location. |
| 113 | EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births. |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 114 | EXPECT_EQ(1u, death_map.size()); // 1 location. |
| 115 | EXPECT_EQ(1, death_map.begin()->second.count()); // 1 death. |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 116 | if (ThreadData::tracking_parent_child_status()) { |
| 117 | EXPECT_EQ(1u, parent_child_set.size()); // 1 child. |
| 118 | EXPECT_EQ(parent_child_set.begin()->first, |
| 119 | parent_child_set.begin()->second); |
| 120 | } else { |
| 121 | EXPECT_EQ(0u, parent_child_set.size()); // no stats. |
| 122 | } |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 123 | |
| 124 | // The births were at the same location as the one known death. |
| 125 | EXPECT_EQ(birth_map.begin()->second, death_map.begin()->first); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 126 | } |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 127 | |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 128 | TEST_F(TrackedObjectsTest, ParentChildTest) { |
| 129 | if (!ThreadData::InitializeAndSetTrackingStatus(true)) |
| 130 | return; |
| 131 | if (!ThreadData::tracking_parent_child_status()) |
| 132 | return; // Feature not compiled in. |
| 133 | |
| 134 | // Instigate tracking on a single tracked object, on our thread. |
| 135 | const int kFakeLineNumber = 1776; |
| 136 | const char* kFile = "FixedUnitTestFileName"; |
| 137 | const char* kFunction = "ParentChildTest"; |
| 138 | Location location(kFunction, kFile, kFakeLineNumber, NULL); |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 139 | |
| 140 | // Now instigate another birth, while we are timing the run of the first |
| 141 | // execution. |
[email protected] | 8e3d327e | 2011-12-21 12:54:47 | [diff] [blame] | 142 | |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 143 | // Create a child (using the same birth location). |
| 144 | // TrackingInfo will call TallyABirth() during construction. |
| 145 | base::TimeTicks kBogusBirthTime; |
| 146 | base::TrackingInfo pending_task(location, kBogusBirthTime); |
| 147 | |
| 148 | // Don't conclude the run, so that we don't use the actual timer that we |
| 149 | // started for the outer profile. This way the JSON will not include some |
| 150 | // random time. |
| 151 | ThreadData* data = ThreadData::first(); |
| 152 | ASSERT_TRUE(data); |
| 153 | EXPECT_TRUE(!data->next()); |
| 154 | EXPECT_EQ(data, ThreadData::Get()); |
| 155 | |
| 156 | ThreadData::BirthMap birth_map; |
| 157 | ThreadData::DeathMap death_map; |
| 158 | ThreadData::ParentChildSet parent_child_set; |
| 159 | |
| 160 | data->SnapshotMaps(false, &birth_map, &death_map, &parent_child_set); |
| 161 | EXPECT_EQ(1u, birth_map.size()); // 1 birth location. |
| 162 | EXPECT_EQ(2, birth_map.begin()->second->birth_count()); // 2 births. |
| 163 | EXPECT_EQ(0u, death_map.size()); // No status yet. |
| 164 | // Just like TinyStartupShutdown test. |
| 165 | EXPECT_EQ(1u, parent_child_set.size()); // 1 child. |
| 166 | EXPECT_EQ(parent_child_set.begin()->first, |
| 167 | parent_child_set.begin()->second); |
| 168 | |
| 169 | scoped_ptr<base::Value> value(ThreadData::ToValue(false)); |
| 170 | std::string json; |
| 171 | base::JSONWriter::Write(value.get(), false, &json); |
| 172 | std::string birth_only_result = "{" |
| 173 | "\"descendants\":[" |
| 174 | "{" |
| 175 | "\"child_location\":{" |
| 176 | "\"file_name\":\"FixedUnitTestFileName\"," |
| 177 | "\"function_name\":\"ParentChildTest\"," |
| 178 | "\"line_number\":1776" |
| 179 | "}," |
| 180 | "\"child_thread\":\"WorkerThread-1\"," |
| 181 | "\"parent_location\":{" |
| 182 | "\"file_name\":\"FixedUnitTestFileName\"," |
| 183 | "\"function_name\":\"ParentChildTest\"," |
| 184 | "\"line_number\":1776" |
| 185 | "}," |
| 186 | "\"parent_thread\":\"WorkerThread-1\"" |
| 187 | "}" |
| 188 | "]," |
| 189 | "\"list\":[" |
| 190 | "{" |
| 191 | "\"birth_thread\":\"WorkerThread-1\"," |
| 192 | "\"death_data\":{" |
| 193 | "\"count\":2," |
| 194 | "\"queue_ms\":0," |
| 195 | "\"queue_ms_max\":0," |
| 196 | "\"queue_ms_sample\":0," |
| 197 | "\"run_ms\":0," |
| 198 | "\"run_ms_max\":0," |
| 199 | "\"run_ms_sample\":0" |
| 200 | "}," |
| 201 | "\"death_thread\":\"Still_Alive\"," |
| 202 | "\"location\":{" |
| 203 | "\"file_name\":\"FixedUnitTestFileName\"," |
| 204 | "\"function_name\":\"ParentChildTest\"," |
| 205 | "\"line_number\":1776" |
| 206 | "}" |
| 207 | "}" |
| 208 | "]" |
| 209 | "}"; |
| 210 | EXPECT_EQ(json, birth_only_result); |
| 211 | } |
| 212 | |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 213 | TEST_F(TrackedObjectsTest, DeathDataTest) { |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 214 | if (!ThreadData::InitializeAndSetTrackingStatus(true)) |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 215 | return; |
| 216 | |
| 217 | scoped_ptr<DeathData> data(new DeathData()); |
| 218 | ASSERT_NE(data, reinterpret_cast<DeathData*>(NULL)); |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 219 | EXPECT_EQ(data->run_duration_sum(), 0); |
| 220 | EXPECT_EQ(data->run_duration_sample(), 0); |
| 221 | EXPECT_EQ(data->queue_duration_sum(), 0); |
| 222 | EXPECT_EQ(data->queue_duration_sample(), 0); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 223 | EXPECT_EQ(data->count(), 0); |
| 224 | |
[email protected] | c25db18 | 2011-11-11 22:40:27 | [diff] [blame] | 225 | DurationInt run_ms = 42; |
| 226 | DurationInt queue_ms = 8; |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 227 | |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 228 | const int kUnrandomInt = 0; // Fake random int that ensure we sample data. |
| 229 | data->RecordDeath(queue_ms, run_ms, kUnrandomInt); |
| 230 | EXPECT_EQ(data->run_duration_sum(), run_ms); |
| 231 | EXPECT_EQ(data->run_duration_sample(), run_ms); |
| 232 | EXPECT_EQ(data->queue_duration_sum(), queue_ms); |
| 233 | EXPECT_EQ(data->queue_duration_sample(), queue_ms); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 234 | EXPECT_EQ(data->count(), 1); |
| 235 | |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 236 | data->RecordDeath(queue_ms, run_ms, kUnrandomInt); |
| 237 | EXPECT_EQ(data->run_duration_sum(), run_ms + run_ms); |
| 238 | EXPECT_EQ(data->run_duration_sample(), run_ms); |
| 239 | EXPECT_EQ(data->queue_duration_sum(), queue_ms + queue_ms); |
| 240 | EXPECT_EQ(data->queue_duration_sample(), queue_ms); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 241 | EXPECT_EQ(data->count(), 2); |
| 242 | |
| 243 | scoped_ptr<base::DictionaryValue> dictionary(data->ToValue()); |
| 244 | int integer; |
| 245 | EXPECT_TRUE(dictionary->GetInteger("run_ms", &integer)); |
| 246 | EXPECT_EQ(integer, 2 * run_ms); |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 247 | EXPECT_TRUE(dictionary->GetInteger("run_ms_sample", &integer)); |
| 248 | EXPECT_EQ(integer, run_ms); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 249 | EXPECT_TRUE(dictionary->GetInteger("queue_ms", &integer)); |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 250 | EXPECT_EQ(integer, 2 * queue_ms); |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 251 | EXPECT_TRUE(dictionary->GetInteger("queue_ms_sample", &integer)); |
| 252 | EXPECT_EQ(integer, queue_ms); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 253 | EXPECT_TRUE(dictionary->GetInteger("count", &integer)); |
| 254 | EXPECT_EQ(integer, 2); |
| 255 | |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 256 | scoped_ptr<base::Value> value(data->ToValue()); |
| 257 | std::string json; |
| 258 | base::JSONWriter::Write(value.get(), false, &json); |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 259 | std::string birth_only_result = "{" |
| 260 | "\"count\":2," |
| 261 | "\"queue_ms\":16," |
| 262 | "\"queue_ms_max\":8," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 263 | "\"queue_ms_sample\":8," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 264 | "\"run_ms\":84," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 265 | "\"run_ms_max\":42," |
| 266 | "\"run_ms_sample\":42" |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 267 | "}"; |
| 268 | EXPECT_EQ(birth_only_result, json); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 269 | } |
| 270 | |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 271 | TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToValueWorkerThread) { |
| 272 | // Transition to Deactivated state before doing anything. |
| 273 | if (!ThreadData::InitializeAndSetTrackingStatus(false)) |
[email protected] | f0ab5ba | 2011-10-30 03:44:25 | [diff] [blame] | 274 | return; |
| 275 | // We don't initialize system with a thread name, so we're viewed as a worker |
| 276 | // thread. |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 277 | const int kFakeLineNumber = 173; |
[email protected] | f0ab5ba | 2011-10-30 03:44:25 | [diff] [blame] | 278 | const char* kFile = "FixedFileName"; |
| 279 | const char* kFunction = "BirthOnlyToValueWorkerThread"; |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 280 | Location location(kFunction, kFile, kFakeLineNumber, NULL); |
| 281 | Births* birth = ThreadData::TallyABirthIfActive(location); |
| 282 | // We should now see a NULL birth record. |
| 283 | EXPECT_EQ(birth, reinterpret_cast<Births*>(NULL)); |
| 284 | |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 285 | scoped_ptr<base::Value> value(ThreadData::ToValue(false)); |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 286 | std::string json; |
| 287 | base::JSONWriter::Write(value.get(), false, &json); |
| 288 | std::string birth_only_result = "{" |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 289 | "\"descendants\":[" |
| 290 | "]," |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 291 | "\"list\":[" |
| 292 | "]" |
| 293 | "}"; |
| 294 | EXPECT_EQ(json, birth_only_result); |
| 295 | } |
| 296 | |
| 297 | TEST_F(TrackedObjectsTest, DeactivatedBirthOnlyToValueMainThread) { |
| 298 | // Start in the deactivated state. |
| 299 | if (!ThreadData::InitializeAndSetTrackingStatus(false)) |
| 300 | return; |
| 301 | |
| 302 | // Use a well named thread. |
| 303 | ThreadData::InitializeThreadContext("SomeMainThreadName"); |
| 304 | const int kFakeLineNumber = 173; |
| 305 | const char* kFile = "FixedFileName"; |
| 306 | const char* kFunction = "BirthOnlyToValueMainThread"; |
| 307 | Location location(kFunction, kFile, kFakeLineNumber, NULL); |
| 308 | // Do not delete birth. We don't own it. |
| 309 | Births* birth = ThreadData::TallyABirthIfActive(location); |
| 310 | // We expect to not get a birth record. |
| 311 | EXPECT_EQ(birth, reinterpret_cast<Births*>(NULL)); |
| 312 | |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 313 | scoped_ptr<base::Value> value(ThreadData::ToValue(false)); |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 314 | std::string json; |
| 315 | base::JSONWriter::Write(value.get(), false, &json); |
| 316 | std::string birth_only_result = "{" |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 317 | "\"descendants\":[" |
| 318 | "]," |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 319 | "\"list\":[" |
| 320 | "]" |
| 321 | "}"; |
| 322 | EXPECT_EQ(json, birth_only_result); |
| 323 | } |
| 324 | |
| 325 | TEST_F(TrackedObjectsTest, BirthOnlyToValueWorkerThread) { |
| 326 | if (!ThreadData::InitializeAndSetTrackingStatus(true)) |
| 327 | return; |
| 328 | // We don't initialize system with a thread name, so we're viewed as a worker |
| 329 | // thread. |
| 330 | const int kFakeLineNumber = 173; |
| 331 | const char* kFile = "FixedFileName"; |
| 332 | const char* kFunction = "BirthOnlyToValueWorkerThread"; |
| 333 | Location location(kFunction, kFile, kFakeLineNumber, NULL); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 334 | Births* birth = ThreadData::TallyABirthIfActive(location); |
| 335 | EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); |
| 336 | |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 337 | scoped_ptr<base::Value> value(ThreadData::ToValue(false)); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 338 | std::string json; |
| 339 | base::JSONWriter::Write(value.get(), false, &json); |
| 340 | std::string birth_only_result = "{" |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 341 | "\"descendants\":[" |
| 342 | "]," |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 343 | "\"list\":[" |
| 344 | "{" |
| 345 | "\"birth_thread\":\"WorkerThread-1\"," |
| 346 | "\"death_data\":{" |
| 347 | "\"count\":1," |
| 348 | "\"queue_ms\":0," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 349 | "\"queue_ms_max\":0," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 350 | "\"queue_ms_sample\":0," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 351 | "\"run_ms\":0," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 352 | "\"run_ms_max\":0," |
| 353 | "\"run_ms_sample\":0" |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 354 | "}," |
| 355 | "\"death_thread\":\"Still_Alive\"," |
| 356 | "\"location\":{" |
| 357 | "\"file_name\":\"FixedFileName\"," |
| 358 | "\"function_name\":\"BirthOnlyToValueWorkerThread\"," |
| 359 | "\"line_number\":173" |
| 360 | "}" |
| 361 | "}" |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 362 | "]" |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 363 | "}"; |
| 364 | EXPECT_EQ(json, birth_only_result); |
| 365 | } |
| 366 | |
| 367 | TEST_F(TrackedObjectsTest, BirthOnlyToValueMainThread) { |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 368 | if (!ThreadData::InitializeAndSetTrackingStatus(true)) |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 369 | return; |
| 370 | |
| 371 | // Use a well named thread. |
| 372 | ThreadData::InitializeThreadContext("SomeMainThreadName"); |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 373 | const int kFakeLineNumber = 173; |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 374 | const char* kFile = "FixedFileName"; |
| 375 | const char* kFunction = "BirthOnlyToValueMainThread"; |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 376 | Location location(kFunction, kFile, kFakeLineNumber, NULL); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 377 | // Do not delete birth. We don't own it. |
| 378 | Births* birth = ThreadData::TallyABirthIfActive(location); |
| 379 | EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); |
| 380 | |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 381 | scoped_ptr<base::Value> value(ThreadData::ToValue(false)); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 382 | std::string json; |
| 383 | base::JSONWriter::Write(value.get(), false, &json); |
| 384 | std::string birth_only_result = "{" |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 385 | "\"descendants\":[" |
| 386 | "]," |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 387 | "\"list\":[" |
| 388 | "{" |
| 389 | "\"birth_thread\":\"SomeMainThreadName\"," |
| 390 | "\"death_data\":{" |
| 391 | "\"count\":1," |
| 392 | "\"queue_ms\":0," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 393 | "\"queue_ms_max\":0," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 394 | "\"queue_ms_sample\":0," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 395 | "\"run_ms\":0," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 396 | "\"run_ms_max\":0," |
| 397 | "\"run_ms_sample\":0" |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 398 | "}," |
| 399 | "\"death_thread\":\"Still_Alive\"," |
| 400 | "\"location\":{" |
| 401 | "\"file_name\":\"FixedFileName\"," |
| 402 | "\"function_name\":\"BirthOnlyToValueMainThread\"," |
| 403 | "\"line_number\":173" |
| 404 | "}" |
| 405 | "}" |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 406 | "]" |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 407 | "}"; |
| 408 | EXPECT_EQ(json, birth_only_result); |
| 409 | } |
| 410 | |
| 411 | TEST_F(TrackedObjectsTest, LifeCycleToValueMainThread) { |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 412 | if (!ThreadData::InitializeAndSetTrackingStatus(true)) |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 413 | return; |
| 414 | |
| 415 | // Use a well named thread. |
| 416 | ThreadData::InitializeThreadContext("SomeMainThreadName"); |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 417 | const int kFakeLineNumber = 236; |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 418 | const char* kFile = "FixedFileName"; |
| 419 | const char* kFunction = "LifeCycleToValueMainThread"; |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 420 | Location location(kFunction, kFile, kFakeLineNumber, NULL); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 421 | // Do not delete birth. We don't own it. |
| 422 | Births* birth = ThreadData::TallyABirthIfActive(location); |
| 423 | EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); |
| 424 | |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 425 | const base::TimeTicks kTimePosted = base::TimeTicks() |
| 426 | + base::TimeDelta::FromMilliseconds(1); |
| 427 | const base::TimeTicks kDelayedStartTime = base::TimeTicks(); |
| 428 | // TrackingInfo will call TallyABirth() during construction. |
| 429 | base::TrackingInfo pending_task(location, kDelayedStartTime); |
| 430 | pending_task.time_posted = kTimePosted; // Overwrite implied Now(). |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 431 | |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 432 | const TrackedTime kStartOfRun = TrackedTime() + |
| 433 | Duration::FromMilliseconds(5); |
| 434 | const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); |
| 435 | ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, |
| 436 | kStartOfRun, kEndOfRun); |
| 437 | |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 438 | scoped_ptr<base::Value> value(ThreadData::ToValue(false)); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 439 | std::string json; |
| 440 | base::JSONWriter::Write(value.get(), false, &json); |
| 441 | std::string one_line_result = "{" |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 442 | "\"descendants\":[" |
| 443 | "]," |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 444 | "\"list\":[" |
| 445 | "{" |
| 446 | "\"birth_thread\":\"SomeMainThreadName\"," |
| 447 | "\"death_data\":{" |
| 448 | "\"count\":1," |
| 449 | "\"queue_ms\":4," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 450 | "\"queue_ms_max\":4," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 451 | "\"queue_ms_sample\":4," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 452 | "\"run_ms\":2," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 453 | "\"run_ms_max\":2," |
| 454 | "\"run_ms_sample\":2" |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 455 | "}," |
| 456 | "\"death_thread\":\"SomeMainThreadName\"," |
| 457 | "\"location\":{" |
| 458 | "\"file_name\":\"FixedFileName\"," |
| 459 | "\"function_name\":\"LifeCycleToValueMainThread\"," |
| 460 | "\"line_number\":236" |
| 461 | "}" |
| 462 | "}" |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 463 | "]" |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 464 | "}"; |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 465 | EXPECT_EQ(one_line_result, json); |
[email protected] | f0ab5ba | 2011-10-30 03:44:25 | [diff] [blame] | 466 | } |
| 467 | |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 468 | // We will deactivate tracking after the birth, and before the death, and |
| 469 | // demonstrate that the lifecycle is completely tallied. This ensures that |
| 470 | // our tallied births are matched by tallied deaths (except for when the |
| 471 | // task is still running, or is queued). |
| 472 | TEST_F(TrackedObjectsTest, LifeCycleMidDeactivatedToValueMainThread) { |
| 473 | if (!ThreadData::InitializeAndSetTrackingStatus(true)) |
[email protected] | f0ab5ba | 2011-10-30 03:44:25 | [diff] [blame] | 474 | return; |
| 475 | |
| 476 | // Use a well named thread. |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 477 | ThreadData::InitializeThreadContext("SomeMainThreadName"); |
| 478 | const int kFakeLineNumber = 236; |
| 479 | const char* kFile = "FixedFileName"; |
| 480 | const char* kFunction = "LifeCycleToValueMainThread"; |
| 481 | Location location(kFunction, kFile, kFakeLineNumber, NULL); |
[email protected] | f0ab5ba | 2011-10-30 03:44:25 | [diff] [blame] | 482 | // Do not delete birth. We don't own it. |
| 483 | Births* birth = ThreadData::TallyABirthIfActive(location); |
| 484 | EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); |
| 485 | |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 486 | const base::TimeTicks kTimePosted = base::TimeTicks() |
| 487 | + base::TimeDelta::FromMilliseconds(1); |
| 488 | const base::TimeTicks kDelayedStartTime = base::TimeTicks(); |
| 489 | // TrackingInfo will call TallyABirth() during construction. |
| 490 | base::TrackingInfo pending_task(location, kDelayedStartTime); |
| 491 | pending_task.time_posted = kTimePosted; // Overwrite implied Now(). |
[email protected] | f0ab5ba | 2011-10-30 03:44:25 | [diff] [blame] | 492 | |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 493 | // Turn off tracking now that we have births. |
| 494 | EXPECT_TRUE(ThreadData::InitializeAndSetTrackingStatus(false)); |
[email protected] | f0ab5ba | 2011-10-30 03:44:25 | [diff] [blame] | 495 | |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 496 | const TrackedTime kStartOfRun = TrackedTime() + |
| 497 | Duration::FromMilliseconds(5); |
| 498 | const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); |
| 499 | ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, |
| 500 | kStartOfRun, kEndOfRun); |
| 501 | |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 502 | scoped_ptr<base::Value> value(ThreadData::ToValue(false)); |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 503 | std::string json; |
| 504 | base::JSONWriter::Write(value.get(), false, &json); |
| 505 | std::string one_line_result = "{" |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 506 | "\"descendants\":[" |
| 507 | "]," |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 508 | "\"list\":[" |
| 509 | "{" |
| 510 | "\"birth_thread\":\"SomeMainThreadName\"," |
| 511 | "\"death_data\":{" |
| 512 | "\"count\":1," |
| 513 | "\"queue_ms\":4," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 514 | "\"queue_ms_max\":4," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 515 | "\"queue_ms_sample\":4," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 516 | "\"run_ms\":2," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 517 | "\"run_ms_max\":2," |
| 518 | "\"run_ms_sample\":2" |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 519 | "}," |
| 520 | "\"death_thread\":\"SomeMainThreadName\"," |
| 521 | "\"location\":{" |
| 522 | "\"file_name\":\"FixedFileName\"," |
| 523 | "\"function_name\":\"LifeCycleToValueMainThread\"," |
| 524 | "\"line_number\":236" |
| 525 | "}" |
| 526 | "}" |
| 527 | "]" |
| 528 | "}"; |
| 529 | EXPECT_EQ(one_line_result, json); |
| 530 | } |
| 531 | |
| 532 | // We will deactivate tracking before starting a life cycle, and neither |
| 533 | // the birth nor the death will be recorded. |
| 534 | TEST_F(TrackedObjectsTest, LifeCyclePreDeactivatedToValueMainThread) { |
| 535 | if (!ThreadData::InitializeAndSetTrackingStatus(false)) |
| 536 | return; |
| 537 | |
| 538 | // Use a well named thread. |
| 539 | ThreadData::InitializeThreadContext("SomeMainThreadName"); |
| 540 | const int kFakeLineNumber = 236; |
| 541 | const char* kFile = "FixedFileName"; |
| 542 | const char* kFunction = "LifeCycleToValueMainThread"; |
| 543 | Location location(kFunction, kFile, kFakeLineNumber, NULL); |
| 544 | // Do not delete birth. We don't own it. |
| 545 | Births* birth = ThreadData::TallyABirthIfActive(location); |
| 546 | EXPECT_EQ(birth, reinterpret_cast<Births*>(NULL)); |
| 547 | |
| 548 | const base::TimeTicks kTimePosted = base::TimeTicks() |
| 549 | + base::TimeDelta::FromMilliseconds(1); |
| 550 | const base::TimeTicks kDelayedStartTime = base::TimeTicks(); |
| 551 | // TrackingInfo will call TallyABirth() during construction. |
| 552 | base::TrackingInfo pending_task(location, kDelayedStartTime); |
| 553 | pending_task.time_posted = kTimePosted; // Overwrite implied Now(). |
| 554 | |
| 555 | const TrackedTime kStartOfRun = TrackedTime() + |
| 556 | Duration::FromMilliseconds(5); |
| 557 | const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); |
| 558 | ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, |
| 559 | kStartOfRun, kEndOfRun); |
| 560 | |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 561 | scoped_ptr<base::Value> value(ThreadData::ToValue(false)); |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 562 | std::string json; |
| 563 | base::JSONWriter::Write(value.get(), false, &json); |
| 564 | std::string one_line_result = "{" |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 565 | "\"descendants\":[" |
| 566 | "]," |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 567 | "\"list\":[" |
| 568 | "]" |
| 569 | "}"; |
| 570 | EXPECT_EQ(one_line_result, json); |
| 571 | } |
| 572 | |
| 573 | TEST_F(TrackedObjectsTest, LifeCycleToValueWorkerThread) { |
| 574 | if (!ThreadData::InitializeAndSetTrackingStatus(true)) |
| 575 | return; |
| 576 | |
| 577 | // Don't initialize thread, so that we appear as a worker thread. |
| 578 | // ThreadData::InitializeThreadContext("SomeMainThreadName"); |
| 579 | |
| 580 | const int kFakeLineNumber = 236; |
| 581 | const char* kFile = "FixedFileName"; |
| 582 | const char* kFunction = "LifeCycleToValueWorkerThread"; |
| 583 | Location location(kFunction, kFile, kFakeLineNumber, NULL); |
| 584 | // Do not delete birth. We don't own it. |
| 585 | Births* birth = ThreadData::TallyABirthIfActive(location); |
| 586 | EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); |
| 587 | |
| 588 | const TrackedTime kTimePosted = TrackedTime() + Duration::FromMilliseconds(1); |
| 589 | const TrackedTime kStartOfRun = TrackedTime() + |
| 590 | Duration::FromMilliseconds(5); |
| 591 | const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); |
| 592 | ThreadData::TallyRunOnWorkerThreadIfTracking(birth, kTimePosted, |
| 593 | kStartOfRun, kEndOfRun); |
| 594 | |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 595 | // Call for the ToValue, but tell it to not the maxes after scanning. |
| 596 | scoped_ptr<base::Value> value(ThreadData::ToValue(false)); |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 597 | std::string json; |
| 598 | base::JSONWriter::Write(value.get(), false, &json); |
| 599 | std::string one_line_result = "{" |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 600 | "\"descendants\":[" |
| 601 | "]," |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 602 | "\"list\":[" |
| 603 | "{" |
| 604 | "\"birth_thread\":\"WorkerThread-1\"," |
| 605 | "\"death_data\":{" |
| 606 | "\"count\":1," |
| 607 | "\"queue_ms\":4," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 608 | "\"queue_ms_max\":4," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 609 | "\"queue_ms_sample\":4," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 610 | "\"run_ms\":2," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 611 | "\"run_ms_max\":2," |
| 612 | "\"run_ms_sample\":2" |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 613 | "}," |
| 614 | "\"death_thread\":\"WorkerThread-1\"," |
| 615 | "\"location\":{" |
| 616 | "\"file_name\":\"FixedFileName\"," |
| 617 | "\"function_name\":\"LifeCycleToValueWorkerThread\"," |
| 618 | "\"line_number\":236" |
| 619 | "}" |
| 620 | "}" |
| 621 | "]" |
| 622 | "}"; |
| 623 | EXPECT_EQ(one_line_result, json); |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 624 | |
| 625 | // Call for the ToValue, but tell it to reset the maxes after scanning. |
| 626 | // We'll still get the same values, but the data will be reset (which we'll |
| 627 | // see in a moment). |
| 628 | value.reset(ThreadData::ToValue(true)); |
| 629 | base::JSONWriter::Write(value.get(), false, &json); |
| 630 | // Result should be unchanged. |
| 631 | EXPECT_EQ(one_line_result, json); |
| 632 | |
| 633 | // Call for the ToValue, and now we'll see the result of the last translation, |
| 634 | // as the max will have been pushed back to zero. |
| 635 | value.reset(ThreadData::ToValue(false)); |
| 636 | base::JSONWriter::Write(value.get(), false, &json); |
| 637 | std::string one_line_result_with_zeros = "{" |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 638 | "\"descendants\":[" |
| 639 | "]," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 640 | "\"list\":[" |
| 641 | "{" |
| 642 | "\"birth_thread\":\"WorkerThread-1\"," |
| 643 | "\"death_data\":{" |
| 644 | "\"count\":1," |
| 645 | "\"queue_ms\":4," |
| 646 | "\"queue_ms_max\":0," // Note zero here. |
| 647 | "\"queue_ms_sample\":4," |
| 648 | "\"run_ms\":2," |
| 649 | "\"run_ms_max\":0," // Note zero here. |
| 650 | "\"run_ms_sample\":2" |
| 651 | "}," |
| 652 | "\"death_thread\":\"WorkerThread-1\"," |
| 653 | "\"location\":{" |
| 654 | "\"file_name\":\"FixedFileName\"," |
| 655 | "\"function_name\":\"LifeCycleToValueWorkerThread\"," |
| 656 | "\"line_number\":236" |
| 657 | "}" |
| 658 | "}" |
| 659 | "]" |
| 660 | "}"; |
| 661 | EXPECT_EQ(one_line_result_with_zeros, json); |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 662 | } |
| 663 | |
| 664 | TEST_F(TrackedObjectsTest, TwoLives) { |
| 665 | if (!ThreadData::InitializeAndSetTrackingStatus(true)) |
| 666 | return; |
| 667 | |
| 668 | // Use a well named thread. |
| 669 | ThreadData::InitializeThreadContext("SomeFileThreadName"); |
| 670 | const int kFakeLineNumber = 222; |
| 671 | const char* kFile = "AnotherFileName"; |
| 672 | const char* kFunction = "TwoLives"; |
| 673 | Location location(kFunction, kFile, kFakeLineNumber, NULL); |
| 674 | // Do not delete birth. We don't own it. |
| 675 | Births* birth = ThreadData::TallyABirthIfActive(location); |
| 676 | EXPECT_NE(birth, reinterpret_cast<Births*>(NULL)); |
| 677 | |
| 678 | |
| 679 | const base::TimeTicks kTimePosted = base::TimeTicks() |
| 680 | + base::TimeDelta::FromMilliseconds(1); |
| 681 | const base::TimeTicks kDelayedStartTime = base::TimeTicks(); |
| 682 | // TrackingInfo will call TallyABirth() during construction. |
| 683 | base::TrackingInfo pending_task(location, kDelayedStartTime); |
| 684 | pending_task.time_posted = kTimePosted; // Overwrite implied Now(). |
| 685 | |
| 686 | const TrackedTime kStartOfRun = TrackedTime() + |
| 687 | Duration::FromMilliseconds(5); |
| 688 | const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); |
| 689 | ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, |
| 690 | kStartOfRun, kEndOfRun); |
| 691 | |
| 692 | // TrackingInfo will call TallyABirth() during construction. |
| 693 | base::TrackingInfo pending_task2(location, kDelayedStartTime); |
| 694 | pending_task2.time_posted = kTimePosted; // Overwrite implied Now(). |
| 695 | |
| 696 | ThreadData::TallyRunOnNamedThreadIfTracking(pending_task2, |
| 697 | kStartOfRun, kEndOfRun); |
| 698 | |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 699 | scoped_ptr<base::Value> value(ThreadData::ToValue(false)); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 700 | std::string json; |
| 701 | base::JSONWriter::Write(value.get(), false, &json); |
| 702 | std::string one_line_result = "{" |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 703 | "\"descendants\":[" |
| 704 | "]," |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 705 | "\"list\":[" |
| 706 | "{" |
| 707 | "\"birth_thread\":\"SomeFileThreadName\"," |
| 708 | "\"death_data\":{" |
| 709 | "\"count\":2," |
| 710 | "\"queue_ms\":8," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 711 | "\"queue_ms_max\":4," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 712 | "\"queue_ms_sample\":4," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 713 | "\"run_ms\":4," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 714 | "\"run_ms_max\":2," |
| 715 | "\"run_ms_sample\":2" |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 716 | "}," |
| 717 | "\"death_thread\":\"SomeFileThreadName\"," |
| 718 | "\"location\":{" |
| 719 | "\"file_name\":\"AnotherFileName\"," |
| 720 | "\"function_name\":\"TwoLives\"," |
| 721 | "\"line_number\":222" |
| 722 | "}" |
| 723 | "}" |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 724 | "]" |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 725 | "}"; |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 726 | EXPECT_EQ(one_line_result, json); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 727 | } |
| 728 | |
| 729 | TEST_F(TrackedObjectsTest, DifferentLives) { |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 730 | if (!ThreadData::InitializeAndSetTrackingStatus(true)) |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 731 | return; |
| 732 | |
| 733 | // Use a well named thread. |
| 734 | ThreadData::InitializeThreadContext("SomeFileThreadName"); |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 735 | const int kFakeLineNumber = 567; |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 736 | const char* kFile = "AnotherFileName"; |
| 737 | const char* kFunction = "DifferentLives"; |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 738 | Location location(kFunction, kFile, kFakeLineNumber, NULL); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 739 | |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 740 | const base::TimeTicks kTimePosted = base::TimeTicks() |
| 741 | + base::TimeDelta::FromMilliseconds(1); |
| 742 | const base::TimeTicks kDelayedStartTime = base::TimeTicks(); |
| 743 | // TrackingInfo will call TallyABirth() during construction. |
| 744 | base::TrackingInfo pending_task(location, kDelayedStartTime); |
| 745 | pending_task.time_posted = kTimePosted; // Overwrite implied Now(). |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 746 | |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 747 | const TrackedTime kStartOfRun = TrackedTime() + |
| 748 | Duration::FromMilliseconds(5); |
| 749 | const TrackedTime kEndOfRun = TrackedTime() + Duration::FromMilliseconds(7); |
| 750 | ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, |
| 751 | kStartOfRun, kEndOfRun); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 752 | |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 753 | const int kSecondFakeLineNumber = 999; |
| 754 | Location second_location(kFunction, kFile, kSecondFakeLineNumber, NULL); |
| 755 | |
| 756 | // TrackingInfo will call TallyABirth() during construction. |
| 757 | base::TrackingInfo pending_task2(second_location, kDelayedStartTime); |
| 758 | pending_task2.time_posted = kTimePosted; // Overwrite implied Now(). |
| 759 | |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 760 | scoped_ptr<base::Value> value(ThreadData::ToValue(false)); |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 761 | std::string json; |
| 762 | base::JSONWriter::Write(value.get(), false, &json); |
| 763 | std::string one_line_result = "{" |
[email protected] | 8aa1e6e | 2011-12-14 01:36:48 | [diff] [blame] | 764 | "\"descendants\":[" |
| 765 | "]," |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 766 | "\"list\":[" |
| 767 | "{" |
| 768 | "\"birth_thread\":\"SomeFileThreadName\"," |
| 769 | "\"death_data\":{" |
| 770 | "\"count\":1," |
| 771 | "\"queue_ms\":4," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 772 | "\"queue_ms_max\":4," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 773 | "\"queue_ms_sample\":4," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 774 | "\"run_ms\":2," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 775 | "\"run_ms_max\":2," |
| 776 | "\"run_ms_sample\":2" |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 777 | "}," |
| 778 | "\"death_thread\":\"SomeFileThreadName\"," |
| 779 | "\"location\":{" |
| 780 | "\"file_name\":\"AnotherFileName\"," |
| 781 | "\"function_name\":\"DifferentLives\"," |
| 782 | "\"line_number\":567" |
| 783 | "}" |
| 784 | "}," |
| 785 | "{" |
| 786 | "\"birth_thread\":\"SomeFileThreadName\"," |
| 787 | "\"death_data\":{" |
| 788 | "\"count\":1," |
| 789 | "\"queue_ms\":0," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 790 | "\"queue_ms_max\":0," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 791 | "\"queue_ms_sample\":0," |
[email protected] | 63f5b0e | 2011-11-04 00:23:27 | [diff] [blame] | 792 | "\"run_ms\":0," |
[email protected] | b6b2b89 | 2011-12-04 07:19:10 | [diff] [blame] | 793 | "\"run_ms_max\":0," |
| 794 | "\"run_ms_sample\":0" |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 795 | "}," |
| 796 | "\"death_thread\":\"Still_Alive\"," |
| 797 | "\"location\":{" |
| 798 | "\"file_name\":\"AnotherFileName\"," |
| 799 | "\"function_name\":\"DifferentLives\"," |
| 800 | "\"line_number\":999" |
| 801 | "}" |
| 802 | "}" |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 803 | "]" |
[email protected] | 84baeca | 2011-10-24 18:55:16 | [diff] [blame] | 804 | "}"; |
[email protected] | b2a9bbd | 2011-10-31 22:36:21 | [diff] [blame] | 805 | EXPECT_EQ(one_line_result, json); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 806 | } |
| 807 | |
[email protected] | 92735c4 | 2011-11-02 01:35:05 | [diff] [blame] | 808 | |
[email protected] | 0ce642c | 2008-08-26 11:29:01 | [diff] [blame] | 809 | } // namespace tracked_objects |