blob: 1f358fb6e72fc9ce9f0ce5d149431c14e557d63c [file] [log] [blame]
jbates@chromium.org59c27602012-01-13 12:12:44 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
scheib@chromium.org603f46e2011-05-10 11:23:58 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
jbates@chromium.org5e2f67d2012-08-16 13:32:49 +09005#include "base/debug/trace_event_unittest.h"
scheib@chromium.org603f46e2011-05-10 11:23:58 +09006
7#include "base/bind.h"
8#include "base/command_line.h"
jbates@chromium.org5e2f67d2012-08-16 13:32:49 +09009#include "base/debug/trace_event.h"
scheib@chromium.org603f46e2011-05-10 11:23:58 +090010#include "base/json/json_reader.h"
11#include "base/json/json_writer.h"
jbates@chromium.org1f18e462011-09-07 02:56:24 +090012#include "base/memory/ref_counted_memory.h"
scheib@chromium.org603f46e2011-05-10 11:23:58 +090013#include "base/memory/scoped_ptr.h"
joth@chromium.org088ae012011-11-11 01:26:23 +090014#include "base/memory/singleton.h"
nduca@chromium.org6d048772011-08-10 00:16:25 +090015#include "base/process_util.h"
scheib@chromium.org603f46e2011-05-10 11:23:58 +090016#include "base/stringprintf.h"
17#include "base/synchronization/waitable_event.h"
joth@chromium.org088ae012011-11-11 01:26:23 +090018#include "base/threading/platform_thread.h"
scheib@chromium.org603f46e2011-05-10 11:23:58 +090019#include "base/threading/thread.h"
20#include "base/values.h"
21#include "testing/gmock/include/gmock/gmock.h"
22#include "testing/gtest/include/gtest/gtest.h"
23
jbates@chromium.org5e2f67d2012-08-16 13:32:49 +090024using base::debug::HighResSleepForTraceTest;
25
scheib@chromium.org603f46e2011-05-10 11:23:58 +090026namespace base {
27namespace debug {
28
29namespace {
30
jbates@chromium.org11d4c362011-09-13 07:03:41 +090031enum CompareOp {
32 IS_EQUAL,
33 IS_NOT_EQUAL,
34};
35
jbates@chromium.orgb3cab862011-05-14 08:30:35 +090036struct JsonKeyValue {
37 const char* key;
38 const char* value;
jbates@chromium.org11d4c362011-09-13 07:03:41 +090039 CompareOp op;
jbates@chromium.orgb3cab862011-05-14 08:30:35 +090040};
41
scheib@chromium.org603f46e2011-05-10 11:23:58 +090042class TraceEventTestFixture : public testing::Test {
43 public:
joth@chromium.org113de992011-07-21 21:28:59 +090044 // This fixture does not use SetUp() because the fixture must be manually set
45 // up multiple times when testing AtExit. Use ManualTestSetUp for this.
scheib@chromium.org603f46e2011-05-10 11:23:58 +090046 void ManualTestSetUp();
ajwong@chromium.orgec1750a2011-06-27 01:22:50 +090047 void OnTraceDataCollected(
husky@chromium.org3b366292012-02-24 13:17:06 +090048 const scoped_refptr<base::RefCountedString>& events_str);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +090049 void OnTraceNotification(int notification) {
50 if (notification & TraceLog::EVENT_WATCH_NOTIFICATION)
51 ++event_watch_notification_;
52 }
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +090053 DictionaryValue* FindMatchingTraceEntry(const JsonKeyValue* key_values);
54 DictionaryValue* FindNamePhase(const char* name, const char* phase);
55 DictionaryValue* FindNamePhaseKeyValue(const char* name,
56 const char* phase,
57 const char* key,
58 const char* value);
jbates@chromium.org11d4c362011-09-13 07:03:41 +090059 bool FindMatchingValue(const char* key,
60 const char* value);
61 bool FindNonMatchingValue(const char* key,
62 const char* value);
63 void Clear() {
jbates@chromium.org11d4c362011-09-13 07:03:41 +090064 trace_parsed_.Clear();
jbates@chromium.org6a092d72011-10-25 01:34:08 +090065 json_output_.json_output.clear();
jbates@chromium.org11d4c362011-09-13 07:03:41 +090066 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +090067
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +090068 void BeginTrace() {
69 event_watch_notification_ = 0;
70 TraceLog::GetInstance()->SetEnabled("*");
71 }
72
73 void EndTraceAndFlush() {
74 TraceLog::GetInstance()->SetDisabled();
75 TraceLog::GetInstance()->Flush(
76 base::Bind(&TraceEventTestFixture::OnTraceDataCollected,
77 base::Unretained(this)));
78 }
79
rsleevi@chromium.orgde3a6cf2012-04-06 12:53:02 +090080 virtual void SetUp() OVERRIDE {
joth@chromium.org088ae012011-11-11 01:26:23 +090081 old_thread_name_ = PlatformThread::GetName();
82 }
rsleevi@chromium.orgde3a6cf2012-04-06 12:53:02 +090083 virtual void TearDown() OVERRIDE {
nduca@chromium.org6a7360c2012-02-20 15:35:15 +090084 if (TraceLog::GetInstance())
85 EXPECT_FALSE(TraceLog::GetInstance()->IsEnabled());
joth@chromium.org088ae012011-11-11 01:26:23 +090086 PlatformThread::SetName(old_thread_name_ ? old_thread_name_ : "");
87 }
88
89 const char* old_thread_name_;
scheib@chromium.org603f46e2011-05-10 11:23:58 +090090 ListValue trace_parsed_;
jbates@chromium.org6a092d72011-10-25 01:34:08 +090091 base::debug::TraceResultBuffer trace_buffer_;
92 base::debug::TraceResultBuffer::SimpleOutput json_output_;
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +090093 int event_watch_notification_;
scheib@chromium.org603f46e2011-05-10 11:23:58 +090094
95 private:
96 // We want our singleton torn down after each test.
97 ShadowingAtExitManager at_exit_manager_;
jbates@chromium.orgb84db522011-10-04 02:51:25 +090098 Lock lock_;
scheib@chromium.org603f46e2011-05-10 11:23:58 +090099};
100
101void TraceEventTestFixture::ManualTestSetUp() {
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900102 TraceLog::DeleteForTesting();
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900103 TraceLog::Resurrect();
104 TraceLog* tracelog = TraceLog::GetInstance();
105 ASSERT_TRUE(tracelog);
106 ASSERT_FALSE(tracelog->IsEnabled());
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900107 tracelog->SetNotificationCallback(
108 base::Bind(&TraceEventTestFixture::OnTraceNotification,
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900109 base::Unretained(this)));
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900110 trace_buffer_.SetOutputCallback(json_output_.GetCallback());
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900111}
112
113void TraceEventTestFixture::OnTraceDataCollected(
husky@chromium.org3b366292012-02-24 13:17:06 +0900114 const scoped_refptr<base::RefCountedString>& events_str) {
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900115 AutoLock lock(lock_);
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900116 json_output_.json_output.clear();
117 trace_buffer_.Start();
husky@chromium.org3b366292012-02-24 13:17:06 +0900118 trace_buffer_.AddFragment(events_str->data());
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900119 trace_buffer_.Finish();
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900120
121 scoped_ptr<Value> root;
rsesek@chromium.orgc2d2b202012-05-17 00:23:30 +0900122 root.reset(base::JSONReader::Read(json_output_.json_output,
123 JSON_PARSE_RFC | JSON_DETACHABLE_CHILDREN));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900124
jbates@chromium.org59c27602012-01-13 12:12:44 +0900125 if (!root.get()) {
126 LOG(ERROR) << json_output_.json_output;
127 }
128
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900129 ListValue* root_list = NULL;
130 ASSERT_TRUE(root.get());
131 ASSERT_TRUE(root->GetAsList(&root_list));
132
133 // Move items into our aggregate collection
134 while (root_list->GetSize()) {
135 Value* item = NULL;
136 root_list->Remove(0, &item);
137 trace_parsed_.Append(item);
138 }
139}
140
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900141static bool CompareJsonValues(const std::string& lhs,
142 const std::string& rhs,
143 CompareOp op) {
144 switch (op) {
145 case IS_EQUAL:
146 return lhs == rhs;
147 case IS_NOT_EQUAL:
148 return lhs != rhs;
149 default:
150 CHECK(0);
151 }
152 return false;
153}
154
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900155static bool IsKeyValueInDict(const JsonKeyValue* key_value,
156 DictionaryValue* dict) {
157 Value* value = NULL;
158 std::string value_str;
159 if (dict->Get(key_value->key, &value) &&
160 value->GetAsString(&value_str) &&
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900161 CompareJsonValues(value_str, key_value->value, key_value->op))
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900162 return true;
163
164 // Recurse to test arguments
165 DictionaryValue* args_dict = NULL;
166 dict->GetDictionary("args", &args_dict);
167 if (args_dict)
168 return IsKeyValueInDict(key_value, args_dict);
169
170 return false;
171}
172
173static bool IsAllKeyValueInDict(const JsonKeyValue* key_values,
174 DictionaryValue* dict) {
175 // Scan all key_values, they must all be present and equal.
176 while (key_values && key_values->key) {
177 if (!IsKeyValueInDict(key_values, dict))
178 return false;
179 ++key_values;
180 }
181 return true;
182}
183
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900184DictionaryValue* TraceEventTestFixture::FindMatchingTraceEntry(
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900185 const JsonKeyValue* key_values) {
186 // Scan all items
187 size_t trace_parsed_count = trace_parsed_.GetSize();
188 for (size_t i = 0; i < trace_parsed_count; i++) {
189 Value* value = NULL;
190 trace_parsed_.Get(i, &value);
191 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
192 continue;
193 DictionaryValue* dict = static_cast<DictionaryValue*>(value);
194
195 if (IsAllKeyValueInDict(key_values, dict))
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900196 return dict;
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900197 }
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900198 return NULL;
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900199}
200
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900201DictionaryValue* TraceEventTestFixture::FindNamePhase(const char* name,
202 const char* phase) {
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900203 JsonKeyValue key_values[] = {
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900204 {"name", name, IS_EQUAL},
205 {"ph", phase, IS_EQUAL},
206 {0, 0, IS_EQUAL}
207 };
208 return FindMatchingTraceEntry(key_values);
209}
210
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900211DictionaryValue* TraceEventTestFixture::FindNamePhaseKeyValue(
212 const char* name,
213 const char* phase,
214 const char* key,
215 const char* value) {
216 JsonKeyValue key_values[] = {
217 {"name", name, IS_EQUAL},
218 {"ph", phase, IS_EQUAL},
219 {key, value, IS_EQUAL},
220 {0, 0, IS_EQUAL}
221 };
222 return FindMatchingTraceEntry(key_values);
223}
224
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900225bool TraceEventTestFixture::FindMatchingValue(const char* key,
226 const char* value) {
227 JsonKeyValue key_values[] = {
228 {key, value, IS_EQUAL},
229 {0, 0, IS_EQUAL}
230 };
231 return FindMatchingTraceEntry(key_values);
232}
233
234bool TraceEventTestFixture::FindNonMatchingValue(const char* key,
235 const char* value) {
236 JsonKeyValue key_values[] = {
237 {key, value, IS_NOT_EQUAL},
238 {0, 0, IS_EQUAL}
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900239 };
240 return FindMatchingTraceEntry(key_values);
241}
242
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900243bool IsStringInDict(const char* string_to_match, const DictionaryValue* dict) {
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900244 for (DictionaryValue::key_iterator ikey = dict->begin_keys();
245 ikey != dict->end_keys(); ++ikey) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900246 const Value* child = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900247 if (!dict->GetWithoutPathExpansion(*ikey, &child))
248 continue;
249
250 if ((*ikey).find(string_to_match) != std::string::npos)
251 return true;
252
253 std::string value_str;
254 child->GetAsString(&value_str);
255 if (value_str.find(string_to_match) != std::string::npos)
256 return true;
257 }
258
259 // Recurse to test arguments
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900260 const DictionaryValue* args_dict = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900261 dict->GetDictionary("args", &args_dict);
262 if (args_dict)
263 return IsStringInDict(string_to_match, args_dict);
264
265 return false;
266}
267
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900268const DictionaryValue* FindTraceEntry(
269 const ListValue& trace_parsed,
270 const char* string_to_match,
271 const DictionaryValue* match_after_this_item = NULL) {
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900272 // Scan all items
273 size_t trace_parsed_count = trace_parsed.GetSize();
274 for (size_t i = 0; i < trace_parsed_count; i++) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900275 const Value* value = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900276 trace_parsed.Get(i, &value);
277 if (match_after_this_item) {
278 if (value == match_after_this_item)
279 match_after_this_item = NULL;
280 continue;
281 }
282 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
283 continue;
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900284 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900285
286 if (IsStringInDict(string_to_match, dict))
287 return dict;
288 }
289 return NULL;
290}
291
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900292std::vector<const DictionaryValue*> FindTraceEntries(
nduca@chromium.org6d048772011-08-10 00:16:25 +0900293 const ListValue& trace_parsed,
294 const char* string_to_match) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900295 std::vector<const DictionaryValue*> hits;
nduca@chromium.org6d048772011-08-10 00:16:25 +0900296 size_t trace_parsed_count = trace_parsed.GetSize();
297 for (size_t i = 0; i < trace_parsed_count; i++) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900298 const Value* value = NULL;
nduca@chromium.org6d048772011-08-10 00:16:25 +0900299 trace_parsed.Get(i, &value);
300 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
301 continue;
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900302 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
nduca@chromium.org6d048772011-08-10 00:16:25 +0900303
304 if (IsStringInDict(string_to_match, dict))
305 hits.push_back(dict);
306 }
307 return hits;
308}
309
310void TraceWithAllMacroVariants(WaitableEvent* task_complete_event) {
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900311 {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900312 TRACE_EVENT_BEGIN_ETW("TRACE_EVENT_BEGIN_ETW call", 0x1122, "extrastring1");
313 TRACE_EVENT_END_ETW("TRACE_EVENT_END_ETW call", 0x3344, "extrastring2");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900314 TRACE_EVENT_INSTANT_ETW("TRACE_EVENT_INSTANT_ETW call",
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900315 0x5566, "extrastring3");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900316
317 TRACE_EVENT0("all", "TRACE_EVENT0 call");
318 TRACE_EVENT1("all", "TRACE_EVENT1 call", "name1", "value1");
319 TRACE_EVENT2("all", "TRACE_EVENT2 call",
jbates@chromium.org788d5a12011-09-07 09:43:11 +0900320 "name1", "\"value1\"",
321 "name2", "value\\2");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900322
323 TRACE_EVENT_INSTANT0("all", "TRACE_EVENT_INSTANT0 call");
324 TRACE_EVENT_INSTANT1("all", "TRACE_EVENT_INSTANT1 call", "name1", "value1");
325 TRACE_EVENT_INSTANT2("all", "TRACE_EVENT_INSTANT2 call",
326 "name1", "value1",
327 "name2", "value2");
328
329 TRACE_EVENT_BEGIN0("all", "TRACE_EVENT_BEGIN0 call");
330 TRACE_EVENT_BEGIN1("all", "TRACE_EVENT_BEGIN1 call", "name1", "value1");
331 TRACE_EVENT_BEGIN2("all", "TRACE_EVENT_BEGIN2 call",
332 "name1", "value1",
333 "name2", "value2");
334
335 TRACE_EVENT_END0("all", "TRACE_EVENT_END0 call");
336 TRACE_EVENT_END1("all", "TRACE_EVENT_END1 call", "name1", "value1");
337 TRACE_EVENT_END2("all", "TRACE_EVENT_END2 call",
338 "name1", "value1",
339 "name2", "value2");
nduca@chromium.org62210b02011-11-18 18:36:36 +0900340
jbates@chromium.org59c27602012-01-13 12:12:44 +0900341 TRACE_EVENT_IF_LONGER_THAN0(0, "all", "TRACE_EVENT_IF_LONGER_THAN0 call");
342 TRACE_EVENT_IF_LONGER_THAN1(0, "all", "TRACE_EVENT_IF_LONGER_THAN1 call",
343 "name1", "value1");
344 TRACE_EVENT_IF_LONGER_THAN2(0, "all", "TRACE_EVENT_IF_LONGER_THAN2 call",
345 "name1", "value1",
346 "name2", "value2");
347
jbates@chromium.org88295f92012-03-01 12:04:59 +0900348 TRACE_EVENT_ASYNC_BEGIN0("all", "TRACE_EVENT_ASYNC_BEGIN0 call", 5);
349 TRACE_EVENT_ASYNC_BEGIN1("all", "TRACE_EVENT_ASYNC_BEGIN1 call", 5,
350 "name1", "value1");
351 TRACE_EVENT_ASYNC_BEGIN2("all", "TRACE_EVENT_ASYNC_BEGIN2 call", 5,
352 "name1", "value1",
353 "name2", "value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900354
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900355 TRACE_EVENT_ASYNC_BEGIN_STEP0("all", "TRACE_EVENT_ASYNC_BEGIN_STEP0 call",
356 5, "step1");
357 TRACE_EVENT_ASYNC_BEGIN_STEP1("all", "TRACE_EVENT_ASYNC_BEGIN_STEP1 call",
358 5, "step2", "name1", "value1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900359
360 TRACE_EVENT_ASYNC_END0("all", "TRACE_EVENT_ASYNC_END0 call", 5);
361 TRACE_EVENT_ASYNC_END1("all", "TRACE_EVENT_ASYNC_END1 call", 5,
362 "name1", "value1");
363 TRACE_EVENT_ASYNC_END2("all", "TRACE_EVENT_ASYNC_END2 call", 5,
364 "name1", "value1",
365 "name2", "value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900366
367 TRACE_EVENT_BEGIN_ETW("TRACE_EVENT_BEGIN_ETW0 call", 5, NULL);
368 TRACE_EVENT_BEGIN_ETW("TRACE_EVENT_BEGIN_ETW1 call", 5, "value");
369 TRACE_EVENT_END_ETW("TRACE_EVENT_END_ETW0 call", 5, NULL);
370 TRACE_EVENT_END_ETW("TRACE_EVENT_END_ETW1 call", 5, "value");
371 TRACE_EVENT_INSTANT_ETW("TRACE_EVENT_INSTANT_ETW0 call", 5, NULL);
372 TRACE_EVENT_INSTANT_ETW("TRACE_EVENT_INSTANT_ETW1 call", 5, "value");
373
nduca@chromium.org62210b02011-11-18 18:36:36 +0900374 TRACE_COUNTER1("all", "TRACE_COUNTER1 call", 31415);
375 TRACE_COUNTER2("all", "TRACE_COUNTER2 call",
376 "a", 30000,
377 "b", 1415);
piman@chromium.org902b2952011-12-16 10:19:06 +0900378
379 TRACE_COUNTER_ID1("all", "TRACE_COUNTER_ID1 call", 0x319009, 31415);
380 TRACE_COUNTER_ID2("all", "TRACE_COUNTER_ID2 call", 0x319009,
381 "a", 30000, "b", 1415);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900382 } // Scope close causes TRACE_EVENT0 etc to send their END events.
383
384 if (task_complete_event)
385 task_complete_event->Signal();
386}
387
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900388void ValidateAllTraceMacrosCreatedData(const ListValue& trace_parsed) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900389 const DictionaryValue* item = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900390
391#define EXPECT_FIND_(string) \
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900392 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, string)));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900393#define EXPECT_NOT_FIND_(string) \
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900394 EXPECT_FALSE((item = FindTraceEntry(trace_parsed, string)));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900395#define EXPECT_SUB_FIND_(string) \
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900396 if (item) EXPECT_TRUE((IsStringInDict(string, item)));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900397
398 EXPECT_FIND_("ETW Trace Event");
399 EXPECT_FIND_("all");
400 EXPECT_FIND_("TRACE_EVENT_BEGIN_ETW call");
401 {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900402 std::string str_val;
403 EXPECT_TRUE(item && item->GetString("args.id", &str_val));
404 EXPECT_STREQ("1122", str_val.c_str());
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900405 }
406 EXPECT_SUB_FIND_("extrastring1");
407 EXPECT_FIND_("TRACE_EVENT_END_ETW call");
408 EXPECT_FIND_("TRACE_EVENT_INSTANT_ETW call");
409 EXPECT_FIND_("TRACE_EVENT0 call");
410 {
411 std::string ph_begin;
412 std::string ph_end;
413 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, "TRACE_EVENT0 call")));
414 EXPECT_TRUE((item && item->GetString("ph", &ph_begin)));
415 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, "TRACE_EVENT0 call",
416 item)));
417 EXPECT_TRUE((item && item->GetString("ph", &ph_end)));
418 EXPECT_EQ("B", ph_begin);
419 EXPECT_EQ("E", ph_end);
420 }
421 EXPECT_FIND_("TRACE_EVENT1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900422 EXPECT_SUB_FIND_("name1");
423 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900424 EXPECT_FIND_("TRACE_EVENT2 call");
425 EXPECT_SUB_FIND_("name1");
jbates@chromium.org788d5a12011-09-07 09:43:11 +0900426 EXPECT_SUB_FIND_("\"value1\"");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900427 EXPECT_SUB_FIND_("name2");
jbates@chromium.org788d5a12011-09-07 09:43:11 +0900428 EXPECT_SUB_FIND_("value\\2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900429
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900430 EXPECT_FIND_("TRACE_EVENT_INSTANT0 call");
431 EXPECT_FIND_("TRACE_EVENT_INSTANT1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900432 EXPECT_SUB_FIND_("name1");
433 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900434 EXPECT_FIND_("TRACE_EVENT_INSTANT2 call");
435 EXPECT_SUB_FIND_("name1");
436 EXPECT_SUB_FIND_("value1");
437 EXPECT_SUB_FIND_("name2");
438 EXPECT_SUB_FIND_("value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900439
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900440 EXPECT_FIND_("TRACE_EVENT_BEGIN0 call");
441 EXPECT_FIND_("TRACE_EVENT_BEGIN1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900442 EXPECT_SUB_FIND_("name1");
443 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900444 EXPECT_FIND_("TRACE_EVENT_BEGIN2 call");
445 EXPECT_SUB_FIND_("name1");
446 EXPECT_SUB_FIND_("value1");
447 EXPECT_SUB_FIND_("name2");
448 EXPECT_SUB_FIND_("value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900449
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900450 EXPECT_FIND_("TRACE_EVENT_END0 call");
451 EXPECT_FIND_("TRACE_EVENT_END1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900452 EXPECT_SUB_FIND_("name1");
453 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900454 EXPECT_FIND_("TRACE_EVENT_END2 call");
455 EXPECT_SUB_FIND_("name1");
456 EXPECT_SUB_FIND_("value1");
457 EXPECT_SUB_FIND_("name2");
458 EXPECT_SUB_FIND_("value2");
nduca@chromium.org62210b02011-11-18 18:36:36 +0900459
jbates@chromium.org59c27602012-01-13 12:12:44 +0900460 EXPECT_FIND_("TRACE_EVENT_IF_LONGER_THAN0 call");
461 EXPECT_FIND_("TRACE_EVENT_IF_LONGER_THAN1 call");
462 EXPECT_SUB_FIND_("name1");
463 EXPECT_SUB_FIND_("value1");
464 EXPECT_FIND_("TRACE_EVENT_IF_LONGER_THAN2 call");
465 EXPECT_SUB_FIND_("name1");
466 EXPECT_SUB_FIND_("value1");
467 EXPECT_SUB_FIND_("name2");
468 EXPECT_SUB_FIND_("value2");
469
jbates@chromium.org88295f92012-03-01 12:04:59 +0900470 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN0 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900471 EXPECT_SUB_FIND_("id");
472 EXPECT_SUB_FIND_("5");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900473 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900474 EXPECT_SUB_FIND_("id");
475 EXPECT_SUB_FIND_("5");
476 EXPECT_SUB_FIND_("name1");
477 EXPECT_SUB_FIND_("value1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900478 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN2 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900479 EXPECT_SUB_FIND_("id");
480 EXPECT_SUB_FIND_("5");
481 EXPECT_SUB_FIND_("name1");
482 EXPECT_SUB_FIND_("value1");
483 EXPECT_SUB_FIND_("name2");
484 EXPECT_SUB_FIND_("value2");
485
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900486 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN_STEP0 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900487 EXPECT_SUB_FIND_("id");
488 EXPECT_SUB_FIND_("5");
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900489 EXPECT_SUB_FIND_("step1");
490 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN_STEP1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900491 EXPECT_SUB_FIND_("id");
492 EXPECT_SUB_FIND_("5");
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900493 EXPECT_SUB_FIND_("step2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900494 EXPECT_SUB_FIND_("name1");
495 EXPECT_SUB_FIND_("value1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900496
497 EXPECT_FIND_("TRACE_EVENT_ASYNC_END0 call");
498 EXPECT_SUB_FIND_("id");
499 EXPECT_SUB_FIND_("5");
500 EXPECT_FIND_("TRACE_EVENT_ASYNC_END1 call");
501 EXPECT_SUB_FIND_("id");
502 EXPECT_SUB_FIND_("5");
503 EXPECT_SUB_FIND_("name1");
504 EXPECT_SUB_FIND_("value1");
505 EXPECT_FIND_("TRACE_EVENT_ASYNC_END2 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900506 EXPECT_SUB_FIND_("id");
507 EXPECT_SUB_FIND_("5");
508 EXPECT_SUB_FIND_("name1");
509 EXPECT_SUB_FIND_("value1");
510 EXPECT_SUB_FIND_("name2");
511 EXPECT_SUB_FIND_("value2");
512
513 EXPECT_FIND_("TRACE_EVENT_BEGIN_ETW0 call");
514 EXPECT_SUB_FIND_("id");
515 EXPECT_SUB_FIND_("5");
516 EXPECT_SUB_FIND_("extra");
517 EXPECT_SUB_FIND_("NULL");
518 EXPECT_FIND_("TRACE_EVENT_BEGIN_ETW1 call");
519 EXPECT_SUB_FIND_("id");
520 EXPECT_SUB_FIND_("5");
521 EXPECT_SUB_FIND_("extra");
522 EXPECT_SUB_FIND_("value");
523 EXPECT_FIND_("TRACE_EVENT_END_ETW0 call");
524 EXPECT_SUB_FIND_("id");
525 EXPECT_SUB_FIND_("5");
526 EXPECT_SUB_FIND_("extra");
527 EXPECT_SUB_FIND_("NULL");
528 EXPECT_FIND_("TRACE_EVENT_END_ETW1 call");
529 EXPECT_SUB_FIND_("id");
530 EXPECT_SUB_FIND_("5");
531 EXPECT_SUB_FIND_("extra");
532 EXPECT_SUB_FIND_("value");
533 EXPECT_FIND_("TRACE_EVENT_INSTANT_ETW0 call");
534 EXPECT_SUB_FIND_("id");
535 EXPECT_SUB_FIND_("5");
536 EXPECT_SUB_FIND_("extra");
537 EXPECT_SUB_FIND_("NULL");
538 EXPECT_FIND_("TRACE_EVENT_INSTANT_ETW1 call");
539 EXPECT_SUB_FIND_("id");
540 EXPECT_SUB_FIND_("5");
541 EXPECT_SUB_FIND_("extra");
542 EXPECT_SUB_FIND_("value");
543
nduca@chromium.org62210b02011-11-18 18:36:36 +0900544 EXPECT_FIND_("TRACE_COUNTER1 call");
545 {
546 std::string ph;
547 EXPECT_TRUE((item && item->GetString("ph", &ph)));
548 EXPECT_EQ("C", ph);
549
550 int value;
551 EXPECT_TRUE((item && item->GetInteger("args.value", &value)));
552 EXPECT_EQ(31415, value);
553 }
554
555 EXPECT_FIND_("TRACE_COUNTER2 call");
556 {
557 std::string ph;
558 EXPECT_TRUE((item && item->GetString("ph", &ph)));
559 EXPECT_EQ("C", ph);
560
561 int value;
562 EXPECT_TRUE((item && item->GetInteger("args.a", &value)));
563 EXPECT_EQ(30000, value);
564
565 EXPECT_TRUE((item && item->GetInteger("args.b", &value)));
566 EXPECT_EQ(1415, value);
567 }
568
piman@chromium.org902b2952011-12-16 10:19:06 +0900569 EXPECT_FIND_("TRACE_COUNTER_ID1 call");
570 {
571 std::string id;
572 EXPECT_TRUE((item && item->GetString("id", &id)));
573 EXPECT_EQ("319009", id);
574
575 std::string ph;
576 EXPECT_TRUE((item && item->GetString("ph", &ph)));
577 EXPECT_EQ("C", ph);
578
579 int value;
580 EXPECT_TRUE((item && item->GetInteger("args.value", &value)));
581 EXPECT_EQ(31415, value);
582 }
583
584 EXPECT_FIND_("TRACE_COUNTER_ID2 call");
585 {
586 std::string id;
587 EXPECT_TRUE((item && item->GetString("id", &id)));
588 EXPECT_EQ("319009", id);
589
590 std::string ph;
591 EXPECT_TRUE((item && item->GetString("ph", &ph)));
592 EXPECT_EQ("C", ph);
593
594 int value;
595 EXPECT_TRUE((item && item->GetInteger("args.a", &value)));
596 EXPECT_EQ(30000, value);
597
598 EXPECT_TRUE((item && item->GetInteger("args.b", &value)));
599 EXPECT_EQ(1415, value);
600 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900601}
602
nduca@chromium.org6d048772011-08-10 00:16:25 +0900603void TraceManyInstantEvents(int thread_id, int num_events,
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900604 WaitableEvent* task_complete_event) {
nduca@chromium.org6d048772011-08-10 00:16:25 +0900605 for (int i = 0; i < num_events; i++) {
606 TRACE_EVENT_INSTANT2("all", "multi thread event",
607 "thread", thread_id,
608 "event", i);
609 }
610
611 if (task_complete_event)
612 task_complete_event->Signal();
613}
614
615void ValidateInstantEventPresentOnEveryThread(const ListValue& trace_parsed,
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900616 int num_threads,
617 int num_events) {
nduca@chromium.org6d048772011-08-10 00:16:25 +0900618 std::map<int, std::map<int, bool> > results;
619
620 size_t trace_parsed_count = trace_parsed.GetSize();
621 for (size_t i = 0; i < trace_parsed_count; i++) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900622 const Value* value = NULL;
nduca@chromium.org6d048772011-08-10 00:16:25 +0900623 trace_parsed.Get(i, &value);
624 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
625 continue;
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900626 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
nduca@chromium.org6d048772011-08-10 00:16:25 +0900627 std::string name;
628 dict->GetString("name", &name);
629 if (name != "multi thread event")
630 continue;
631
632 int thread = 0;
633 int event = 0;
634 EXPECT_TRUE(dict->GetInteger("args.thread", &thread));
635 EXPECT_TRUE(dict->GetInteger("args.event", &event));
636 results[thread][event] = true;
637 }
638
639 EXPECT_FALSE(results[-1][-1]);
640 for (int thread = 0; thread < num_threads; thread++) {
641 for (int event = 0; event < num_events; event++) {
642 EXPECT_TRUE(results[thread][event]);
643 }
644 }
645}
646
647void TraceCallsWithCachedCategoryPointersPointers(const char* name_str) {
648 TRACE_EVENT0("category name1", name_str);
649 TRACE_EVENT_INSTANT0("category name2", name_str);
650 TRACE_EVENT_BEGIN0("category name3", name_str);
651 TRACE_EVENT_END0("category name4", name_str);
652}
653
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900654} // namespace
655
jbates@chromium.org5e2f67d2012-08-16 13:32:49 +0900656void HighResSleepForTraceTest(base::TimeDelta elapsed) {
657 base::TimeTicks end_time = base::TimeTicks::HighResNow() + elapsed;
658 do {
659 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
660 } while (base::TimeTicks::HighResNow() < end_time);
661}
662
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900663// Simple Test for emitting data and validating it was received.
664TEST_F(TraceEventTestFixture, DataCaptured) {
665 ManualTestSetUp();
666 TraceLog::GetInstance()->SetEnabled(true);
667
nduca@chromium.org6d048772011-08-10 00:16:25 +0900668 TraceWithAllMacroVariants(NULL);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900669
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900670 EndTraceAndFlush();
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900671
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900672 ValidateAllTraceMacrosCreatedData(trace_parsed_);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900673}
674
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900675class MockEnabledStateChangedObserver :
676 public base::debug::TraceLog::EnabledStateChangedObserver {
677 public:
678 MOCK_METHOD0(OnTraceLogWillEnable, void());
679 MOCK_METHOD0(OnTraceLogWillDisable, void());
680};
681
682TEST_F(TraceEventTestFixture, EnabledObserverFiresOnEnable) {
683 ManualTestSetUp();
684
685 MockEnabledStateChangedObserver observer;
686 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
687
688 EXPECT_CALL(observer, OnTraceLogWillEnable())
689 .Times(1);
690 TraceLog::GetInstance()->SetEnabled(true);
691 testing::Mock::VerifyAndClear(&observer);
692
693 // Cleanup.
694 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
695 TraceLog::GetInstance()->SetEnabled(false);
696}
697
698TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnSecondEnable) {
699 ManualTestSetUp();
700
701 TraceLog::GetInstance()->SetEnabled(true);
702
703 testing::StrictMock<MockEnabledStateChangedObserver> observer;
704 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
705
706 EXPECT_CALL(observer, OnTraceLogWillEnable())
707 .Times(0);
708 EXPECT_CALL(observer, OnTraceLogWillDisable())
709 .Times(0);
710 TraceLog::GetInstance()->SetEnabled(true);
711 testing::Mock::VerifyAndClear(&observer);
712
713 // Cleanup.
714 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
715 TraceLog::GetInstance()->SetEnabled(false);
716}
717
718TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnUselessDisable) {
719 ManualTestSetUp();
720
721
722 testing::StrictMock<MockEnabledStateChangedObserver> observer;
723 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
724
725 EXPECT_CALL(observer, OnTraceLogWillEnable())
726 .Times(0);
727 EXPECT_CALL(observer, OnTraceLogWillDisable())
728 .Times(0);
729 TraceLog::GetInstance()->SetEnabled(false);
730 testing::Mock::VerifyAndClear(&observer);
731
732 // Cleanup.
733 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
734}
735
736TEST_F(TraceEventTestFixture, EnabledObserverFiresOnDisable) {
737 ManualTestSetUp();
738
739 TraceLog::GetInstance()->SetEnabled(true);
740
741 MockEnabledStateChangedObserver observer;
742 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
743
744 EXPECT_CALL(observer, OnTraceLogWillDisable())
745 .Times(1);
746 TraceLog::GetInstance()->SetEnabled(false);
747 testing::Mock::VerifyAndClear(&observer);
748
749 // Cleanup.
750 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
751}
752
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900753// Test that categories work.
754TEST_F(TraceEventTestFixture, Categories) {
755 ManualTestSetUp();
756
757 // Test that categories that are used can be retrieved whether trace was
758 // enabled or disabled when the trace event was encountered.
759 TRACE_EVENT_INSTANT0("c1", "name");
760 TRACE_EVENT_INSTANT0("c2", "name");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900761 BeginTrace();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900762 TRACE_EVENT_INSTANT0("c3", "name");
763 TRACE_EVENT_INSTANT0("c4", "name");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900764 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900765 std::vector<std::string> cats;
766 TraceLog::GetInstance()->GetKnownCategories(&cats);
767 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c1") != cats.end());
768 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c2") != cats.end());
769 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c3") != cats.end());
770 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c4") != cats.end());
771
772 const std::vector<std::string> empty_categories;
773 std::vector<std::string> included_categories;
774 std::vector<std::string> excluded_categories;
775
776 // Test that category filtering works.
777
778 // Include nonexistent category -> no events
779 Clear();
780 included_categories.clear();
781 included_categories.push_back("not_found823564786");
782 TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories);
783 TRACE_EVENT_INSTANT0("cat1", "name");
784 TRACE_EVENT_INSTANT0("cat2", "name");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900785 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900786 EXPECT_TRUE(trace_parsed_.empty());
787
788 // Include existent category -> only events of that category
789 Clear();
790 included_categories.clear();
791 included_categories.push_back("inc");
792 TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories);
793 TRACE_EVENT_INSTANT0("inc", "name");
794 TRACE_EVENT_INSTANT0("inc2", "name");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900795 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900796 EXPECT_TRUE(FindMatchingValue("cat", "inc"));
797 EXPECT_FALSE(FindNonMatchingValue("cat", "inc"));
798
799 // Include existent wildcard -> all categories matching wildcard
800 Clear();
801 included_categories.clear();
802 included_categories.push_back("inc_wildcard_*");
803 included_categories.push_back("inc_wildchar_?_end");
804 TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories);
805 TRACE_EVENT_INSTANT0("inc_wildcard_abc", "included");
806 TRACE_EVENT_INSTANT0("inc_wildcard_", "included");
807 TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "included");
808 TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "not_inc");
809 TRACE_EVENT_INSTANT0("cat1", "not_inc");
810 TRACE_EVENT_INSTANT0("cat2", "not_inc");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900811 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900812 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_abc"));
813 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_"));
814 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildchar_x_end"));
815 EXPECT_FALSE(FindMatchingValue("name", "not_inc"));
816
817 included_categories.clear();
818
819 // Exclude nonexistent category -> all events
820 Clear();
821 excluded_categories.clear();
822 excluded_categories.push_back("not_found823564786");
823 TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories);
824 TRACE_EVENT_INSTANT0("cat1", "name");
825 TRACE_EVENT_INSTANT0("cat2", "name");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900826 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900827 EXPECT_TRUE(FindMatchingValue("cat", "cat1"));
828 EXPECT_TRUE(FindMatchingValue("cat", "cat2"));
829
830 // Exclude existent category -> only events of other categories
831 Clear();
832 excluded_categories.clear();
833 excluded_categories.push_back("inc");
834 TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories);
835 TRACE_EVENT_INSTANT0("inc", "name");
836 TRACE_EVENT_INSTANT0("inc2", "name");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900837 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900838 EXPECT_TRUE(FindMatchingValue("cat", "inc2"));
839 EXPECT_FALSE(FindMatchingValue("cat", "inc"));
840
841 // Exclude existent wildcard -> all categories not matching wildcard
842 Clear();
843 excluded_categories.clear();
844 excluded_categories.push_back("inc_wildcard_*");
845 excluded_categories.push_back("inc_wildchar_?_end");
846 TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories);
847 TRACE_EVENT_INSTANT0("inc_wildcard_abc", "not_inc");
848 TRACE_EVENT_INSTANT0("inc_wildcard_", "not_inc");
849 TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "not_inc");
850 TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "included");
851 TRACE_EVENT_INSTANT0("cat1", "included");
852 TRACE_EVENT_INSTANT0("cat2", "included");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900853 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900854 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildchar_bla_end"));
855 EXPECT_TRUE(FindMatchingValue("cat", "cat1"));
856 EXPECT_TRUE(FindMatchingValue("cat", "cat2"));
857 EXPECT_FALSE(FindMatchingValue("name", "not_inc"));
858}
859
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900860// Simple Test for time threshold events.
861TEST_F(TraceEventTestFixture, DataCapturedThreshold) {
862 ManualTestSetUp();
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900863 BeginTrace();
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900864
865 // Test that events at the same level are properly filtered by threshold.
866 {
867 TRACE_EVENT_IF_LONGER_THAN0(100, "time", "threshold 100");
868 TRACE_EVENT_IF_LONGER_THAN0(1000, "time", "threshold 1000");
869 TRACE_EVENT_IF_LONGER_THAN0(10000, "time", "threshold 10000");
870 // 100+ seconds to avoid flakiness.
871 TRACE_EVENT_IF_LONGER_THAN0(100000000, "time", "threshold long1");
872 TRACE_EVENT_IF_LONGER_THAN0(200000000, "time", "threshold long2");
jbates@chromium.org5e2f67d2012-08-16 13:32:49 +0900873 HighResSleepForTraceTest(base::TimeDelta::FromMilliseconds(20));
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900874 }
875
876 // Test that a normal nested event remains after it's parent event is dropped.
877 {
878 TRACE_EVENT_IF_LONGER_THAN0(1000000, "time", "2threshold10000");
879 {
880 TRACE_EVENT0("time", "nonthreshold1");
881 }
882 }
883
884 // Test that parent thresholded events are dropped while some nested events
885 // remain.
886 {
887 TRACE_EVENT0("time", "nonthreshold3");
888 {
889 TRACE_EVENT_IF_LONGER_THAN0(200000000, "time", "3thresholdlong2");
890 {
891 TRACE_EVENT_IF_LONGER_THAN0(100000000, "time", "3thresholdlong1");
892 {
893 TRACE_EVENT_IF_LONGER_THAN0(10000, "time", "3threshold10000");
894 {
895 TRACE_EVENT_IF_LONGER_THAN0(1000, "time", "3threshold1000");
896 {
897 TRACE_EVENT_IF_LONGER_THAN0(100, "time", "3threshold100");
jbates@chromium.org5e2f67d2012-08-16 13:32:49 +0900898 HighResSleepForTraceTest(base::TimeDelta::FromMilliseconds(20));
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900899 }
900 }
901 }
902 }
903 }
904 }
905
906 // Test that child thresholded events are dropped while some parent events
907 // remain.
908 {
909 TRACE_EVENT0("time", "nonthreshold4");
910 {
911 TRACE_EVENT_IF_LONGER_THAN0(100, "time", "4threshold100");
912 {
913 TRACE_EVENT_IF_LONGER_THAN0(1000, "time", "4threshold1000");
914 {
915 TRACE_EVENT_IF_LONGER_THAN0(10000, "time", "4threshold10000");
916 {
917 TRACE_EVENT_IF_LONGER_THAN0(100000000, "time",
918 "4thresholdlong1");
919 {
920 TRACE_EVENT_IF_LONGER_THAN0(200000000, "time",
921 "4thresholdlong2");
jbates@chromium.org5e2f67d2012-08-16 13:32:49 +0900922 HighResSleepForTraceTest(base::TimeDelta::FromMilliseconds(20));
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900923 }
924 }
925 }
926 }
927 }
928 }
929
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900930 EndTraceAndFlush();
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900931
932#define EXPECT_FIND_BE_(str) \
933 EXPECT_TRUE(FindNamePhase(str, "B")); \
934 EXPECT_TRUE(FindNamePhase(str, "E"))
935#define EXPECT_NOT_FIND_BE_(str) \
936 EXPECT_FALSE(FindNamePhase(str, "B")); \
937 EXPECT_FALSE(FindNamePhase(str, "E"))
938
939 EXPECT_FIND_BE_("threshold 100");
940 EXPECT_FIND_BE_("threshold 1000");
941 EXPECT_FIND_BE_("threshold 10000");
942 EXPECT_NOT_FIND_BE_("threshold long1");
943 EXPECT_NOT_FIND_BE_("threshold long2");
944
945 EXPECT_NOT_FIND_BE_("2threshold10000");
946 EXPECT_FIND_BE_("nonthreshold1");
947
948 EXPECT_FIND_BE_("nonthreshold3");
949 EXPECT_FIND_BE_("3threshold100");
950 EXPECT_FIND_BE_("3threshold1000");
951 EXPECT_FIND_BE_("3threshold10000");
952 EXPECT_NOT_FIND_BE_("3thresholdlong1");
953 EXPECT_NOT_FIND_BE_("3thresholdlong2");
954
955 EXPECT_FIND_BE_("nonthreshold4");
956 EXPECT_FIND_BE_("4threshold100");
957 EXPECT_FIND_BE_("4threshold1000");
958 EXPECT_FIND_BE_("4threshold10000");
959 EXPECT_NOT_FIND_BE_("4thresholdlong1");
960 EXPECT_NOT_FIND_BE_("4thresholdlong2");
961}
962
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900963// Test EVENT_WATCH_NOTIFICATION
964TEST_F(TraceEventTestFixture, EventWatchNotification) {
965 ManualTestSetUp();
966
967 // Basic one occurrence.
968 BeginTrace();
969 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
970 TRACE_EVENT_INSTANT0("cat", "event");
971 EndTraceAndFlush();
972 EXPECT_EQ(event_watch_notification_, 1);
973
974 // Basic one occurrence before Set.
975 BeginTrace();
976 TRACE_EVENT_INSTANT0("cat", "event");
977 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
978 EndTraceAndFlush();
979 EXPECT_EQ(event_watch_notification_, 1);
980
981 // Auto-reset after end trace.
982 BeginTrace();
983 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
984 EndTraceAndFlush();
985 BeginTrace();
986 TRACE_EVENT_INSTANT0("cat", "event");
987 EndTraceAndFlush();
988 EXPECT_EQ(event_watch_notification_, 0);
989
990 // Multiple occurrence.
991 BeginTrace();
992 int num_occurrences = 5;
993 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
994 for (int i = 0; i < num_occurrences; ++i)
995 TRACE_EVENT_INSTANT0("cat", "event");
996 EndTraceAndFlush();
997 EXPECT_EQ(event_watch_notification_, num_occurrences);
998
999 // Wrong category.
1000 BeginTrace();
1001 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
1002 TRACE_EVENT_INSTANT0("wrong_cat", "event");
1003 EndTraceAndFlush();
1004 EXPECT_EQ(event_watch_notification_, 0);
1005
1006 // Wrong name.
1007 BeginTrace();
1008 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
1009 TRACE_EVENT_INSTANT0("cat", "wrong_event");
1010 EndTraceAndFlush();
1011 EXPECT_EQ(event_watch_notification_, 0);
1012
1013 // Canceled.
1014 BeginTrace();
1015 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
1016 TraceLog::GetInstance()->CancelWatchEvent();
1017 TRACE_EVENT_INSTANT0("cat", "event");
1018 EndTraceAndFlush();
1019 EXPECT_EQ(event_watch_notification_, 0);
1020}
1021
jbates@chromium.org88295f92012-03-01 12:04:59 +09001022// Test ASYNC_BEGIN/END events
1023TEST_F(TraceEventTestFixture, AsyncBeginEndEvents) {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001024 ManualTestSetUp();
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001025 BeginTrace();
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001026
1027 unsigned long long id = 0xfeedbeeffeedbeefull;
jbates@chromium.org88295f92012-03-01 12:04:59 +09001028 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name1", id);
simonjam@chromium.org87d003c2012-03-28 09:14:11 +09001029 TRACE_EVENT_ASYNC_BEGIN_STEP0( "cat", "name1", id, "step1");
jbates@chromium.org88295f92012-03-01 12:04:59 +09001030 TRACE_EVENT_ASYNC_END0("cat", "name1", id);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001031 TRACE_EVENT_BEGIN0( "cat", "name2");
jbates@chromium.org88295f92012-03-01 12:04:59 +09001032 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name3", 0);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001033
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001034 EndTraceAndFlush();
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001035
1036 EXPECT_TRUE(FindNamePhase("name1", "S"));
jbates@chromium.org88295f92012-03-01 12:04:59 +09001037 EXPECT_TRUE(FindNamePhase("name1", "T"));
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001038 EXPECT_TRUE(FindNamePhase("name1", "F"));
1039
1040 std::string id_str;
1041 StringAppendF(&id_str, "%llx", id);
1042
1043 EXPECT_TRUE(FindNamePhaseKeyValue("name1", "S", "id", id_str.c_str()));
jbates@chromium.org88295f92012-03-01 12:04:59 +09001044 EXPECT_TRUE(FindNamePhaseKeyValue("name1", "T", "id", id_str.c_str()));
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001045 EXPECT_TRUE(FindNamePhaseKeyValue("name1", "F", "id", id_str.c_str()));
1046 EXPECT_TRUE(FindNamePhaseKeyValue("name3", "S", "id", "0"));
1047
1048 // BEGIN events should not have id
1049 EXPECT_FALSE(FindNamePhaseKeyValue("name2", "B", "id", "0"));
1050}
1051
jbates@chromium.org88295f92012-03-01 12:04:59 +09001052// Test ASYNC_BEGIN/END events
1053TEST_F(TraceEventTestFixture, AsyncBeginEndPointerMangling) {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001054 ManualTestSetUp();
1055
1056 void* ptr = this;
1057
1058 TraceLog::GetInstance()->SetProcessID(100);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001059 BeginTrace();
jbates@chromium.org88295f92012-03-01 12:04:59 +09001060 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name1", ptr);
1061 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name2", ptr);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001062 EndTraceAndFlush();
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001063
1064 TraceLog::GetInstance()->SetProcessID(200);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001065 BeginTrace();
jbates@chromium.org88295f92012-03-01 12:04:59 +09001066 TRACE_EVENT_ASYNC_END0( "cat", "name1", ptr);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001067 EndTraceAndFlush();
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001068
jbates@chromium.org88295f92012-03-01 12:04:59 +09001069 DictionaryValue* async_begin = FindNamePhase("name1", "S");
1070 DictionaryValue* async_begin2 = FindNamePhase("name2", "S");
1071 DictionaryValue* async_end = FindNamePhase("name1", "F");
1072 EXPECT_TRUE(async_begin);
1073 EXPECT_TRUE(async_begin2);
1074 EXPECT_TRUE(async_end);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001075
1076 Value* value = NULL;
jbates@chromium.org88295f92012-03-01 12:04:59 +09001077 std::string async_begin_id_str;
1078 std::string async_begin2_id_str;
1079 std::string async_end_id_str;
1080 ASSERT_TRUE(async_begin->Get("id", &value));
1081 ASSERT_TRUE(value->GetAsString(&async_begin_id_str));
1082 ASSERT_TRUE(async_begin2->Get("id", &value));
1083 ASSERT_TRUE(value->GetAsString(&async_begin2_id_str));
1084 ASSERT_TRUE(async_end->Get("id", &value));
1085 ASSERT_TRUE(value->GetAsString(&async_end_id_str));
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001086
jbates@chromium.org88295f92012-03-01 12:04:59 +09001087 EXPECT_STREQ(async_begin_id_str.c_str(), async_begin2_id_str.c_str());
1088 EXPECT_STRNE(async_begin_id_str.c_str(), async_end_id_str.c_str());
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001089}
1090
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001091// Test that static strings are not copied.
1092TEST_F(TraceEventTestFixture, StaticStringVsString) {
1093 ManualTestSetUp();
1094 TraceLog* tracer = TraceLog::GetInstance();
1095 // Make sure old events are flushed:
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001096 EndTraceAndFlush();
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001097 EXPECT_EQ(0u, tracer->GetEventsSize());
1098
1099 {
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001100 BeginTrace();
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001101 // Test that string arguments are copied.
1102 TRACE_EVENT2("cat", "name1",
1103 "arg1", std::string("argval"), "arg2", std::string("argval"));
1104 // Test that static TRACE_STR_COPY string arguments are copied.
1105 TRACE_EVENT2("cat", "name2",
1106 "arg1", TRACE_STR_COPY("argval"),
1107 "arg2", TRACE_STR_COPY("argval"));
1108 size_t num_events = tracer->GetEventsSize();
1109 EXPECT_GT(num_events, 1u);
1110 const TraceEvent& event1 = tracer->GetEventAt(num_events - 2);
1111 const TraceEvent& event2 = tracer->GetEventAt(num_events - 1);
1112 EXPECT_STREQ("name1", event1.name());
1113 EXPECT_STREQ("name2", event2.name());
1114 EXPECT_TRUE(event1.parameter_copy_storage() != NULL);
1115 EXPECT_TRUE(event2.parameter_copy_storage() != NULL);
1116 EXPECT_GT(event1.parameter_copy_storage()->size(), 0u);
1117 EXPECT_GT(event2.parameter_copy_storage()->size(), 0u);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001118 EndTraceAndFlush();
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001119 }
1120
1121 {
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001122 BeginTrace();
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001123 // Test that static literal string arguments are not copied.
1124 TRACE_EVENT2("cat", "name1",
1125 "arg1", "argval", "arg2", "argval");
1126 // Test that static TRACE_STR_COPY NULL string arguments are not copied.
1127 const char* str1 = NULL;
1128 const char* str2 = NULL;
1129 TRACE_EVENT2("cat", "name2",
1130 "arg1", TRACE_STR_COPY(str1),
1131 "arg2", TRACE_STR_COPY(str2));
1132 size_t num_events = tracer->GetEventsSize();
1133 EXPECT_GT(num_events, 1u);
1134 const TraceEvent& event1 = tracer->GetEventAt(num_events - 2);
1135 const TraceEvent& event2 = tracer->GetEventAt(num_events - 1);
1136 EXPECT_STREQ("name1", event1.name());
1137 EXPECT_STREQ("name2", event2.name());
1138 EXPECT_TRUE(event1.parameter_copy_storage() == NULL);
1139 EXPECT_TRUE(event2.parameter_copy_storage() == NULL);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001140 EndTraceAndFlush();
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001141 }
1142}
1143
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001144// Test that data sent from other threads is gathered
1145TEST_F(TraceEventTestFixture, DataCapturedOnThread) {
1146 ManualTestSetUp();
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001147 BeginTrace();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001148
1149 Thread thread("1");
1150 WaitableEvent task_complete_event(false, false);
1151 thread.Start();
1152
1153 thread.message_loop()->PostTask(
jbates@chromium.org0b837e42011-10-06 01:58:20 +09001154 FROM_HERE, base::Bind(&TraceWithAllMacroVariants, &task_complete_event));
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001155 task_complete_event.Wait();
jbates@chromium.orgb84db522011-10-04 02:51:25 +09001156 thread.Stop();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001157
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001158 EndTraceAndFlush();
jbates@chromium.org6a092d72011-10-25 01:34:08 +09001159 ValidateAllTraceMacrosCreatedData(trace_parsed_);
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001160}
1161
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001162// Test that data sent from multiple threads is gathered
1163TEST_F(TraceEventTestFixture, DataCapturedManyThreads) {
1164 ManualTestSetUp();
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001165 BeginTrace();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001166
1167 const int num_threads = 4;
1168 const int num_events = 4000;
1169 Thread* threads[num_threads];
1170 WaitableEvent* task_complete_events[num_threads];
1171 for (int i = 0; i < num_threads; i++) {
1172 threads[i] = new Thread(StringPrintf("Thread %d", i).c_str());
1173 task_complete_events[i] = new WaitableEvent(false, false);
1174 threads[i]->Start();
1175 threads[i]->message_loop()->PostTask(
jbates@chromium.org0b837e42011-10-06 01:58:20 +09001176 FROM_HERE, base::Bind(&TraceManyInstantEvents,
1177 i, num_events, task_complete_events[i]));
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001178 }
1179
1180 for (int i = 0; i < num_threads; i++) {
1181 task_complete_events[i]->Wait();
1182 }
1183
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001184 for (int i = 0; i < num_threads; i++) {
1185 threads[i]->Stop();
1186 delete threads[i];
1187 delete task_complete_events[i];
1188 }
1189
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001190 EndTraceAndFlush();
jbates@chromium.orgb84db522011-10-04 02:51:25 +09001191
jbates@chromium.org6a092d72011-10-25 01:34:08 +09001192 ValidateInstantEventPresentOnEveryThread(trace_parsed_,
nduca@chromium.org6d048772011-08-10 00:16:25 +09001193 num_threads, num_events);
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001194}
1195
nduca@chromium.org6d048772011-08-10 00:16:25 +09001196// Test that thread and process names show up in the trace
1197TEST_F(TraceEventTestFixture, ThreadNames) {
1198 ManualTestSetUp();
1199
1200 // Create threads before we enable tracing to make sure
1201 // that tracelog still captures them.
1202 const int num_threads = 4;
1203 const int num_events = 10;
1204 Thread* threads[num_threads];
1205 PlatformThreadId thread_ids[num_threads];
1206 for (int i = 0; i < num_threads; i++)
1207 threads[i] = new Thread(StringPrintf("Thread %d", i).c_str());
1208
1209 // Enable tracing.
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001210 BeginTrace();
nduca@chromium.org6d048772011-08-10 00:16:25 +09001211
1212 // Now run some trace code on these threads.
1213 WaitableEvent* task_complete_events[num_threads];
1214 for (int i = 0; i < num_threads; i++) {
1215 task_complete_events[i] = new WaitableEvent(false, false);
1216 threads[i]->Start();
1217 thread_ids[i] = threads[i]->thread_id();
1218 threads[i]->message_loop()->PostTask(
jbates@chromium.org0b837e42011-10-06 01:58:20 +09001219 FROM_HERE, base::Bind(&TraceManyInstantEvents,
1220 i, num_events, task_complete_events[i]));
nduca@chromium.org6d048772011-08-10 00:16:25 +09001221 }
1222 for (int i = 0; i < num_threads; i++) {
1223 task_complete_events[i]->Wait();
1224 }
1225
1226 // Shut things down.
nduca@chromium.org6d048772011-08-10 00:16:25 +09001227 for (int i = 0; i < num_threads; i++) {
1228 threads[i]->Stop();
1229 delete threads[i];
1230 delete task_complete_events[i];
1231 }
1232
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001233 EndTraceAndFlush();
jbates@chromium.orgb84db522011-10-04 02:51:25 +09001234
nduca@chromium.org6d048772011-08-10 00:16:25 +09001235 std::string tmp;
1236 int tmp_int;
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001237 const DictionaryValue* item;
nduca@chromium.org6d048772011-08-10 00:16:25 +09001238
1239 // Make sure we get thread name metadata.
1240 // Note, the test suite may have created a ton of threads.
1241 // So, we'll have thread names for threads we didn't create.
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001242 std::vector<const DictionaryValue*> items =
nduca@chromium.org6d048772011-08-10 00:16:25 +09001243 FindTraceEntries(trace_parsed_, "thread_name");
1244 for (int i = 0; i < static_cast<int>(items.size()); i++) {
1245 item = items[i];
joth@chromium.org088ae012011-11-11 01:26:23 +09001246 ASSERT_TRUE(item);
nduca@chromium.org6d048772011-08-10 00:16:25 +09001247 EXPECT_TRUE(item->GetInteger("tid", &tmp_int));
1248
1249 // See if this thread name is one of the threads we just created
1250 for (int j = 0; j < num_threads; j++) {
1251 if(static_cast<int>(thread_ids[j]) != tmp_int)
1252 continue;
1253
jbates@chromium.org62a16662012-02-04 08:18:06 +09001254 std::string expected_name = StringPrintf("Thread %d", j);
nduca@chromium.org6d048772011-08-10 00:16:25 +09001255 EXPECT_TRUE(item->GetString("ph", &tmp) && tmp == "M");
1256 EXPECT_TRUE(item->GetInteger("pid", &tmp_int) &&
1257 tmp_int == static_cast<int>(base::GetCurrentProcId()));
jbates@chromium.org62a16662012-02-04 08:18:06 +09001258 // If the thread name changes or the tid gets reused, the name will be
1259 // a comma-separated list of thread names, so look for a substring.
nduca@chromium.org6d048772011-08-10 00:16:25 +09001260 EXPECT_TRUE(item->GetString("args.name", &tmp) &&
jbates@chromium.org62a16662012-02-04 08:18:06 +09001261 tmp.find(expected_name) != std::string::npos);
nduca@chromium.org6d048772011-08-10 00:16:25 +09001262 }
1263 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001264}
1265
joth@chromium.org088ae012011-11-11 01:26:23 +09001266TEST_F(TraceEventTestFixture, ThreadNameChanges) {
1267 ManualTestSetUp();
1268
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001269 BeginTrace();
joth@chromium.org088ae012011-11-11 01:26:23 +09001270
1271 PlatformThread::SetName("");
1272 TRACE_EVENT_INSTANT0("drink", "water");
1273
1274 PlatformThread::SetName("cafe");
1275 TRACE_EVENT_INSTANT0("drink", "coffee");
1276
1277 PlatformThread::SetName("shop");
1278 // No event here, so won't appear in combined name.
1279
1280 PlatformThread::SetName("pub");
1281 TRACE_EVENT_INSTANT0("drink", "beer");
1282 TRACE_EVENT_INSTANT0("drink", "wine");
1283
1284 PlatformThread::SetName(" bar");
1285 TRACE_EVENT_INSTANT0("drink", "whisky");
1286
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001287 EndTraceAndFlush();
joth@chromium.org088ae012011-11-11 01:26:23 +09001288
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001289 std::vector<const DictionaryValue*> items =
joth@chromium.org088ae012011-11-11 01:26:23 +09001290 FindTraceEntries(trace_parsed_, "thread_name");
1291 EXPECT_EQ(1u, items.size());
1292 ASSERT_GT(items.size(), 0u);
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001293 const DictionaryValue* item = items[0];
joth@chromium.org088ae012011-11-11 01:26:23 +09001294 ASSERT_TRUE(item);
1295 int tid;
1296 EXPECT_TRUE(item->GetInteger("tid", &tid));
1297 EXPECT_EQ(PlatformThread::CurrentId(), static_cast<PlatformThreadId>(tid));
1298
1299 std::string expected_name = "cafe,pub, bar";
1300 std::string tmp;
1301 EXPECT_TRUE(item->GetString("args.name", &tmp));
1302 EXPECT_EQ(expected_name, tmp);
1303}
nduca@chromium.org6d048772011-08-10 00:16:25 +09001304
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001305// Test trace calls made after tracing singleton shut down.
1306//
1307// The singleton is destroyed by our base::AtExitManager, but there can be
1308// code still executing as the C++ static objects are destroyed. This test
1309// forces the singleton to destroy early, and intentinally makes trace calls
1310// afterwards.
1311TEST_F(TraceEventTestFixture, AtExit) {
1312 // Repeat this test a few times. Besides just showing robustness, it also
1313 // allows us to test that events at shutdown do not appear with valid events
1314 // recorded after the system is started again.
1315 for (int i = 0; i < 4; i++) {
1316 // Scope to contain the then destroy the TraceLog singleton.
1317 {
1318 base::ShadowingAtExitManager exit_manager_will_destroy_singletons;
1319
1320 // Setup TraceLog singleton inside this test's exit manager scope
1321 // so that it will be destroyed when this scope closes.
1322 ManualTestSetUp();
1323
1324 TRACE_EVENT_INSTANT0("all", "not recorded; system not enabled");
1325
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001326 BeginTrace();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001327
1328 TRACE_EVENT_INSTANT0("all", "is recorded 1; system has been enabled");
1329 // Trace calls that will cache pointers to categories; they're valid here
1330 TraceCallsWithCachedCategoryPointersPointers(
1331 "is recorded 2; system has been enabled");
1332
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001333 EndTraceAndFlush();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001334 } // scope to destroy singleton
1335 ASSERT_FALSE(TraceLog::GetInstance());
1336
1337 // Now that singleton is destroyed, check what trace events were recorded
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001338 const DictionaryValue* item = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001339 ListValue& trace_parsed = trace_parsed_;
1340 EXPECT_FIND_("is recorded 1");
1341 EXPECT_FIND_("is recorded 2");
1342 EXPECT_NOT_FIND_("not recorded");
1343
1344 // Make additional trace event calls on the shutdown system. They should
1345 // all pass cleanly, but the data not be recorded. We'll verify that next
1346 // time around the loop (the only way to flush the trace buffers).
1347 TRACE_EVENT_BEGIN_ETW("not recorded; system shutdown", 0, NULL);
1348 TRACE_EVENT_END_ETW("not recorded; system shutdown", 0, NULL);
1349 TRACE_EVENT_INSTANT_ETW("not recorded; system shutdown", 0, NULL);
1350 TRACE_EVENT0("all", "not recorded; system shutdown");
1351 TRACE_EVENT_INSTANT0("all", "not recorded; system shutdown");
1352 TRACE_EVENT_BEGIN0("all", "not recorded; system shutdown");
1353 TRACE_EVENT_END0("all", "not recorded; system shutdown");
1354
1355 TRACE_EVENT0("new category 0!", "not recorded; system shutdown");
1356 TRACE_EVENT_INSTANT0("new category 1!", "not recorded; system shutdown");
1357 TRACE_EVENT_BEGIN0("new category 2!", "not recorded; system shutdown");
1358 TRACE_EVENT_END0("new category 3!", "not recorded; system shutdown");
1359
1360 // Cached categories should be safe to check, and still disable traces
1361 TraceCallsWithCachedCategoryPointersPointers(
1362 "not recorded; system shutdown");
1363 }
1364}
1365
joth@chromium.org113de992011-07-21 21:28:59 +09001366TEST_F(TraceEventTestFixture, NormallyNoDeepCopy) {
1367 // Test that the TRACE_EVENT macros do not deep-copy their string. If they
1368 // do so it may indicate a performance regression, but more-over it would
1369 // make the DEEP_COPY overloads redundant.
1370 ManualTestSetUp();
1371
1372 std::string name_string("event name");
1373
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001374 BeginTrace();
joth@chromium.org113de992011-07-21 21:28:59 +09001375 TRACE_EVENT_INSTANT0("category", name_string.c_str());
1376
1377 // Modify the string in place (a wholesale reassignment may leave the old
1378 // string intact on the heap).
1379 name_string[0] = '@';
1380
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001381 EndTraceAndFlush();
joth@chromium.org113de992011-07-21 21:28:59 +09001382
1383 EXPECT_FALSE(FindTraceEntry(trace_parsed_, "event name"));
1384 EXPECT_TRUE(FindTraceEntry(trace_parsed_, name_string.c_str()));
1385}
1386
1387TEST_F(TraceEventTestFixture, DeepCopy) {
1388 ManualTestSetUp();
1389
1390 static const char kOriginalName1[] = "name1";
1391 static const char kOriginalName2[] = "name2";
1392 static const char kOriginalName3[] = "name3";
1393 std::string name1(kOriginalName1);
1394 std::string name2(kOriginalName2);
1395 std::string name3(kOriginalName3);
1396 std::string arg1("arg1");
1397 std::string arg2("arg2");
1398 std::string val1("val1");
1399 std::string val2("val2");
1400
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001401 BeginTrace();
joth@chromium.org113de992011-07-21 21:28:59 +09001402 TRACE_EVENT_COPY_INSTANT0("category", name1.c_str());
1403 TRACE_EVENT_COPY_BEGIN1("category", name2.c_str(),
1404 arg1.c_str(), 5);
1405 TRACE_EVENT_COPY_END2("category", name3.c_str(),
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001406 arg1.c_str(), val1,
1407 arg2.c_str(), val2);
joth@chromium.org113de992011-07-21 21:28:59 +09001408
1409 // As per NormallyNoDeepCopy, modify the strings in place.
1410 name1[0] = name2[0] = name3[0] = arg1[0] = arg2[0] = val1[0] = val2[0] = '@';
1411
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001412 EndTraceAndFlush();
joth@chromium.org113de992011-07-21 21:28:59 +09001413
1414 EXPECT_FALSE(FindTraceEntry(trace_parsed_, name1.c_str()));
1415 EXPECT_FALSE(FindTraceEntry(trace_parsed_, name2.c_str()));
1416 EXPECT_FALSE(FindTraceEntry(trace_parsed_, name3.c_str()));
1417
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001418 const DictionaryValue* entry1 = FindTraceEntry(trace_parsed_, kOriginalName1);
1419 const DictionaryValue* entry2 = FindTraceEntry(trace_parsed_, kOriginalName2);
1420 const DictionaryValue* entry3 = FindTraceEntry(trace_parsed_, kOriginalName3);
joth@chromium.org113de992011-07-21 21:28:59 +09001421 ASSERT_TRUE(entry1);
1422 ASSERT_TRUE(entry2);
1423 ASSERT_TRUE(entry3);
1424
1425 int i;
1426 EXPECT_FALSE(entry2->GetInteger("args.@rg1", &i));
1427 EXPECT_TRUE(entry2->GetInteger("args.arg1", &i));
1428 EXPECT_EQ(5, i);
1429
1430 std::string s;
1431 EXPECT_TRUE(entry3->GetString("args.arg1", &s));
1432 EXPECT_EQ("val1", s);
1433 EXPECT_TRUE(entry3->GetString("args.arg2", &s));
1434 EXPECT_EQ("val2", s);
1435}
1436
jbates@chromium.org6a092d72011-10-25 01:34:08 +09001437// Test that TraceResultBuffer outputs the correct result whether it is added
1438// in chunks or added all at once.
1439TEST_F(TraceEventTestFixture, TraceResultBuffer) {
1440 ManualTestSetUp();
1441
1442 Clear();
1443
1444 trace_buffer_.Start();
1445 trace_buffer_.AddFragment("bla1");
1446 trace_buffer_.AddFragment("bla2");
1447 trace_buffer_.AddFragment("bla3,bla4");
1448 trace_buffer_.Finish();
1449 EXPECT_STREQ(json_output_.json_output.c_str(), "[bla1,bla2,bla3,bla4]");
1450
1451 Clear();
1452
1453 trace_buffer_.Start();
1454 trace_buffer_.AddFragment("bla1,bla2,bla3,bla4");
1455 trace_buffer_.Finish();
1456 EXPECT_STREQ(json_output_.json_output.c_str(), "[bla1,bla2,bla3,bla4]");
1457}
1458
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001459} // namespace debug
1460} // namespace base