OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/debug/trace_event_unittest.h" | 5 #include "base/debug/trace_event_unittest.h" |
6 | 6 |
7 #include <cstdlib> | 7 #include <cstdlib> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 | 43 |
44 const int kThreadId = 42; | 44 const int kThreadId = 42; |
45 const int kAsyncId = 5; | 45 const int kAsyncId = 5; |
46 const char kAsyncIdStr[] = "0x5"; | 46 const char kAsyncIdStr[] = "0x5"; |
47 const int kAsyncId2 = 6; | 47 const int kAsyncId2 = 6; |
48 const char kAsyncId2Str[] = "0x6"; | 48 const char kAsyncId2Str[] = "0x6"; |
49 | 49 |
50 class TraceEventTestFixture : public testing::Test { | 50 class TraceEventTestFixture : public testing::Test { |
51 public: | 51 public: |
52 void OnTraceDataCollected( | 52 void OnTraceDataCollected( |
53 const scoped_refptr<base::RefCountedString>& events_str); | 53 WaitableEvent* flush_complete_event, |
| 54 const scoped_refptr<base::RefCountedString>& events_str, |
| 55 bool has_more_events); |
54 void OnTraceNotification(int notification) { | 56 void OnTraceNotification(int notification) { |
55 if (notification & TraceLog::EVENT_WATCH_NOTIFICATION) | 57 if (notification & TraceLog::EVENT_WATCH_NOTIFICATION) |
56 ++event_watch_notification_; | 58 ++event_watch_notification_; |
57 notifications_received_ |= notification; | 59 notifications_received_ |= notification; |
58 } | 60 } |
59 DictionaryValue* FindMatchingTraceEntry(const JsonKeyValue* key_values); | 61 DictionaryValue* FindMatchingTraceEntry(const JsonKeyValue* key_values); |
60 DictionaryValue* FindNamePhase(const char* name, const char* phase); | 62 DictionaryValue* FindNamePhase(const char* name, const char* phase); |
61 DictionaryValue* FindNamePhaseKeyValue(const char* name, | 63 DictionaryValue* FindNamePhaseKeyValue(const char* name, |
62 const char* phase, | 64 const char* phase, |
63 const char* key, | 65 const char* key, |
(...skipping 12 matching lines...) Expand all Loading... |
76 } | 78 } |
77 | 79 |
78 void BeginSpecificTrace(const std::string& filter) { | 80 void BeginSpecificTrace(const std::string& filter) { |
79 event_watch_notification_ = 0; | 81 event_watch_notification_ = 0; |
80 notifications_received_ = 0; | 82 notifications_received_ = 0; |
81 TraceLog::GetInstance()->SetEnabled(CategoryFilter(filter), | 83 TraceLog::GetInstance()->SetEnabled(CategoryFilter(filter), |
82 TraceLog::RECORD_UNTIL_FULL); | 84 TraceLog::RECORD_UNTIL_FULL); |
83 } | 85 } |
84 | 86 |
85 void EndTraceAndFlush() { | 87 void EndTraceAndFlush() { |
| 88 WaitableEvent flush_complete_event(false, false); |
| 89 EndTraceAndFlushAsync(&flush_complete_event); |
| 90 flush_complete_event.Wait(); |
| 91 } |
| 92 |
| 93 void EndTraceAndFlushAsync(WaitableEvent* flush_complete_event) { |
86 while (TraceLog::GetInstance()->IsEnabled()) | 94 while (TraceLog::GetInstance()->IsEnabled()) |
87 TraceLog::GetInstance()->SetDisabled(); | 95 TraceLog::GetInstance()->SetDisabled(); |
88 TraceLog::GetInstance()->Flush( | 96 TraceLog::GetInstance()->Flush( |
89 base::Bind(&TraceEventTestFixture::OnTraceDataCollected, | 97 base::Bind(&TraceEventTestFixture::OnTraceDataCollected, |
90 base::Unretained(this))); | 98 base::Unretained(static_cast<TraceEventTestFixture*>(this)), |
| 99 base::Unretained(flush_complete_event))); |
91 } | 100 } |
92 | 101 |
93 virtual void SetUp() OVERRIDE { | 102 virtual void SetUp() OVERRIDE { |
94 const char* name = PlatformThread::GetName(); | 103 const char* name = PlatformThread::GetName(); |
95 old_thread_name_ = name ? strdup(name) : NULL; | 104 old_thread_name_ = name ? strdup(name) : NULL; |
96 notifications_received_ = 0; | 105 notifications_received_ = 0; |
97 | 106 |
98 TraceLog::DeleteForTesting(); | 107 TraceLog::DeleteForTesting(); |
99 TraceLog* tracelog = TraceLog::GetInstance(); | 108 TraceLog* tracelog = TraceLog::GetInstance(); |
100 ASSERT_TRUE(tracelog); | 109 ASSERT_TRUE(tracelog); |
(...skipping 20 matching lines...) Expand all Loading... |
121 int event_watch_notification_; | 130 int event_watch_notification_; |
122 int notifications_received_; | 131 int notifications_received_; |
123 | 132 |
124 private: | 133 private: |
125 // We want our singleton torn down after each test. | 134 // We want our singleton torn down after each test. |
126 ShadowingAtExitManager at_exit_manager_; | 135 ShadowingAtExitManager at_exit_manager_; |
127 Lock lock_; | 136 Lock lock_; |
128 }; | 137 }; |
129 | 138 |
130 void TraceEventTestFixture::OnTraceDataCollected( | 139 void TraceEventTestFixture::OnTraceDataCollected( |
131 const scoped_refptr<base::RefCountedString>& events_str) { | 140 WaitableEvent* flush_complete_event, |
| 141 const scoped_refptr<base::RefCountedString>& events_str, |
| 142 bool has_more_events) { |
132 AutoLock lock(lock_); | 143 AutoLock lock(lock_); |
133 json_output_.json_output.clear(); | 144 json_output_.json_output.clear(); |
134 trace_buffer_.Start(); | 145 trace_buffer_.Start(); |
135 trace_buffer_.AddFragment(events_str->data()); | 146 trace_buffer_.AddFragment(events_str->data()); |
136 trace_buffer_.Finish(); | 147 trace_buffer_.Finish(); |
137 | 148 |
138 scoped_ptr<Value> root; | 149 scoped_ptr<Value> root; |
139 root.reset(base::JSONReader::Read(json_output_.json_output, | 150 root.reset(base::JSONReader::Read(json_output_.json_output, |
140 JSON_PARSE_RFC | JSON_DETACHABLE_CHILDREN)); | 151 JSON_PARSE_RFC | JSON_DETACHABLE_CHILDREN)); |
141 | 152 |
142 if (!root.get()) { | 153 if (!root.get()) { |
143 LOG(ERROR) << json_output_.json_output; | 154 LOG(ERROR) << json_output_.json_output; |
144 } | 155 } |
145 | 156 |
146 ListValue* root_list = NULL; | 157 ListValue* root_list = NULL; |
147 ASSERT_TRUE(root.get()); | 158 ASSERT_TRUE(root.get()); |
148 ASSERT_TRUE(root->GetAsList(&root_list)); | 159 ASSERT_TRUE(root->GetAsList(&root_list)); |
149 | 160 |
150 // Move items into our aggregate collection | 161 // Move items into our aggregate collection |
151 while (root_list->GetSize()) { | 162 while (root_list->GetSize()) { |
152 scoped_ptr<Value> item; | 163 scoped_ptr<Value> item; |
153 root_list->Remove(0, &item); | 164 root_list->Remove(0, &item); |
154 trace_parsed_.Append(item.release()); | 165 trace_parsed_.Append(item.release()); |
155 } | 166 } |
| 167 |
| 168 if (!has_more_events) |
| 169 flush_complete_event->Signal(); |
156 } | 170 } |
157 | 171 |
158 static bool CompareJsonValues(const std::string& lhs, | 172 static bool CompareJsonValues(const std::string& lhs, |
159 const std::string& rhs, | 173 const std::string& rhs, |
160 CompareOp op) { | 174 CompareOp op) { |
161 switch (op) { | 175 switch (op) { |
162 case IS_EQUAL: | 176 case IS_EQUAL: |
163 return lhs == rhs; | 177 return lhs == rhs; |
164 case IS_NOT_EQUAL: | 178 case IS_NOT_EQUAL: |
165 return lhs != rhs; | 179 return lhs != rhs; |
(...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1334 threads[i]->Start(); | 1348 threads[i]->Start(); |
1335 threads[i]->message_loop()->PostTask( | 1349 threads[i]->message_loop()->PostTask( |
1336 FROM_HERE, base::Bind(&TraceManyInstantEvents, | 1350 FROM_HERE, base::Bind(&TraceManyInstantEvents, |
1337 i, num_events, task_complete_events[i])); | 1351 i, num_events, task_complete_events[i])); |
1338 } | 1352 } |
1339 | 1353 |
1340 for (int i = 0; i < num_threads; i++) { | 1354 for (int i = 0; i < num_threads; i++) { |
1341 task_complete_events[i]->Wait(); | 1355 task_complete_events[i]->Wait(); |
1342 } | 1356 } |
1343 | 1357 |
1344 for (int i = 0; i < num_threads; i++) { | 1358 // Let half of the threads end before flush. |
| 1359 for (int i = 0; i < num_threads / 2; i++) { |
1345 threads[i]->Stop(); | 1360 threads[i]->Stop(); |
1346 delete threads[i]; | 1361 delete threads[i]; |
1347 delete task_complete_events[i]; | 1362 delete task_complete_events[i]; |
1348 } | 1363 } |
1349 | 1364 |
1350 EndTraceAndFlush(); | 1365 WaitableEvent flush_complete_event(false, false); |
1351 | 1366 Thread flush_thread("flush"); |
| 1367 flush_thread.Start(); |
| 1368 flush_thread.message_loop()->PostTask(FROM_HERE, |
| 1369 base::Bind(&TraceEventTestFixture::EndTraceAndFlushAsync, |
| 1370 base::Unretained(this), |
| 1371 &flush_complete_event)); |
| 1372 flush_complete_event.Wait(); |
1352 ValidateInstantEventPresentOnEveryThread(trace_parsed_, | 1373 ValidateInstantEventPresentOnEveryThread(trace_parsed_, |
1353 num_threads, num_events); | 1374 num_threads, num_events); |
| 1375 |
| 1376 // Let the other half of the threads end after flush. |
| 1377 for (int i = num_threads / 2; i < num_threads; i++) { |
| 1378 threads[i]->Stop(); |
| 1379 delete threads[i]; |
| 1380 delete task_complete_events[i]; |
| 1381 } |
1354 } | 1382 } |
1355 | 1383 |
1356 // Test that thread and process names show up in the trace | 1384 // Test that thread and process names show up in the trace |
1357 TEST_F(TraceEventTestFixture, ThreadNames) { | 1385 TEST_F(TraceEventTestFixture, ThreadNames) { |
1358 // Create threads before we enable tracing to make sure | 1386 // Create threads before we enable tracing to make sure |
1359 // that tracelog still captures them. | 1387 // that tracelog still captures them. |
1360 const int num_threads = 4; | 1388 const int num_threads = 4; |
1361 const int num_events = 10; | 1389 const int num_events = 10; |
1362 Thread* threads[num_threads]; | 1390 Thread* threads[num_threads]; |
1363 PlatformThreadId thread_ids[num_threads]; | 1391 PlatformThreadId thread_ids[num_threads]; |
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2015 EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( | 2043 EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( |
2016 " bad_category ")); | 2044 " bad_category ")); |
2017 EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( | 2045 EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( |
2018 "")); | 2046 "")); |
2019 EXPECT_FALSE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( | 2047 EXPECT_FALSE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( |
2020 "good_category")); | 2048 "good_category")); |
2021 } | 2049 } |
2022 | 2050 |
2023 } // namespace debug | 2051 } // namespace debug |
2024 } // namespace base | 2052 } // namespace base |
OLD | NEW |