blob: a78b002066eb0ffb17b17a91d81ce00a037e9b34 [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
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +09007#include <cstdlib>
8
scheib@chromium.org603f46e2011-05-10 11:23:58 +09009#include "base/bind.h"
10#include "base/command_line.h"
jbates@chromium.org5e2f67d2012-08-16 13:32:49 +090011#include "base/debug/trace_event.h"
scheib@chromium.org603f46e2011-05-10 11:23:58 +090012#include "base/json/json_reader.h"
13#include "base/json/json_writer.h"
jbates@chromium.org1f18e462011-09-07 02:56:24 +090014#include "base/memory/ref_counted_memory.h"
scheib@chromium.org603f46e2011-05-10 11:23:58 +090015#include "base/memory/scoped_ptr.h"
joth@chromium.org088ae012011-11-11 01:26:23 +090016#include "base/memory/singleton.h"
nduca@chromium.org6d048772011-08-10 00:16:25 +090017#include "base/process_util.h"
scheib@chromium.org603f46e2011-05-10 11:23:58 +090018#include "base/stringprintf.h"
19#include "base/synchronization/waitable_event.h"
joth@chromium.org088ae012011-11-11 01:26:23 +090020#include "base/threading/platform_thread.h"
scheib@chromium.org603f46e2011-05-10 11:23:58 +090021#include "base/threading/thread.h"
22#include "base/values.h"
23#include "testing/gmock/include/gmock/gmock.h"
24#include "testing/gtest/include/gtest/gtest.h"
25
jbates@chromium.org5e2f67d2012-08-16 13:32:49 +090026using base::debug::HighResSleepForTraceTest;
27
scheib@chromium.org603f46e2011-05-10 11:23:58 +090028namespace base {
29namespace debug {
30
31namespace {
32
jbates@chromium.org11d4c362011-09-13 07:03:41 +090033enum CompareOp {
34 IS_EQUAL,
35 IS_NOT_EQUAL,
36};
37
jbates@chromium.orgb3cab862011-05-14 08:30:35 +090038struct JsonKeyValue {
39 const char* key;
40 const char* value;
jbates@chromium.org11d4c362011-09-13 07:03:41 +090041 CompareOp op;
jbates@chromium.orgb3cab862011-05-14 08:30:35 +090042};
43
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +090044static int kThreadId = 42;
45static int kAsyncId = 5;
46static const char kAsyncIdStr[] = "5";
47
scheib@chromium.org603f46e2011-05-10 11:23:58 +090048class TraceEventTestFixture : public testing::Test {
49 public:
joth@chromium.org113de992011-07-21 21:28:59 +090050 // This fixture does not use SetUp() because the fixture must be manually set
51 // up multiple times when testing AtExit. Use ManualTestSetUp for this.
scheib@chromium.org603f46e2011-05-10 11:23:58 +090052 void ManualTestSetUp();
ajwong@chromium.orgec1750a2011-06-27 01:22:50 +090053 void OnTraceDataCollected(
husky@chromium.org3b366292012-02-24 13:17:06 +090054 const scoped_refptr<base::RefCountedString>& events_str);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +090055 void OnTraceNotification(int notification) {
56 if (notification & TraceLog::EVENT_WATCH_NOTIFICATION)
57 ++event_watch_notification_;
caseq@google.com4cba9892013-04-29 18:08:28 +090058 notifications_received_ |= notification;
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +090059 }
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +090060 DictionaryValue* FindMatchingTraceEntry(const JsonKeyValue* key_values);
61 DictionaryValue* FindNamePhase(const char* name, const char* phase);
62 DictionaryValue* FindNamePhaseKeyValue(const char* name,
63 const char* phase,
64 const char* key,
65 const char* value);
jbates@chromium.org11d4c362011-09-13 07:03:41 +090066 bool FindMatchingValue(const char* key,
67 const char* value);
68 bool FindNonMatchingValue(const char* key,
69 const char* value);
70 void Clear() {
jbates@chromium.org11d4c362011-09-13 07:03:41 +090071 trace_parsed_.Clear();
jbates@chromium.org6a092d72011-10-25 01:34:08 +090072 json_output_.json_output.clear();
jbates@chromium.org11d4c362011-09-13 07:03:41 +090073 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +090074
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +090075 void BeginTrace() {
76 event_watch_notification_ = 0;
caseq@google.com4cba9892013-04-29 18:08:28 +090077 notifications_received_ = 0;
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +090078 TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
dsinclair@chromium.orga7fb8d62013-02-23 11:09:53 +090079 TraceLog::RECORD_UNTIL_FULL);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +090080 }
81
82 void EndTraceAndFlush() {
caseq@google.comedcf6262013-01-16 20:41:57 +090083 while (TraceLog::GetInstance()->IsEnabled())
84 TraceLog::GetInstance()->SetDisabled();
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +090085 TraceLog::GetInstance()->Flush(
86 base::Bind(&TraceEventTestFixture::OnTraceDataCollected,
87 base::Unretained(this)));
88 }
89
rsleevi@chromium.orgde3a6cf2012-04-06 12:53:02 +090090 virtual void SetUp() OVERRIDE {
dsinclair@chromium.org38608f82013-01-26 05:41:19 +090091 const char* name = PlatformThread::GetName();
92 old_thread_name_ = name ? strdup(name) : NULL;
joth@chromium.org088ae012011-11-11 01:26:23 +090093 }
rsleevi@chromium.orgde3a6cf2012-04-06 12:53:02 +090094 virtual void TearDown() OVERRIDE {
nduca@chromium.org6a7360c2012-02-20 15:35:15 +090095 if (TraceLog::GetInstance())
96 EXPECT_FALSE(TraceLog::GetInstance()->IsEnabled());
dsinclair@chromium.org38608f82013-01-26 05:41:19 +090097 PlatformThread::SetName(old_thread_name_ ? old_thread_name_ : "");
98 free(old_thread_name_);
99 old_thread_name_ = NULL;
joth@chromium.org088ae012011-11-11 01:26:23 +0900100 }
101
dsinclair@chromium.org38608f82013-01-26 05:41:19 +0900102 char* old_thread_name_;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900103 ListValue trace_parsed_;
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900104 base::debug::TraceResultBuffer trace_buffer_;
105 base::debug::TraceResultBuffer::SimpleOutput json_output_;
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900106 int event_watch_notification_;
caseq@google.com4cba9892013-04-29 18:08:28 +0900107 int notifications_received_;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900108
109 private:
110 // We want our singleton torn down after each test.
111 ShadowingAtExitManager at_exit_manager_;
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900112 Lock lock_;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900113};
114
115void TraceEventTestFixture::ManualTestSetUp() {
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900116 TraceLog::DeleteForTesting();
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900117 TraceLog::Resurrect();
118 TraceLog* tracelog = TraceLog::GetInstance();
119 ASSERT_TRUE(tracelog);
120 ASSERT_FALSE(tracelog->IsEnabled());
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900121 tracelog->SetNotificationCallback(
122 base::Bind(&TraceEventTestFixture::OnTraceNotification,
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900123 base::Unretained(this)));
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900124 trace_buffer_.SetOutputCallback(json_output_.GetCallback());
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900125}
126
127void TraceEventTestFixture::OnTraceDataCollected(
husky@chromium.org3b366292012-02-24 13:17:06 +0900128 const scoped_refptr<base::RefCountedString>& events_str) {
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900129 AutoLock lock(lock_);
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900130 json_output_.json_output.clear();
131 trace_buffer_.Start();
husky@chromium.org3b366292012-02-24 13:17:06 +0900132 trace_buffer_.AddFragment(events_str->data());
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900133 trace_buffer_.Finish();
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900134
135 scoped_ptr<Value> root;
rsesek@chromium.orgc2d2b202012-05-17 00:23:30 +0900136 root.reset(base::JSONReader::Read(json_output_.json_output,
137 JSON_PARSE_RFC | JSON_DETACHABLE_CHILDREN));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900138
jbates@chromium.org59c27602012-01-13 12:12:44 +0900139 if (!root.get()) {
140 LOG(ERROR) << json_output_.json_output;
141 }
142
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900143 ListValue* root_list = NULL;
144 ASSERT_TRUE(root.get());
145 ASSERT_TRUE(root->GetAsList(&root_list));
146
147 // Move items into our aggregate collection
148 while (root_list->GetSize()) {
149 Value* item = NULL;
150 root_list->Remove(0, &item);
151 trace_parsed_.Append(item);
152 }
153}
154
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900155static bool CompareJsonValues(const std::string& lhs,
156 const std::string& rhs,
157 CompareOp op) {
158 switch (op) {
159 case IS_EQUAL:
160 return lhs == rhs;
161 case IS_NOT_EQUAL:
162 return lhs != rhs;
163 default:
164 CHECK(0);
165 }
166 return false;
167}
168
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900169static bool IsKeyValueInDict(const JsonKeyValue* key_value,
170 DictionaryValue* dict) {
171 Value* value = NULL;
172 std::string value_str;
173 if (dict->Get(key_value->key, &value) &&
174 value->GetAsString(&value_str) &&
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900175 CompareJsonValues(value_str, key_value->value, key_value->op))
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900176 return true;
177
178 // Recurse to test arguments
179 DictionaryValue* args_dict = NULL;
180 dict->GetDictionary("args", &args_dict);
181 if (args_dict)
182 return IsKeyValueInDict(key_value, args_dict);
183
184 return false;
185}
186
187static bool IsAllKeyValueInDict(const JsonKeyValue* key_values,
188 DictionaryValue* dict) {
189 // Scan all key_values, they must all be present and equal.
190 while (key_values && key_values->key) {
191 if (!IsKeyValueInDict(key_values, dict))
192 return false;
193 ++key_values;
194 }
195 return true;
196}
197
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900198DictionaryValue* TraceEventTestFixture::FindMatchingTraceEntry(
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900199 const JsonKeyValue* key_values) {
200 // Scan all items
201 size_t trace_parsed_count = trace_parsed_.GetSize();
202 for (size_t i = 0; i < trace_parsed_count; i++) {
203 Value* value = NULL;
204 trace_parsed_.Get(i, &value);
205 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
206 continue;
207 DictionaryValue* dict = static_cast<DictionaryValue*>(value);
208
209 if (IsAllKeyValueInDict(key_values, dict))
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900210 return dict;
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900211 }
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900212 return NULL;
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900213}
214
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900215DictionaryValue* TraceEventTestFixture::FindNamePhase(const char* name,
216 const char* phase) {
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900217 JsonKeyValue key_values[] = {
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900218 {"name", name, IS_EQUAL},
219 {"ph", phase, IS_EQUAL},
220 {0, 0, IS_EQUAL}
221 };
222 return FindMatchingTraceEntry(key_values);
223}
224
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900225DictionaryValue* TraceEventTestFixture::FindNamePhaseKeyValue(
226 const char* name,
227 const char* phase,
228 const char* key,
229 const char* value) {
230 JsonKeyValue key_values[] = {
231 {"name", name, IS_EQUAL},
232 {"ph", phase, IS_EQUAL},
233 {key, value, IS_EQUAL},
234 {0, 0, IS_EQUAL}
235 };
236 return FindMatchingTraceEntry(key_values);
237}
238
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900239bool TraceEventTestFixture::FindMatchingValue(const char* key,
240 const char* value) {
241 JsonKeyValue key_values[] = {
242 {key, value, IS_EQUAL},
243 {0, 0, IS_EQUAL}
244 };
245 return FindMatchingTraceEntry(key_values);
246}
247
248bool TraceEventTestFixture::FindNonMatchingValue(const char* key,
249 const char* value) {
250 JsonKeyValue key_values[] = {
251 {key, value, IS_NOT_EQUAL},
252 {0, 0, IS_EQUAL}
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900253 };
254 return FindMatchingTraceEntry(key_values);
255}
256
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900257bool IsStringInDict(const char* string_to_match, const DictionaryValue* dict) {
pneubeck@chromium.orga2fbefc2013-01-18 23:43:27 +0900258 for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
259 if (it.key().find(string_to_match) != std::string::npos)
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900260 return true;
261
262 std::string value_str;
pneubeck@chromium.orga2fbefc2013-01-18 23:43:27 +0900263 it.value().GetAsString(&value_str);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900264 if (value_str.find(string_to_match) != std::string::npos)
265 return true;
266 }
267
268 // Recurse to test arguments
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900269 const DictionaryValue* args_dict = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900270 dict->GetDictionary("args", &args_dict);
271 if (args_dict)
272 return IsStringInDict(string_to_match, args_dict);
273
274 return false;
275}
276
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900277const DictionaryValue* FindTraceEntry(
278 const ListValue& trace_parsed,
279 const char* string_to_match,
280 const DictionaryValue* match_after_this_item = NULL) {
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900281 // Scan all items
282 size_t trace_parsed_count = trace_parsed.GetSize();
283 for (size_t i = 0; i < trace_parsed_count; i++) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900284 const Value* value = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900285 trace_parsed.Get(i, &value);
286 if (match_after_this_item) {
287 if (value == match_after_this_item)
288 match_after_this_item = NULL;
289 continue;
290 }
291 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
292 continue;
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900293 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900294
295 if (IsStringInDict(string_to_match, dict))
296 return dict;
297 }
298 return NULL;
299}
300
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900301std::vector<const DictionaryValue*> FindTraceEntries(
nduca@chromium.org6d048772011-08-10 00:16:25 +0900302 const ListValue& trace_parsed,
303 const char* string_to_match) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900304 std::vector<const DictionaryValue*> hits;
nduca@chromium.org6d048772011-08-10 00:16:25 +0900305 size_t trace_parsed_count = trace_parsed.GetSize();
306 for (size_t i = 0; i < trace_parsed_count; i++) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900307 const Value* value = NULL;
nduca@chromium.org6d048772011-08-10 00:16:25 +0900308 trace_parsed.Get(i, &value);
309 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
310 continue;
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900311 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
nduca@chromium.org6d048772011-08-10 00:16:25 +0900312
313 if (IsStringInDict(string_to_match, dict))
314 hits.push_back(dict);
315 }
316 return hits;
317}
318
319void TraceWithAllMacroVariants(WaitableEvent* task_complete_event) {
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900320 {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900321 TRACE_EVENT_BEGIN_ETW("TRACE_EVENT_BEGIN_ETW call", 0x1122, "extrastring1");
322 TRACE_EVENT_END_ETW("TRACE_EVENT_END_ETW call", 0x3344, "extrastring2");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900323 TRACE_EVENT_INSTANT_ETW("TRACE_EVENT_INSTANT_ETW call",
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900324 0x5566, "extrastring3");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900325
326 TRACE_EVENT0("all", "TRACE_EVENT0 call");
327 TRACE_EVENT1("all", "TRACE_EVENT1 call", "name1", "value1");
328 TRACE_EVENT2("all", "TRACE_EVENT2 call",
jbates@chromium.org788d5a12011-09-07 09:43:11 +0900329 "name1", "\"value1\"",
330 "name2", "value\\2");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900331
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900332 TRACE_EVENT_INSTANT0("all", "TRACE_EVENT_INSTANT0 call",
333 TRACE_EVENT_SCOPE_GLOBAL);
334 TRACE_EVENT_INSTANT1("all", "TRACE_EVENT_INSTANT1 call",
335 TRACE_EVENT_SCOPE_PROCESS, "name1", "value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900336 TRACE_EVENT_INSTANT2("all", "TRACE_EVENT_INSTANT2 call",
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900337 TRACE_EVENT_SCOPE_THREAD,
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900338 "name1", "value1",
339 "name2", "value2");
340
341 TRACE_EVENT_BEGIN0("all", "TRACE_EVENT_BEGIN0 call");
342 TRACE_EVENT_BEGIN1("all", "TRACE_EVENT_BEGIN1 call", "name1", "value1");
343 TRACE_EVENT_BEGIN2("all", "TRACE_EVENT_BEGIN2 call",
344 "name1", "value1",
345 "name2", "value2");
346
347 TRACE_EVENT_END0("all", "TRACE_EVENT_END0 call");
348 TRACE_EVENT_END1("all", "TRACE_EVENT_END1 call", "name1", "value1");
349 TRACE_EVENT_END2("all", "TRACE_EVENT_END2 call",
350 "name1", "value1",
351 "name2", "value2");
nduca@chromium.org62210b02011-11-18 18:36:36 +0900352
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900353 TRACE_EVENT_ASYNC_BEGIN0("all", "TRACE_EVENT_ASYNC_BEGIN0 call", kAsyncId);
354 TRACE_EVENT_ASYNC_BEGIN1("all", "TRACE_EVENT_ASYNC_BEGIN1 call", kAsyncId,
jbates@chromium.org88295f92012-03-01 12:04:59 +0900355 "name1", "value1");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900356 TRACE_EVENT_ASYNC_BEGIN2("all", "TRACE_EVENT_ASYNC_BEGIN2 call", kAsyncId,
jbates@chromium.org88295f92012-03-01 12:04:59 +0900357 "name1", "value1",
358 "name2", "value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900359
jbates@chromium.orgbd9d20a2012-09-11 14:56:05 +0900360 TRACE_EVENT_ASYNC_STEP0("all", "TRACE_EVENT_ASYNC_STEP0 call",
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900361 5, "step1");
jbates@chromium.orgbd9d20a2012-09-11 14:56:05 +0900362 TRACE_EVENT_ASYNC_STEP1("all", "TRACE_EVENT_ASYNC_STEP1 call",
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900363 5, "step2", "name1", "value1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900364
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900365 TRACE_EVENT_ASYNC_END0("all", "TRACE_EVENT_ASYNC_END0 call", kAsyncId);
366 TRACE_EVENT_ASYNC_END1("all", "TRACE_EVENT_ASYNC_END1 call", kAsyncId,
jbates@chromium.org88295f92012-03-01 12:04:59 +0900367 "name1", "value1");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900368 TRACE_EVENT_ASYNC_END2("all", "TRACE_EVENT_ASYNC_END2 call", kAsyncId,
jbates@chromium.org88295f92012-03-01 12:04:59 +0900369 "name1", "value1",
370 "name2", "value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900371
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900372 TRACE_EVENT_BEGIN_ETW("TRACE_EVENT_BEGIN_ETW0 call", kAsyncId, NULL);
373 TRACE_EVENT_BEGIN_ETW("TRACE_EVENT_BEGIN_ETW1 call", kAsyncId, "value");
374 TRACE_EVENT_END_ETW("TRACE_EVENT_END_ETW0 call", kAsyncId, NULL);
375 TRACE_EVENT_END_ETW("TRACE_EVENT_END_ETW1 call", kAsyncId, "value");
376 TRACE_EVENT_INSTANT_ETW("TRACE_EVENT_INSTANT_ETW0 call", kAsyncId, NULL);
377 TRACE_EVENT_INSTANT_ETW("TRACE_EVENT_INSTANT_ETW1 call", kAsyncId, "value");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900378
nduca@chromium.org62210b02011-11-18 18:36:36 +0900379 TRACE_COUNTER1("all", "TRACE_COUNTER1 call", 31415);
380 TRACE_COUNTER2("all", "TRACE_COUNTER2 call",
381 "a", 30000,
382 "b", 1415);
piman@chromium.org902b2952011-12-16 10:19:06 +0900383
384 TRACE_COUNTER_ID1("all", "TRACE_COUNTER_ID1 call", 0x319009, 31415);
385 TRACE_COUNTER_ID2("all", "TRACE_COUNTER_ID2 call", 0x319009,
386 "a", 30000, "b", 1415);
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900387
388 TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0("all",
389 "TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0 call",
390 kAsyncId, kThreadId, 12345);
391 TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0("all",
392 "TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0 call",
393 kAsyncId, kThreadId, 23456);
394
395 TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0("all",
396 "TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0 call",
397 kAsyncId + 1, kThreadId, 34567);
398 TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0("all",
399 "TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0 call",
400 kAsyncId + 1, kThreadId, 45678);
401
caseq@google.coma88a9c52013-02-26 23:33:33 +0900402 TRACE_EVENT_OBJECT_CREATED_WITH_ID("all", "tracked object 1", 0x42);
403 TRACE_EVENT_OBJECT_DELETED_WITH_ID("all", "tracked object 1", 0x42);
404
405 TraceScopedTrackableObject<int> trackable("all", "tracked object 2",
406 0x2128506);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900407 } // Scope close causes TRACE_EVENT0 etc to send their END events.
408
409 if (task_complete_event)
410 task_complete_event->Signal();
411}
412
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900413void ValidateAllTraceMacrosCreatedData(const ListValue& trace_parsed) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900414 const DictionaryValue* item = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900415
416#define EXPECT_FIND_(string) \
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900417 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, string)));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900418#define EXPECT_NOT_FIND_(string) \
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900419 EXPECT_FALSE((item = FindTraceEntry(trace_parsed, string)));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900420#define EXPECT_SUB_FIND_(string) \
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900421 if (item) EXPECT_TRUE((IsStringInDict(string, item)));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900422
423 EXPECT_FIND_("ETW Trace Event");
424 EXPECT_FIND_("all");
425 EXPECT_FIND_("TRACE_EVENT_BEGIN_ETW call");
426 {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900427 std::string str_val;
428 EXPECT_TRUE(item && item->GetString("args.id", &str_val));
429 EXPECT_STREQ("1122", str_val.c_str());
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900430 }
431 EXPECT_SUB_FIND_("extrastring1");
432 EXPECT_FIND_("TRACE_EVENT_END_ETW call");
433 EXPECT_FIND_("TRACE_EVENT_INSTANT_ETW call");
434 EXPECT_FIND_("TRACE_EVENT0 call");
435 {
436 std::string ph_begin;
437 std::string ph_end;
438 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, "TRACE_EVENT0 call")));
439 EXPECT_TRUE((item && item->GetString("ph", &ph_begin)));
440 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, "TRACE_EVENT0 call",
441 item)));
442 EXPECT_TRUE((item && item->GetString("ph", &ph_end)));
443 EXPECT_EQ("B", ph_begin);
444 EXPECT_EQ("E", ph_end);
445 }
446 EXPECT_FIND_("TRACE_EVENT1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900447 EXPECT_SUB_FIND_("name1");
448 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900449 EXPECT_FIND_("TRACE_EVENT2 call");
450 EXPECT_SUB_FIND_("name1");
jbates@chromium.org788d5a12011-09-07 09:43:11 +0900451 EXPECT_SUB_FIND_("\"value1\"");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900452 EXPECT_SUB_FIND_("name2");
jbates@chromium.org788d5a12011-09-07 09:43:11 +0900453 EXPECT_SUB_FIND_("value\\2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900454
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900455 EXPECT_FIND_("TRACE_EVENT_INSTANT0 call");
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900456 {
457 std::string scope;
458 EXPECT_TRUE((item && item->GetString("s", &scope)));
459 EXPECT_EQ("g", scope);
460 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900461 EXPECT_FIND_("TRACE_EVENT_INSTANT1 call");
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900462 {
463 std::string scope;
464 EXPECT_TRUE((item && item->GetString("s", &scope)));
465 EXPECT_EQ("p", scope);
466 }
jbates@chromium.org59c27602012-01-13 12:12:44 +0900467 EXPECT_SUB_FIND_("name1");
468 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900469 EXPECT_FIND_("TRACE_EVENT_INSTANT2 call");
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900470 {
471 std::string scope;
472 EXPECT_TRUE((item && item->GetString("s", &scope)));
473 EXPECT_EQ("t", scope);
474 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900475 EXPECT_SUB_FIND_("name1");
476 EXPECT_SUB_FIND_("value1");
477 EXPECT_SUB_FIND_("name2");
478 EXPECT_SUB_FIND_("value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900479
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900480 EXPECT_FIND_("TRACE_EVENT_BEGIN0 call");
481 EXPECT_FIND_("TRACE_EVENT_BEGIN1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900482 EXPECT_SUB_FIND_("name1");
483 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900484 EXPECT_FIND_("TRACE_EVENT_BEGIN2 call");
485 EXPECT_SUB_FIND_("name1");
486 EXPECT_SUB_FIND_("value1");
487 EXPECT_SUB_FIND_("name2");
488 EXPECT_SUB_FIND_("value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900489
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900490 EXPECT_FIND_("TRACE_EVENT_END0 call");
491 EXPECT_FIND_("TRACE_EVENT_END1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900492 EXPECT_SUB_FIND_("name1");
493 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900494 EXPECT_FIND_("TRACE_EVENT_END2 call");
495 EXPECT_SUB_FIND_("name1");
496 EXPECT_SUB_FIND_("value1");
497 EXPECT_SUB_FIND_("name2");
498 EXPECT_SUB_FIND_("value2");
nduca@chromium.org62210b02011-11-18 18:36:36 +0900499
jbates@chromium.org88295f92012-03-01 12:04:59 +0900500 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN0 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900501 EXPECT_SUB_FIND_("id");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900502 EXPECT_SUB_FIND_(kAsyncIdStr);
jbates@chromium.org88295f92012-03-01 12:04:59 +0900503 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900504 EXPECT_SUB_FIND_("id");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900505 EXPECT_SUB_FIND_(kAsyncIdStr);
jbates@chromium.org59c27602012-01-13 12:12:44 +0900506 EXPECT_SUB_FIND_("name1");
507 EXPECT_SUB_FIND_("value1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900508 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN2 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900509 EXPECT_SUB_FIND_("id");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900510 EXPECT_SUB_FIND_(kAsyncIdStr);
jbates@chromium.org59c27602012-01-13 12:12:44 +0900511 EXPECT_SUB_FIND_("name1");
512 EXPECT_SUB_FIND_("value1");
513 EXPECT_SUB_FIND_("name2");
514 EXPECT_SUB_FIND_("value2");
515
jbates@chromium.orgbd9d20a2012-09-11 14:56:05 +0900516 EXPECT_FIND_("TRACE_EVENT_ASYNC_STEP0 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900517 EXPECT_SUB_FIND_("id");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900518 EXPECT_SUB_FIND_(kAsyncIdStr);
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900519 EXPECT_SUB_FIND_("step1");
jbates@chromium.orgbd9d20a2012-09-11 14:56:05 +0900520 EXPECT_FIND_("TRACE_EVENT_ASYNC_STEP1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900521 EXPECT_SUB_FIND_("id");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900522 EXPECT_SUB_FIND_(kAsyncIdStr);
simonjam@chromium.org87d003c2012-03-28 09:14:11 +0900523 EXPECT_SUB_FIND_("step2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900524 EXPECT_SUB_FIND_("name1");
525 EXPECT_SUB_FIND_("value1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900526
527 EXPECT_FIND_("TRACE_EVENT_ASYNC_END0 call");
528 EXPECT_SUB_FIND_("id");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900529 EXPECT_SUB_FIND_(kAsyncIdStr);
jbates@chromium.org88295f92012-03-01 12:04:59 +0900530 EXPECT_FIND_("TRACE_EVENT_ASYNC_END1 call");
531 EXPECT_SUB_FIND_("id");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900532 EXPECT_SUB_FIND_(kAsyncIdStr);
jbates@chromium.org88295f92012-03-01 12:04:59 +0900533 EXPECT_SUB_FIND_("name1");
534 EXPECT_SUB_FIND_("value1");
535 EXPECT_FIND_("TRACE_EVENT_ASYNC_END2 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900536 EXPECT_SUB_FIND_("id");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900537 EXPECT_SUB_FIND_(kAsyncIdStr);
jbates@chromium.org59c27602012-01-13 12:12:44 +0900538 EXPECT_SUB_FIND_("name1");
539 EXPECT_SUB_FIND_("value1");
540 EXPECT_SUB_FIND_("name2");
541 EXPECT_SUB_FIND_("value2");
542
543 EXPECT_FIND_("TRACE_EVENT_BEGIN_ETW0 call");
544 EXPECT_SUB_FIND_("id");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900545 EXPECT_SUB_FIND_(kAsyncIdStr);
jbates@chromium.org59c27602012-01-13 12:12:44 +0900546 EXPECT_SUB_FIND_("extra");
547 EXPECT_SUB_FIND_("NULL");
548 EXPECT_FIND_("TRACE_EVENT_BEGIN_ETW1 call");
549 EXPECT_SUB_FIND_("id");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900550 EXPECT_SUB_FIND_(kAsyncIdStr);
jbates@chromium.org59c27602012-01-13 12:12:44 +0900551 EXPECT_SUB_FIND_("extra");
552 EXPECT_SUB_FIND_("value");
553 EXPECT_FIND_("TRACE_EVENT_END_ETW0 call");
554 EXPECT_SUB_FIND_("id");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900555 EXPECT_SUB_FIND_(kAsyncIdStr);
jbates@chromium.org59c27602012-01-13 12:12:44 +0900556 EXPECT_SUB_FIND_("extra");
557 EXPECT_SUB_FIND_("NULL");
558 EXPECT_FIND_("TRACE_EVENT_END_ETW1 call");
559 EXPECT_SUB_FIND_("id");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900560 EXPECT_SUB_FIND_(kAsyncIdStr);
jbates@chromium.org59c27602012-01-13 12:12:44 +0900561 EXPECT_SUB_FIND_("extra");
562 EXPECT_SUB_FIND_("value");
563 EXPECT_FIND_("TRACE_EVENT_INSTANT_ETW0 call");
564 EXPECT_SUB_FIND_("id");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900565 EXPECT_SUB_FIND_(kAsyncIdStr);
jbates@chromium.org59c27602012-01-13 12:12:44 +0900566 EXPECT_SUB_FIND_("extra");
567 EXPECT_SUB_FIND_("NULL");
568 EXPECT_FIND_("TRACE_EVENT_INSTANT_ETW1 call");
569 EXPECT_SUB_FIND_("id");
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900570 EXPECT_SUB_FIND_(kAsyncIdStr);
jbates@chromium.org59c27602012-01-13 12:12:44 +0900571 EXPECT_SUB_FIND_("extra");
572 EXPECT_SUB_FIND_("value");
573
nduca@chromium.org62210b02011-11-18 18:36:36 +0900574 EXPECT_FIND_("TRACE_COUNTER1 call");
575 {
576 std::string ph;
577 EXPECT_TRUE((item && item->GetString("ph", &ph)));
578 EXPECT_EQ("C", ph);
579
580 int value;
581 EXPECT_TRUE((item && item->GetInteger("args.value", &value)));
582 EXPECT_EQ(31415, value);
583 }
584
585 EXPECT_FIND_("TRACE_COUNTER2 call");
586 {
587 std::string ph;
588 EXPECT_TRUE((item && item->GetString("ph", &ph)));
589 EXPECT_EQ("C", ph);
590
591 int value;
592 EXPECT_TRUE((item && item->GetInteger("args.a", &value)));
593 EXPECT_EQ(30000, value);
594
595 EXPECT_TRUE((item && item->GetInteger("args.b", &value)));
596 EXPECT_EQ(1415, value);
597 }
598
piman@chromium.org902b2952011-12-16 10:19:06 +0900599 EXPECT_FIND_("TRACE_COUNTER_ID1 call");
600 {
601 std::string id;
602 EXPECT_TRUE((item && item->GetString("id", &id)));
603 EXPECT_EQ("319009", id);
604
605 std::string ph;
606 EXPECT_TRUE((item && item->GetString("ph", &ph)));
607 EXPECT_EQ("C", ph);
608
609 int value;
610 EXPECT_TRUE((item && item->GetInteger("args.value", &value)));
611 EXPECT_EQ(31415, value);
612 }
613
614 EXPECT_FIND_("TRACE_COUNTER_ID2 call");
615 {
616 std::string id;
617 EXPECT_TRUE((item && item->GetString("id", &id)));
618 EXPECT_EQ("319009", id);
619
620 std::string ph;
621 EXPECT_TRUE((item && item->GetString("ph", &ph)));
622 EXPECT_EQ("C", ph);
623
624 int value;
625 EXPECT_TRUE((item && item->GetInteger("args.a", &value)));
626 EXPECT_EQ(30000, value);
627
628 EXPECT_TRUE((item && item->GetInteger("args.b", &value)));
629 EXPECT_EQ(1415, value);
630 }
dsinclair@chromium.org9aed8362013-02-16 03:58:25 +0900631
632 EXPECT_FIND_("TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0 call");
633 {
634 int val;
635 EXPECT_TRUE((item && item->GetInteger("ts", &val)));
636 EXPECT_EQ(12345, val);
637 EXPECT_TRUE((item && item->GetInteger("tid", &val)));
638 EXPECT_EQ(kThreadId, val);
639 std::string id;
640 EXPECT_TRUE((item && item->GetString("id", &id)));
641 EXPECT_EQ(kAsyncId, atoi(id.c_str()));
642 }
643
644 EXPECT_FIND_("TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0 call");
645 {
646 int val;
647 EXPECT_TRUE((item && item->GetInteger("ts", &val)));
648 EXPECT_EQ(23456, val);
649 EXPECT_TRUE((item && item->GetInteger("tid", &val)));
650 EXPECT_EQ(kThreadId, val);
651 std::string id;
652 EXPECT_TRUE((item && item->GetString("id", &id)));
653 EXPECT_EQ(kAsyncId, atoi(id.c_str()));
654 }
655
656 EXPECT_FIND_("TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0 call");
657 {
658 int val;
659 EXPECT_TRUE((item && item->GetInteger("ts", &val)));
660 EXPECT_EQ(34567, val);
661 EXPECT_TRUE((item && item->GetInteger("tid", &val)));
662 EXPECT_EQ(kThreadId, val);
663 std::string id;
664 EXPECT_TRUE((item && item->GetString("id", &id)));
665 EXPECT_EQ(kAsyncId + 1, atoi(id.c_str()));
666 }
667
668 EXPECT_FIND_("TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0 call");
669 {
670 int val;
671 EXPECT_TRUE((item && item->GetInteger("ts", &val)));
672 EXPECT_EQ(45678, val);
673 EXPECT_TRUE((item && item->GetInteger("tid", &val)));
674 EXPECT_EQ(kThreadId, val);
675 std::string id;
676 EXPECT_TRUE((item && item->GetString("id", &id)));
677 EXPECT_EQ(kAsyncId + 1, atoi(id.c_str()));
678 }
caseq@google.coma88a9c52013-02-26 23:33:33 +0900679
680 EXPECT_FIND_("tracked object 1");
681 {
682 std::string phase;
683 std::string id;
684
685 EXPECT_TRUE((item && item->GetString("ph", &phase)));
686 EXPECT_EQ("N", phase);
687 EXPECT_TRUE((item && item->GetString("id", &id)));
688 EXPECT_EQ("42", id);
689 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, "tracked object 1",
690 item)));
691 EXPECT_TRUE((item && item->GetString("ph", &phase)));
692 EXPECT_EQ("D", phase);
693 EXPECT_TRUE((item && item->GetString("id", &id)));
694 EXPECT_EQ("42", id);
695 }
696
697 EXPECT_FIND_("tracked object 2");
698 {
699 std::string phase;
700 std::string id;
701
702 EXPECT_TRUE((item && item->GetString("ph", &phase)));
703 EXPECT_EQ("N", phase);
704 EXPECT_TRUE((item && item->GetString("id", &id)));
705 EXPECT_EQ("2128506", id);
706 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, "tracked object 2",
707 item)));
708 EXPECT_TRUE((item && item->GetString("ph", &phase)));
709 EXPECT_EQ("D", phase);
710 EXPECT_TRUE((item && item->GetString("id", &id)));
711 EXPECT_EQ("2128506", id);
712 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900713}
714
nduca@chromium.org6d048772011-08-10 00:16:25 +0900715void TraceManyInstantEvents(int thread_id, int num_events,
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900716 WaitableEvent* task_complete_event) {
nduca@chromium.org6d048772011-08-10 00:16:25 +0900717 for (int i = 0; i < num_events; i++) {
718 TRACE_EVENT_INSTANT2("all", "multi thread event",
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900719 TRACE_EVENT_SCOPE_THREAD,
nduca@chromium.org6d048772011-08-10 00:16:25 +0900720 "thread", thread_id,
721 "event", i);
722 }
723
724 if (task_complete_event)
725 task_complete_event->Signal();
726}
727
728void ValidateInstantEventPresentOnEveryThread(const ListValue& trace_parsed,
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900729 int num_threads,
730 int num_events) {
nduca@chromium.org6d048772011-08-10 00:16:25 +0900731 std::map<int, std::map<int, bool> > results;
732
733 size_t trace_parsed_count = trace_parsed.GetSize();
734 for (size_t i = 0; i < trace_parsed_count; i++) {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900735 const Value* value = NULL;
nduca@chromium.org6d048772011-08-10 00:16:25 +0900736 trace_parsed.Get(i, &value);
737 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
738 continue;
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900739 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
nduca@chromium.org6d048772011-08-10 00:16:25 +0900740 std::string name;
741 dict->GetString("name", &name);
742 if (name != "multi thread event")
743 continue;
744
745 int thread = 0;
746 int event = 0;
747 EXPECT_TRUE(dict->GetInteger("args.thread", &thread));
748 EXPECT_TRUE(dict->GetInteger("args.event", &event));
749 results[thread][event] = true;
750 }
751
752 EXPECT_FALSE(results[-1][-1]);
753 for (int thread = 0; thread < num_threads; thread++) {
754 for (int event = 0; event < num_events; event++) {
755 EXPECT_TRUE(results[thread][event]);
756 }
757 }
758}
759
760void TraceCallsWithCachedCategoryPointersPointers(const char* name_str) {
761 TRACE_EVENT0("category name1", name_str);
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900762 TRACE_EVENT_INSTANT0("category name2", name_str, TRACE_EVENT_SCOPE_THREAD);
nduca@chromium.org6d048772011-08-10 00:16:25 +0900763 TRACE_EVENT_BEGIN0("category name3", name_str);
764 TRACE_EVENT_END0("category name4", name_str);
765}
766
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900767} // namespace
768
jbates@chromium.org5e2f67d2012-08-16 13:32:49 +0900769void HighResSleepForTraceTest(base::TimeDelta elapsed) {
770 base::TimeTicks end_time = base::TimeTicks::HighResNow() + elapsed;
771 do {
772 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
773 } while (base::TimeTicks::HighResNow() < end_time);
774}
775
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900776// Simple Test for emitting data and validating it was received.
777TEST_F(TraceEventTestFixture, DataCaptured) {
778 ManualTestSetUp();
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900779 TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
780 TraceLog::RECORD_UNTIL_FULL);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900781
nduca@chromium.org6d048772011-08-10 00:16:25 +0900782 TraceWithAllMacroVariants(NULL);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900783
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900784 EndTraceAndFlush();
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900785
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900786 ValidateAllTraceMacrosCreatedData(trace_parsed_);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900787}
788
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900789class MockEnabledStateChangedObserver :
790 public base::debug::TraceLog::EnabledStateChangedObserver {
791 public:
792 MOCK_METHOD0(OnTraceLogWillEnable, void());
793 MOCK_METHOD0(OnTraceLogWillDisable, void());
794};
795
796TEST_F(TraceEventTestFixture, EnabledObserverFiresOnEnable) {
797 ManualTestSetUp();
798
799 MockEnabledStateChangedObserver observer;
800 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
801
802 EXPECT_CALL(observer, OnTraceLogWillEnable())
803 .Times(1);
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900804 TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
805 TraceLog::RECORD_UNTIL_FULL);
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900806 testing::Mock::VerifyAndClear(&observer);
807
808 // Cleanup.
809 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900810 TraceLog::GetInstance()->SetDisabled();
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900811}
812
813TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnSecondEnable) {
814 ManualTestSetUp();
815
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900816 TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
817 TraceLog::RECORD_UNTIL_FULL);
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900818
819 testing::StrictMock<MockEnabledStateChangedObserver> observer;
820 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
821
822 EXPECT_CALL(observer, OnTraceLogWillEnable())
823 .Times(0);
824 EXPECT_CALL(observer, OnTraceLogWillDisable())
825 .Times(0);
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900826 TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
827 TraceLog::RECORD_UNTIL_FULL);
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900828 testing::Mock::VerifyAndClear(&observer);
829
830 // Cleanup.
831 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900832 TraceLog::GetInstance()->SetDisabled();
833 TraceLog::GetInstance()->SetDisabled();
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900834}
835
caseq@google.comedcf6262013-01-16 20:41:57 +0900836TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnNestedDisable) {
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900837 ManualTestSetUp();
838
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900839 CategoryFilter cf_inc_all("*");
840 TraceLog::GetInstance()->SetEnabled(cf_inc_all, TraceLog::RECORD_UNTIL_FULL);
841 TraceLog::GetInstance()->SetEnabled(cf_inc_all, TraceLog::RECORD_UNTIL_FULL);
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900842
843 testing::StrictMock<MockEnabledStateChangedObserver> observer;
844 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
845
846 EXPECT_CALL(observer, OnTraceLogWillEnable())
847 .Times(0);
848 EXPECT_CALL(observer, OnTraceLogWillDisable())
849 .Times(0);
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900850 TraceLog::GetInstance()->SetDisabled();
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900851 testing::Mock::VerifyAndClear(&observer);
852
853 // Cleanup.
854 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900855 TraceLog::GetInstance()->SetDisabled();
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900856}
857
858TEST_F(TraceEventTestFixture, EnabledObserverFiresOnDisable) {
859 ManualTestSetUp();
860
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900861 TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
862 TraceLog::RECORD_UNTIL_FULL);
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900863
864 MockEnabledStateChangedObserver observer;
865 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
866
867 EXPECT_CALL(observer, OnTraceLogWillDisable())
868 .Times(1);
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900869 TraceLog::GetInstance()->SetDisabled();
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900870 testing::Mock::VerifyAndClear(&observer);
871
872 // Cleanup.
873 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
874}
875
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900876// Test that categories work.
877TEST_F(TraceEventTestFixture, Categories) {
878 ManualTestSetUp();
879
880 // Test that categories that are used can be retrieved whether trace was
881 // enabled or disabled when the trace event was encountered.
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900882 TRACE_EVENT_INSTANT0("c1", "name", TRACE_EVENT_SCOPE_THREAD);
883 TRACE_EVENT_INSTANT0("c2", "name", TRACE_EVENT_SCOPE_THREAD);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900884 BeginTrace();
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900885 TRACE_EVENT_INSTANT0("c3", "name", TRACE_EVENT_SCOPE_THREAD);
886 TRACE_EVENT_INSTANT0("c4", "name", TRACE_EVENT_SCOPE_THREAD);
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900887 // Category groups containing more than one category.
888 TRACE_EVENT_INSTANT0("c5,c6", "name", TRACE_EVENT_SCOPE_THREAD);
889 TRACE_EVENT_INSTANT0("c7,c8", "name", TRACE_EVENT_SCOPE_THREAD);
890
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900891 EndTraceAndFlush();
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900892 std::vector<std::string> cat_groups;
893 TraceLog::GetInstance()->GetKnownCategoryGroups(&cat_groups);
894 EXPECT_TRUE(std::find(cat_groups.begin(),
895 cat_groups.end(), "c1") != cat_groups.end());
896 EXPECT_TRUE(std::find(cat_groups.begin(),
897 cat_groups.end(), "c2") != cat_groups.end());
898 EXPECT_TRUE(std::find(cat_groups.begin(),
899 cat_groups.end(), "c3") != cat_groups.end());
900 EXPECT_TRUE(std::find(cat_groups.begin(),
901 cat_groups.end(), "c4") != cat_groups.end());
902 EXPECT_TRUE(std::find(cat_groups.begin(),
903 cat_groups.end(), "c5,c6") != cat_groups.end());
904 EXPECT_TRUE(std::find(cat_groups.begin(),
905 cat_groups.end(), "c7,c8") != cat_groups.end());
dsinclair@chromium.orgc61f1842013-04-20 06:29:21 +0900906 // Make sure metadata isn't returned.
907 EXPECT_TRUE(std::find(cat_groups.begin(),
908 cat_groups.end(), "__metadata") == cat_groups.end());
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900909
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900910 const std::vector<std::string> empty_categories;
911 std::vector<std::string> included_categories;
912 std::vector<std::string> excluded_categories;
913
914 // Test that category filtering works.
915
916 // Include nonexistent category -> no events
917 Clear();
918 included_categories.clear();
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900919 TraceLog::GetInstance()->SetEnabled(CategoryFilter("not_found823564786"),
dsinclair@chromium.orga7fb8d62013-02-23 11:09:53 +0900920 TraceLog::RECORD_UNTIL_FULL);
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900921 TRACE_EVENT_INSTANT0("cat1", "name", TRACE_EVENT_SCOPE_THREAD);
922 TRACE_EVENT_INSTANT0("cat2", "name", TRACE_EVENT_SCOPE_THREAD);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900923 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900924 EXPECT_TRUE(trace_parsed_.empty());
925
926 // Include existent category -> only events of that category
927 Clear();
928 included_categories.clear();
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900929 TraceLog::GetInstance()->SetEnabled(CategoryFilter("inc"),
dsinclair@chromium.orga7fb8d62013-02-23 11:09:53 +0900930 TraceLog::RECORD_UNTIL_FULL);
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900931 TRACE_EVENT_INSTANT0("inc", "name", TRACE_EVENT_SCOPE_THREAD);
932 TRACE_EVENT_INSTANT0("inc2", "name", TRACE_EVENT_SCOPE_THREAD);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900933 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900934 EXPECT_TRUE(FindMatchingValue("cat", "inc"));
935 EXPECT_FALSE(FindNonMatchingValue("cat", "inc"));
936
937 // Include existent wildcard -> all categories matching wildcard
938 Clear();
939 included_categories.clear();
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900940 TraceLog::GetInstance()->SetEnabled(
941 CategoryFilter("inc_wildcard_*,inc_wildchar_?_end"),
942 TraceLog::RECORD_UNTIL_FULL);
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900943 TRACE_EVENT_INSTANT0("inc_wildcard_abc", "included",
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900944 TRACE_EVENT_SCOPE_THREAD);
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900945 TRACE_EVENT_INSTANT0("inc_wildcard_", "included", TRACE_EVENT_SCOPE_THREAD);
946 TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "included",
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900947 TRACE_EVENT_SCOPE_THREAD);
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900948 TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "not_inc",
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900949 TRACE_EVENT_SCOPE_THREAD);
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900950 TRACE_EVENT_INSTANT0("cat1", "not_inc", TRACE_EVENT_SCOPE_THREAD);
951 TRACE_EVENT_INSTANT0("cat2", "not_inc", TRACE_EVENT_SCOPE_THREAD);
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900952 TRACE_EVENT_INSTANT0("inc_wildcard_category,other_category", "included",
953 TRACE_EVENT_SCOPE_THREAD);
954 TRACE_EVENT_INSTANT0(
955 "non_included_category,inc_wildcard_category", "included",
956 TRACE_EVENT_SCOPE_THREAD);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900957 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900958 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_abc"));
959 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_"));
960 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildchar_x_end"));
961 EXPECT_FALSE(FindMatchingValue("name", "not_inc"));
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900962 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_category,other_category"));
963 EXPECT_TRUE(FindMatchingValue("cat",
964 "non_included_category,inc_wildcard_category"));
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900965
966 included_categories.clear();
967
968 // Exclude nonexistent category -> all events
969 Clear();
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900970 TraceLog::GetInstance()->SetEnabled(CategoryFilter("-not_found823564786"),
dsinclair@chromium.orga7fb8d62013-02-23 11:09:53 +0900971 TraceLog::RECORD_UNTIL_FULL);
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900972 TRACE_EVENT_INSTANT0("cat1", "name", TRACE_EVENT_SCOPE_THREAD);
973 TRACE_EVENT_INSTANT0("cat2", "name", TRACE_EVENT_SCOPE_THREAD);
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900974 TRACE_EVENT_INSTANT0("category1,category2", "name", TRACE_EVENT_SCOPE_THREAD);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900975 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900976 EXPECT_TRUE(FindMatchingValue("cat", "cat1"));
977 EXPECT_TRUE(FindMatchingValue("cat", "cat2"));
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900978 EXPECT_TRUE(FindMatchingValue("cat", "category1,category2"));
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900979
980 // Exclude existent category -> only events of other categories
981 Clear();
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900982 TraceLog::GetInstance()->SetEnabled(CategoryFilter("-inc"),
dsinclair@chromium.orga7fb8d62013-02-23 11:09:53 +0900983 TraceLog::RECORD_UNTIL_FULL);
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +0900984 TRACE_EVENT_INSTANT0("inc", "name", TRACE_EVENT_SCOPE_THREAD);
985 TRACE_EVENT_INSTANT0("inc2", "name", TRACE_EVENT_SCOPE_THREAD);
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900986 TRACE_EVENT_INSTANT0("inc2,inc", "name", TRACE_EVENT_SCOPE_THREAD);
987 TRACE_EVENT_INSTANT0("inc,inc2", "name", TRACE_EVENT_SCOPE_THREAD);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +0900988 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900989 EXPECT_TRUE(FindMatchingValue("cat", "inc2"));
990 EXPECT_FALSE(FindMatchingValue("cat", "inc"));
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900991 EXPECT_FALSE(FindMatchingValue("cat", "inc2,inc"));
992 EXPECT_FALSE(FindMatchingValue("cat", "inc,inc2"));
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900993
994 // Exclude existent wildcard -> all categories not matching wildcard
995 Clear();
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +0900996 TraceLog::GetInstance()->SetEnabled(
997 CategoryFilter("-inc_wildcard_*,-inc_wildchar_?_end"),
998 TraceLog::RECORD_UNTIL_FULL);
999 TRACE_EVENT_INSTANT0("inc_wildcard_abc", "not_inc",
1000 TRACE_EVENT_SCOPE_THREAD);
1001 TRACE_EVENT_INSTANT0("inc_wildcard_", "not_inc",
1002 TRACE_EVENT_SCOPE_THREAD);
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001003 TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "not_inc",
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +09001004 TRACE_EVENT_SCOPE_THREAD);
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001005 TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "included",
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +09001006 TRACE_EVENT_SCOPE_THREAD);
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001007 TRACE_EVENT_INSTANT0("cat1", "included", TRACE_EVENT_SCOPE_THREAD);
1008 TRACE_EVENT_INSTANT0("cat2", "included", TRACE_EVENT_SCOPE_THREAD);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001009 EndTraceAndFlush();
jbates@chromium.org11d4c362011-09-13 07:03:41 +09001010 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildchar_bla_end"));
1011 EXPECT_TRUE(FindMatchingValue("cat", "cat1"));
1012 EXPECT_TRUE(FindMatchingValue("cat", "cat2"));
1013 EXPECT_FALSE(FindMatchingValue("name", "not_inc"));
1014}
1015
jbates@chromium.orgb3cab862011-05-14 08:30:35 +09001016
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001017// Test EVENT_WATCH_NOTIFICATION
1018TEST_F(TraceEventTestFixture, EventWatchNotification) {
1019 ManualTestSetUp();
1020
1021 // Basic one occurrence.
1022 BeginTrace();
1023 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001024 TRACE_EVENT_INSTANT0("cat", "event", TRACE_EVENT_SCOPE_THREAD);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001025 EndTraceAndFlush();
1026 EXPECT_EQ(event_watch_notification_, 1);
1027
1028 // Basic one occurrence before Set.
1029 BeginTrace();
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001030 TRACE_EVENT_INSTANT0("cat", "event", TRACE_EVENT_SCOPE_THREAD);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001031 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
1032 EndTraceAndFlush();
1033 EXPECT_EQ(event_watch_notification_, 1);
1034
1035 // Auto-reset after end trace.
1036 BeginTrace();
1037 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
1038 EndTraceAndFlush();
1039 BeginTrace();
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001040 TRACE_EVENT_INSTANT0("cat", "event", TRACE_EVENT_SCOPE_THREAD);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001041 EndTraceAndFlush();
1042 EXPECT_EQ(event_watch_notification_, 0);
1043
1044 // Multiple occurrence.
1045 BeginTrace();
1046 int num_occurrences = 5;
1047 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
1048 for (int i = 0; i < num_occurrences; ++i)
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001049 TRACE_EVENT_INSTANT0("cat", "event", TRACE_EVENT_SCOPE_THREAD);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001050 EndTraceAndFlush();
1051 EXPECT_EQ(event_watch_notification_, num_occurrences);
1052
1053 // Wrong category.
1054 BeginTrace();
1055 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001056 TRACE_EVENT_INSTANT0("wrong_cat", "event", TRACE_EVENT_SCOPE_THREAD);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001057 EndTraceAndFlush();
1058 EXPECT_EQ(event_watch_notification_, 0);
1059
1060 // Wrong name.
1061 BeginTrace();
1062 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001063 TRACE_EVENT_INSTANT0("cat", "wrong_event", TRACE_EVENT_SCOPE_THREAD);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001064 EndTraceAndFlush();
1065 EXPECT_EQ(event_watch_notification_, 0);
1066
1067 // Canceled.
1068 BeginTrace();
1069 TraceLog::GetInstance()->SetWatchEvent("cat", "event");
1070 TraceLog::GetInstance()->CancelWatchEvent();
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001071 TRACE_EVENT_INSTANT0("cat", "event", TRACE_EVENT_SCOPE_THREAD);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001072 EndTraceAndFlush();
1073 EXPECT_EQ(event_watch_notification_, 0);
1074}
1075
jbates@chromium.org88295f92012-03-01 12:04:59 +09001076// Test ASYNC_BEGIN/END events
1077TEST_F(TraceEventTestFixture, AsyncBeginEndEvents) {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001078 ManualTestSetUp();
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001079 BeginTrace();
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001080
1081 unsigned long long id = 0xfeedbeeffeedbeefull;
jbates@chromium.org88295f92012-03-01 12:04:59 +09001082 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name1", id);
jbates@chromium.orgbd9d20a2012-09-11 14:56:05 +09001083 TRACE_EVENT_ASYNC_STEP0( "cat", "name1", id, "step1");
jbates@chromium.org88295f92012-03-01 12:04:59 +09001084 TRACE_EVENT_ASYNC_END0("cat", "name1", id);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001085 TRACE_EVENT_BEGIN0( "cat", "name2");
jbates@chromium.org88295f92012-03-01 12:04:59 +09001086 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name3", 0);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001087
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001088 EndTraceAndFlush();
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001089
1090 EXPECT_TRUE(FindNamePhase("name1", "S"));
jbates@chromium.org88295f92012-03-01 12:04:59 +09001091 EXPECT_TRUE(FindNamePhase("name1", "T"));
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001092 EXPECT_TRUE(FindNamePhase("name1", "F"));
1093
1094 std::string id_str;
1095 StringAppendF(&id_str, "%llx", id);
1096
1097 EXPECT_TRUE(FindNamePhaseKeyValue("name1", "S", "id", id_str.c_str()));
jbates@chromium.org88295f92012-03-01 12:04:59 +09001098 EXPECT_TRUE(FindNamePhaseKeyValue("name1", "T", "id", id_str.c_str()));
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001099 EXPECT_TRUE(FindNamePhaseKeyValue("name1", "F", "id", id_str.c_str()));
1100 EXPECT_TRUE(FindNamePhaseKeyValue("name3", "S", "id", "0"));
1101
1102 // BEGIN events should not have id
1103 EXPECT_FALSE(FindNamePhaseKeyValue("name2", "B", "id", "0"));
1104}
1105
jbates@chromium.org88295f92012-03-01 12:04:59 +09001106// Test ASYNC_BEGIN/END events
1107TEST_F(TraceEventTestFixture, AsyncBeginEndPointerMangling) {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001108 ManualTestSetUp();
1109
1110 void* ptr = this;
1111
1112 TraceLog::GetInstance()->SetProcessID(100);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001113 BeginTrace();
jbates@chromium.org88295f92012-03-01 12:04:59 +09001114 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name1", ptr);
1115 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name2", ptr);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001116 EndTraceAndFlush();
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001117
1118 TraceLog::GetInstance()->SetProcessID(200);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001119 BeginTrace();
jbates@chromium.org88295f92012-03-01 12:04:59 +09001120 TRACE_EVENT_ASYNC_END0( "cat", "name1", ptr);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001121 EndTraceAndFlush();
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001122
jbates@chromium.org88295f92012-03-01 12:04:59 +09001123 DictionaryValue* async_begin = FindNamePhase("name1", "S");
1124 DictionaryValue* async_begin2 = FindNamePhase("name2", "S");
1125 DictionaryValue* async_end = FindNamePhase("name1", "F");
1126 EXPECT_TRUE(async_begin);
1127 EXPECT_TRUE(async_begin2);
1128 EXPECT_TRUE(async_end);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001129
1130 Value* value = NULL;
jbates@chromium.org88295f92012-03-01 12:04:59 +09001131 std::string async_begin_id_str;
1132 std::string async_begin2_id_str;
1133 std::string async_end_id_str;
1134 ASSERT_TRUE(async_begin->Get("id", &value));
1135 ASSERT_TRUE(value->GetAsString(&async_begin_id_str));
1136 ASSERT_TRUE(async_begin2->Get("id", &value));
1137 ASSERT_TRUE(value->GetAsString(&async_begin2_id_str));
1138 ASSERT_TRUE(async_end->Get("id", &value));
1139 ASSERT_TRUE(value->GetAsString(&async_end_id_str));
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001140
jbates@chromium.org88295f92012-03-01 12:04:59 +09001141 EXPECT_STREQ(async_begin_id_str.c_str(), async_begin2_id_str.c_str());
1142 EXPECT_STRNE(async_begin_id_str.c_str(), async_end_id_str.c_str());
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001143}
1144
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001145// Test that static strings are not copied.
1146TEST_F(TraceEventTestFixture, StaticStringVsString) {
1147 ManualTestSetUp();
1148 TraceLog* tracer = TraceLog::GetInstance();
1149 // Make sure old events are flushed:
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001150 EndTraceAndFlush();
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001151 EXPECT_EQ(0u, tracer->GetEventsSize());
1152
1153 {
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001154 BeginTrace();
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001155 // Test that string arguments are copied.
1156 TRACE_EVENT2("cat", "name1",
1157 "arg1", std::string("argval"), "arg2", std::string("argval"));
1158 // Test that static TRACE_STR_COPY string arguments are copied.
1159 TRACE_EVENT2("cat", "name2",
1160 "arg1", TRACE_STR_COPY("argval"),
1161 "arg2", TRACE_STR_COPY("argval"));
1162 size_t num_events = tracer->GetEventsSize();
1163 EXPECT_GT(num_events, 1u);
1164 const TraceEvent& event1 = tracer->GetEventAt(num_events - 2);
1165 const TraceEvent& event2 = tracer->GetEventAt(num_events - 1);
1166 EXPECT_STREQ("name1", event1.name());
1167 EXPECT_STREQ("name2", event2.name());
1168 EXPECT_TRUE(event1.parameter_copy_storage() != NULL);
1169 EXPECT_TRUE(event2.parameter_copy_storage() != NULL);
1170 EXPECT_GT(event1.parameter_copy_storage()->size(), 0u);
1171 EXPECT_GT(event2.parameter_copy_storage()->size(), 0u);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001172 EndTraceAndFlush();
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001173 }
1174
1175 {
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001176 BeginTrace();
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001177 // Test that static literal string arguments are not copied.
1178 TRACE_EVENT2("cat", "name1",
1179 "arg1", "argval", "arg2", "argval");
1180 // Test that static TRACE_STR_COPY NULL string arguments are not copied.
1181 const char* str1 = NULL;
1182 const char* str2 = NULL;
1183 TRACE_EVENT2("cat", "name2",
1184 "arg1", TRACE_STR_COPY(str1),
1185 "arg2", TRACE_STR_COPY(str2));
1186 size_t num_events = tracer->GetEventsSize();
1187 EXPECT_GT(num_events, 1u);
1188 const TraceEvent& event1 = tracer->GetEventAt(num_events - 2);
1189 const TraceEvent& event2 = tracer->GetEventAt(num_events - 1);
1190 EXPECT_STREQ("name1", event1.name());
1191 EXPECT_STREQ("name2", event2.name());
1192 EXPECT_TRUE(event1.parameter_copy_storage() == NULL);
1193 EXPECT_TRUE(event2.parameter_copy_storage() == NULL);
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001194 EndTraceAndFlush();
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001195 }
1196}
1197
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001198// Test that data sent from other threads is gathered
1199TEST_F(TraceEventTestFixture, DataCapturedOnThread) {
1200 ManualTestSetUp();
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001201 BeginTrace();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001202
1203 Thread thread("1");
1204 WaitableEvent task_complete_event(false, false);
1205 thread.Start();
1206
1207 thread.message_loop()->PostTask(
jbates@chromium.org0b837e42011-10-06 01:58:20 +09001208 FROM_HERE, base::Bind(&TraceWithAllMacroVariants, &task_complete_event));
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001209 task_complete_event.Wait();
jbates@chromium.orgb84db522011-10-04 02:51:25 +09001210 thread.Stop();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001211
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001212 EndTraceAndFlush();
jbates@chromium.org6a092d72011-10-25 01:34:08 +09001213 ValidateAllTraceMacrosCreatedData(trace_parsed_);
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001214}
1215
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001216// Test that data sent from multiple threads is gathered
1217TEST_F(TraceEventTestFixture, DataCapturedManyThreads) {
1218 ManualTestSetUp();
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001219 BeginTrace();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001220
1221 const int num_threads = 4;
1222 const int num_events = 4000;
1223 Thread* threads[num_threads];
1224 WaitableEvent* task_complete_events[num_threads];
1225 for (int i = 0; i < num_threads; i++) {
1226 threads[i] = new Thread(StringPrintf("Thread %d", i).c_str());
1227 task_complete_events[i] = new WaitableEvent(false, false);
1228 threads[i]->Start();
1229 threads[i]->message_loop()->PostTask(
jbates@chromium.org0b837e42011-10-06 01:58:20 +09001230 FROM_HERE, base::Bind(&TraceManyInstantEvents,
1231 i, num_events, task_complete_events[i]));
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001232 }
1233
1234 for (int i = 0; i < num_threads; i++) {
1235 task_complete_events[i]->Wait();
1236 }
1237
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001238 for (int i = 0; i < num_threads; i++) {
1239 threads[i]->Stop();
1240 delete threads[i];
1241 delete task_complete_events[i];
1242 }
1243
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001244 EndTraceAndFlush();
jbates@chromium.orgb84db522011-10-04 02:51:25 +09001245
jbates@chromium.org6a092d72011-10-25 01:34:08 +09001246 ValidateInstantEventPresentOnEveryThread(trace_parsed_,
nduca@chromium.org6d048772011-08-10 00:16:25 +09001247 num_threads, num_events);
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001248}
1249
nduca@chromium.org6d048772011-08-10 00:16:25 +09001250// Test that thread and process names show up in the trace
1251TEST_F(TraceEventTestFixture, ThreadNames) {
1252 ManualTestSetUp();
1253
1254 // Create threads before we enable tracing to make sure
1255 // that tracelog still captures them.
1256 const int num_threads = 4;
1257 const int num_events = 10;
1258 Thread* threads[num_threads];
1259 PlatformThreadId thread_ids[num_threads];
1260 for (int i = 0; i < num_threads; i++)
1261 threads[i] = new Thread(StringPrintf("Thread %d", i).c_str());
1262
1263 // Enable tracing.
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001264 BeginTrace();
nduca@chromium.org6d048772011-08-10 00:16:25 +09001265
1266 // Now run some trace code on these threads.
1267 WaitableEvent* task_complete_events[num_threads];
1268 for (int i = 0; i < num_threads; i++) {
1269 task_complete_events[i] = new WaitableEvent(false, false);
1270 threads[i]->Start();
1271 thread_ids[i] = threads[i]->thread_id();
1272 threads[i]->message_loop()->PostTask(
jbates@chromium.org0b837e42011-10-06 01:58:20 +09001273 FROM_HERE, base::Bind(&TraceManyInstantEvents,
1274 i, num_events, task_complete_events[i]));
nduca@chromium.org6d048772011-08-10 00:16:25 +09001275 }
1276 for (int i = 0; i < num_threads; i++) {
1277 task_complete_events[i]->Wait();
1278 }
1279
1280 // Shut things down.
nduca@chromium.org6d048772011-08-10 00:16:25 +09001281 for (int i = 0; i < num_threads; i++) {
1282 threads[i]->Stop();
1283 delete threads[i];
1284 delete task_complete_events[i];
1285 }
1286
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001287 EndTraceAndFlush();
jbates@chromium.orgb84db522011-10-04 02:51:25 +09001288
nduca@chromium.org6d048772011-08-10 00:16:25 +09001289 std::string tmp;
1290 int tmp_int;
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001291 const DictionaryValue* item;
nduca@chromium.org6d048772011-08-10 00:16:25 +09001292
1293 // Make sure we get thread name metadata.
1294 // Note, the test suite may have created a ton of threads.
1295 // So, we'll have thread names for threads we didn't create.
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001296 std::vector<const DictionaryValue*> items =
nduca@chromium.org6d048772011-08-10 00:16:25 +09001297 FindTraceEntries(trace_parsed_, "thread_name");
1298 for (int i = 0; i < static_cast<int>(items.size()); i++) {
1299 item = items[i];
joth@chromium.org088ae012011-11-11 01:26:23 +09001300 ASSERT_TRUE(item);
nduca@chromium.org6d048772011-08-10 00:16:25 +09001301 EXPECT_TRUE(item->GetInteger("tid", &tmp_int));
1302
1303 // See if this thread name is one of the threads we just created
1304 for (int j = 0; j < num_threads; j++) {
1305 if(static_cast<int>(thread_ids[j]) != tmp_int)
1306 continue;
1307
jbates@chromium.org62a16662012-02-04 08:18:06 +09001308 std::string expected_name = StringPrintf("Thread %d", j);
nduca@chromium.org6d048772011-08-10 00:16:25 +09001309 EXPECT_TRUE(item->GetString("ph", &tmp) && tmp == "M");
1310 EXPECT_TRUE(item->GetInteger("pid", &tmp_int) &&
1311 tmp_int == static_cast<int>(base::GetCurrentProcId()));
jbates@chromium.org62a16662012-02-04 08:18:06 +09001312 // If the thread name changes or the tid gets reused, the name will be
1313 // a comma-separated list of thread names, so look for a substring.
nduca@chromium.org6d048772011-08-10 00:16:25 +09001314 EXPECT_TRUE(item->GetString("args.name", &tmp) &&
jbates@chromium.org62a16662012-02-04 08:18:06 +09001315 tmp.find(expected_name) != std::string::npos);
nduca@chromium.org6d048772011-08-10 00:16:25 +09001316 }
1317 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001318}
1319
joth@chromium.org088ae012011-11-11 01:26:23 +09001320TEST_F(TraceEventTestFixture, ThreadNameChanges) {
1321 ManualTestSetUp();
1322
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001323 BeginTrace();
joth@chromium.org088ae012011-11-11 01:26:23 +09001324
1325 PlatformThread::SetName("");
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001326 TRACE_EVENT_INSTANT0("drink", "water", TRACE_EVENT_SCOPE_THREAD);
joth@chromium.org088ae012011-11-11 01:26:23 +09001327
1328 PlatformThread::SetName("cafe");
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001329 TRACE_EVENT_INSTANT0("drink", "coffee", TRACE_EVENT_SCOPE_THREAD);
joth@chromium.org088ae012011-11-11 01:26:23 +09001330
1331 PlatformThread::SetName("shop");
1332 // No event here, so won't appear in combined name.
1333
1334 PlatformThread::SetName("pub");
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001335 TRACE_EVENT_INSTANT0("drink", "beer", TRACE_EVENT_SCOPE_THREAD);
1336 TRACE_EVENT_INSTANT0("drink", "wine", TRACE_EVENT_SCOPE_THREAD);
joth@chromium.org088ae012011-11-11 01:26:23 +09001337
1338 PlatformThread::SetName(" bar");
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001339 TRACE_EVENT_INSTANT0("drink", "whisky", TRACE_EVENT_SCOPE_THREAD);
joth@chromium.org088ae012011-11-11 01:26:23 +09001340
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001341 EndTraceAndFlush();
joth@chromium.org088ae012011-11-11 01:26:23 +09001342
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001343 std::vector<const DictionaryValue*> items =
joth@chromium.org088ae012011-11-11 01:26:23 +09001344 FindTraceEntries(trace_parsed_, "thread_name");
1345 EXPECT_EQ(1u, items.size());
1346 ASSERT_GT(items.size(), 0u);
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001347 const DictionaryValue* item = items[0];
joth@chromium.org088ae012011-11-11 01:26:23 +09001348 ASSERT_TRUE(item);
1349 int tid;
1350 EXPECT_TRUE(item->GetInteger("tid", &tid));
1351 EXPECT_EQ(PlatformThread::CurrentId(), static_cast<PlatformThreadId>(tid));
1352
1353 std::string expected_name = "cafe,pub, bar";
1354 std::string tmp;
1355 EXPECT_TRUE(item->GetString("args.name", &tmp));
1356 EXPECT_EQ(expected_name, tmp);
1357}
nduca@chromium.org6d048772011-08-10 00:16:25 +09001358
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001359// Test trace calls made after tracing singleton shut down.
1360//
1361// The singleton is destroyed by our base::AtExitManager, but there can be
1362// code still executing as the C++ static objects are destroyed. This test
1363// forces the singleton to destroy early, and intentinally makes trace calls
1364// afterwards.
1365TEST_F(TraceEventTestFixture, AtExit) {
1366 // Repeat this test a few times. Besides just showing robustness, it also
1367 // allows us to test that events at shutdown do not appear with valid events
1368 // recorded after the system is started again.
1369 for (int i = 0; i < 4; i++) {
1370 // Scope to contain the then destroy the TraceLog singleton.
1371 {
1372 base::ShadowingAtExitManager exit_manager_will_destroy_singletons;
1373
1374 // Setup TraceLog singleton inside this test's exit manager scope
1375 // so that it will be destroyed when this scope closes.
1376 ManualTestSetUp();
1377
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001378 TRACE_EVENT_INSTANT0("all", "not recorded; system not enabled",
1379 TRACE_EVENT_SCOPE_THREAD);
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001380
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001381 BeginTrace();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001382
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001383 TRACE_EVENT_INSTANT0("all", "is recorded 1; system has been enabled",
1384 TRACE_EVENT_SCOPE_THREAD);
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001385 // Trace calls that will cache pointers to categories; they're valid here
1386 TraceCallsWithCachedCategoryPointersPointers(
1387 "is recorded 2; system has been enabled");
1388
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001389 EndTraceAndFlush();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001390 } // scope to destroy singleton
1391 ASSERT_FALSE(TraceLog::GetInstance());
1392
1393 // Now that singleton is destroyed, check what trace events were recorded
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001394 const DictionaryValue* item = NULL;
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001395 ListValue& trace_parsed = trace_parsed_;
1396 EXPECT_FIND_("is recorded 1");
1397 EXPECT_FIND_("is recorded 2");
1398 EXPECT_NOT_FIND_("not recorded");
1399
1400 // Make additional trace event calls on the shutdown system. They should
1401 // all pass cleanly, but the data not be recorded. We'll verify that next
1402 // time around the loop (the only way to flush the trace buffers).
1403 TRACE_EVENT_BEGIN_ETW("not recorded; system shutdown", 0, NULL);
1404 TRACE_EVENT_END_ETW("not recorded; system shutdown", 0, NULL);
1405 TRACE_EVENT_INSTANT_ETW("not recorded; system shutdown", 0, NULL);
1406 TRACE_EVENT0("all", "not recorded; system shutdown");
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001407 TRACE_EVENT_INSTANT0("all", "not recorded; system shutdown",
1408 TRACE_EVENT_SCOPE_THREAD);
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001409 TRACE_EVENT_BEGIN0("all", "not recorded; system shutdown");
1410 TRACE_EVENT_END0("all", "not recorded; system shutdown");
1411
1412 TRACE_EVENT0("new category 0!", "not recorded; system shutdown");
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001413 TRACE_EVENT_INSTANT0("new category 1!", "not recorded; system shutdown",
1414 TRACE_EVENT_SCOPE_THREAD);
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001415 TRACE_EVENT_BEGIN0("new category 2!", "not recorded; system shutdown");
1416 TRACE_EVENT_END0("new category 3!", "not recorded; system shutdown");
1417
1418 // Cached categories should be safe to check, and still disable traces
1419 TraceCallsWithCachedCategoryPointersPointers(
1420 "not recorded; system shutdown");
1421 }
1422}
1423
joth@chromium.org113de992011-07-21 21:28:59 +09001424TEST_F(TraceEventTestFixture, NormallyNoDeepCopy) {
1425 // Test that the TRACE_EVENT macros do not deep-copy their string. If they
1426 // do so it may indicate a performance regression, but more-over it would
1427 // make the DEEP_COPY overloads redundant.
1428 ManualTestSetUp();
1429
1430 std::string name_string("event name");
1431
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001432 BeginTrace();
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001433 TRACE_EVENT_INSTANT0("category", name_string.c_str(),
1434 TRACE_EVENT_SCOPE_THREAD);
joth@chromium.org113de992011-07-21 21:28:59 +09001435
1436 // Modify the string in place (a wholesale reassignment may leave the old
1437 // string intact on the heap).
1438 name_string[0] = '@';
1439
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001440 EndTraceAndFlush();
joth@chromium.org113de992011-07-21 21:28:59 +09001441
1442 EXPECT_FALSE(FindTraceEntry(trace_parsed_, "event name"));
1443 EXPECT_TRUE(FindTraceEntry(trace_parsed_, name_string.c_str()));
1444}
1445
1446TEST_F(TraceEventTestFixture, DeepCopy) {
1447 ManualTestSetUp();
1448
1449 static const char kOriginalName1[] = "name1";
1450 static const char kOriginalName2[] = "name2";
1451 static const char kOriginalName3[] = "name3";
1452 std::string name1(kOriginalName1);
1453 std::string name2(kOriginalName2);
1454 std::string name3(kOriginalName3);
1455 std::string arg1("arg1");
1456 std::string arg2("arg2");
1457 std::string val1("val1");
1458 std::string val2("val2");
1459
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001460 BeginTrace();
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001461 TRACE_EVENT_COPY_INSTANT0("category", name1.c_str(),
1462 TRACE_EVENT_SCOPE_THREAD);
joth@chromium.org113de992011-07-21 21:28:59 +09001463 TRACE_EVENT_COPY_BEGIN1("category", name2.c_str(),
1464 arg1.c_str(), 5);
1465 TRACE_EVENT_COPY_END2("category", name3.c_str(),
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001466 arg1.c_str(), val1,
1467 arg2.c_str(), val2);
joth@chromium.org113de992011-07-21 21:28:59 +09001468
1469 // As per NormallyNoDeepCopy, modify the strings in place.
1470 name1[0] = name2[0] = name3[0] = arg1[0] = arg2[0] = val1[0] = val2[0] = '@';
1471
jbates@chromium.org6f1b35c2012-09-01 09:52:15 +09001472 EndTraceAndFlush();
joth@chromium.org113de992011-07-21 21:28:59 +09001473
1474 EXPECT_FALSE(FindTraceEntry(trace_parsed_, name1.c_str()));
1475 EXPECT_FALSE(FindTraceEntry(trace_parsed_, name2.c_str()));
1476 EXPECT_FALSE(FindTraceEntry(trace_parsed_, name3.c_str()));
1477
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +09001478 const DictionaryValue* entry1 = FindTraceEntry(trace_parsed_, kOriginalName1);
1479 const DictionaryValue* entry2 = FindTraceEntry(trace_parsed_, kOriginalName2);
1480 const DictionaryValue* entry3 = FindTraceEntry(trace_parsed_, kOriginalName3);
joth@chromium.org113de992011-07-21 21:28:59 +09001481 ASSERT_TRUE(entry1);
1482 ASSERT_TRUE(entry2);
1483 ASSERT_TRUE(entry3);
1484
1485 int i;
1486 EXPECT_FALSE(entry2->GetInteger("args.@rg1", &i));
1487 EXPECT_TRUE(entry2->GetInteger("args.arg1", &i));
1488 EXPECT_EQ(5, i);
1489
1490 std::string s;
1491 EXPECT_TRUE(entry3->GetString("args.arg1", &s));
1492 EXPECT_EQ("val1", s);
1493 EXPECT_TRUE(entry3->GetString("args.arg2", &s));
1494 EXPECT_EQ("val2", s);
1495}
1496
jbates@chromium.org6a092d72011-10-25 01:34:08 +09001497// Test that TraceResultBuffer outputs the correct result whether it is added
1498// in chunks or added all at once.
1499TEST_F(TraceEventTestFixture, TraceResultBuffer) {
1500 ManualTestSetUp();
1501
1502 Clear();
1503
1504 trace_buffer_.Start();
1505 trace_buffer_.AddFragment("bla1");
1506 trace_buffer_.AddFragment("bla2");
1507 trace_buffer_.AddFragment("bla3,bla4");
1508 trace_buffer_.Finish();
1509 EXPECT_STREQ(json_output_.json_output.c_str(), "[bla1,bla2,bla3,bla4]");
1510
1511 Clear();
1512
1513 trace_buffer_.Start();
1514 trace_buffer_.AddFragment("bla1,bla2,bla3,bla4");
1515 trace_buffer_.Finish();
1516 EXPECT_STREQ(json_output_.json_output.c_str(), "[bla1,bla2,bla3,bla4]");
1517}
1518
dsinclair@chromium.org1cde1592013-01-15 01:53:06 +09001519// Test that trace_event parameters are not evaluated if the tracing
1520// system is disabled.
1521TEST_F(TraceEventTestFixture, TracingIsLazy) {
1522 ManualTestSetUp();
1523 BeginTrace();
1524
1525 int a = 0;
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001526 TRACE_EVENT_INSTANT1("category", "test", TRACE_EVENT_SCOPE_THREAD, "a", a++);
dsinclair@chromium.org1cde1592013-01-15 01:53:06 +09001527 EXPECT_EQ(1, a);
1528
1529 TraceLog::GetInstance()->SetDisabled();
1530
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001531 TRACE_EVENT_INSTANT1("category", "test", TRACE_EVENT_SCOPE_THREAD, "a", a++);
dsinclair@chromium.org1cde1592013-01-15 01:53:06 +09001532 EXPECT_EQ(1, a);
1533
1534 EndTraceAndFlush();
1535}
1536
caseq@google.comedcf6262013-01-16 20:41:57 +09001537TEST_F(TraceEventTestFixture, TraceEnableDisable) {
1538 ManualTestSetUp();
1539
1540 TraceLog* trace_log = TraceLog::GetInstance();
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +09001541 CategoryFilter cf_inc_all("*");
1542 trace_log->SetEnabled(cf_inc_all, TraceLog::RECORD_UNTIL_FULL);
caseq@google.comedcf6262013-01-16 20:41:57 +09001543 EXPECT_TRUE(trace_log->IsEnabled());
1544 trace_log->SetDisabled();
1545 EXPECT_FALSE(trace_log->IsEnabled());
1546
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +09001547 trace_log->SetEnabled(cf_inc_all, TraceLog::RECORD_UNTIL_FULL);
caseq@google.comedcf6262013-01-16 20:41:57 +09001548 EXPECT_TRUE(trace_log->IsEnabled());
1549 const std::vector<std::string> empty;
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +09001550 trace_log->SetEnabled(CategoryFilter(""), TraceLog::RECORD_UNTIL_FULL);
caseq@google.comedcf6262013-01-16 20:41:57 +09001551 EXPECT_TRUE(trace_log->IsEnabled());
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +09001552 trace_log->SetDisabled();
caseq@google.comedcf6262013-01-16 20:41:57 +09001553 EXPECT_TRUE(trace_log->IsEnabled());
1554 trace_log->SetDisabled();
1555 EXPECT_FALSE(trace_log->IsEnabled());
1556}
1557
1558TEST_F(TraceEventTestFixture, TraceCategoriesAfterNestedEnable) {
1559 ManualTestSetUp();
1560
1561 TraceLog* trace_log = TraceLog::GetInstance();
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +09001562 trace_log->SetEnabled(CategoryFilter("foo,bar"), TraceLog::RECORD_UNTIL_FULL);
1563 EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("foo"));
1564 EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("bar"));
1565 EXPECT_FALSE(*trace_log->GetCategoryGroupEnabled("baz"));
1566 trace_log->SetEnabled(CategoryFilter("foo2"), TraceLog::RECORD_UNTIL_FULL);
1567 EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("foo2"));
1568 EXPECT_FALSE(*trace_log->GetCategoryGroupEnabled("baz"));
1569 trace_log->SetEnabled(CategoryFilter(""), TraceLog::RECORD_UNTIL_FULL);
1570 EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("foo"));
1571 EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("baz"));
caseq@google.comedcf6262013-01-16 20:41:57 +09001572 trace_log->SetDisabled();
1573 trace_log->SetDisabled();
1574 trace_log->SetDisabled();
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +09001575 EXPECT_FALSE(*trace_log->GetCategoryGroupEnabled("foo"));
1576 EXPECT_FALSE(*trace_log->GetCategoryGroupEnabled("baz"));
caseq@google.comedcf6262013-01-16 20:41:57 +09001577
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +09001578 trace_log->SetEnabled(CategoryFilter("-foo,-bar"),
1579 TraceLog::RECORD_UNTIL_FULL);
1580 EXPECT_FALSE(*trace_log->GetCategoryGroupEnabled("foo"));
1581 EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("baz"));
1582 trace_log->SetEnabled(CategoryFilter("moo"), TraceLog::RECORD_UNTIL_FULL);
1583 EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("baz"));
1584 EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("moo"));
1585 EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("foo"));
caseq@google.comedcf6262013-01-16 20:41:57 +09001586 trace_log->SetDisabled();
1587 trace_log->SetDisabled();
1588}
1589
dsinclair@chromium.orga7fb8d62013-02-23 11:09:53 +09001590TEST_F(TraceEventTestFixture, TraceOptionsParsing) {
1591 ManualTestSetUp();
1592
dcheng@chromium.org8164c2c2013-04-09 17:46:45 +09001593 EXPECT_EQ(TraceLog::RECORD_UNTIL_FULL,
1594 TraceLog::TraceOptionsFromString(std::string()));
dsinclair@chromium.orga7fb8d62013-02-23 11:09:53 +09001595
1596 EXPECT_EQ(TraceLog::RECORD_UNTIL_FULL,
1597 TraceLog::TraceOptionsFromString("record-until-full"));
dsinclair@chromium.org9e717e82013-03-16 08:28:44 +09001598 EXPECT_EQ(TraceLog::RECORD_CONTINUOUSLY,
1599 TraceLog::TraceOptionsFromString("record-continuously"));
dsinclair@chromium.orga7fb8d62013-02-23 11:09:53 +09001600}
1601
scottmg@chromium.orgcdd292f2013-02-26 10:39:52 +09001602TEST_F(TraceEventTestFixture, TraceSampling) {
1603 ManualTestSetUp();
1604
1605 event_watch_notification_ = 0;
1606 TraceLog::GetInstance()->SetEnabled(
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +09001607 CategoryFilter("*"),
scottmg@chromium.orgcdd292f2013-02-26 10:39:52 +09001608 TraceLog::Options(TraceLog::RECORD_UNTIL_FULL |
1609 TraceLog::ENABLE_SAMPLING));
1610
1611 WaitableEvent* sampled = new WaitableEvent(false, false);
1612 TraceLog::GetInstance()->InstallWaitableEventForSamplingTesting(sampled);
1613
1614 TRACE_EVENT_SAMPLE_STATE(1, "cc", "Stuff");
1615 sampled->Wait();
1616 TRACE_EVENT_SAMPLE_STATE(1, "cc", "Things");
1617 sampled->Wait();
1618
1619 EndTraceAndFlush();
1620
1621 // Make sure we hit at least once.
1622 EXPECT_TRUE(FindNamePhase("Stuff", "P"));
1623 EXPECT_TRUE(FindNamePhase("Things", "P"));
1624}
1625
caseq@google.com5f3846c2013-02-27 18:11:12 +09001626class TraceEventCallbackTest : public TraceEventTestFixture {
1627 public:
1628 virtual void SetUp() OVERRIDE {
1629 TraceEventTestFixture::SetUp();
1630 ManualTestSetUp();
1631 ASSERT_EQ(NULL, s_instance);
1632 s_instance = this;
1633 }
1634 virtual void TearDown() OVERRIDE {
1635 while (TraceLog::GetInstance()->IsEnabled())
1636 TraceLog::GetInstance()->SetDisabled();
1637 ASSERT_TRUE(!!s_instance);
1638 s_instance = NULL;
1639 TraceEventTestFixture::TearDown();
1640 }
1641
1642 protected:
1643 std::vector<std::string> collected_events_;
1644
1645 static TraceEventCallbackTest* s_instance;
1646 static void Callback(char phase,
1647 const unsigned char* category_enabled,
1648 const char* name,
1649 unsigned long long id,
1650 int num_args,
1651 const char* const arg_names[],
1652 const unsigned char arg_types[],
1653 const unsigned long long arg_values[],
1654 unsigned char flags) {
1655 s_instance->collected_events_.push_back(name);
1656 }
1657};
1658
1659TraceEventCallbackTest* TraceEventCallbackTest::s_instance;
1660
1661TEST_F(TraceEventCallbackTest, TraceEventCallback) {
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +09001662 TRACE_EVENT_INSTANT0("all", "before enable", TRACE_EVENT_SCOPE_THREAD);
1663 TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
1664 TraceLog::RECORD_UNTIL_FULL);
1665 TRACE_EVENT_INSTANT0("all", "before callback set", TRACE_EVENT_SCOPE_THREAD);
caseq@google.com5f3846c2013-02-27 18:11:12 +09001666 TraceLog::GetInstance()->SetEventCallback(Callback);
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001667 TRACE_EVENT_INSTANT0("all", "event1", TRACE_EVENT_SCOPE_GLOBAL);
1668 TRACE_EVENT_INSTANT0("all", "event2", TRACE_EVENT_SCOPE_GLOBAL);
caseq@google.com5f3846c2013-02-27 18:11:12 +09001669 TraceLog::GetInstance()->SetEventCallback(NULL);
simonjam@chromium.orgfd92ef32013-03-26 16:42:42 +09001670 TRACE_EVENT_INSTANT0("all", "after callback removed",
1671 TRACE_EVENT_SCOPE_GLOBAL);
caseq@google.com4cba9892013-04-29 18:08:28 +09001672 ASSERT_EQ(2u, collected_events_.size());
caseq@google.com5f3846c2013-02-27 18:11:12 +09001673 EXPECT_EQ("event1", collected_events_[0]);
1674 EXPECT_EQ("event2", collected_events_[1]);
1675}
1676
caseq@google.com4cba9892013-04-29 18:08:28 +09001677TEST_F(TraceEventCallbackTest, TraceEventCallbackWhileFull) {
1678 TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"),
1679 TraceLog::RECORD_UNTIL_FULL);
1680 do {
1681 TRACE_EVENT_INSTANT0("all", "badger badger", TRACE_EVENT_SCOPE_GLOBAL);
1682 } while ((notifications_received_ & TraceLog::TRACE_BUFFER_FULL) == 0);
1683 TraceLog::GetInstance()->SetEventCallback(Callback);
1684 TRACE_EVENT_INSTANT0("all", "a snake", TRACE_EVENT_SCOPE_GLOBAL);
1685 TraceLog::GetInstance()->SetEventCallback(NULL);
1686 ASSERT_EQ(1u, collected_events_.size());
1687 EXPECT_EQ("a snake", collected_events_[0]);
1688}
1689
dsinclair@chromium.org9e717e82013-03-16 08:28:44 +09001690// TODO(dsinclair): Continuous Tracing unit test.
1691
rubentopo@gmail.com56a2b642013-04-19 17:49:03 +09001692// Test the category filter.
1693TEST_F(TraceEventTestFixture, CategoryFilter) {
1694 ManualTestSetUp();
1695
1696 // Using the default filter.
1697 CategoryFilter default_cf = CategoryFilter(
1698 CategoryFilter::kDefaultCategoryFilterString);
1699 std::string category_filter_str = default_cf.ToString();
1700 EXPECT_STREQ("-*Debug,-*Test", category_filter_str.c_str());
1701 EXPECT_TRUE(default_cf.IsCategoryGroupEnabled("not-excluded-category"));
1702 EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("Category1,CategoryDebug"));
1703 EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("CategoryDebug,Category1"));
1704 EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("CategoryTest,Category2"));
1705
1706 // Make sure that upon an empty string, we fall back to the default filter.
1707 default_cf = CategoryFilter("");
1708 category_filter_str = default_cf.ToString();
1709 EXPECT_STREQ("-*Debug,-*Test", category_filter_str.c_str());
1710 EXPECT_TRUE(default_cf.IsCategoryGroupEnabled("not-excluded-category"));
1711 EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("Category1,CategoryDebug"));
1712 EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("CategoryDebug,Category1"));
1713 EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("CategoryTest,Category2"));
1714
1715 // Using an arbitrary non-empty filter.
1716 CategoryFilter cf("included,-excluded,inc_pattern*,-exc_pattern*");
1717 category_filter_str = cf.ToString();
1718 EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*",
1719 category_filter_str.c_str());
1720 EXPECT_TRUE(cf.IsCategoryGroupEnabled("included"));
1721 EXPECT_TRUE(cf.IsCategoryGroupEnabled("inc_pattern_category"));
1722 EXPECT_FALSE(cf.IsCategoryGroupEnabled("exc_pattern_category"));
1723 EXPECT_FALSE(cf.IsCategoryGroupEnabled("excluded"));
1724 EXPECT_FALSE(cf.IsCategoryGroupEnabled("not-excluded-nor-included"));
1725 EXPECT_FALSE(cf.IsCategoryGroupEnabled("Category1,CategoryDebug"));
1726 EXPECT_FALSE(cf.IsCategoryGroupEnabled("CategoryDebug,Category1"));
1727 EXPECT_FALSE(cf.IsCategoryGroupEnabled("CategoryTest,Category2"));
1728
1729 cf.Merge(default_cf);
1730 category_filter_str = cf.ToString();
1731 EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*,-*Debug,-*Test",
1732 category_filter_str.c_str());
1733 cf.Clear();
1734 EXPECT_FALSE(cf.HasIncludedPatterns());
1735
1736 CategoryFilter reconstructed_cf(category_filter_str);
1737 category_filter_str = reconstructed_cf.ToString();
1738 EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*,-*Debug,-*Test",
1739 category_filter_str.c_str());
1740
1741 // One included category.
1742 CategoryFilter one_inc_cf("only_inc_cat");
1743 category_filter_str = one_inc_cf.ToString();
1744 EXPECT_STREQ("only_inc_cat", category_filter_str.c_str());
1745
1746 // One excluded category.
1747 CategoryFilter one_exc_cf("-only_exc_cat");
1748 category_filter_str = one_exc_cf.ToString();
1749 EXPECT_STREQ("-only_exc_cat", category_filter_str.c_str());
1750
1751 // Test that IsEmptyOrContainsLeadingOrTrailingWhitespace actually catches
1752 // categories that are explicitly forbiden.
1753 // This method is called in a DCHECK to assert that we don't have these types
1754 // of strings as categories.
1755 EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
1756 " bad_category "));
1757 EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
1758 " bad_category"));
1759 EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
1760 "bad_category "));
1761 EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
1762 " bad_category"));
1763 EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
1764 "bad_category "));
1765 EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
1766 " bad_category "));
1767 EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
1768 ""));
1769 EXPECT_FALSE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
1770 "good_category"));
1771}
1772
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001773} // namespace debug
1774} // namespace base