OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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.h" | 5 #include "base/debug/trace_event.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 const char* value; | 33 const char* value; |
34 CompareOp op; | 34 CompareOp op; |
35 }; | 35 }; |
36 | 36 |
37 class TraceEventTestFixture : public testing::Test { | 37 class TraceEventTestFixture : public testing::Test { |
38 public: | 38 public: |
39 // This fixture does not use SetUp() because the fixture must be manually set | 39 // This fixture does not use SetUp() because the fixture must be manually set |
40 // up multiple times when testing AtExit. Use ManualTestSetUp for this. | 40 // up multiple times when testing AtExit. Use ManualTestSetUp for this. |
41 void ManualTestSetUp(); | 41 void ManualTestSetUp(); |
42 void OnTraceDataCollected( | 42 void OnTraceDataCollected( |
43 scoped_refptr<TraceLog::RefCountedString> events_str); | 43 scoped_refptr<TraceLog::RefCountedString> json_events_str); |
44 bool FindMatchingTraceEntry(const JsonKeyValue* key_values); | 44 bool FindMatchingTraceEntry(const JsonKeyValue* key_values); |
45 bool FindNamePhase(const char* name, const char* phase); | 45 bool FindNamePhase(const char* name, const char* phase); |
46 bool FindMatchingValue(const char* key, | 46 bool FindMatchingValue(const char* key, |
47 const char* value); | 47 const char* value); |
48 bool FindNonMatchingValue(const char* key, | 48 bool FindNonMatchingValue(const char* key, |
49 const char* value); | 49 const char* value); |
50 void Clear() { | 50 void Clear() { |
| 51 trace_string_.clear(); |
51 trace_parsed_.Clear(); | 52 trace_parsed_.Clear(); |
52 json_output_.json_output.clear(); | |
53 } | 53 } |
54 | 54 |
| 55 std::string trace_string_; |
55 ListValue trace_parsed_; | 56 ListValue trace_parsed_; |
56 base::debug::TraceResultBuffer trace_buffer_; | |
57 base::debug::TraceResultBuffer::SimpleOutput json_output_; | |
58 | 57 |
59 private: | 58 private: |
60 // We want our singleton torn down after each test. | 59 // We want our singleton torn down after each test. |
61 ShadowingAtExitManager at_exit_manager_; | 60 ShadowingAtExitManager at_exit_manager_; |
62 Lock lock_; | 61 Lock lock_; |
63 }; | 62 }; |
64 | 63 |
65 void TraceEventTestFixture::ManualTestSetUp() { | 64 void TraceEventTestFixture::ManualTestSetUp() { |
66 TraceLog::DeleteForTesting(); | 65 TraceLog::DeleteForTesting(); |
67 TraceLog::Resurrect(); | 66 TraceLog::Resurrect(); |
68 TraceLog* tracelog = TraceLog::GetInstance(); | 67 TraceLog* tracelog = TraceLog::GetInstance(); |
69 ASSERT_TRUE(tracelog); | 68 ASSERT_TRUE(tracelog); |
70 ASSERT_FALSE(tracelog->IsEnabled()); | 69 ASSERT_FALSE(tracelog->IsEnabled()); |
71 tracelog->SetOutputCallback( | 70 tracelog->SetOutputCallback( |
72 base::Bind(&TraceEventTestFixture::OnTraceDataCollected, | 71 base::Bind(&TraceEventTestFixture::OnTraceDataCollected, |
73 base::Unretained(this))); | 72 base::Unretained(this))); |
74 trace_buffer_.SetOutputCallback(json_output_.GetCallback()); | |
75 } | 73 } |
76 | 74 |
77 void TraceEventTestFixture::OnTraceDataCollected( | 75 void TraceEventTestFixture::OnTraceDataCollected( |
78 scoped_refptr<TraceLog::RefCountedString> events_str) { | 76 scoped_refptr<TraceLog::RefCountedString> json_events_str) { |
79 AutoLock lock(lock_); | 77 AutoLock lock(lock_); |
80 json_output_.json_output.clear(); | 78 trace_string_ += json_events_str->data; |
81 trace_buffer_.Start(); | |
82 trace_buffer_.AddFragment(events_str->data); | |
83 trace_buffer_.Finish(); | |
84 | 79 |
85 scoped_ptr<Value> root; | 80 scoped_ptr<Value> root; |
86 root.reset(base::JSONReader::Read(json_output_.json_output, false)); | 81 root.reset(base::JSONReader::Read(json_events_str->data, false)); |
87 | 82 |
88 ListValue* root_list = NULL; | 83 ListValue* root_list = NULL; |
89 ASSERT_TRUE(root.get()); | 84 ASSERT_TRUE(root.get()); |
90 ASSERT_TRUE(root->GetAsList(&root_list)); | 85 ASSERT_TRUE(root->GetAsList(&root_list)); |
91 | 86 |
92 // Move items into our aggregate collection | 87 // Move items into our aggregate collection |
93 while (root_list->GetSize()) { | 88 while (root_list->GetSize()) { |
94 Value* item = NULL; | 89 Value* item = NULL; |
95 root_list->Remove(0, &item); | 90 root_list->Remove(0, &item); |
96 trace_parsed_.Append(item); | 91 trace_parsed_.Append(item); |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 TRACE_EVENT_END1("all", "TRACE_EVENT_END1 call", "name1", "value1"); | 274 TRACE_EVENT_END1("all", "TRACE_EVENT_END1 call", "name1", "value1"); |
280 TRACE_EVENT_END2("all", "TRACE_EVENT_END2 call", | 275 TRACE_EVENT_END2("all", "TRACE_EVENT_END2 call", |
281 "name1", "value1", | 276 "name1", "value1", |
282 "name2", "value2"); | 277 "name2", "value2"); |
283 } // Scope close causes TRACE_EVENT0 etc to send their END events. | 278 } // Scope close causes TRACE_EVENT0 etc to send their END events. |
284 | 279 |
285 if (task_complete_event) | 280 if (task_complete_event) |
286 task_complete_event->Signal(); | 281 task_complete_event->Signal(); |
287 } | 282 } |
288 | 283 |
289 void ValidateAllTraceMacrosCreatedData(const ListValue& trace_parsed) { | 284 void ValidateAllTraceMacrosCreatedData(const ListValue& trace_parsed, |
| 285 const std::string& trace_string) { |
290 DictionaryValue* item = NULL; | 286 DictionaryValue* item = NULL; |
291 | 287 |
292 #define EXPECT_FIND_(string) \ | 288 #define EXPECT_FIND_(string) \ |
293 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, string))); | 289 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, string))); |
294 #define EXPECT_NOT_FIND_(string) \ | 290 #define EXPECT_NOT_FIND_(string) \ |
295 EXPECT_FALSE((item = FindTraceEntry(trace_parsed, string))); | 291 EXPECT_FALSE((item = FindTraceEntry(trace_parsed, string))); |
296 #define EXPECT_SUB_FIND_(string) \ | 292 #define EXPECT_SUB_FIND_(string) \ |
297 if (item) EXPECT_TRUE((IsStringInDict(string, item))); | 293 if (item) EXPECT_TRUE((IsStringInDict(string, item))); |
298 | 294 |
299 EXPECT_FIND_("ETW Trace Event"); | 295 EXPECT_FIND_("ETW Trace Event"); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 EXPECT_FIND_("TRACE_EVENT_END0 call"); | 338 EXPECT_FIND_("TRACE_EVENT_END0 call"); |
343 EXPECT_FIND_("TRACE_EVENT_END1 call"); | 339 EXPECT_FIND_("TRACE_EVENT_END1 call"); |
344 EXPECT_FIND_("TRACE_EVENT_END2 call"); | 340 EXPECT_FIND_("TRACE_EVENT_END2 call"); |
345 EXPECT_SUB_FIND_("name1"); | 341 EXPECT_SUB_FIND_("name1"); |
346 EXPECT_SUB_FIND_("value1"); | 342 EXPECT_SUB_FIND_("value1"); |
347 EXPECT_SUB_FIND_("name2"); | 343 EXPECT_SUB_FIND_("name2"); |
348 EXPECT_SUB_FIND_("value2"); | 344 EXPECT_SUB_FIND_("value2"); |
349 } | 345 } |
350 | 346 |
351 void TraceManyInstantEvents(int thread_id, int num_events, | 347 void TraceManyInstantEvents(int thread_id, int num_events, |
352 WaitableEvent* task_complete_event) { | 348 WaitableEvent* task_complete_event) { |
353 for (int i = 0; i < num_events; i++) { | 349 for (int i = 0; i < num_events; i++) { |
354 TRACE_EVENT_INSTANT2("all", "multi thread event", | 350 TRACE_EVENT_INSTANT2("all", "multi thread event", |
355 "thread", thread_id, | 351 "thread", thread_id, |
356 "event", i); | 352 "event", i); |
357 } | 353 } |
358 | 354 |
359 if (task_complete_event) | 355 if (task_complete_event) |
360 task_complete_event->Signal(); | 356 task_complete_event->Signal(); |
361 } | 357 } |
362 | 358 |
363 void ValidateInstantEventPresentOnEveryThread(const ListValue& trace_parsed, | 359 void ValidateInstantEventPresentOnEveryThread(const ListValue& trace_parsed, |
364 int num_threads, | 360 const std::string& trace_string, |
365 int num_events) { | 361 int num_threads, int num_events) { |
366 std::map<int, std::map<int, bool> > results; | 362 std::map<int, std::map<int, bool> > results; |
367 | 363 |
368 size_t trace_parsed_count = trace_parsed.GetSize(); | 364 size_t trace_parsed_count = trace_parsed.GetSize(); |
369 for (size_t i = 0; i < trace_parsed_count; i++) { | 365 for (size_t i = 0; i < trace_parsed_count; i++) { |
370 Value* value = NULL; | 366 Value* value = NULL; |
371 trace_parsed.Get(i, &value); | 367 trace_parsed.Get(i, &value); |
372 if (!value || value->GetType() != Value::TYPE_DICTIONARY) | 368 if (!value || value->GetType() != Value::TYPE_DICTIONARY) |
373 continue; | 369 continue; |
374 DictionaryValue* dict = static_cast<DictionaryValue*>(value); | 370 DictionaryValue* dict = static_cast<DictionaryValue*>(value); |
375 std::string name; | 371 std::string name; |
(...skipping 27 matching lines...) Expand all Loading... |
403 | 399 |
404 // Simple Test for emitting data and validating it was received. | 400 // Simple Test for emitting data and validating it was received. |
405 TEST_F(TraceEventTestFixture, DataCaptured) { | 401 TEST_F(TraceEventTestFixture, DataCaptured) { |
406 ManualTestSetUp(); | 402 ManualTestSetUp(); |
407 TraceLog::GetInstance()->SetEnabled(true); | 403 TraceLog::GetInstance()->SetEnabled(true); |
408 | 404 |
409 TraceWithAllMacroVariants(NULL); | 405 TraceWithAllMacroVariants(NULL); |
410 | 406 |
411 TraceLog::GetInstance()->SetEnabled(false); | 407 TraceLog::GetInstance()->SetEnabled(false); |
412 | 408 |
413 ValidateAllTraceMacrosCreatedData(trace_parsed_); | 409 ValidateAllTraceMacrosCreatedData(trace_parsed_, trace_string_); |
414 } | 410 } |
415 | 411 |
416 // Test that categories work. | 412 // Test that categories work. |
417 TEST_F(TraceEventTestFixture, Categories) { | 413 TEST_F(TraceEventTestFixture, Categories) { |
418 ManualTestSetUp(); | 414 ManualTestSetUp(); |
419 | 415 |
420 // Test that categories that are used can be retrieved whether trace was | 416 // Test that categories that are used can be retrieved whether trace was |
421 // enabled or disabled when the trace event was encountered. | 417 // enabled or disabled when the trace event was encountered. |
422 TRACE_EVENT_INSTANT0("c1", "name"); | 418 TRACE_EVENT_INSTANT0("c1", "name"); |
423 TRACE_EVENT_INSTANT0("c2", "name"); | 419 TRACE_EVENT_INSTANT0("c2", "name"); |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 Thread thread("1"); | 680 Thread thread("1"); |
685 WaitableEvent task_complete_event(false, false); | 681 WaitableEvent task_complete_event(false, false); |
686 thread.Start(); | 682 thread.Start(); |
687 | 683 |
688 thread.message_loop()->PostTask( | 684 thread.message_loop()->PostTask( |
689 FROM_HERE, base::Bind(&TraceWithAllMacroVariants, &task_complete_event)); | 685 FROM_HERE, base::Bind(&TraceWithAllMacroVariants, &task_complete_event)); |
690 task_complete_event.Wait(); | 686 task_complete_event.Wait(); |
691 thread.Stop(); | 687 thread.Stop(); |
692 | 688 |
693 TraceLog::GetInstance()->SetEnabled(false); | 689 TraceLog::GetInstance()->SetEnabled(false); |
694 ValidateAllTraceMacrosCreatedData(trace_parsed_); | 690 ValidateAllTraceMacrosCreatedData(trace_parsed_, trace_string_); |
695 } | 691 } |
696 | 692 |
697 // Test that data sent from multiple threads is gathered | 693 // Test that data sent from multiple threads is gathered |
698 TEST_F(TraceEventTestFixture, DataCapturedManyThreads) { | 694 TEST_F(TraceEventTestFixture, DataCapturedManyThreads) { |
699 ManualTestSetUp(); | 695 ManualTestSetUp(); |
700 TraceLog::GetInstance()->SetEnabled(true); | 696 TraceLog::GetInstance()->SetEnabled(true); |
701 | 697 |
702 const int num_threads = 4; | 698 const int num_threads = 4; |
703 const int num_events = 4000; | 699 const int num_events = 4000; |
704 Thread* threads[num_threads]; | 700 Thread* threads[num_threads]; |
(...skipping 12 matching lines...) Expand all Loading... |
717 } | 713 } |
718 | 714 |
719 for (int i = 0; i < num_threads; i++) { | 715 for (int i = 0; i < num_threads; i++) { |
720 threads[i]->Stop(); | 716 threads[i]->Stop(); |
721 delete threads[i]; | 717 delete threads[i]; |
722 delete task_complete_events[i]; | 718 delete task_complete_events[i]; |
723 } | 719 } |
724 | 720 |
725 TraceLog::GetInstance()->SetEnabled(false); | 721 TraceLog::GetInstance()->SetEnabled(false); |
726 | 722 |
727 ValidateInstantEventPresentOnEveryThread(trace_parsed_, | 723 ValidateInstantEventPresentOnEveryThread(trace_parsed_, trace_string_, |
728 num_threads, num_events); | 724 num_threads, num_events); |
729 } | 725 } |
730 | 726 |
731 // Test that thread and process names show up in the trace | 727 // Test that thread and process names show up in the trace |
732 TEST_F(TraceEventTestFixture, ThreadNames) { | 728 TEST_F(TraceEventTestFixture, ThreadNames) { |
733 ManualTestSetUp(); | 729 ManualTestSetUp(); |
734 | 730 |
735 // Create threads before we enable tracing to make sure | 731 // Create threads before we enable tracing to make sure |
736 // that tracelog still captures them. | 732 // that tracelog still captures them. |
737 const int num_threads = 4; | 733 const int num_threads = 4; |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 EXPECT_TRUE(entry2->GetInteger("args.arg1", &i)); | 918 EXPECT_TRUE(entry2->GetInteger("args.arg1", &i)); |
923 EXPECT_EQ(5, i); | 919 EXPECT_EQ(5, i); |
924 | 920 |
925 std::string s; | 921 std::string s; |
926 EXPECT_TRUE(entry3->GetString("args.arg1", &s)); | 922 EXPECT_TRUE(entry3->GetString("args.arg1", &s)); |
927 EXPECT_EQ("val1", s); | 923 EXPECT_EQ("val1", s); |
928 EXPECT_TRUE(entry3->GetString("args.arg2", &s)); | 924 EXPECT_TRUE(entry3->GetString("args.arg2", &s)); |
929 EXPECT_EQ("val2", s); | 925 EXPECT_EQ("val2", s); |
930 } | 926 } |
931 | 927 |
932 // Test that TraceResultBuffer outputs the correct result whether it is added | |
933 // in chunks or added all at once. | |
934 TEST_F(TraceEventTestFixture, TraceResultBuffer) { | |
935 ManualTestSetUp(); | |
936 | |
937 Clear(); | |
938 | |
939 trace_buffer_.Start(); | |
940 trace_buffer_.AddFragment("bla1"); | |
941 trace_buffer_.AddFragment("bla2"); | |
942 trace_buffer_.AddFragment("bla3,bla4"); | |
943 trace_buffer_.Finish(); | |
944 EXPECT_STREQ(json_output_.json_output.c_str(), "[bla1,bla2,bla3,bla4]"); | |
945 | |
946 Clear(); | |
947 | |
948 trace_buffer_.Start(); | |
949 trace_buffer_.AddFragment("bla1,bla2,bla3,bla4"); | |
950 trace_buffer_.Finish(); | |
951 EXPECT_STREQ(json_output_.json_output.c_str(), "[bla1,bla2,bla3,bla4]"); | |
952 } | |
953 | |
954 } // namespace debug | 928 } // namespace debug |
955 } // namespace base | 929 } // namespace base |
OLD | NEW |