| 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 |