blob: f806cf1928e870dd1ba637f3cb14ba05e13cb160 [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.org8bb0ee62011-12-03 02:17:38 +090049 DictionaryValue* FindMatchingTraceEntry(const JsonKeyValue* key_values);
50 DictionaryValue* FindNamePhase(const char* name, const char* phase);
51 DictionaryValue* FindNamePhaseKeyValue(const char* name,
52 const char* phase,
53 const char* key,
54 const char* value);
jbates@chromium.org11d4c362011-09-13 07:03:41 +090055 bool FindMatchingValue(const char* key,
56 const char* value);
57 bool FindNonMatchingValue(const char* key,
58 const char* value);
59 void Clear() {
jbates@chromium.org11d4c362011-09-13 07:03:41 +090060 trace_parsed_.Clear();
jbates@chromium.org6a092d72011-10-25 01:34:08 +090061 json_output_.json_output.clear();
jbates@chromium.org11d4c362011-09-13 07:03:41 +090062 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +090063
rsleevi@chromium.orgde3a6cf2012-04-06 12:53:02 +090064 virtual void SetUp() OVERRIDE {
joth@chromium.org088ae012011-11-11 01:26:23 +090065 old_thread_name_ = PlatformThread::GetName();
66 }
rsleevi@chromium.orgde3a6cf2012-04-06 12:53:02 +090067 virtual void TearDown() OVERRIDE {
nduca@chromium.org6a7360c2012-02-20 15:35:15 +090068 if (TraceLog::GetInstance())
69 EXPECT_FALSE(TraceLog::GetInstance()->IsEnabled());
joth@chromium.org088ae012011-11-11 01:26:23 +090070 PlatformThread::SetName(old_thread_name_ ? old_thread_name_ : "");
71 }
72
73 const char* old_thread_name_;
scheib@chromium.org603f46e2011-05-10 11:23:58 +090074 ListValue trace_parsed_;
jbates@chromium.org6a092d72011-10-25 01:34:08 +090075 base::debug::TraceResultBuffer trace_buffer_;
76 base::debug::TraceResultBuffer::SimpleOutput json_output_;
scheib@chromium.org603f46e2011-05-10 11:23:58 +090077
78 private:
79 // We want our singleton torn down after each test.
80 ShadowingAtExitManager at_exit_manager_;
jbates@chromium.orgb84db522011-10-04 02:51:25 +090081 Lock lock_;
scheib@chromium.org603f46e2011-05-10 11:23:58 +090082};
83
84void TraceEventTestFixture::ManualTestSetUp() {
jbates@chromium.orgb84db522011-10-04 02:51:25 +090085 TraceLog::DeleteForTesting();
scheib@chromium.org603f46e2011-05-10 11:23:58 +090086 TraceLog::Resurrect();
87 TraceLog* tracelog = TraceLog::GetInstance();
88 ASSERT_TRUE(tracelog);
89 ASSERT_FALSE(tracelog->IsEnabled());
90 tracelog->SetOutputCallback(
jbates@chromium.orgb84db522011-10-04 02:51:25 +090091 base::Bind(&TraceEventTestFixture::OnTraceDataCollected,
92 base::Unretained(this)));
jbates@chromium.org6a092d72011-10-25 01:34:08 +090093 trace_buffer_.SetOutputCallback(json_output_.GetCallback());
scheib@chromium.org603f46e2011-05-10 11:23:58 +090094}
95
96void TraceEventTestFixture::OnTraceDataCollected(
husky@chromium.org3b366292012-02-24 13:17:06 +090097 const scoped_refptr<base::RefCountedString>& events_str) {
jbates@chromium.orgb84db522011-10-04 02:51:25 +090098 AutoLock lock(lock_);
jbates@chromium.org6a092d72011-10-25 01:34:08 +090099 json_output_.json_output.clear();
100 trace_buffer_.Start();
husky@chromium.org3b366292012-02-24 13:17:06 +0900101 trace_buffer_.AddFragment(events_str->data());
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900102 trace_buffer_.Finish();
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900103
104 scoped_ptr<Value> root;
rsesek@chromium.orgc2d2b202012-05-17 00:23:30 +0900105 root.reset(base::JSONReader::Read(json_output_.json_output,
106 JSON_PARSE_RFC | JSON_DETACHABLE_CHILDREN));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900107
jbates@chromium.org59c27602012-01-13 12:12:44 +0900108 if (!root.get()) {
109 LOG(ERROR) << json_output_.json_output;
110 }
111
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900112 ListValue* root_list = NULL;
113 ASSERT_TRUE(root.get());
114 ASSERT_TRUE(root->GetAsList(&root_list));
115
116 // Move items into our aggregate collection
117 while (root_list->GetSize()) {
118 Value* item = NULL;
119 root_list->Remove(0, &item);
120 trace_parsed_.Append(item);
121 }
122}
123
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900124static bool CompareJsonValues(const std::string& lhs,
125 const std::string& rhs,
126 CompareOp op) {
127 switch (op) {
128 case IS_EQUAL:
129 return lhs == rhs;
130 case IS_NOT_EQUAL:
131 return lhs != rhs;
132 default:
133 CHECK(0);
134 }
135 return false;
136}
137
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900138static bool IsKeyValueInDict(const JsonKeyValue* key_value,
139 DictionaryValue* dict) {
140 Value* value = NULL;
141 std::string value_str;
142 if (dict->Get(key_value->key, &value) &&
143 value->GetAsString(&value_str) &&
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900144 CompareJsonValues(value_str, key_value->value, key_value->op))
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900145 return true;
146
147 // Recurse to test arguments
148 DictionaryValue* args_dict = NULL;
149 dict->GetDictionary("args", &args_dict);
150 if (args_dict)
151 return IsKeyValueInDict(key_value, args_dict);
152
153 return false;
154}
155
156static bool IsAllKeyValueInDict(const JsonKeyValue* key_values,
157 DictionaryValue* dict) {
158 // Scan all key_values, they must all be present and equal.
159 while (key_values && key_values->key) {
160 if (!IsKeyValueInDict(key_values, dict))
161 return false;
162 ++key_values;
163 }
164 return true;
165}
166
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900167DictionaryValue* TraceEventTestFixture::FindMatchingTraceEntry(
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900168 const JsonKeyValue* key_values) {
169 // Scan all items
170 size_t trace_parsed_count = trace_parsed_.GetSize();
171 for (size_t i = 0; i < trace_parsed_count; i++) {
172 Value* value = NULL;
173 trace_parsed_.Get(i, &value);
174 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
175 continue;
176 DictionaryValue* dict = static_cast<DictionaryValue*>(value);
177
178 if (IsAllKeyValueInDict(key_values, dict))
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900179 return dict;
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900180 }
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900181 return NULL;
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900182}
183
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900184DictionaryValue* TraceEventTestFixture::FindNamePhase(const char* name,
185 const char* phase) {
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900186 JsonKeyValue key_values[] = {
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900187 {"name", name, IS_EQUAL},
188 {"ph", phase, IS_EQUAL},
189 {0, 0, IS_EQUAL}
190 };
191 return FindMatchingTraceEntry(key_values);
192}
193
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900194DictionaryValue* TraceEventTestFixture::FindNamePhaseKeyValue(
195 const char* name,
196 const char* phase,
197 const char* key,
198 const char* value) {
199 JsonKeyValue key_values[] = {
200 {"name", name, IS_EQUAL},
201 {"ph", phase, IS_EQUAL},
202 {key, value, IS_EQUAL},
203 {0, 0, IS_EQUAL}
204 };
205 return FindMatchingTraceEntry(key_values);
206}
207
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900208bool TraceEventTestFixture::FindMatchingValue(const char* key,
209 const char* value) {
210 JsonKeyValue key_values[] = {
211 {key, value, IS_EQUAL},
212 {0, 0, IS_EQUAL}
213 };
214 return FindMatchingTraceEntry(key_values);
215}
216
217bool TraceEventTestFixture::FindNonMatchingValue(const char* key,
218 const char* value) {
219 JsonKeyValue key_values[] = {
220 {key, value, IS_NOT_EQUAL},
221 {0, 0, IS_EQUAL}
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900222 };
223 return FindMatchingTraceEntry(key_values);
224}
225
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900226bool IsStringInDict(const char* string_to_match, const DictionaryValue* dict) {
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900227 for (DictionaryValue::key_iterator ikey = dict->begin_keys();
228 ikey != dict->end_keys(); ++ikey) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900229 const Value* child = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900230 if (!dict->GetWithoutPathExpansion(*ikey, &child))
231 continue;
232
233 if ((*ikey).find(string_to_match) != std::string::npos)
234 return true;
235
236 std::string value_str;
237 child->GetAsString(&value_str);
238 if (value_str.find(string_to_match) != std::string::npos)
239 return true;
240 }
241
242 // Recurse to test arguments
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900243 const DictionaryValue* args_dict = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900244 dict->GetDictionary("args", &args_dict);
245 if (args_dict)
246 return IsStringInDict(string_to_match, args_dict);
247
248 return false;
249}
250
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900251const DictionaryValue* FindTraceEntry(
252 const ListValue& trace_parsed,
253 const char* string_to_match,
254 const DictionaryValue* match_after_this_item = NULL) {
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900255 // Scan all items
256 size_t trace_parsed_count = trace_parsed.GetSize();
257 for (size_t i = 0; i < trace_parsed_count; i++) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900258 const Value* value = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900259 trace_parsed.Get(i, &value);
260 if (match_after_this_item) {
261 if (value == match_after_this_item)
262 match_after_this_item = NULL;
263 continue;
264 }
265 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
266 continue;
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900267 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900268
269 if (IsStringInDict(string_to_match, dict))
270 return dict;
271 }
272 return NULL;
273}
274
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900275std::vector<const DictionaryValue*> FindTraceEntries(
nduca@chromium.org6d048772011-08-10 00:16:25 +0900276 const ListValue& trace_parsed,
277 const char* string_to_match) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900278 std::vector<const DictionaryValue*> hits;
nduca@chromium.org6d048772011-08-10 00:16:25 +0900279 size_t trace_parsed_count = trace_parsed.GetSize();
280 for (size_t i = 0; i < trace_parsed_count; i++) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900281 const Value* value = NULL;
nduca@chromium.org6d048772011-08-10 00:16:25 +0900282 trace_parsed.Get(i, &value);
283 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
284 continue;
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900285 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
nduca@chromium.org6d048772011-08-10 00:16:25 +0900286
287 if (IsStringInDict(string_to_match, dict))
288 hits.push_back(dict);
289 }
290 return hits;
291}
292
293void TraceWithAllMacroVariants(WaitableEvent* task_complete_event) {
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900294 {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900295 TRACE_EVENT_BEGIN_ETW("TRACE_EVENT_BEGIN_ETW call", 0x1122, "extrastring1");
296 TRACE_EVENT_END_ETW("TRACE_EVENT_END_ETW call", 0x3344, "extrastring2");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900297 TRACE_EVENT_INSTANT_ETW("TRACE_EVENT_INSTANT_ETW call",
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900298 0x5566, "extrastring3");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900299
300 TRACE_EVENT0("all", "TRACE_EVENT0 call");
301 TRACE_EVENT1("all", "TRACE_EVENT1 call", "name1", "value1");
302 TRACE_EVENT2("all", "TRACE_EVENT2 call",
jbates@chromium.org788d5a12011-09-07 09:43:11 +0900303 "name1", "\"value1\"",
304 "name2", "value\\2");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900305
306 TRACE_EVENT_INSTANT0("all", "TRACE_EVENT_INSTANT0 call");
307 TRACE_EVENT_INSTANT1("all", "TRACE_EVENT_INSTANT1 call", "name1", "value1");
308 TRACE_EVENT_INSTANT2("all", "TRACE_EVENT_INSTANT2 call",
309 "name1", "value1",
310 "name2", "value2");
311
312 TRACE_EVENT_BEGIN0("all", "TRACE_EVENT_BEGIN0 call");
313 TRACE_EVENT_BEGIN1("all", "TRACE_EVENT_BEGIN1 call", "name1", "value1");
314 TRACE_EVENT_BEGIN2("all", "TRACE_EVENT_BEGIN2 call",
315 "name1", "value1",
316 "name2", "value2");
317
318 TRACE_EVENT_END0("all", "TRACE_EVENT_END0 call");
319 TRACE_EVENT_END1("all", "TRACE_EVENT_END1 call", "name1", "value1");
320 TRACE_EVENT_END2("all", "TRACE_EVENT_END2 call",
321 "name1", "value1",
322 "name2", "value2");
nduca@chromium.org62210b02011-11-18 18:36:36 +0900323
jbates@chromium.org59c27602012-01-13 12:12:44 +0900324 TRACE_EVENT_IF_LONGER_THAN0(0, "all", "TRACE_EVENT_IF_LONGER_THAN0 call");
325 TRACE_EVENT_IF_LONGER_THAN1(0, "all", "TRACE_EVENT_IF_LONGER_THAN1 call",
326 "name1", "value1");
327 TRACE_EVENT_IF_LONGER_THAN2(0, "all", "TRACE_EVENT_IF_LONGER_THAN2 call",
328 "name1", "value1",
329 "name2", "value2");
330
jbates@chromium.org88295f92012-03-01 12:04:59 +0900331 TRACE_EVENT_ASYNC_BEGIN0("all", "TRACE_EVENT_ASYNC_BEGIN0 call", 5);
332 TRACE_EVENT_ASYNC_BEGIN1("all", "TRACE_EVENT_ASYNC_BEGIN1 call", 5,
333 "name1", "value1");
334 TRACE_EVENT_ASYNC_BEGIN2("all", "TRACE_EVENT_ASYNC_BEGIN2 call", 5,
335 "name1", "value1",
336 "name2", "value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900337
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900338 TRACE_EVENT_ASYNC_BEGIN_STEP0("all", "TRACE_EVENT_ASYNC_BEGIN_STEP0 call",
339 5, "step1");
340 TRACE_EVENT_ASYNC_BEGIN_STEP1("all", "TRACE_EVENT_ASYNC_BEGIN_STEP1 call",
341 5, "step2", "name1", "value1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900342
343 TRACE_EVENT_ASYNC_END0("all", "TRACE_EVENT_ASYNC_END0 call", 5);
344 TRACE_EVENT_ASYNC_END1("all", "TRACE_EVENT_ASYNC_END1 call", 5,
345 "name1", "value1");
346 TRACE_EVENT_ASYNC_END2("all", "TRACE_EVENT_ASYNC_END2 call", 5,
347 "name1", "value1",
348 "name2", "value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900349
350 TRACE_EVENT_BEGIN_ETW("TRACE_EVENT_BEGIN_ETW0 call", 5, NULL);
351 TRACE_EVENT_BEGIN_ETW("TRACE_EVENT_BEGIN_ETW1 call", 5, "value");
352 TRACE_EVENT_END_ETW("TRACE_EVENT_END_ETW0 call", 5, NULL);
353 TRACE_EVENT_END_ETW("TRACE_EVENT_END_ETW1 call", 5, "value");
354 TRACE_EVENT_INSTANT_ETW("TRACE_EVENT_INSTANT_ETW0 call", 5, NULL);
355 TRACE_EVENT_INSTANT_ETW("TRACE_EVENT_INSTANT_ETW1 call", 5, "value");
356
nduca@chromium.org62210b02011-11-18 18:36:36 +0900357 TRACE_COUNTER1("all", "TRACE_COUNTER1 call", 31415);
358 TRACE_COUNTER2("all", "TRACE_COUNTER2 call",
359 "a", 30000,
360 "b", 1415);
piman@chromium.org902b2952011-12-16 10:19:06 +0900361
362 TRACE_COUNTER_ID1("all", "TRACE_COUNTER_ID1 call", 0x319009, 31415);
363 TRACE_COUNTER_ID2("all", "TRACE_COUNTER_ID2 call", 0x319009,
364 "a", 30000, "b", 1415);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900365 } // Scope close causes TRACE_EVENT0 etc to send their END events.
366
367 if (task_complete_event)
368 task_complete_event->Signal();
369}
370
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900371void ValidateAllTraceMacrosCreatedData(const ListValue& trace_parsed) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900372 const DictionaryValue* item = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900373
374#define EXPECT_FIND_(string) \
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900375 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, string)));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900376#define EXPECT_NOT_FIND_(string) \
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900377 EXPECT_FALSE((item = FindTraceEntry(trace_parsed, string)));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900378#define EXPECT_SUB_FIND_(string) \
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900379 if (item) EXPECT_TRUE((IsStringInDict(string, item)));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900380
381 EXPECT_FIND_("ETW Trace Event");
382 EXPECT_FIND_("all");
383 EXPECT_FIND_("TRACE_EVENT_BEGIN_ETW call");
384 {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900385 std::string str_val;
386 EXPECT_TRUE(item && item->GetString("args.id", &str_val));
387 EXPECT_STREQ("1122", str_val.c_str());
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900388 }
389 EXPECT_SUB_FIND_("extrastring1");
390 EXPECT_FIND_("TRACE_EVENT_END_ETW call");
391 EXPECT_FIND_("TRACE_EVENT_INSTANT_ETW call");
392 EXPECT_FIND_("TRACE_EVENT0 call");
393 {
394 std::string ph_begin;
395 std::string ph_end;
396 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, "TRACE_EVENT0 call")));
397 EXPECT_TRUE((item && item->GetString("ph", &ph_begin)));
398 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, "TRACE_EVENT0 call",
399 item)));
400 EXPECT_TRUE((item && item->GetString("ph", &ph_end)));
401 EXPECT_EQ("B", ph_begin);
402 EXPECT_EQ("E", ph_end);
403 }
404 EXPECT_FIND_("TRACE_EVENT1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900405 EXPECT_SUB_FIND_("name1");
406 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900407 EXPECT_FIND_("TRACE_EVENT2 call");
408 EXPECT_SUB_FIND_("name1");
jbates@chromium.org788d5a12011-09-07 09:43:11 +0900409 EXPECT_SUB_FIND_("\"value1\"");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900410 EXPECT_SUB_FIND_("name2");
jbates@chromium.org788d5a12011-09-07 09:43:11 +0900411 EXPECT_SUB_FIND_("value\\2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900412
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900413 EXPECT_FIND_("TRACE_EVENT_INSTANT0 call");
414 EXPECT_FIND_("TRACE_EVENT_INSTANT1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900415 EXPECT_SUB_FIND_("name1");
416 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900417 EXPECT_FIND_("TRACE_EVENT_INSTANT2 call");
418 EXPECT_SUB_FIND_("name1");
419 EXPECT_SUB_FIND_("value1");
420 EXPECT_SUB_FIND_("name2");
421 EXPECT_SUB_FIND_("value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900422
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900423 EXPECT_FIND_("TRACE_EVENT_BEGIN0 call");
424 EXPECT_FIND_("TRACE_EVENT_BEGIN1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900425 EXPECT_SUB_FIND_("name1");
426 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900427 EXPECT_FIND_("TRACE_EVENT_BEGIN2 call");
428 EXPECT_SUB_FIND_("name1");
429 EXPECT_SUB_FIND_("value1");
430 EXPECT_SUB_FIND_("name2");
431 EXPECT_SUB_FIND_("value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900432
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900433 EXPECT_FIND_("TRACE_EVENT_END0 call");
434 EXPECT_FIND_("TRACE_EVENT_END1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900435 EXPECT_SUB_FIND_("name1");
436 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900437 EXPECT_FIND_("TRACE_EVENT_END2 call");
438 EXPECT_SUB_FIND_("name1");
439 EXPECT_SUB_FIND_("value1");
440 EXPECT_SUB_FIND_("name2");
441 EXPECT_SUB_FIND_("value2");
nduca@chromium.org62210b02011-11-18 18:36:36 +0900442
jbates@chromium.org59c27602012-01-13 12:12:44 +0900443 EXPECT_FIND_("TRACE_EVENT_IF_LONGER_THAN0 call");
444 EXPECT_FIND_("TRACE_EVENT_IF_LONGER_THAN1 call");
445 EXPECT_SUB_FIND_("name1");
446 EXPECT_SUB_FIND_("value1");
447 EXPECT_FIND_("TRACE_EVENT_IF_LONGER_THAN2 call");
448 EXPECT_SUB_FIND_("name1");
449 EXPECT_SUB_FIND_("value1");
450 EXPECT_SUB_FIND_("name2");
451 EXPECT_SUB_FIND_("value2");
452
jbates@chromium.org88295f92012-03-01 12:04:59 +0900453 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN0 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900454 EXPECT_SUB_FIND_("id");
455 EXPECT_SUB_FIND_("5");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900456 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900457 EXPECT_SUB_FIND_("id");
458 EXPECT_SUB_FIND_("5");
459 EXPECT_SUB_FIND_("name1");
460 EXPECT_SUB_FIND_("value1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900461 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN2 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900462 EXPECT_SUB_FIND_("id");
463 EXPECT_SUB_FIND_("5");
464 EXPECT_SUB_FIND_("name1");
465 EXPECT_SUB_FIND_("value1");
466 EXPECT_SUB_FIND_("name2");
467 EXPECT_SUB_FIND_("value2");
468
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900469 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN_STEP0 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900470 EXPECT_SUB_FIND_("id");
471 EXPECT_SUB_FIND_("5");
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900472 EXPECT_SUB_FIND_("step1");
473 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN_STEP1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900474 EXPECT_SUB_FIND_("id");
475 EXPECT_SUB_FIND_("5");
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900476 EXPECT_SUB_FIND_("step2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900477 EXPECT_SUB_FIND_("name1");
478 EXPECT_SUB_FIND_("value1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900479
480 EXPECT_FIND_("TRACE_EVENT_ASYNC_END0 call");
481 EXPECT_SUB_FIND_("id");
482 EXPECT_SUB_FIND_("5");
483 EXPECT_FIND_("TRACE_EVENT_ASYNC_END1 call");
484 EXPECT_SUB_FIND_("id");
485 EXPECT_SUB_FIND_("5");
486 EXPECT_SUB_FIND_("name1");
487 EXPECT_SUB_FIND_("value1");
488 EXPECT_FIND_("TRACE_EVENT_ASYNC_END2 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900489 EXPECT_SUB_FIND_("id");
490 EXPECT_SUB_FIND_("5");
491 EXPECT_SUB_FIND_("name1");
492 EXPECT_SUB_FIND_("value1");
493 EXPECT_SUB_FIND_("name2");
494 EXPECT_SUB_FIND_("value2");
495
496 EXPECT_FIND_("TRACE_EVENT_BEGIN_ETW0 call");
497 EXPECT_SUB_FIND_("id");
498 EXPECT_SUB_FIND_("5");
499 EXPECT_SUB_FIND_("extra");
500 EXPECT_SUB_FIND_("NULL");
501 EXPECT_FIND_("TRACE_EVENT_BEGIN_ETW1 call");
502 EXPECT_SUB_FIND_("id");
503 EXPECT_SUB_FIND_("5");
504 EXPECT_SUB_FIND_("extra");
505 EXPECT_SUB_FIND_("value");
506 EXPECT_FIND_("TRACE_EVENT_END_ETW0 call");
507 EXPECT_SUB_FIND_("id");
508 EXPECT_SUB_FIND_("5");
509 EXPECT_SUB_FIND_("extra");
510 EXPECT_SUB_FIND_("NULL");
511 EXPECT_FIND_("TRACE_EVENT_END_ETW1 call");
512 EXPECT_SUB_FIND_("id");
513 EXPECT_SUB_FIND_("5");
514 EXPECT_SUB_FIND_("extra");
515 EXPECT_SUB_FIND_("value");
516 EXPECT_FIND_("TRACE_EVENT_INSTANT_ETW0 call");
517 EXPECT_SUB_FIND_("id");
518 EXPECT_SUB_FIND_("5");
519 EXPECT_SUB_FIND_("extra");
520 EXPECT_SUB_FIND_("NULL");
521 EXPECT_FIND_("TRACE_EVENT_INSTANT_ETW1 call");
522 EXPECT_SUB_FIND_("id");
523 EXPECT_SUB_FIND_("5");
524 EXPECT_SUB_FIND_("extra");
525 EXPECT_SUB_FIND_("value");
526
nduca@chromium.org62210b02011-11-18 18:36:36 +0900527 EXPECT_FIND_("TRACE_COUNTER1 call");
528 {
529 std::string ph;
530 EXPECT_TRUE((item && item->GetString("ph", &ph)));
531 EXPECT_EQ("C", ph);
532
533 int value;
534 EXPECT_TRUE((item && item->GetInteger("args.value", &value)));
535 EXPECT_EQ(31415, value);
536 }
537
538 EXPECT_FIND_("TRACE_COUNTER2 call");
539 {
540 std::string ph;
541 EXPECT_TRUE((item && item->GetString("ph", &ph)));
542 EXPECT_EQ("C", ph);
543
544 int value;
545 EXPECT_TRUE((item && item->GetInteger("args.a", &value)));
546 EXPECT_EQ(30000, value);
547
548 EXPECT_TRUE((item && item->GetInteger("args.b", &value)));
549 EXPECT_EQ(1415, value);
550 }
551
piman@chromium.org902b2952011-12-16 10:19:06 +0900552 EXPECT_FIND_("TRACE_COUNTER_ID1 call");
553 {
554 std::string id;
555 EXPECT_TRUE((item && item->GetString("id", &id)));
556 EXPECT_EQ("319009", id);
557
558 std::string ph;
559 EXPECT_TRUE((item && item->GetString("ph", &ph)));
560 EXPECT_EQ("C", ph);
561
562 int value;
563 EXPECT_TRUE((item && item->GetInteger("args.value", &value)));
564 EXPECT_EQ(31415, value);
565 }
566
567 EXPECT_FIND_("TRACE_COUNTER_ID2 call");
568 {
569 std::string id;
570 EXPECT_TRUE((item && item->GetString("id", &id)));
571 EXPECT_EQ("319009", id);
572
573 std::string ph;
574 EXPECT_TRUE((item && item->GetString("ph", &ph)));
575 EXPECT_EQ("C", ph);
576
577 int value;
578 EXPECT_TRUE((item && item->GetInteger("args.a", &value)));
579 EXPECT_EQ(30000, value);
580
581 EXPECT_TRUE((item && item->GetInteger("args.b", &value)));
582 EXPECT_EQ(1415, value);
583 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900584}
585
nduca@chromium.org6d048772011-08-10 00:16:25 +0900586void TraceManyInstantEvents(int thread_id, int num_events,
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900587 WaitableEvent* task_complete_event) {
nduca@chromium.org6d048772011-08-10 00:16:25 +0900588 for (int i = 0; i < num_events; i++) {
589 TRACE_EVENT_INSTANT2("all", "multi thread event",
590 "thread", thread_id,
591 "event", i);
592 }
593
594 if (task_complete_event)
595 task_complete_event->Signal();
596}
597
598void ValidateInstantEventPresentOnEveryThread(const ListValue& trace_parsed,
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900599 int num_threads,
600 int num_events) {
nduca@chromium.org6d048772011-08-10 00:16:25 +0900601 std::map<int, std::map<int, bool> > results;
602
603 size_t trace_parsed_count = trace_parsed.GetSize();
604 for (size_t i = 0; i < trace_parsed_count; i++) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900605 const Value* value = NULL;
nduca@chromium.org6d048772011-08-10 00:16:25 +0900606 trace_parsed.Get(i, &value);
607 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
608 continue;
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900609 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
nduca@chromium.org6d048772011-08-10 00:16:25 +0900610 std::string name;
611 dict->GetString("name", &name);
612 if (name != "multi thread event")
613 continue;
614
615 int thread = 0;
616 int event = 0;
617 EXPECT_TRUE(dict->GetInteger("args.thread", &thread));
618 EXPECT_TRUE(dict->GetInteger("args.event", &event));
619 results[thread][event] = true;
620 }
621
622 EXPECT_FALSE(results[-1][-1]);
623 for (int thread = 0; thread < num_threads; thread++) {
624 for (int event = 0; event < num_events; event++) {
625 EXPECT_TRUE(results[thread][event]);
626 }
627 }
628}
629
630void TraceCallsWithCachedCategoryPointersPointers(const char* name_str) {
631 TRACE_EVENT0("category name1", name_str);
632 TRACE_EVENT_INSTANT0("category name2", name_str);
633 TRACE_EVENT_BEGIN0("category name3", name_str);
634 TRACE_EVENT_END0("category name4", name_str);
635}
636
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900637} // namespace
638
jbates@chromium.org5e2f67d2012-08-16 13:32:49 +0900639void HighResSleepForTraceTest(base::TimeDelta elapsed) {
640 base::TimeTicks end_time = base::TimeTicks::HighResNow() + elapsed;
641 do {
642 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
643 } while (base::TimeTicks::HighResNow() < end_time);
644}
645
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900646// Simple Test for emitting data and validating it was received.
647TEST_F(TraceEventTestFixture, DataCaptured) {
648 ManualTestSetUp();
649 TraceLog::GetInstance()->SetEnabled(true);
650
nduca@chromium.org6d048772011-08-10 00:16:25 +0900651 TraceWithAllMacroVariants(NULL);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900652
653 TraceLog::GetInstance()->SetEnabled(false);
654
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900655 ValidateAllTraceMacrosCreatedData(trace_parsed_);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900656}
657
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900658class MockEnabledStateChangedObserver :
659 public base::debug::TraceLog::EnabledStateChangedObserver {
660 public:
661 MOCK_METHOD0(OnTraceLogWillEnable, void());
662 MOCK_METHOD0(OnTraceLogWillDisable, void());
663};
664
665TEST_F(TraceEventTestFixture, EnabledObserverFiresOnEnable) {
666 ManualTestSetUp();
667
668 MockEnabledStateChangedObserver observer;
669 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
670
671 EXPECT_CALL(observer, OnTraceLogWillEnable())
672 .Times(1);
673 TraceLog::GetInstance()->SetEnabled(true);
674 testing::Mock::VerifyAndClear(&observer);
675
676 // Cleanup.
677 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
678 TraceLog::GetInstance()->SetEnabled(false);
679}
680
681TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnSecondEnable) {
682 ManualTestSetUp();
683
684 TraceLog::GetInstance()->SetEnabled(true);
685
686 testing::StrictMock<MockEnabledStateChangedObserver> observer;
687 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
688
689 EXPECT_CALL(observer, OnTraceLogWillEnable())
690 .Times(0);
691 EXPECT_CALL(observer, OnTraceLogWillDisable())
692 .Times(0);
693 TraceLog::GetInstance()->SetEnabled(true);
694 testing::Mock::VerifyAndClear(&observer);
695
696 // Cleanup.
697 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
698 TraceLog::GetInstance()->SetEnabled(false);
699}
700
701TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnUselessDisable) {
702 ManualTestSetUp();
703
704
705 testing::StrictMock<MockEnabledStateChangedObserver> observer;
706 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
707
708 EXPECT_CALL(observer, OnTraceLogWillEnable())
709 .Times(0);
710 EXPECT_CALL(observer, OnTraceLogWillDisable())
711 .Times(0);
712 TraceLog::GetInstance()->SetEnabled(false);
713 testing::Mock::VerifyAndClear(&observer);
714
715 // Cleanup.
716 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
717}
718
719TEST_F(TraceEventTestFixture, EnabledObserverFiresOnDisable) {
720 ManualTestSetUp();
721
722 TraceLog::GetInstance()->SetEnabled(true);
723
724 MockEnabledStateChangedObserver observer;
725 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
726
727 EXPECT_CALL(observer, OnTraceLogWillDisable())
728 .Times(1);
729 TraceLog::GetInstance()->SetEnabled(false);
730 testing::Mock::VerifyAndClear(&observer);
731
732 // Cleanup.
733 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
734}
735
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900736// Test that categories work.
737TEST_F(TraceEventTestFixture, Categories) {
738 ManualTestSetUp();
739
740 // Test that categories that are used can be retrieved whether trace was
741 // enabled or disabled when the trace event was encountered.
742 TRACE_EVENT_INSTANT0("c1", "name");
743 TRACE_EVENT_INSTANT0("c2", "name");
744 TraceLog::GetInstance()->SetEnabled(true);
745 TRACE_EVENT_INSTANT0("c3", "name");
746 TRACE_EVENT_INSTANT0("c4", "name");
747 TraceLog::GetInstance()->SetEnabled(false);
748 std::vector<std::string> cats;
749 TraceLog::GetInstance()->GetKnownCategories(&cats);
750 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c1") != cats.end());
751 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c2") != cats.end());
752 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c3") != cats.end());
753 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c4") != cats.end());
754
755 const std::vector<std::string> empty_categories;
756 std::vector<std::string> included_categories;
757 std::vector<std::string> excluded_categories;
758
759 // Test that category filtering works.
760
761 // Include nonexistent category -> no events
762 Clear();
763 included_categories.clear();
764 included_categories.push_back("not_found823564786");
765 TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories);
766 TRACE_EVENT_INSTANT0("cat1", "name");
767 TRACE_EVENT_INSTANT0("cat2", "name");
768 TraceLog::GetInstance()->SetDisabled();
769 EXPECT_TRUE(trace_parsed_.empty());
770
771 // Include existent category -> only events of that category
772 Clear();
773 included_categories.clear();
774 included_categories.push_back("inc");
775 TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories);
776 TRACE_EVENT_INSTANT0("inc", "name");
777 TRACE_EVENT_INSTANT0("inc2", "name");
778 TraceLog::GetInstance()->SetDisabled();
779 EXPECT_TRUE(FindMatchingValue("cat", "inc"));
780 EXPECT_FALSE(FindNonMatchingValue("cat", "inc"));
781
782 // Include existent wildcard -> all categories matching wildcard
783 Clear();
784 included_categories.clear();
785 included_categories.push_back("inc_wildcard_*");
786 included_categories.push_back("inc_wildchar_?_end");
787 TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories);
788 TRACE_EVENT_INSTANT0("inc_wildcard_abc", "included");
789 TRACE_EVENT_INSTANT0("inc_wildcard_", "included");
790 TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "included");
791 TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "not_inc");
792 TRACE_EVENT_INSTANT0("cat1", "not_inc");
793 TRACE_EVENT_INSTANT0("cat2", "not_inc");
794 TraceLog::GetInstance()->SetDisabled();
795 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_abc"));
796 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_"));
797 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildchar_x_end"));
798 EXPECT_FALSE(FindMatchingValue("name", "not_inc"));
799
800 included_categories.clear();
801
802 // Exclude nonexistent category -> all events
803 Clear();
804 excluded_categories.clear();
805 excluded_categories.push_back("not_found823564786");
806 TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories);
807 TRACE_EVENT_INSTANT0("cat1", "name");
808 TRACE_EVENT_INSTANT0("cat2", "name");
809 TraceLog::GetInstance()->SetDisabled();
810 EXPECT_TRUE(FindMatchingValue("cat", "cat1"));
811 EXPECT_TRUE(FindMatchingValue("cat", "cat2"));
812
813 // Exclude existent category -> only events of other categories
814 Clear();
815 excluded_categories.clear();
816 excluded_categories.push_back("inc");
817 TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories);
818 TRACE_EVENT_INSTANT0("inc", "name");
819 TRACE_EVENT_INSTANT0("inc2", "name");
820 TraceLog::GetInstance()->SetDisabled();
821 EXPECT_TRUE(FindMatchingValue("cat", "inc2"));
822 EXPECT_FALSE(FindMatchingValue("cat", "inc"));
823
824 // Exclude existent wildcard -> all categories not matching wildcard
825 Clear();
826 excluded_categories.clear();
827 excluded_categories.push_back("inc_wildcard_*");
828 excluded_categories.push_back("inc_wildchar_?_end");
829 TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories);
830 TRACE_EVENT_INSTANT0("inc_wildcard_abc", "not_inc");
831 TRACE_EVENT_INSTANT0("inc_wildcard_", "not_inc");
832 TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "not_inc");
833 TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "included");
834 TRACE_EVENT_INSTANT0("cat1", "included");
835 TRACE_EVENT_INSTANT0("cat2", "included");
836 TraceLog::GetInstance()->SetDisabled();
837 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildchar_bla_end"));
838 EXPECT_TRUE(FindMatchingValue("cat", "cat1"));
839 EXPECT_TRUE(FindMatchingValue("cat", "cat2"));
840 EXPECT_FALSE(FindMatchingValue("name", "not_inc"));
841}
842
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900843// Simple Test for time threshold events.
844TEST_F(TraceEventTestFixture, DataCapturedThreshold) {
845 ManualTestSetUp();
846 TraceLog::GetInstance()->SetEnabled(true);
847
848 // Test that events at the same level are properly filtered by threshold.
849 {
850 TRACE_EVENT_IF_LONGER_THAN0(100, "time", "threshold 100");
851 TRACE_EVENT_IF_LONGER_THAN0(1000, "time", "threshold 1000");
852 TRACE_EVENT_IF_LONGER_THAN0(10000, "time", "threshold 10000");
853 // 100+ seconds to avoid flakiness.
854 TRACE_EVENT_IF_LONGER_THAN0(100000000, "time", "threshold long1");
855 TRACE_EVENT_IF_LONGER_THAN0(200000000, "time", "threshold long2");
jbates@chromium.org5e2f67d2012-08-16 13:32:49 +0900856 HighResSleepForTraceTest(base::TimeDelta::FromMilliseconds(20));
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900857 }
858
859 // Test that a normal nested event remains after it's parent event is dropped.
860 {
861 TRACE_EVENT_IF_LONGER_THAN0(1000000, "time", "2threshold10000");
862 {
863 TRACE_EVENT0("time", "nonthreshold1");
864 }
865 }
866
867 // Test that parent thresholded events are dropped while some nested events
868 // remain.
869 {
870 TRACE_EVENT0("time", "nonthreshold3");
871 {
872 TRACE_EVENT_IF_LONGER_THAN0(200000000, "time", "3thresholdlong2");
873 {
874 TRACE_EVENT_IF_LONGER_THAN0(100000000, "time", "3thresholdlong1");
875 {
876 TRACE_EVENT_IF_LONGER_THAN0(10000, "time", "3threshold10000");
877 {
878 TRACE_EVENT_IF_LONGER_THAN0(1000, "time", "3threshold1000");
879 {
880 TRACE_EVENT_IF_LONGER_THAN0(100, "time", "3threshold100");
jbates@chromium.org5e2f67d2012-08-16 13:32:49 +0900881 HighResSleepForTraceTest(base::TimeDelta::FromMilliseconds(20));
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900882 }
883 }
884 }
885 }
886 }
887 }
888
889 // Test that child thresholded events are dropped while some parent events
890 // remain.
891 {
892 TRACE_EVENT0("time", "nonthreshold4");
893 {
894 TRACE_EVENT_IF_LONGER_THAN0(100, "time", "4threshold100");
895 {
896 TRACE_EVENT_IF_LONGER_THAN0(1000, "time", "4threshold1000");
897 {
898 TRACE_EVENT_IF_LONGER_THAN0(10000, "time", "4threshold10000");
899 {
900 TRACE_EVENT_IF_LONGER_THAN0(100000000, "time",
901 "4thresholdlong1");
902 {
903 TRACE_EVENT_IF_LONGER_THAN0(200000000, "time",
904 "4thresholdlong2");
jbates@chromium.org5e2f67d2012-08-16 13:32:49 +0900905 HighResSleepForTraceTest(base::TimeDelta::FromMilliseconds(20));
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900906 }
907 }
908 }
909 }
910 }
911 }
912
913 TraceLog::GetInstance()->SetEnabled(false);
914
915#define EXPECT_FIND_BE_(str) \
916 EXPECT_TRUE(FindNamePhase(str, "B")); \
917 EXPECT_TRUE(FindNamePhase(str, "E"))
918#define EXPECT_NOT_FIND_BE_(str) \
919 EXPECT_FALSE(FindNamePhase(str, "B")); \
920 EXPECT_FALSE(FindNamePhase(str, "E"))
921
922 EXPECT_FIND_BE_("threshold 100");
923 EXPECT_FIND_BE_("threshold 1000");
924 EXPECT_FIND_BE_("threshold 10000");
925 EXPECT_NOT_FIND_BE_("threshold long1");
926 EXPECT_NOT_FIND_BE_("threshold long2");
927
928 EXPECT_NOT_FIND_BE_("2threshold10000");
929 EXPECT_FIND_BE_("nonthreshold1");
930
931 EXPECT_FIND_BE_("nonthreshold3");
932 EXPECT_FIND_BE_("3threshold100");
933 EXPECT_FIND_BE_("3threshold1000");
934 EXPECT_FIND_BE_("3threshold10000");
935 EXPECT_NOT_FIND_BE_("3thresholdlong1");
936 EXPECT_NOT_FIND_BE_("3thresholdlong2");
937
938 EXPECT_FIND_BE_("nonthreshold4");
939 EXPECT_FIND_BE_("4threshold100");
940 EXPECT_FIND_BE_("4threshold1000");
941 EXPECT_FIND_BE_("4threshold10000");
942 EXPECT_NOT_FIND_BE_("4thresholdlong1");
943 EXPECT_NOT_FIND_BE_("4thresholdlong2");
944}
945
jbates@chromium.org88295f92012-03-01 12:04:59 +0900946// Test ASYNC_BEGIN/END events
947TEST_F(TraceEventTestFixture, AsyncBeginEndEvents) {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900948 ManualTestSetUp();
949 TraceLog::GetInstance()->SetEnabled(true);
950
951 unsigned long long id = 0xfeedbeeffeedbeefull;
jbates@chromium.org88295f92012-03-01 12:04:59 +0900952 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name1", id);
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900953 TRACE_EVENT_ASYNC_BEGIN_STEP0( "cat", "name1", id, "step1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900954 TRACE_EVENT_ASYNC_END0("cat", "name1", id);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900955 TRACE_EVENT_BEGIN0( "cat", "name2");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900956 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name3", 0);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900957
958 TraceLog::GetInstance()->SetEnabled(false);
959
960 EXPECT_TRUE(FindNamePhase("name1", "S"));
jbates@chromium.org88295f92012-03-01 12:04:59 +0900961 EXPECT_TRUE(FindNamePhase("name1", "T"));
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900962 EXPECT_TRUE(FindNamePhase("name1", "F"));
963
964 std::string id_str;
965 StringAppendF(&id_str, "%llx", id);
966
967 EXPECT_TRUE(FindNamePhaseKeyValue("name1", "S", "id", id_str.c_str()));
jbates@chromium.org88295f92012-03-01 12:04:59 +0900968 EXPECT_TRUE(FindNamePhaseKeyValue("name1", "T", "id", id_str.c_str()));
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900969 EXPECT_TRUE(FindNamePhaseKeyValue("name1", "F", "id", id_str.c_str()));
970 EXPECT_TRUE(FindNamePhaseKeyValue("name3", "S", "id", "0"));
971
972 // BEGIN events should not have id
973 EXPECT_FALSE(FindNamePhaseKeyValue("name2", "B", "id", "0"));
974}
975
jbates@chromium.org88295f92012-03-01 12:04:59 +0900976// Test ASYNC_BEGIN/END events
977TEST_F(TraceEventTestFixture, AsyncBeginEndPointerMangling) {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900978 ManualTestSetUp();
979
980 void* ptr = this;
981
982 TraceLog::GetInstance()->SetProcessID(100);
983 TraceLog::GetInstance()->SetEnabled(true);
jbates@chromium.org88295f92012-03-01 12:04:59 +0900984 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name1", ptr);
985 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name2", ptr);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900986 TraceLog::GetInstance()->SetEnabled(false);
987
988 TraceLog::GetInstance()->SetProcessID(200);
989 TraceLog::GetInstance()->SetEnabled(true);
jbates@chromium.org88295f92012-03-01 12:04:59 +0900990 TRACE_EVENT_ASYNC_END0( "cat", "name1", ptr);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900991 TraceLog::GetInstance()->SetEnabled(false);
992
jbates@chromium.org88295f92012-03-01 12:04:59 +0900993 DictionaryValue* async_begin = FindNamePhase("name1", "S");
994 DictionaryValue* async_begin2 = FindNamePhase("name2", "S");
995 DictionaryValue* async_end = FindNamePhase("name1", "F");
996 EXPECT_TRUE(async_begin);
997 EXPECT_TRUE(async_begin2);
998 EXPECT_TRUE(async_end);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900999
1000 Value* value = NULL;
jbates@chromium.org88295f92012-03-01 12:04:59 +09001001 std::string async_begin_id_str;
1002 std::string async_begin2_id_str;
1003 std::string async_end_id_str;
1004 ASSERT_TRUE(async_begin->Get("id", &value));
1005 ASSERT_TRUE(value->GetAsString(&async_begin_id_str));
1006 ASSERT_TRUE(async_begin2->Get("id", &value));
1007 ASSERT_TRUE(value->GetAsString(&async_begin2_id_str));
1008 ASSERT_TRUE(async_end->Get("id", &value));
1009 ASSERT_TRUE(value->GetAsString(&async_end_id_str));
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001010
jbates@chromium.org88295f92012-03-01 12:04:59 +09001011 EXPECT_STREQ(async_begin_id_str.c_str(), async_begin2_id_str.c_str());
1012 EXPECT_STRNE(async_begin_id_str.c_str(), async_end_id_str.c_str());
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001013}
1014
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001015// Test that static strings are not copied.
1016TEST_F(TraceEventTestFixture, StaticStringVsString) {
1017 ManualTestSetUp();
1018 TraceLog* tracer = TraceLog::GetInstance();
1019 // Make sure old events are flushed:
1020 tracer->SetEnabled(false);
1021 EXPECT_EQ(0u, tracer->GetEventsSize());
1022
1023 {
1024 tracer->SetEnabled(true);
1025 // Test that string arguments are copied.
1026 TRACE_EVENT2("cat", "name1",
1027 "arg1", std::string("argval"), "arg2", std::string("argval"));
1028 // Test that static TRACE_STR_COPY string arguments are copied.
1029 TRACE_EVENT2("cat", "name2",
1030 "arg1", TRACE_STR_COPY("argval"),
1031 "arg2", TRACE_STR_COPY("argval"));
1032 size_t num_events = tracer->GetEventsSize();
1033 EXPECT_GT(num_events, 1u);
1034 const TraceEvent& event1 = tracer->GetEventAt(num_events - 2);
1035 const TraceEvent& event2 = tracer->GetEventAt(num_events - 1);
1036 EXPECT_STREQ("name1", event1.name());
1037 EXPECT_STREQ("name2", event2.name());
1038 EXPECT_TRUE(event1.parameter_copy_storage() != NULL);
1039 EXPECT_TRUE(event2.parameter_copy_storage() != NULL);
1040 EXPECT_GT(event1.parameter_copy_storage()->size(), 0u);
1041 EXPECT_GT(event2.parameter_copy_storage()->size(), 0u);
1042 tracer->SetEnabled(false);
1043 }
1044
1045 {
1046 tracer->SetEnabled(true);
1047 // Test that static literal string arguments are not copied.
1048 TRACE_EVENT2("cat", "name1",
1049 "arg1", "argval", "arg2", "argval");
1050 // Test that static TRACE_STR_COPY NULL string arguments are not copied.
1051 const char* str1 = NULL;
1052 const char* str2 = NULL;
1053 TRACE_EVENT2("cat", "name2",
1054 "arg1", TRACE_STR_COPY(str1),
1055 "arg2", TRACE_STR_COPY(str2));
1056 size_t num_events = tracer->GetEventsSize();
1057 EXPECT_GT(num_events, 1u);
1058 const TraceEvent& event1 = tracer->GetEventAt(num_events - 2);
1059 const TraceEvent& event2 = tracer->GetEventAt(num_events - 1);
1060 EXPECT_STREQ("name1", event1.name());
1061 EXPECT_STREQ("name2", event2.name());
1062 EXPECT_TRUE(event1.parameter_copy_storage() == NULL);
1063 EXPECT_TRUE(event2.parameter_copy_storage() == NULL);
1064 tracer->SetEnabled(false);
1065 }
1066}
1067
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001068// Test that data sent from other threads is gathered
1069TEST_F(TraceEventTestFixture, DataCapturedOnThread) {
1070 ManualTestSetUp();
1071 TraceLog::GetInstance()->SetEnabled(true);
1072
1073 Thread thread("1");
1074 WaitableEvent task_complete_event(false, false);
1075 thread.Start();
1076
1077 thread.message_loop()->PostTask(
jbates@chromium.org0b837e42011-10-06 01:58:20 +09001078 FROM_HERE, base::Bind(&TraceWithAllMacroVariants, &task_complete_event));
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001079 task_complete_event.Wait();
jbates@chromium.orgb84db522011-10-04 02:51:25 +09001080 thread.Stop();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001081
1082 TraceLog::GetInstance()->SetEnabled(false);
jbates@chromium.org6a092d72011-10-25 01:34:08 +09001083 ValidateAllTraceMacrosCreatedData(trace_parsed_);
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001084}
1085
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001086// Test that data sent from multiple threads is gathered
1087TEST_F(TraceEventTestFixture, DataCapturedManyThreads) {
1088 ManualTestSetUp();
1089 TraceLog::GetInstance()->SetEnabled(true);
1090
1091 const int num_threads = 4;
1092 const int num_events = 4000;
1093 Thread* threads[num_threads];
1094 WaitableEvent* task_complete_events[num_threads];
1095 for (int i = 0; i < num_threads; i++) {
1096 threads[i] = new Thread(StringPrintf("Thread %d", i).c_str());
1097 task_complete_events[i] = new WaitableEvent(false, false);
1098 threads[i]->Start();
1099 threads[i]->message_loop()->PostTask(
jbates@chromium.org0b837e42011-10-06 01:58:20 +09001100 FROM_HERE, base::Bind(&TraceManyInstantEvents,
1101 i, num_events, task_complete_events[i]));
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001102 }
1103
1104 for (int i = 0; i < num_threads; i++) {
1105 task_complete_events[i]->Wait();
1106 }
1107
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001108 for (int i = 0; i < num_threads; i++) {
1109 threads[i]->Stop();
1110 delete threads[i];
1111 delete task_complete_events[i];
1112 }
1113
jbates@chromium.orgb84db522011-10-04 02:51:25 +09001114 TraceLog::GetInstance()->SetEnabled(false);
1115
jbates@chromium.org6a092d72011-10-25 01:34:08 +09001116 ValidateInstantEventPresentOnEveryThread(trace_parsed_,
nduca@chromium.org6d048772011-08-10 00:16:25 +09001117 num_threads, num_events);
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001118}
1119
nduca@chromium.org6d048772011-08-10 00:16:25 +09001120// Test that thread and process names show up in the trace
1121TEST_F(TraceEventTestFixture, ThreadNames) {
1122 ManualTestSetUp();
1123
1124 // Create threads before we enable tracing to make sure
1125 // that tracelog still captures them.
1126 const int num_threads = 4;
1127 const int num_events = 10;
1128 Thread* threads[num_threads];
1129 PlatformThreadId thread_ids[num_threads];
1130 for (int i = 0; i < num_threads; i++)
1131 threads[i] = new Thread(StringPrintf("Thread %d", i).c_str());
1132
1133 // Enable tracing.
1134 TraceLog::GetInstance()->SetEnabled(true);
1135
1136 // Now run some trace code on these threads.
1137 WaitableEvent* task_complete_events[num_threads];
1138 for (int i = 0; i < num_threads; i++) {
1139 task_complete_events[i] = new WaitableEvent(false, false);
1140 threads[i]->Start();
1141 thread_ids[i] = threads[i]->thread_id();
1142 threads[i]->message_loop()->PostTask(
jbates@chromium.org0b837e42011-10-06 01:58:20 +09001143 FROM_HERE, base::Bind(&TraceManyInstantEvents,
1144 i, num_events, task_complete_events[i]));
nduca@chromium.org6d048772011-08-10 00:16:25 +09001145 }
1146 for (int i = 0; i < num_threads; i++) {
1147 task_complete_events[i]->Wait();
1148 }
1149
1150 // Shut things down.
nduca@chromium.org6d048772011-08-10 00:16:25 +09001151 for (int i = 0; i < num_threads; i++) {
1152 threads[i]->Stop();
1153 delete threads[i];
1154 delete task_complete_events[i];
1155 }
1156
jbates@chromium.orgb84db522011-10-04 02:51:25 +09001157 TraceLog::GetInstance()->SetEnabled(false);
1158
nduca@chromium.org6d048772011-08-10 00:16:25 +09001159 std::string tmp;
1160 int tmp_int;
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001161 const DictionaryValue* item;
nduca@chromium.org6d048772011-08-10 00:16:25 +09001162
1163 // Make sure we get thread name metadata.
1164 // Note, the test suite may have created a ton of threads.
1165 // So, we'll have thread names for threads we didn't create.
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001166 std::vector<const DictionaryValue*> items =
nduca@chromium.org6d048772011-08-10 00:16:25 +09001167 FindTraceEntries(trace_parsed_, "thread_name");
1168 for (int i = 0; i < static_cast<int>(items.size()); i++) {
1169 item = items[i];
joth@chromium.org088ae012011-11-11 01:26:23 +09001170 ASSERT_TRUE(item);
nduca@chromium.org6d048772011-08-10 00:16:25 +09001171 EXPECT_TRUE(item->GetInteger("tid", &tmp_int));
1172
1173 // See if this thread name is one of the threads we just created
1174 for (int j = 0; j < num_threads; j++) {
1175 if(static_cast<int>(thread_ids[j]) != tmp_int)
1176 continue;
1177
jbates@chromium.org62a16662012-02-04 08:18:06 +09001178 std::string expected_name = StringPrintf("Thread %d", j);
nduca@chromium.org6d048772011-08-10 00:16:25 +09001179 EXPECT_TRUE(item->GetString("ph", &tmp) && tmp == "M");
1180 EXPECT_TRUE(item->GetInteger("pid", &tmp_int) &&
1181 tmp_int == static_cast<int>(base::GetCurrentProcId()));
jbates@chromium.org62a16662012-02-04 08:18:06 +09001182 // If the thread name changes or the tid gets reused, the name will be
1183 // a comma-separated list of thread names, so look for a substring.
nduca@chromium.org6d048772011-08-10 00:16:25 +09001184 EXPECT_TRUE(item->GetString("args.name", &tmp) &&
jbates@chromium.org62a16662012-02-04 08:18:06 +09001185 tmp.find(expected_name) != std::string::npos);
nduca@chromium.org6d048772011-08-10 00:16:25 +09001186 }
1187 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001188}
1189
joth@chromium.org088ae012011-11-11 01:26:23 +09001190TEST_F(TraceEventTestFixture, ThreadNameChanges) {
1191 ManualTestSetUp();
1192
1193 TraceLog::GetInstance()->SetEnabled(true);
1194
1195 PlatformThread::SetName("");
1196 TRACE_EVENT_INSTANT0("drink", "water");
1197
1198 PlatformThread::SetName("cafe");
1199 TRACE_EVENT_INSTANT0("drink", "coffee");
1200
1201 PlatformThread::SetName("shop");
1202 // No event here, so won't appear in combined name.
1203
1204 PlatformThread::SetName("pub");
1205 TRACE_EVENT_INSTANT0("drink", "beer");
1206 TRACE_EVENT_INSTANT0("drink", "wine");
1207
1208 PlatformThread::SetName(" bar");
1209 TRACE_EVENT_INSTANT0("drink", "whisky");
1210
1211 TraceLog::GetInstance()->SetEnabled(false);
1212
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001213 std::vector<const DictionaryValue*> items =
joth@chromium.org088ae012011-11-11 01:26:23 +09001214 FindTraceEntries(trace_parsed_, "thread_name");
1215 EXPECT_EQ(1u, items.size());
1216 ASSERT_GT(items.size(), 0u);
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001217 const DictionaryValue* item = items[0];
joth@chromium.org088ae012011-11-11 01:26:23 +09001218 ASSERT_TRUE(item);
1219 int tid;
1220 EXPECT_TRUE(item->GetInteger("tid", &tid));
1221 EXPECT_EQ(PlatformThread::CurrentId(), static_cast<PlatformThreadId>(tid));
1222
1223 std::string expected_name = "cafe,pub, bar";
1224 std::string tmp;
1225 EXPECT_TRUE(item->GetString("args.name", &tmp));
1226 EXPECT_EQ(expected_name, tmp);
1227}
nduca@chromium.org6d048772011-08-10 00:16:25 +09001228
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001229// Test trace calls made after tracing singleton shut down.
1230//
1231// The singleton is destroyed by our base::AtExitManager, but there can be
1232// code still executing as the C++ static objects are destroyed. This test
1233// forces the singleton to destroy early, and intentinally makes trace calls
1234// afterwards.
1235TEST_F(TraceEventTestFixture, AtExit) {
1236 // Repeat this test a few times. Besides just showing robustness, it also
1237 // allows us to test that events at shutdown do not appear with valid events
1238 // recorded after the system is started again.
1239 for (int i = 0; i < 4; i++) {
1240 // Scope to contain the then destroy the TraceLog singleton.
1241 {
1242 base::ShadowingAtExitManager exit_manager_will_destroy_singletons;
1243
1244 // Setup TraceLog singleton inside this test's exit manager scope
1245 // so that it will be destroyed when this scope closes.
1246 ManualTestSetUp();
1247
1248 TRACE_EVENT_INSTANT0("all", "not recorded; system not enabled");
1249
1250 TraceLog::GetInstance()->SetEnabled(true);
1251
1252 TRACE_EVENT_INSTANT0("all", "is recorded 1; system has been enabled");
1253 // Trace calls that will cache pointers to categories; they're valid here
1254 TraceCallsWithCachedCategoryPointersPointers(
1255 "is recorded 2; system has been enabled");
1256
1257 TraceLog::GetInstance()->SetEnabled(false);
1258 } // scope to destroy singleton
1259 ASSERT_FALSE(TraceLog::GetInstance());
1260
1261 // Now that singleton is destroyed, check what trace events were recorded
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001262 const DictionaryValue* item = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001263 ListValue& trace_parsed = trace_parsed_;
1264 EXPECT_FIND_("is recorded 1");
1265 EXPECT_FIND_("is recorded 2");
1266 EXPECT_NOT_FIND_("not recorded");
1267
1268 // Make additional trace event calls on the shutdown system. They should
1269 // all pass cleanly, but the data not be recorded. We'll verify that next
1270 // time around the loop (the only way to flush the trace buffers).
1271 TRACE_EVENT_BEGIN_ETW("not recorded; system shutdown", 0, NULL);
1272 TRACE_EVENT_END_ETW("not recorded; system shutdown", 0, NULL);
1273 TRACE_EVENT_INSTANT_ETW("not recorded; system shutdown", 0, NULL);
1274 TRACE_EVENT0("all", "not recorded; system shutdown");
1275 TRACE_EVENT_INSTANT0("all", "not recorded; system shutdown");
1276 TRACE_EVENT_BEGIN0("all", "not recorded; system shutdown");
1277 TRACE_EVENT_END0("all", "not recorded; system shutdown");
1278
1279 TRACE_EVENT0("new category 0!", "not recorded; system shutdown");
1280 TRACE_EVENT_INSTANT0("new category 1!", "not recorded; system shutdown");
1281 TRACE_EVENT_BEGIN0("new category 2!", "not recorded; system shutdown");
1282 TRACE_EVENT_END0("new category 3!", "not recorded; system shutdown");
1283
1284 // Cached categories should be safe to check, and still disable traces
1285 TraceCallsWithCachedCategoryPointersPointers(
1286 "not recorded; system shutdown");
1287 }
1288}
1289
joth@chromium.org113de992011-07-21 21:28:59 +09001290TEST_F(TraceEventTestFixture, NormallyNoDeepCopy) {
1291 // Test that the TRACE_EVENT macros do not deep-copy their string. If they
1292 // do so it may indicate a performance regression, but more-over it would
1293 // make the DEEP_COPY overloads redundant.
1294 ManualTestSetUp();
1295
1296 std::string name_string("event name");
1297
1298 TraceLog::GetInstance()->SetEnabled(true);
1299 TRACE_EVENT_INSTANT0("category", name_string.c_str());
1300
1301 // Modify the string in place (a wholesale reassignment may leave the old
1302 // string intact on the heap).
1303 name_string[0] = '@';
1304
1305 TraceLog::GetInstance()->SetEnabled(false);
1306
1307 EXPECT_FALSE(FindTraceEntry(trace_parsed_, "event name"));
1308 EXPECT_TRUE(FindTraceEntry(trace_parsed_, name_string.c_str()));
1309}
1310
1311TEST_F(TraceEventTestFixture, DeepCopy) {
1312 ManualTestSetUp();
1313
1314 static const char kOriginalName1[] = "name1";
1315 static const char kOriginalName2[] = "name2";
1316 static const char kOriginalName3[] = "name3";
1317 std::string name1(kOriginalName1);
1318 std::string name2(kOriginalName2);
1319 std::string name3(kOriginalName3);
1320 std::string arg1("arg1");
1321 std::string arg2("arg2");
1322 std::string val1("val1");
1323 std::string val2("val2");
1324
1325 TraceLog::GetInstance()->SetEnabled(true);
1326 TRACE_EVENT_COPY_INSTANT0("category", name1.c_str());
1327 TRACE_EVENT_COPY_BEGIN1("category", name2.c_str(),
1328 arg1.c_str(), 5);
1329 TRACE_EVENT_COPY_END2("category", name3.c_str(),
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001330 arg1.c_str(), val1,
1331 arg2.c_str(), val2);
joth@chromium.org113de992011-07-21 21:28:59 +09001332
1333 // As per NormallyNoDeepCopy, modify the strings in place.
1334 name1[0] = name2[0] = name3[0] = arg1[0] = arg2[0] = val1[0] = val2[0] = '@';
1335
1336 TraceLog::GetInstance()->SetEnabled(false);
1337
1338 EXPECT_FALSE(FindTraceEntry(trace_parsed_, name1.c_str()));
1339 EXPECT_FALSE(FindTraceEntry(trace_parsed_, name2.c_str()));
1340 EXPECT_FALSE(FindTraceEntry(trace_parsed_, name3.c_str()));
1341
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001342 const DictionaryValue* entry1 = FindTraceEntry(trace_parsed_, kOriginalName1);
1343 const DictionaryValue* entry2 = FindTraceEntry(trace_parsed_, kOriginalName2);
1344 const DictionaryValue* entry3 = FindTraceEntry(trace_parsed_, kOriginalName3);
joth@chromium.org113de992011-07-21 21:28:59 +09001345 ASSERT_TRUE(entry1);
1346 ASSERT_TRUE(entry2);
1347 ASSERT_TRUE(entry3);
1348
1349 int i;
1350 EXPECT_FALSE(entry2->GetInteger("args.@rg1", &i));
1351 EXPECT_TRUE(entry2->GetInteger("args.arg1", &i));
1352 EXPECT_EQ(5, i);
1353
1354 std::string s;
1355 EXPECT_TRUE(entry3->GetString("args.arg1", &s));
1356 EXPECT_EQ("val1", s);
1357 EXPECT_TRUE(entry3->GetString("args.arg2", &s));
1358 EXPECT_EQ("val2", s);
1359}
1360
jbates@chromium.org6a092d72011-10-25 01:34:08 +09001361// Test that TraceResultBuffer outputs the correct result whether it is added
1362// in chunks or added all at once.
1363TEST_F(TraceEventTestFixture, TraceResultBuffer) {
1364 ManualTestSetUp();
1365
1366 Clear();
1367
1368 trace_buffer_.Start();
1369 trace_buffer_.AddFragment("bla1");
1370 trace_buffer_.AddFragment("bla2");
1371 trace_buffer_.AddFragment("bla3,bla4");
1372 trace_buffer_.Finish();
1373 EXPECT_STREQ(json_output_.json_output.c_str(), "[bla1,bla2,bla3,bla4]");
1374
1375 Clear();
1376
1377 trace_buffer_.Start();
1378 trace_buffer_.AddFragment("bla1,bla2,bla3,bla4");
1379 trace_buffer_.Finish();
1380 EXPECT_STREQ(json_output_.json_output.c_str(), "[bla1,bla2,bla3,bla4]");
1381}
1382
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001383} // namespace debug
1384} // namespace base