blob: 2d549df77fab068a41287df4695e4b6cad2b68bb [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() {
caseq@google.comedcf6262013-01-16 20:41:57 +090074 while (TraceLog::GetInstance()->IsEnabled())
75 TraceLog::GetInstance()->SetDisabled();
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +090076 TraceLog::GetInstance()->Flush(
77 base::Bind(&TraceEventTestFixture::OnTraceDataCollected,
78 base::Unretained(this)));
79 }
80
rsleevi@chromium.orgde3a6cf2012-04-06 12:53:02 +090081 virtual void SetUp() OVERRIDE {
joth@chromium.org088ae012011-11-11 01:26:23 +090082 old_thread_name_ = PlatformThread::GetName();
83 }
rsleevi@chromium.orgde3a6cf2012-04-06 12:53:02 +090084 virtual void TearDown() OVERRIDE {
nduca@chromium.org6a7360c2012-02-20 15:35:15 +090085 if (TraceLog::GetInstance())
86 EXPECT_FALSE(TraceLog::GetInstance()->IsEnabled());
joth@chromium.org088ae012011-11-11 01:26:23 +090087 PlatformThread::SetName(old_thread_name_ ? old_thread_name_ : "");
88 }
89
90 const char* old_thread_name_;
scheib@chromium.org603f46e2011-05-10 11:23:58 +090091 ListValue trace_parsed_;
jbates@chromium.org6a092d72011-10-25 01:34:08 +090092 base::debug::TraceResultBuffer trace_buffer_;
93 base::debug::TraceResultBuffer::SimpleOutput json_output_;
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +090094 int event_watch_notification_;
scheib@chromium.org603f46e2011-05-10 11:23:58 +090095
96 private:
97 // We want our singleton torn down after each test.
98 ShadowingAtExitManager at_exit_manager_;
jbates@chromium.orgb84db522011-10-04 02:51:25 +090099 Lock lock_;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900100};
101
102void TraceEventTestFixture::ManualTestSetUp() {
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900103 TraceLog::DeleteForTesting();
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900104 TraceLog::Resurrect();
105 TraceLog* tracelog = TraceLog::GetInstance();
106 ASSERT_TRUE(tracelog);
107 ASSERT_FALSE(tracelog->IsEnabled());
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900108 tracelog->SetNotificationCallback(
109 base::Bind(&TraceEventTestFixture::OnTraceNotification,
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900110 base::Unretained(this)));
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900111 trace_buffer_.SetOutputCallback(json_output_.GetCallback());
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900112}
113
114void TraceEventTestFixture::OnTraceDataCollected(
husky@chromium.org3b366292012-02-24 13:17:06 +0900115 const scoped_refptr<base::RefCountedString>& events_str) {
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900116 AutoLock lock(lock_);
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900117 json_output_.json_output.clear();
118 trace_buffer_.Start();
husky@chromium.org3b366292012-02-24 13:17:06 +0900119 trace_buffer_.AddFragment(events_str->data());
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900120 trace_buffer_.Finish();
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900121
122 scoped_ptr<Value> root;
rsesek@chromium.orgc2d2b202012-05-17 00:23:30 +0900123 root.reset(base::JSONReader::Read(json_output_.json_output,
124 JSON_PARSE_RFC | JSON_DETACHABLE_CHILDREN));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900125
jbates@chromium.org59c27602012-01-13 12:12:44 +0900126 if (!root.get()) {
127 LOG(ERROR) << json_output_.json_output;
128 }
129
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900130 ListValue* root_list = NULL;
131 ASSERT_TRUE(root.get());
132 ASSERT_TRUE(root->GetAsList(&root_list));
133
134 // Move items into our aggregate collection
135 while (root_list->GetSize()) {
136 Value* item = NULL;
137 root_list->Remove(0, &item);
138 trace_parsed_.Append(item);
139 }
140}
141
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900142static bool CompareJsonValues(const std::string& lhs,
143 const std::string& rhs,
144 CompareOp op) {
145 switch (op) {
146 case IS_EQUAL:
147 return lhs == rhs;
148 case IS_NOT_EQUAL:
149 return lhs != rhs;
150 default:
151 CHECK(0);
152 }
153 return false;
154}
155
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900156static bool IsKeyValueInDict(const JsonKeyValue* key_value,
157 DictionaryValue* dict) {
158 Value* value = NULL;
159 std::string value_str;
160 if (dict->Get(key_value->key, &value) &&
161 value->GetAsString(&value_str) &&
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900162 CompareJsonValues(value_str, key_value->value, key_value->op))
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900163 return true;
164
165 // Recurse to test arguments
166 DictionaryValue* args_dict = NULL;
167 dict->GetDictionary("args", &args_dict);
168 if (args_dict)
169 return IsKeyValueInDict(key_value, args_dict);
170
171 return false;
172}
173
174static bool IsAllKeyValueInDict(const JsonKeyValue* key_values,
175 DictionaryValue* dict) {
176 // Scan all key_values, they must all be present and equal.
177 while (key_values && key_values->key) {
178 if (!IsKeyValueInDict(key_values, dict))
179 return false;
180 ++key_values;
181 }
182 return true;
183}
184
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900185DictionaryValue* TraceEventTestFixture::FindMatchingTraceEntry(
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900186 const JsonKeyValue* key_values) {
187 // Scan all items
188 size_t trace_parsed_count = trace_parsed_.GetSize();
189 for (size_t i = 0; i < trace_parsed_count; i++) {
190 Value* value = NULL;
191 trace_parsed_.Get(i, &value);
192 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
193 continue;
194 DictionaryValue* dict = static_cast<DictionaryValue*>(value);
195
196 if (IsAllKeyValueInDict(key_values, dict))
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900197 return dict;
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900198 }
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900199 return NULL;
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900200}
201
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900202DictionaryValue* TraceEventTestFixture::FindNamePhase(const char* name,
203 const char* phase) {
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900204 JsonKeyValue key_values[] = {
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900205 {"name", name, IS_EQUAL},
206 {"ph", phase, IS_EQUAL},
207 {0, 0, IS_EQUAL}
208 };
209 return FindMatchingTraceEntry(key_values);
210}
211
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900212DictionaryValue* TraceEventTestFixture::FindNamePhaseKeyValue(
213 const char* name,
214 const char* phase,
215 const char* key,
216 const char* value) {
217 JsonKeyValue key_values[] = {
218 {"name", name, IS_EQUAL},
219 {"ph", phase, IS_EQUAL},
220 {key, value, IS_EQUAL},
221 {0, 0, IS_EQUAL}
222 };
223 return FindMatchingTraceEntry(key_values);
224}
225
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900226bool TraceEventTestFixture::FindMatchingValue(const char* key,
227 const char* value) {
228 JsonKeyValue key_values[] = {
229 {key, value, IS_EQUAL},
230 {0, 0, IS_EQUAL}
231 };
232 return FindMatchingTraceEntry(key_values);
233}
234
235bool TraceEventTestFixture::FindNonMatchingValue(const char* key,
236 const char* value) {
237 JsonKeyValue key_values[] = {
238 {key, value, IS_NOT_EQUAL},
239 {0, 0, IS_EQUAL}
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900240 };
241 return FindMatchingTraceEntry(key_values);
242}
243
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900244bool IsStringInDict(const char* string_to_match, const DictionaryValue* dict) {
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900245 for (DictionaryValue::key_iterator ikey = dict->begin_keys();
246 ikey != dict->end_keys(); ++ikey) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900247 const Value* child = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900248 if (!dict->GetWithoutPathExpansion(*ikey, &child))
249 continue;
250
251 if ((*ikey).find(string_to_match) != std::string::npos)
252 return true;
253
254 std::string value_str;
255 child->GetAsString(&value_str);
256 if (value_str.find(string_to_match) != std::string::npos)
257 return true;
258 }
259
260 // Recurse to test arguments
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900261 const DictionaryValue* args_dict = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900262 dict->GetDictionary("args", &args_dict);
263 if (args_dict)
264 return IsStringInDict(string_to_match, args_dict);
265
266 return false;
267}
268
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900269const DictionaryValue* FindTraceEntry(
270 const ListValue& trace_parsed,
271 const char* string_to_match,
272 const DictionaryValue* match_after_this_item = NULL) {
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900273 // Scan all items
274 size_t trace_parsed_count = trace_parsed.GetSize();
275 for (size_t i = 0; i < trace_parsed_count; i++) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900276 const Value* value = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900277 trace_parsed.Get(i, &value);
278 if (match_after_this_item) {
279 if (value == match_after_this_item)
280 match_after_this_item = NULL;
281 continue;
282 }
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);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900286
287 if (IsStringInDict(string_to_match, dict))
288 return dict;
289 }
290 return NULL;
291}
292
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900293std::vector<const DictionaryValue*> FindTraceEntries(
nduca@chromium.org6d048772011-08-10 00:16:25 +0900294 const ListValue& trace_parsed,
295 const char* string_to_match) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900296 std::vector<const DictionaryValue*> hits;
nduca@chromium.org6d048772011-08-10 00:16:25 +0900297 size_t trace_parsed_count = trace_parsed.GetSize();
298 for (size_t i = 0; i < trace_parsed_count; i++) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900299 const Value* value = NULL;
nduca@chromium.org6d048772011-08-10 00:16:25 +0900300 trace_parsed.Get(i, &value);
301 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
302 continue;
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900303 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
nduca@chromium.org6d048772011-08-10 00:16:25 +0900304
305 if (IsStringInDict(string_to_match, dict))
306 hits.push_back(dict);
307 }
308 return hits;
309}
310
311void TraceWithAllMacroVariants(WaitableEvent* task_complete_event) {
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900312 {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900313 TRACE_EVENT_BEGIN_ETW("TRACE_EVENT_BEGIN_ETW call", 0x1122, "extrastring1");
314 TRACE_EVENT_END_ETW("TRACE_EVENT_END_ETW call", 0x3344, "extrastring2");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900315 TRACE_EVENT_INSTANT_ETW("TRACE_EVENT_INSTANT_ETW call",
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900316 0x5566, "extrastring3");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900317
318 TRACE_EVENT0("all", "TRACE_EVENT0 call");
319 TRACE_EVENT1("all", "TRACE_EVENT1 call", "name1", "value1");
320 TRACE_EVENT2("all", "TRACE_EVENT2 call",
jbates@chromium.org788d5a12011-09-07 09:43:11 +0900321 "name1", "\"value1\"",
322 "name2", "value\\2");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900323
324 TRACE_EVENT_INSTANT0("all", "TRACE_EVENT_INSTANT0 call");
325 TRACE_EVENT_INSTANT1("all", "TRACE_EVENT_INSTANT1 call", "name1", "value1");
326 TRACE_EVENT_INSTANT2("all", "TRACE_EVENT_INSTANT2 call",
327 "name1", "value1",
328 "name2", "value2");
329
330 TRACE_EVENT_BEGIN0("all", "TRACE_EVENT_BEGIN0 call");
331 TRACE_EVENT_BEGIN1("all", "TRACE_EVENT_BEGIN1 call", "name1", "value1");
332 TRACE_EVENT_BEGIN2("all", "TRACE_EVENT_BEGIN2 call",
333 "name1", "value1",
334 "name2", "value2");
335
336 TRACE_EVENT_END0("all", "TRACE_EVENT_END0 call");
337 TRACE_EVENT_END1("all", "TRACE_EVENT_END1 call", "name1", "value1");
338 TRACE_EVENT_END2("all", "TRACE_EVENT_END2 call",
339 "name1", "value1",
340 "name2", "value2");
nduca@chromium.org62210b02011-11-18 18:36:36 +0900341
jbates@chromium.org88295f92012-03-01 12:04:59 +0900342 TRACE_EVENT_ASYNC_BEGIN0("all", "TRACE_EVENT_ASYNC_BEGIN0 call", 5);
343 TRACE_EVENT_ASYNC_BEGIN1("all", "TRACE_EVENT_ASYNC_BEGIN1 call", 5,
344 "name1", "value1");
345 TRACE_EVENT_ASYNC_BEGIN2("all", "TRACE_EVENT_ASYNC_BEGIN2 call", 5,
346 "name1", "value1",
347 "name2", "value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900348
jbates@chromium.orgbd9d20a2012-09-11 14:56:05 +0900349 TRACE_EVENT_ASYNC_STEP0("all", "TRACE_EVENT_ASYNC_STEP0 call",
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900350 5, "step1");
jbates@chromium.orgbd9d20a2012-09-11 14:56:05 +0900351 TRACE_EVENT_ASYNC_STEP1("all", "TRACE_EVENT_ASYNC_STEP1 call",
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900352 5, "step2", "name1", "value1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900353
354 TRACE_EVENT_ASYNC_END0("all", "TRACE_EVENT_ASYNC_END0 call", 5);
355 TRACE_EVENT_ASYNC_END1("all", "TRACE_EVENT_ASYNC_END1 call", 5,
356 "name1", "value1");
357 TRACE_EVENT_ASYNC_END2("all", "TRACE_EVENT_ASYNC_END2 call", 5,
358 "name1", "value1",
359 "name2", "value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900360
361 TRACE_EVENT_BEGIN_ETW("TRACE_EVENT_BEGIN_ETW0 call", 5, NULL);
362 TRACE_EVENT_BEGIN_ETW("TRACE_EVENT_BEGIN_ETW1 call", 5, "value");
363 TRACE_EVENT_END_ETW("TRACE_EVENT_END_ETW0 call", 5, NULL);
364 TRACE_EVENT_END_ETW("TRACE_EVENT_END_ETW1 call", 5, "value");
365 TRACE_EVENT_INSTANT_ETW("TRACE_EVENT_INSTANT_ETW0 call", 5, NULL);
366 TRACE_EVENT_INSTANT_ETW("TRACE_EVENT_INSTANT_ETW1 call", 5, "value");
367
nduca@chromium.org62210b02011-11-18 18:36:36 +0900368 TRACE_COUNTER1("all", "TRACE_COUNTER1 call", 31415);
369 TRACE_COUNTER2("all", "TRACE_COUNTER2 call",
370 "a", 30000,
371 "b", 1415);
piman@chromium.org902b2952011-12-16 10:19:06 +0900372
373 TRACE_COUNTER_ID1("all", "TRACE_COUNTER_ID1 call", 0x319009, 31415);
374 TRACE_COUNTER_ID2("all", "TRACE_COUNTER_ID2 call", 0x319009,
375 "a", 30000, "b", 1415);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900376 } // Scope close causes TRACE_EVENT0 etc to send their END events.
377
378 if (task_complete_event)
379 task_complete_event->Signal();
380}
381
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900382void ValidateAllTraceMacrosCreatedData(const ListValue& trace_parsed) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900383 const DictionaryValue* item = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900384
385#define EXPECT_FIND_(string) \
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900386 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, string)));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900387#define EXPECT_NOT_FIND_(string) \
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900388 EXPECT_FALSE((item = FindTraceEntry(trace_parsed, string)));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900389#define EXPECT_SUB_FIND_(string) \
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900390 if (item) EXPECT_TRUE((IsStringInDict(string, item)));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900391
392 EXPECT_FIND_("ETW Trace Event");
393 EXPECT_FIND_("all");
394 EXPECT_FIND_("TRACE_EVENT_BEGIN_ETW call");
395 {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900396 std::string str_val;
397 EXPECT_TRUE(item && item->GetString("args.id", &str_val));
398 EXPECT_STREQ("1122", str_val.c_str());
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900399 }
400 EXPECT_SUB_FIND_("extrastring1");
401 EXPECT_FIND_("TRACE_EVENT_END_ETW call");
402 EXPECT_FIND_("TRACE_EVENT_INSTANT_ETW call");
403 EXPECT_FIND_("TRACE_EVENT0 call");
404 {
405 std::string ph_begin;
406 std::string ph_end;
407 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, "TRACE_EVENT0 call")));
408 EXPECT_TRUE((item && item->GetString("ph", &ph_begin)));
409 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, "TRACE_EVENT0 call",
410 item)));
411 EXPECT_TRUE((item && item->GetString("ph", &ph_end)));
412 EXPECT_EQ("B", ph_begin);
413 EXPECT_EQ("E", ph_end);
414 }
415 EXPECT_FIND_("TRACE_EVENT1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900416 EXPECT_SUB_FIND_("name1");
417 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900418 EXPECT_FIND_("TRACE_EVENT2 call");
419 EXPECT_SUB_FIND_("name1");
jbates@chromium.org788d5a12011-09-07 09:43:11 +0900420 EXPECT_SUB_FIND_("\"value1\"");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900421 EXPECT_SUB_FIND_("name2");
jbates@chromium.org788d5a12011-09-07 09:43:11 +0900422 EXPECT_SUB_FIND_("value\\2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900423
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900424 EXPECT_FIND_("TRACE_EVENT_INSTANT0 call");
425 EXPECT_FIND_("TRACE_EVENT_INSTANT1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900426 EXPECT_SUB_FIND_("name1");
427 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900428 EXPECT_FIND_("TRACE_EVENT_INSTANT2 call");
429 EXPECT_SUB_FIND_("name1");
430 EXPECT_SUB_FIND_("value1");
431 EXPECT_SUB_FIND_("name2");
432 EXPECT_SUB_FIND_("value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900433
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900434 EXPECT_FIND_("TRACE_EVENT_BEGIN0 call");
435 EXPECT_FIND_("TRACE_EVENT_BEGIN1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900436 EXPECT_SUB_FIND_("name1");
437 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900438 EXPECT_FIND_("TRACE_EVENT_BEGIN2 call");
439 EXPECT_SUB_FIND_("name1");
440 EXPECT_SUB_FIND_("value1");
441 EXPECT_SUB_FIND_("name2");
442 EXPECT_SUB_FIND_("value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900443
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900444 EXPECT_FIND_("TRACE_EVENT_END0 call");
445 EXPECT_FIND_("TRACE_EVENT_END1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900446 EXPECT_SUB_FIND_("name1");
447 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900448 EXPECT_FIND_("TRACE_EVENT_END2 call");
449 EXPECT_SUB_FIND_("name1");
450 EXPECT_SUB_FIND_("value1");
451 EXPECT_SUB_FIND_("name2");
452 EXPECT_SUB_FIND_("value2");
nduca@chromium.org62210b02011-11-18 18:36:36 +0900453
jbates@chromium.org88295f92012-03-01 12:04:59 +0900454 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN0 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900455 EXPECT_SUB_FIND_("id");
456 EXPECT_SUB_FIND_("5");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900457 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900458 EXPECT_SUB_FIND_("id");
459 EXPECT_SUB_FIND_("5");
460 EXPECT_SUB_FIND_("name1");
461 EXPECT_SUB_FIND_("value1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900462 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN2 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900463 EXPECT_SUB_FIND_("id");
464 EXPECT_SUB_FIND_("5");
465 EXPECT_SUB_FIND_("name1");
466 EXPECT_SUB_FIND_("value1");
467 EXPECT_SUB_FIND_("name2");
468 EXPECT_SUB_FIND_("value2");
469
jbates@chromium.orgbd9d20a2012-09-11 14:56:05 +0900470 EXPECT_FIND_("TRACE_EVENT_ASYNC_STEP0 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900471 EXPECT_SUB_FIND_("id");
472 EXPECT_SUB_FIND_("5");
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900473 EXPECT_SUB_FIND_("step1");
jbates@chromium.orgbd9d20a2012-09-11 14:56:05 +0900474 EXPECT_FIND_("TRACE_EVENT_ASYNC_STEP1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900475 EXPECT_SUB_FIND_("id");
476 EXPECT_SUB_FIND_("5");
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900477 EXPECT_SUB_FIND_("step2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900478 EXPECT_SUB_FIND_("name1");
479 EXPECT_SUB_FIND_("value1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900480
481 EXPECT_FIND_("TRACE_EVENT_ASYNC_END0 call");
482 EXPECT_SUB_FIND_("id");
483 EXPECT_SUB_FIND_("5");
484 EXPECT_FIND_("TRACE_EVENT_ASYNC_END1 call");
485 EXPECT_SUB_FIND_("id");
486 EXPECT_SUB_FIND_("5");
487 EXPECT_SUB_FIND_("name1");
488 EXPECT_SUB_FIND_("value1");
489 EXPECT_FIND_("TRACE_EVENT_ASYNC_END2 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900490 EXPECT_SUB_FIND_("id");
491 EXPECT_SUB_FIND_("5");
492 EXPECT_SUB_FIND_("name1");
493 EXPECT_SUB_FIND_("value1");
494 EXPECT_SUB_FIND_("name2");
495 EXPECT_SUB_FIND_("value2");
496
497 EXPECT_FIND_("TRACE_EVENT_BEGIN_ETW0 call");
498 EXPECT_SUB_FIND_("id");
499 EXPECT_SUB_FIND_("5");
500 EXPECT_SUB_FIND_("extra");
501 EXPECT_SUB_FIND_("NULL");
502 EXPECT_FIND_("TRACE_EVENT_BEGIN_ETW1 call");
503 EXPECT_SUB_FIND_("id");
504 EXPECT_SUB_FIND_("5");
505 EXPECT_SUB_FIND_("extra");
506 EXPECT_SUB_FIND_("value");
507 EXPECT_FIND_("TRACE_EVENT_END_ETW0 call");
508 EXPECT_SUB_FIND_("id");
509 EXPECT_SUB_FIND_("5");
510 EXPECT_SUB_FIND_("extra");
511 EXPECT_SUB_FIND_("NULL");
512 EXPECT_FIND_("TRACE_EVENT_END_ETW1 call");
513 EXPECT_SUB_FIND_("id");
514 EXPECT_SUB_FIND_("5");
515 EXPECT_SUB_FIND_("extra");
516 EXPECT_SUB_FIND_("value");
517 EXPECT_FIND_("TRACE_EVENT_INSTANT_ETW0 call");
518 EXPECT_SUB_FIND_("id");
519 EXPECT_SUB_FIND_("5");
520 EXPECT_SUB_FIND_("extra");
521 EXPECT_SUB_FIND_("NULL");
522 EXPECT_FIND_("TRACE_EVENT_INSTANT_ETW1 call");
523 EXPECT_SUB_FIND_("id");
524 EXPECT_SUB_FIND_("5");
525 EXPECT_SUB_FIND_("extra");
526 EXPECT_SUB_FIND_("value");
527
nduca@chromium.org62210b02011-11-18 18:36:36 +0900528 EXPECT_FIND_("TRACE_COUNTER1 call");
529 {
530 std::string ph;
531 EXPECT_TRUE((item && item->GetString("ph", &ph)));
532 EXPECT_EQ("C", ph);
533
534 int value;
535 EXPECT_TRUE((item && item->GetInteger("args.value", &value)));
536 EXPECT_EQ(31415, value);
537 }
538
539 EXPECT_FIND_("TRACE_COUNTER2 call");
540 {
541 std::string ph;
542 EXPECT_TRUE((item && item->GetString("ph", &ph)));
543 EXPECT_EQ("C", ph);
544
545 int value;
546 EXPECT_TRUE((item && item->GetInteger("args.a", &value)));
547 EXPECT_EQ(30000, value);
548
549 EXPECT_TRUE((item && item->GetInteger("args.b", &value)));
550 EXPECT_EQ(1415, value);
551 }
552
piman@chromium.org902b2952011-12-16 10:19:06 +0900553 EXPECT_FIND_("TRACE_COUNTER_ID1 call");
554 {
555 std::string id;
556 EXPECT_TRUE((item && item->GetString("id", &id)));
557 EXPECT_EQ("319009", id);
558
559 std::string ph;
560 EXPECT_TRUE((item && item->GetString("ph", &ph)));
561 EXPECT_EQ("C", ph);
562
563 int value;
564 EXPECT_TRUE((item && item->GetInteger("args.value", &value)));
565 EXPECT_EQ(31415, value);
566 }
567
568 EXPECT_FIND_("TRACE_COUNTER_ID2 call");
569 {
570 std::string id;
571 EXPECT_TRUE((item && item->GetString("id", &id)));
572 EXPECT_EQ("319009", id);
573
574 std::string ph;
575 EXPECT_TRUE((item && item->GetString("ph", &ph)));
576 EXPECT_EQ("C", ph);
577
578 int value;
579 EXPECT_TRUE((item && item->GetInteger("args.a", &value)));
580 EXPECT_EQ(30000, value);
581
582 EXPECT_TRUE((item && item->GetInteger("args.b", &value)));
583 EXPECT_EQ(1415, value);
584 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900585}
586
nduca@chromium.org6d048772011-08-10 00:16:25 +0900587void TraceManyInstantEvents(int thread_id, int num_events,
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900588 WaitableEvent* task_complete_event) {
nduca@chromium.org6d048772011-08-10 00:16:25 +0900589 for (int i = 0; i < num_events; i++) {
590 TRACE_EVENT_INSTANT2("all", "multi thread event",
591 "thread", thread_id,
592 "event", i);
593 }
594
595 if (task_complete_event)
596 task_complete_event->Signal();
597}
598
599void ValidateInstantEventPresentOnEveryThread(const ListValue& trace_parsed,
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900600 int num_threads,
601 int num_events) {
nduca@chromium.org6d048772011-08-10 00:16:25 +0900602 std::map<int, std::map<int, bool> > results;
603
604 size_t trace_parsed_count = trace_parsed.GetSize();
605 for (size_t i = 0; i < trace_parsed_count; i++) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900606 const Value* value = NULL;
nduca@chromium.org6d048772011-08-10 00:16:25 +0900607 trace_parsed.Get(i, &value);
608 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
609 continue;
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900610 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
nduca@chromium.org6d048772011-08-10 00:16:25 +0900611 std::string name;
612 dict->GetString("name", &name);
613 if (name != "multi thread event")
614 continue;
615
616 int thread = 0;
617 int event = 0;
618 EXPECT_TRUE(dict->GetInteger("args.thread", &thread));
619 EXPECT_TRUE(dict->GetInteger("args.event", &event));
620 results[thread][event] = true;
621 }
622
623 EXPECT_FALSE(results[-1][-1]);
624 for (int thread = 0; thread < num_threads; thread++) {
625 for (int event = 0; event < num_events; event++) {
626 EXPECT_TRUE(results[thread][event]);
627 }
628 }
629}
630
631void TraceCallsWithCachedCategoryPointersPointers(const char* name_str) {
632 TRACE_EVENT0("category name1", name_str);
633 TRACE_EVENT_INSTANT0("category name2", name_str);
634 TRACE_EVENT_BEGIN0("category name3", name_str);
635 TRACE_EVENT_END0("category name4", name_str);
636}
637
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900638} // namespace
639
jbates@chromium.org5e2f67d2012-08-16 13:32:49 +0900640void HighResSleepForTraceTest(base::TimeDelta elapsed) {
641 base::TimeTicks end_time = base::TimeTicks::HighResNow() + elapsed;
642 do {
643 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
644 } while (base::TimeTicks::HighResNow() < end_time);
645}
646
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900647// Simple Test for emitting data and validating it was received.
648TEST_F(TraceEventTestFixture, DataCaptured) {
649 ManualTestSetUp();
650 TraceLog::GetInstance()->SetEnabled(true);
651
nduca@chromium.org6d048772011-08-10 00:16:25 +0900652 TraceWithAllMacroVariants(NULL);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900653
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900654 EndTraceAndFlush();
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900655
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900656 ValidateAllTraceMacrosCreatedData(trace_parsed_);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900657}
658
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900659class MockEnabledStateChangedObserver :
660 public base::debug::TraceLog::EnabledStateChangedObserver {
661 public:
662 MOCK_METHOD0(OnTraceLogWillEnable, void());
663 MOCK_METHOD0(OnTraceLogWillDisable, void());
664};
665
666TEST_F(TraceEventTestFixture, EnabledObserverFiresOnEnable) {
667 ManualTestSetUp();
668
669 MockEnabledStateChangedObserver observer;
670 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
671
672 EXPECT_CALL(observer, OnTraceLogWillEnable())
673 .Times(1);
674 TraceLog::GetInstance()->SetEnabled(true);
675 testing::Mock::VerifyAndClear(&observer);
676
677 // Cleanup.
678 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
679 TraceLog::GetInstance()->SetEnabled(false);
680}
681
682TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnSecondEnable) {
683 ManualTestSetUp();
684
685 TraceLog::GetInstance()->SetEnabled(true);
686
687 testing::StrictMock<MockEnabledStateChangedObserver> observer;
688 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
689
690 EXPECT_CALL(observer, OnTraceLogWillEnable())
691 .Times(0);
692 EXPECT_CALL(observer, OnTraceLogWillDisable())
693 .Times(0);
694 TraceLog::GetInstance()->SetEnabled(true);
695 testing::Mock::VerifyAndClear(&observer);
696
697 // Cleanup.
698 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
699 TraceLog::GetInstance()->SetEnabled(false);
caseq@google.comedcf6262013-01-16 20:41:57 +0900700 TraceLog::GetInstance()->SetEnabled(false);
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900701}
702
caseq@google.comedcf6262013-01-16 20:41:57 +0900703TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnNestedDisable) {
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900704 ManualTestSetUp();
705
caseq@google.comedcf6262013-01-16 20:41:57 +0900706 TraceLog::GetInstance()->SetEnabled(true);
707 TraceLog::GetInstance()->SetEnabled(true);
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900708
709 testing::StrictMock<MockEnabledStateChangedObserver> observer;
710 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
711
712 EXPECT_CALL(observer, OnTraceLogWillEnable())
713 .Times(0);
714 EXPECT_CALL(observer, OnTraceLogWillDisable())
715 .Times(0);
716 TraceLog::GetInstance()->SetEnabled(false);
717 testing::Mock::VerifyAndClear(&observer);
718
719 // Cleanup.
720 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
caseq@google.comedcf6262013-01-16 20:41:57 +0900721 TraceLog::GetInstance()->SetEnabled(false);
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900722}
723
724TEST_F(TraceEventTestFixture, EnabledObserverFiresOnDisable) {
725 ManualTestSetUp();
726
727 TraceLog::GetInstance()->SetEnabled(true);
728
729 MockEnabledStateChangedObserver observer;
730 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
731
732 EXPECT_CALL(observer, OnTraceLogWillDisable())
733 .Times(1);
734 TraceLog::GetInstance()->SetEnabled(false);
735 testing::Mock::VerifyAndClear(&observer);
736
737 // Cleanup.
738 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
739}
740
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900741// Test that categories work.
742TEST_F(TraceEventTestFixture, Categories) {
743 ManualTestSetUp();
744
745 // Test that categories that are used can be retrieved whether trace was
746 // enabled or disabled when the trace event was encountered.
747 TRACE_EVENT_INSTANT0("c1", "name");
748 TRACE_EVENT_INSTANT0("c2", "name");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900749 BeginTrace();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900750 TRACE_EVENT_INSTANT0("c3", "name");
751 TRACE_EVENT_INSTANT0("c4", "name");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900752 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900753 std::vector<std::string> cats;
754 TraceLog::GetInstance()->GetKnownCategories(&cats);
755 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c1") != cats.end());
756 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c2") != cats.end());
757 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c3") != cats.end());
758 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c4") != cats.end());
759
760 const std::vector<std::string> empty_categories;
761 std::vector<std::string> included_categories;
762 std::vector<std::string> excluded_categories;
763
764 // Test that category filtering works.
765
766 // Include nonexistent category -> no events
767 Clear();
768 included_categories.clear();
769 included_categories.push_back("not_found823564786");
770 TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories);
771 TRACE_EVENT_INSTANT0("cat1", "name");
772 TRACE_EVENT_INSTANT0("cat2", "name");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900773 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900774 EXPECT_TRUE(trace_parsed_.empty());
775
776 // Include existent category -> only events of that category
777 Clear();
778 included_categories.clear();
779 included_categories.push_back("inc");
780 TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories);
781 TRACE_EVENT_INSTANT0("inc", "name");
782 TRACE_EVENT_INSTANT0("inc2", "name");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900783 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900784 EXPECT_TRUE(FindMatchingValue("cat", "inc"));
785 EXPECT_FALSE(FindNonMatchingValue("cat", "inc"));
786
787 // Include existent wildcard -> all categories matching wildcard
788 Clear();
789 included_categories.clear();
790 included_categories.push_back("inc_wildcard_*");
791 included_categories.push_back("inc_wildchar_?_end");
792 TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories);
793 TRACE_EVENT_INSTANT0("inc_wildcard_abc", "included");
794 TRACE_EVENT_INSTANT0("inc_wildcard_", "included");
795 TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "included");
796 TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "not_inc");
797 TRACE_EVENT_INSTANT0("cat1", "not_inc");
798 TRACE_EVENT_INSTANT0("cat2", "not_inc");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900799 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900800 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_abc"));
801 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_"));
802 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildchar_x_end"));
803 EXPECT_FALSE(FindMatchingValue("name", "not_inc"));
804
805 included_categories.clear();
806
807 // Exclude nonexistent category -> all events
808 Clear();
809 excluded_categories.clear();
810 excluded_categories.push_back("not_found823564786");
811 TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories);
812 TRACE_EVENT_INSTANT0("cat1", "name");
813 TRACE_EVENT_INSTANT0("cat2", "name");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900814 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900815 EXPECT_TRUE(FindMatchingValue("cat", "cat1"));
816 EXPECT_TRUE(FindMatchingValue("cat", "cat2"));
817
818 // Exclude existent category -> only events of other categories
819 Clear();
820 excluded_categories.clear();
821 excluded_categories.push_back("inc");
822 TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories);
823 TRACE_EVENT_INSTANT0("inc", "name");
824 TRACE_EVENT_INSTANT0("inc2", "name");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900825 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900826 EXPECT_TRUE(FindMatchingValue("cat", "inc2"));
827 EXPECT_FALSE(FindMatchingValue("cat", "inc"));
828
829 // Exclude existent wildcard -> all categories not matching wildcard
830 Clear();
831 excluded_categories.clear();
832 excluded_categories.push_back("inc_wildcard_*");
833 excluded_categories.push_back("inc_wildchar_?_end");
834 TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories);
835 TRACE_EVENT_INSTANT0("inc_wildcard_abc", "not_inc");
836 TRACE_EVENT_INSTANT0("inc_wildcard_", "not_inc");
837 TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "not_inc");
838 TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "included");
839 TRACE_EVENT_INSTANT0("cat1", "included");
840 TRACE_EVENT_INSTANT0("cat2", "included");
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900841 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900842 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildchar_bla_end"));
843 EXPECT_TRUE(FindMatchingValue("cat", "cat1"));
844 EXPECT_TRUE(FindMatchingValue("cat", "cat2"));
845 EXPECT_FALSE(FindMatchingValue("name", "not_inc"));
846}
847
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900848
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900849// Test EVENT_WATCH_NOTIFICATION
850TEST_F(TraceEventTestFixture, EventWatchNotification) {
851 ManualTestSetUp();
852
853 // Basic one occurrence.
854 BeginTrace();
855 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
856 TRACE_EVENT_INSTANT0("cat", "event");
857 EndTraceAndFlush();
858 EXPECT_EQ(event_watch_notification_, 1);
859
860 // Basic one occurrence before Set.
861 BeginTrace();
862 TRACE_EVENT_INSTANT0("cat", "event");
863 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
864 EndTraceAndFlush();
865 EXPECT_EQ(event_watch_notification_, 1);
866
867 // Auto-reset after end trace.
868 BeginTrace();
869 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
870 EndTraceAndFlush();
871 BeginTrace();
872 TRACE_EVENT_INSTANT0("cat", "event");
873 EndTraceAndFlush();
874 EXPECT_EQ(event_watch_notification_, 0);
875
876 // Multiple occurrence.
877 BeginTrace();
878 int num_occurrences = 5;
879 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
880 for (int i = 0; i < num_occurrences; ++i)
881 TRACE_EVENT_INSTANT0("cat", "event");
882 EndTraceAndFlush();
883 EXPECT_EQ(event_watch_notification_, num_occurrences);
884
885 // Wrong category.
886 BeginTrace();
887 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
888 TRACE_EVENT_INSTANT0("wrong_cat", "event");
889 EndTraceAndFlush();
890 EXPECT_EQ(event_watch_notification_, 0);
891
892 // Wrong name.
893 BeginTrace();
894 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
895 TRACE_EVENT_INSTANT0("cat", "wrong_event");
896 EndTraceAndFlush();
897 EXPECT_EQ(event_watch_notification_, 0);
898
899 // Canceled.
900 BeginTrace();
901 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
902 TraceLog::GetInstance()->CancelWatchEvent();
903 TRACE_EVENT_INSTANT0("cat", "event");
904 EndTraceAndFlush();
905 EXPECT_EQ(event_watch_notification_, 0);
906}
907
jbates@chromium.org88295f92012-03-01 12:04:59 +0900908// Test ASYNC_BEGIN/END events
909TEST_F(TraceEventTestFixture, AsyncBeginEndEvents) {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900910 ManualTestSetUp();
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900911 BeginTrace();
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900912
913 unsigned long long id = 0xfeedbeeffeedbeefull;
jbates@chromium.org88295f92012-03-01 12:04:59 +0900914 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name1", id);
jbates@chromium.orgbd9d20a2012-09-11 14:56:05 +0900915 TRACE_EVENT_ASYNC_STEP0( "cat", "name1", id, "step1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900916 TRACE_EVENT_ASYNC_END0("cat", "name1", id);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900917 TRACE_EVENT_BEGIN0( "cat", "name2");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900918 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name3", 0);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900919
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900920 EndTraceAndFlush();
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900921
922 EXPECT_TRUE(FindNamePhase("name1", "S"));
jbates@chromium.org88295f92012-03-01 12:04:59 +0900923 EXPECT_TRUE(FindNamePhase("name1", "T"));
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900924 EXPECT_TRUE(FindNamePhase("name1", "F"));
925
926 std::string id_str;
927 StringAppendF(&id_str, "%llx", id);
928
929 EXPECT_TRUE(FindNamePhaseKeyValue("name1", "S", "id", id_str.c_str()));
jbates@chromium.org88295f92012-03-01 12:04:59 +0900930 EXPECT_TRUE(FindNamePhaseKeyValue("name1", "T", "id", id_str.c_str()));
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900931 EXPECT_TRUE(FindNamePhaseKeyValue("name1", "F", "id", id_str.c_str()));
932 EXPECT_TRUE(FindNamePhaseKeyValue("name3", "S", "id", "0"));
933
934 // BEGIN events should not have id
935 EXPECT_FALSE(FindNamePhaseKeyValue("name2", "B", "id", "0"));
936}
937
jbates@chromium.org88295f92012-03-01 12:04:59 +0900938// Test ASYNC_BEGIN/END events
939TEST_F(TraceEventTestFixture, AsyncBeginEndPointerMangling) {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900940 ManualTestSetUp();
941
942 void* ptr = this;
943
944 TraceLog::GetInstance()->SetProcessID(100);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900945 BeginTrace();
jbates@chromium.org88295f92012-03-01 12:04:59 +0900946 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name1", ptr);
947 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name2", ptr);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900948 EndTraceAndFlush();
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900949
950 TraceLog::GetInstance()->SetProcessID(200);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900951 BeginTrace();
jbates@chromium.org88295f92012-03-01 12:04:59 +0900952 TRACE_EVENT_ASYNC_END0( "cat", "name1", ptr);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900953 EndTraceAndFlush();
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900954
jbates@chromium.org88295f92012-03-01 12:04:59 +0900955 DictionaryValue* async_begin = FindNamePhase("name1", "S");
956 DictionaryValue* async_begin2 = FindNamePhase("name2", "S");
957 DictionaryValue* async_end = FindNamePhase("name1", "F");
958 EXPECT_TRUE(async_begin);
959 EXPECT_TRUE(async_begin2);
960 EXPECT_TRUE(async_end);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900961
962 Value* value = NULL;
jbates@chromium.org88295f92012-03-01 12:04:59 +0900963 std::string async_begin_id_str;
964 std::string async_begin2_id_str;
965 std::string async_end_id_str;
966 ASSERT_TRUE(async_begin->Get("id", &value));
967 ASSERT_TRUE(value->GetAsString(&async_begin_id_str));
968 ASSERT_TRUE(async_begin2->Get("id", &value));
969 ASSERT_TRUE(value->GetAsString(&async_begin2_id_str));
970 ASSERT_TRUE(async_end->Get("id", &value));
971 ASSERT_TRUE(value->GetAsString(&async_end_id_str));
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900972
jbates@chromium.org88295f92012-03-01 12:04:59 +0900973 EXPECT_STREQ(async_begin_id_str.c_str(), async_begin2_id_str.c_str());
974 EXPECT_STRNE(async_begin_id_str.c_str(), async_end_id_str.c_str());
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900975}
976
jbates@chromium.org1f18e462011-09-07 02:56:24 +0900977// Test that static strings are not copied.
978TEST_F(TraceEventTestFixture, StaticStringVsString) {
979 ManualTestSetUp();
980 TraceLog* tracer = TraceLog::GetInstance();
981 // Make sure old events are flushed:
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900982 EndTraceAndFlush();
jbates@chromium.org1f18e462011-09-07 02:56:24 +0900983 EXPECT_EQ(0u, tracer->GetEventsSize());
984
985 {
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900986 BeginTrace();
jbates@chromium.org1f18e462011-09-07 02:56:24 +0900987 // Test that string arguments are copied.
988 TRACE_EVENT2("cat", "name1",
989 "arg1", std::string("argval"), "arg2", std::string("argval"));
990 // Test that static TRACE_STR_COPY string arguments are copied.
991 TRACE_EVENT2("cat", "name2",
992 "arg1", TRACE_STR_COPY("argval"),
993 "arg2", TRACE_STR_COPY("argval"));
994 size_t num_events = tracer->GetEventsSize();
995 EXPECT_GT(num_events, 1u);
996 const TraceEvent& event1 = tracer->GetEventAt(num_events - 2);
997 const TraceEvent& event2 = tracer->GetEventAt(num_events - 1);
998 EXPECT_STREQ("name1", event1.name());
999 EXPECT_STREQ("name2", event2.name());
1000 EXPECT_TRUE(event1.parameter_copy_storage() != NULL);
1001 EXPECT_TRUE(event2.parameter_copy_storage() != NULL);
1002 EXPECT_GT(event1.parameter_copy_storage()->size(), 0u);
1003 EXPECT_GT(event2.parameter_copy_storage()->size(), 0u);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001004 EndTraceAndFlush();
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001005 }
1006
1007 {
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001008 BeginTrace();
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001009 // Test that static literal string arguments are not copied.
1010 TRACE_EVENT2("cat", "name1",
1011 "arg1", "argval", "arg2", "argval");
1012 // Test that static TRACE_STR_COPY NULL string arguments are not copied.
1013 const char* str1 = NULL;
1014 const char* str2 = NULL;
1015 TRACE_EVENT2("cat", "name2",
1016 "arg1", TRACE_STR_COPY(str1),
1017 "arg2", TRACE_STR_COPY(str2));
1018 size_t num_events = tracer->GetEventsSize();
1019 EXPECT_GT(num_events, 1u);
1020 const TraceEvent& event1 = tracer->GetEventAt(num_events - 2);
1021 const TraceEvent& event2 = tracer->GetEventAt(num_events - 1);
1022 EXPECT_STREQ("name1", event1.name());
1023 EXPECT_STREQ("name2", event2.name());
1024 EXPECT_TRUE(event1.parameter_copy_storage() == NULL);
1025 EXPECT_TRUE(event2.parameter_copy_storage() == NULL);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001026 EndTraceAndFlush();
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001027 }
1028}
1029
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001030// Test that data sent from other threads is gathered
1031TEST_F(TraceEventTestFixture, DataCapturedOnThread) {
1032 ManualTestSetUp();
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001033 BeginTrace();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001034
1035 Thread thread("1");
1036 WaitableEvent task_complete_event(false, false);
1037 thread.Start();
1038
1039 thread.message_loop()->PostTask(
jbates@chromium.org0b837e42011-10-06 01:58:20 +09001040 FROM_HERE, base::Bind(&TraceWithAllMacroVariants, &task_complete_event));
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001041 task_complete_event.Wait();
jbates@chromium.orgb84db522011-10-04 02:51:25 +09001042 thread.Stop();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001043
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001044 EndTraceAndFlush();
jbates@chromium.org6a092d72011-10-25 01:34:08 +09001045 ValidateAllTraceMacrosCreatedData(trace_parsed_);
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001046}
1047
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001048// Test that data sent from multiple threads is gathered
1049TEST_F(TraceEventTestFixture, DataCapturedManyThreads) {
1050 ManualTestSetUp();
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001051 BeginTrace();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001052
1053 const int num_threads = 4;
1054 const int num_events = 4000;
1055 Thread* threads[num_threads];
1056 WaitableEvent* task_complete_events[num_threads];
1057 for (int i = 0; i < num_threads; i++) {
1058 threads[i] = new Thread(StringPrintf("Thread %d", i).c_str());
1059 task_complete_events[i] = new WaitableEvent(false, false);
1060 threads[i]->Start();
1061 threads[i]->message_loop()->PostTask(
jbates@chromium.org0b837e42011-10-06 01:58:20 +09001062 FROM_HERE, base::Bind(&TraceManyInstantEvents,
1063 i, num_events, task_complete_events[i]));
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001064 }
1065
1066 for (int i = 0; i < num_threads; i++) {
1067 task_complete_events[i]->Wait();
1068 }
1069
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001070 for (int i = 0; i < num_threads; i++) {
1071 threads[i]->Stop();
1072 delete threads[i];
1073 delete task_complete_events[i];
1074 }
1075
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001076 EndTraceAndFlush();
jbates@chromium.orgb84db522011-10-04 02:51:25 +09001077
jbates@chromium.org6a092d72011-10-25 01:34:08 +09001078 ValidateInstantEventPresentOnEveryThread(trace_parsed_,
nduca@chromium.org6d048772011-08-10 00:16:25 +09001079 num_threads, num_events);
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001080}
1081
nduca@chromium.org6d048772011-08-10 00:16:25 +09001082// Test that thread and process names show up in the trace
1083TEST_F(TraceEventTestFixture, ThreadNames) {
1084 ManualTestSetUp();
1085
1086 // Create threads before we enable tracing to make sure
1087 // that tracelog still captures them.
1088 const int num_threads = 4;
1089 const int num_events = 10;
1090 Thread* threads[num_threads];
1091 PlatformThreadId thread_ids[num_threads];
1092 for (int i = 0; i < num_threads; i++)
1093 threads[i] = new Thread(StringPrintf("Thread %d", i).c_str());
1094
1095 // Enable tracing.
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001096 BeginTrace();
nduca@chromium.org6d048772011-08-10 00:16:25 +09001097
1098 // Now run some trace code on these threads.
1099 WaitableEvent* task_complete_events[num_threads];
1100 for (int i = 0; i < num_threads; i++) {
1101 task_complete_events[i] = new WaitableEvent(false, false);
1102 threads[i]->Start();
1103 thread_ids[i] = threads[i]->thread_id();
1104 threads[i]->message_loop()->PostTask(
jbates@chromium.org0b837e42011-10-06 01:58:20 +09001105 FROM_HERE, base::Bind(&TraceManyInstantEvents,
1106 i, num_events, task_complete_events[i]));
nduca@chromium.org6d048772011-08-10 00:16:25 +09001107 }
1108 for (int i = 0; i < num_threads; i++) {
1109 task_complete_events[i]->Wait();
1110 }
1111
1112 // Shut things down.
nduca@chromium.org6d048772011-08-10 00:16:25 +09001113 for (int i = 0; i < num_threads; i++) {
1114 threads[i]->Stop();
1115 delete threads[i];
1116 delete task_complete_events[i];
1117 }
1118
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001119 EndTraceAndFlush();
jbates@chromium.orgb84db522011-10-04 02:51:25 +09001120
nduca@chromium.org6d048772011-08-10 00:16:25 +09001121 std::string tmp;
1122 int tmp_int;
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001123 const DictionaryValue* item;
nduca@chromium.org6d048772011-08-10 00:16:25 +09001124
1125 // Make sure we get thread name metadata.
1126 // Note, the test suite may have created a ton of threads.
1127 // So, we'll have thread names for threads we didn't create.
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001128 std::vector<const DictionaryValue*> items =
nduca@chromium.org6d048772011-08-10 00:16:25 +09001129 FindTraceEntries(trace_parsed_, "thread_name");
1130 for (int i = 0; i < static_cast<int>(items.size()); i++) {
1131 item = items[i];
joth@chromium.org088ae012011-11-11 01:26:23 +09001132 ASSERT_TRUE(item);
nduca@chromium.org6d048772011-08-10 00:16:25 +09001133 EXPECT_TRUE(item->GetInteger("tid", &tmp_int));
1134
1135 // See if this thread name is one of the threads we just created
1136 for (int j = 0; j < num_threads; j++) {
1137 if(static_cast<int>(thread_ids[j]) != tmp_int)
1138 continue;
1139
jbates@chromium.org62a16662012-02-04 08:18:06 +09001140 std::string expected_name = StringPrintf("Thread %d", j);
nduca@chromium.org6d048772011-08-10 00:16:25 +09001141 EXPECT_TRUE(item->GetString("ph", &tmp) && tmp == "M");
1142 EXPECT_TRUE(item->GetInteger("pid", &tmp_int) &&
1143 tmp_int == static_cast<int>(base::GetCurrentProcId()));
jbates@chromium.org62a16662012-02-04 08:18:06 +09001144 // If the thread name changes or the tid gets reused, the name will be
1145 // a comma-separated list of thread names, so look for a substring.
nduca@chromium.org6d048772011-08-10 00:16:25 +09001146 EXPECT_TRUE(item->GetString("args.name", &tmp) &&
jbates@chromium.org62a16662012-02-04 08:18:06 +09001147 tmp.find(expected_name) != std::string::npos);
nduca@chromium.org6d048772011-08-10 00:16:25 +09001148 }
1149 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001150}
1151
joth@chromium.org088ae012011-11-11 01:26:23 +09001152TEST_F(TraceEventTestFixture, ThreadNameChanges) {
1153 ManualTestSetUp();
1154
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001155 BeginTrace();
joth@chromium.org088ae012011-11-11 01:26:23 +09001156
1157 PlatformThread::SetName("");
1158 TRACE_EVENT_INSTANT0("drink", "water");
1159
1160 PlatformThread::SetName("cafe");
1161 TRACE_EVENT_INSTANT0("drink", "coffee");
1162
1163 PlatformThread::SetName("shop");
1164 // No event here, so won't appear in combined name.
1165
1166 PlatformThread::SetName("pub");
1167 TRACE_EVENT_INSTANT0("drink", "beer");
1168 TRACE_EVENT_INSTANT0("drink", "wine");
1169
1170 PlatformThread::SetName(" bar");
1171 TRACE_EVENT_INSTANT0("drink", "whisky");
1172
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001173 EndTraceAndFlush();
joth@chromium.org088ae012011-11-11 01:26:23 +09001174
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001175 std::vector<const DictionaryValue*> items =
joth@chromium.org088ae012011-11-11 01:26:23 +09001176 FindTraceEntries(trace_parsed_, "thread_name");
1177 EXPECT_EQ(1u, items.size());
1178 ASSERT_GT(items.size(), 0u);
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001179 const DictionaryValue* item = items[0];
joth@chromium.org088ae012011-11-11 01:26:23 +09001180 ASSERT_TRUE(item);
1181 int tid;
1182 EXPECT_TRUE(item->GetInteger("tid", &tid));
1183 EXPECT_EQ(PlatformThread::CurrentId(), static_cast<PlatformThreadId>(tid));
1184
1185 std::string expected_name = "cafe,pub, bar";
1186 std::string tmp;
1187 EXPECT_TRUE(item->GetString("args.name", &tmp));
1188 EXPECT_EQ(expected_name, tmp);
1189}
nduca@chromium.org6d048772011-08-10 00:16:25 +09001190
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001191// Test trace calls made after tracing singleton shut down.
1192//
1193// The singleton is destroyed by our base::AtExitManager, but there can be
1194// code still executing as the C++ static objects are destroyed. This test
1195// forces the singleton to destroy early, and intentinally makes trace calls
1196// afterwards.
1197TEST_F(TraceEventTestFixture, AtExit) {
1198 // Repeat this test a few times. Besides just showing robustness, it also
1199 // allows us to test that events at shutdown do not appear with valid events
1200 // recorded after the system is started again.
1201 for (int i = 0; i < 4; i++) {
1202 // Scope to contain the then destroy the TraceLog singleton.
1203 {
1204 base::ShadowingAtExitManager exit_manager_will_destroy_singletons;
1205
1206 // Setup TraceLog singleton inside this test's exit manager scope
1207 // so that it will be destroyed when this scope closes.
1208 ManualTestSetUp();
1209
1210 TRACE_EVENT_INSTANT0("all", "not recorded; system not enabled");
1211
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001212 BeginTrace();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001213
1214 TRACE_EVENT_INSTANT0("all", "is recorded 1; system has been enabled");
1215 // Trace calls that will cache pointers to categories; they're valid here
1216 TraceCallsWithCachedCategoryPointersPointers(
1217 "is recorded 2; system has been enabled");
1218
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001219 EndTraceAndFlush();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001220 } // scope to destroy singleton
1221 ASSERT_FALSE(TraceLog::GetInstance());
1222
1223 // Now that singleton is destroyed, check what trace events were recorded
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001224 const DictionaryValue* item = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001225 ListValue& trace_parsed = trace_parsed_;
1226 EXPECT_FIND_("is recorded 1");
1227 EXPECT_FIND_("is recorded 2");
1228 EXPECT_NOT_FIND_("not recorded");
1229
1230 // Make additional trace event calls on the shutdown system. They should
1231 // all pass cleanly, but the data not be recorded. We'll verify that next
1232 // time around the loop (the only way to flush the trace buffers).
1233 TRACE_EVENT_BEGIN_ETW("not recorded; system shutdown", 0, NULL);
1234 TRACE_EVENT_END_ETW("not recorded; system shutdown", 0, NULL);
1235 TRACE_EVENT_INSTANT_ETW("not recorded; system shutdown", 0, NULL);
1236 TRACE_EVENT0("all", "not recorded; system shutdown");
1237 TRACE_EVENT_INSTANT0("all", "not recorded; system shutdown");
1238 TRACE_EVENT_BEGIN0("all", "not recorded; system shutdown");
1239 TRACE_EVENT_END0("all", "not recorded; system shutdown");
1240
1241 TRACE_EVENT0("new category 0!", "not recorded; system shutdown");
1242 TRACE_EVENT_INSTANT0("new category 1!", "not recorded; system shutdown");
1243 TRACE_EVENT_BEGIN0("new category 2!", "not recorded; system shutdown");
1244 TRACE_EVENT_END0("new category 3!", "not recorded; system shutdown");
1245
1246 // Cached categories should be safe to check, and still disable traces
1247 TraceCallsWithCachedCategoryPointersPointers(
1248 "not recorded; system shutdown");
1249 }
1250}
1251
joth@chromium.org113de992011-07-21 21:28:59 +09001252TEST_F(TraceEventTestFixture, NormallyNoDeepCopy) {
1253 // Test that the TRACE_EVENT macros do not deep-copy their string. If they
1254 // do so it may indicate a performance regression, but more-over it would
1255 // make the DEEP_COPY overloads redundant.
1256 ManualTestSetUp();
1257
1258 std::string name_string("event name");
1259
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001260 BeginTrace();
joth@chromium.org113de992011-07-21 21:28:59 +09001261 TRACE_EVENT_INSTANT0("category", name_string.c_str());
1262
1263 // Modify the string in place (a wholesale reassignment may leave the old
1264 // string intact on the heap).
1265 name_string[0] = '@';
1266
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001267 EndTraceAndFlush();
joth@chromium.org113de992011-07-21 21:28:59 +09001268
1269 EXPECT_FALSE(FindTraceEntry(trace_parsed_, "event name"));
1270 EXPECT_TRUE(FindTraceEntry(trace_parsed_, name_string.c_str()));
1271}
1272
1273TEST_F(TraceEventTestFixture, DeepCopy) {
1274 ManualTestSetUp();
1275
1276 static const char kOriginalName1[] = "name1";
1277 static const char kOriginalName2[] = "name2";
1278 static const char kOriginalName3[] = "name3";
1279 std::string name1(kOriginalName1);
1280 std::string name2(kOriginalName2);
1281 std::string name3(kOriginalName3);
1282 std::string arg1("arg1");
1283 std::string arg2("arg2");
1284 std::string val1("val1");
1285 std::string val2("val2");
1286
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001287 BeginTrace();
joth@chromium.org113de992011-07-21 21:28:59 +09001288 TRACE_EVENT_COPY_INSTANT0("category", name1.c_str());
1289 TRACE_EVENT_COPY_BEGIN1("category", name2.c_str(),
1290 arg1.c_str(), 5);
1291 TRACE_EVENT_COPY_END2("category", name3.c_str(),
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001292 arg1.c_str(), val1,
1293 arg2.c_str(), val2);
joth@chromium.org113de992011-07-21 21:28:59 +09001294
1295 // As per NormallyNoDeepCopy, modify the strings in place.
1296 name1[0] = name2[0] = name3[0] = arg1[0] = arg2[0] = val1[0] = val2[0] = '@';
1297
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001298 EndTraceAndFlush();
joth@chromium.org113de992011-07-21 21:28:59 +09001299
1300 EXPECT_FALSE(FindTraceEntry(trace_parsed_, name1.c_str()));
1301 EXPECT_FALSE(FindTraceEntry(trace_parsed_, name2.c_str()));
1302 EXPECT_FALSE(FindTraceEntry(trace_parsed_, name3.c_str()));
1303
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001304 const DictionaryValue* entry1 = FindTraceEntry(trace_parsed_, kOriginalName1);
1305 const DictionaryValue* entry2 = FindTraceEntry(trace_parsed_, kOriginalName2);
1306 const DictionaryValue* entry3 = FindTraceEntry(trace_parsed_, kOriginalName3);
joth@chromium.org113de992011-07-21 21:28:59 +09001307 ASSERT_TRUE(entry1);
1308 ASSERT_TRUE(entry2);
1309 ASSERT_TRUE(entry3);
1310
1311 int i;
1312 EXPECT_FALSE(entry2->GetInteger("args.@rg1", &i));
1313 EXPECT_TRUE(entry2->GetInteger("args.arg1", &i));
1314 EXPECT_EQ(5, i);
1315
1316 std::string s;
1317 EXPECT_TRUE(entry3->GetString("args.arg1", &s));
1318 EXPECT_EQ("val1", s);
1319 EXPECT_TRUE(entry3->GetString("args.arg2", &s));
1320 EXPECT_EQ("val2", s);
1321}
1322
jbates@chromium.org6a092d72011-10-25 01:34:08 +09001323// Test that TraceResultBuffer outputs the correct result whether it is added
1324// in chunks or added all at once.
1325TEST_F(TraceEventTestFixture, TraceResultBuffer) {
1326 ManualTestSetUp();
1327
1328 Clear();
1329
1330 trace_buffer_.Start();
1331 trace_buffer_.AddFragment("bla1");
1332 trace_buffer_.AddFragment("bla2");
1333 trace_buffer_.AddFragment("bla3,bla4");
1334 trace_buffer_.Finish();
1335 EXPECT_STREQ(json_output_.json_output.c_str(), "[bla1,bla2,bla3,bla4]");
1336
1337 Clear();
1338
1339 trace_buffer_.Start();
1340 trace_buffer_.AddFragment("bla1,bla2,bla3,bla4");
1341 trace_buffer_.Finish();
1342 EXPECT_STREQ(json_output_.json_output.c_str(), "[bla1,bla2,bla3,bla4]");
1343}
1344
dsinclair@chromium.org1cde1592013-01-15 01:53:06 +09001345// Test that trace_event parameters are not evaluated if the tracing
1346// system is disabled.
1347TEST_F(TraceEventTestFixture, TracingIsLazy) {
1348 ManualTestSetUp();
1349 BeginTrace();
1350
1351 int a = 0;
1352 TRACE_EVENT_INSTANT1("category", "test", "a", a++);
1353 EXPECT_EQ(1, a);
1354
1355 TraceLog::GetInstance()->SetDisabled();
1356
1357 TRACE_EVENT_INSTANT1("category", "test", "a", a++);
1358 EXPECT_EQ(1, a);
1359
1360 EndTraceAndFlush();
1361}
1362
caseq@google.comedcf6262013-01-16 20:41:57 +09001363TEST_F(TraceEventTestFixture, TraceEnableDisable) {
1364 ManualTestSetUp();
1365
1366 TraceLog* trace_log = TraceLog::GetInstance();
1367 trace_log->SetEnabled(std::string());
1368 EXPECT_TRUE(trace_log->IsEnabled());
1369 trace_log->SetDisabled();
1370 EXPECT_FALSE(trace_log->IsEnabled());
1371
1372 trace_log->SetEnabled(true);
1373 EXPECT_TRUE(trace_log->IsEnabled());
1374 const std::vector<std::string> empty;
1375 trace_log->SetEnabled(empty, empty);
1376 EXPECT_TRUE(trace_log->IsEnabled());
1377 trace_log->SetEnabled(false);
1378 EXPECT_TRUE(trace_log->IsEnabled());
1379 trace_log->SetDisabled();
1380 EXPECT_FALSE(trace_log->IsEnabled());
1381}
1382
1383TEST_F(TraceEventTestFixture, TraceCategoriesAfterNestedEnable) {
1384 ManualTestSetUp();
1385
1386 TraceLog* trace_log = TraceLog::GetInstance();
1387 trace_log->SetEnabled(std::string("foo,bar"));
1388 EXPECT_TRUE(*trace_log->GetCategoryEnabled("foo"));
1389 EXPECT_TRUE(*trace_log->GetCategoryEnabled("bar"));
1390 EXPECT_FALSE(*trace_log->GetCategoryEnabled("baz"));
1391 trace_log->SetEnabled(std::string("foo2"));
1392 EXPECT_TRUE(*trace_log->GetCategoryEnabled("foo2"));
1393 EXPECT_FALSE(*trace_log->GetCategoryEnabled("baz"));
1394 trace_log->SetEnabled(std::string(""));
1395 EXPECT_TRUE(*trace_log->GetCategoryEnabled("foo"));
1396 EXPECT_TRUE(*trace_log->GetCategoryEnabled("baz"));
1397 trace_log->SetDisabled();
1398 trace_log->SetDisabled();
1399 trace_log->SetDisabled();
1400 EXPECT_FALSE(*trace_log->GetCategoryEnabled("foo"));
1401 EXPECT_FALSE(*trace_log->GetCategoryEnabled("baz"));
1402
1403 trace_log->SetEnabled(std::string("-foo,-bar"));
1404 EXPECT_FALSE(*trace_log->GetCategoryEnabled("foo"));
1405 EXPECT_TRUE(*trace_log->GetCategoryEnabled("baz"));
1406 trace_log->SetEnabled(std::string("moo"));
1407 EXPECT_TRUE(*trace_log->GetCategoryEnabled("baz"));
1408 EXPECT_TRUE(*trace_log->GetCategoryEnabled("moo"));
1409 EXPECT_TRUE(*trace_log->GetCategoryEnabled("foo"));
1410 trace_log->SetDisabled();
1411 trace_log->SetDisabled();
1412}
1413
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001414} // namespace debug
1415} // namespace base