blob: 94be430a843d0f5c6cc0ffad2b58d6949a5e68e8 [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
5#include "base/debug/trace_event.h"
6
7#include "base/bind.h"
8#include "base/command_line.h"
9#include "base/json/json_reader.h"
10#include "base/json/json_writer.h"
jbates@chromium.org1f18e462011-09-07 02:56:24 +090011#include "base/memory/ref_counted_memory.h"
scheib@chromium.org603f46e2011-05-10 11:23:58 +090012#include "base/memory/scoped_ptr.h"
joth@chromium.org088ae012011-11-11 01:26:23 +090013#include "base/memory/singleton.h"
nduca@chromium.org6d048772011-08-10 00:16:25 +090014#include "base/process_util.h"
scheib@chromium.org603f46e2011-05-10 11:23:58 +090015#include "base/stringprintf.h"
16#include "base/synchronization/waitable_event.h"
joth@chromium.org088ae012011-11-11 01:26:23 +090017#include "base/threading/platform_thread.h"
scheib@chromium.org603f46e2011-05-10 11:23:58 +090018#include "base/threading/thread.h"
19#include "base/values.h"
20#include "testing/gmock/include/gmock/gmock.h"
21#include "testing/gtest/include/gtest/gtest.h"
22
23namespace base {
24namespace debug {
25
26namespace {
27
jbates@chromium.org11d4c362011-09-13 07:03:41 +090028enum CompareOp {
29 IS_EQUAL,
30 IS_NOT_EQUAL,
31};
32
jbates@chromium.orgb3cab862011-05-14 08:30:35 +090033struct JsonKeyValue {
34 const char* key;
35 const char* value;
jbates@chromium.org11d4c362011-09-13 07:03:41 +090036 CompareOp op;
jbates@chromium.orgb3cab862011-05-14 08:30:35 +090037};
38
scheib@chromium.org603f46e2011-05-10 11:23:58 +090039class TraceEventTestFixture : public testing::Test {
40 public:
joth@chromium.org113de992011-07-21 21:28:59 +090041 // This fixture does not use SetUp() because the fixture must be manually set
42 // up multiple times when testing AtExit. Use ManualTestSetUp for this.
scheib@chromium.org603f46e2011-05-10 11:23:58 +090043 void ManualTestSetUp();
ajwong@chromium.orgec1750a2011-06-27 01:22:50 +090044 void OnTraceDataCollected(
husky@chromium.org3b366292012-02-24 13:17:06 +090045 const scoped_refptr<base::RefCountedString>& events_str);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +090046 DictionaryValue* FindMatchingTraceEntry(const JsonKeyValue* key_values);
47 DictionaryValue* FindNamePhase(const char* name, const char* phase);
48 DictionaryValue* FindNamePhaseKeyValue(const char* name,
49 const char* phase,
50 const char* key,
51 const char* value);
jbates@chromium.org11d4c362011-09-13 07:03:41 +090052 bool FindMatchingValue(const char* key,
53 const char* value);
54 bool FindNonMatchingValue(const char* key,
55 const char* value);
56 void Clear() {
jbates@chromium.org11d4c362011-09-13 07:03:41 +090057 trace_parsed_.Clear();
jbates@chromium.org6a092d72011-10-25 01:34:08 +090058 json_output_.json_output.clear();
jbates@chromium.org11d4c362011-09-13 07:03:41 +090059 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +090060
joth@chromium.org088ae012011-11-11 01:26:23 +090061 virtual void SetUp() {
62 old_thread_name_ = PlatformThread::GetName();
63 }
64 virtual void TearDown() {
nduca@chromium.org6a7360c2012-02-20 15:35:15 +090065 if (TraceLog::GetInstance())
66 EXPECT_FALSE(TraceLog::GetInstance()->IsEnabled());
joth@chromium.org088ae012011-11-11 01:26:23 +090067 PlatformThread::SetName(old_thread_name_ ? old_thread_name_ : "");
68 }
69
70 const char* old_thread_name_;
scheib@chromium.org603f46e2011-05-10 11:23:58 +090071 ListValue trace_parsed_;
jbates@chromium.org6a092d72011-10-25 01:34:08 +090072 base::debug::TraceResultBuffer trace_buffer_;
73 base::debug::TraceResultBuffer::SimpleOutput json_output_;
scheib@chromium.org603f46e2011-05-10 11:23:58 +090074
75 private:
76 // We want our singleton torn down after each test.
77 ShadowingAtExitManager at_exit_manager_;
jbates@chromium.orgb84db522011-10-04 02:51:25 +090078 Lock lock_;
scheib@chromium.org603f46e2011-05-10 11:23:58 +090079};
80
81void TraceEventTestFixture::ManualTestSetUp() {
jbates@chromium.orgb84db522011-10-04 02:51:25 +090082 TraceLog::DeleteForTesting();
scheib@chromium.org603f46e2011-05-10 11:23:58 +090083 TraceLog::Resurrect();
84 TraceLog* tracelog = TraceLog::GetInstance();
85 ASSERT_TRUE(tracelog);
86 ASSERT_FALSE(tracelog->IsEnabled());
87 tracelog->SetOutputCallback(
jbates@chromium.orgb84db522011-10-04 02:51:25 +090088 base::Bind(&TraceEventTestFixture::OnTraceDataCollected,
89 base::Unretained(this)));
jbates@chromium.org6a092d72011-10-25 01:34:08 +090090 trace_buffer_.SetOutputCallback(json_output_.GetCallback());
scheib@chromium.org603f46e2011-05-10 11:23:58 +090091}
92
93void TraceEventTestFixture::OnTraceDataCollected(
husky@chromium.org3b366292012-02-24 13:17:06 +090094 const scoped_refptr<base::RefCountedString>& events_str) {
jbates@chromium.orgb84db522011-10-04 02:51:25 +090095 AutoLock lock(lock_);
jbates@chromium.org6a092d72011-10-25 01:34:08 +090096 json_output_.json_output.clear();
97 trace_buffer_.Start();
husky@chromium.org3b366292012-02-24 13:17:06 +090098 trace_buffer_.AddFragment(events_str->data());
jbates@chromium.org6a092d72011-10-25 01:34:08 +090099 trace_buffer_.Finish();
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900100
101 scoped_ptr<Value> root;
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900102 root.reset(base::JSONReader::Read(json_output_.json_output, false));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900103
jbates@chromium.org59c27602012-01-13 12:12:44 +0900104 if (!root.get()) {
105 LOG(ERROR) << json_output_.json_output;
106 }
107
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900108 ListValue* root_list = NULL;
109 ASSERT_TRUE(root.get());
110 ASSERT_TRUE(root->GetAsList(&root_list));
111
112 // Move items into our aggregate collection
113 while (root_list->GetSize()) {
114 Value* item = NULL;
115 root_list->Remove(0, &item);
116 trace_parsed_.Append(item);
117 }
118}
119
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900120static bool CompareJsonValues(const std::string& lhs,
121 const std::string& rhs,
122 CompareOp op) {
123 switch (op) {
124 case IS_EQUAL:
125 return lhs == rhs;
126 case IS_NOT_EQUAL:
127 return lhs != rhs;
128 default:
129 CHECK(0);
130 }
131 return false;
132}
133
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900134static bool IsKeyValueInDict(const JsonKeyValue* key_value,
135 DictionaryValue* dict) {
136 Value* value = NULL;
137 std::string value_str;
138 if (dict->Get(key_value->key, &value) &&
139 value->GetAsString(&value_str) &&
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900140 CompareJsonValues(value_str, key_value->value, key_value->op))
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900141 return true;
142
143 // Recurse to test arguments
144 DictionaryValue* args_dict = NULL;
145 dict->GetDictionary("args", &args_dict);
146 if (args_dict)
147 return IsKeyValueInDict(key_value, args_dict);
148
149 return false;
150}
151
152static bool IsAllKeyValueInDict(const JsonKeyValue* key_values,
153 DictionaryValue* dict) {
154 // Scan all key_values, they must all be present and equal.
155 while (key_values && key_values->key) {
156 if (!IsKeyValueInDict(key_values, dict))
157 return false;
158 ++key_values;
159 }
160 return true;
161}
162
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900163DictionaryValue* TraceEventTestFixture::FindMatchingTraceEntry(
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900164 const JsonKeyValue* key_values) {
165 // Scan all items
166 size_t trace_parsed_count = trace_parsed_.GetSize();
167 for (size_t i = 0; i < trace_parsed_count; i++) {
168 Value* value = NULL;
169 trace_parsed_.Get(i, &value);
170 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
171 continue;
172 DictionaryValue* dict = static_cast<DictionaryValue*>(value);
173
174 if (IsAllKeyValueInDict(key_values, dict))
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900175 return dict;
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900176 }
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900177 return NULL;
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900178}
179
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900180DictionaryValue* TraceEventTestFixture::FindNamePhase(const char* name,
181 const char* phase) {
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900182 JsonKeyValue key_values[] = {
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900183 {"name", name, IS_EQUAL},
184 {"ph", phase, IS_EQUAL},
185 {0, 0, IS_EQUAL}
186 };
187 return FindMatchingTraceEntry(key_values);
188}
189
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900190DictionaryValue* TraceEventTestFixture::FindNamePhaseKeyValue(
191 const char* name,
192 const char* phase,
193 const char* key,
194 const char* value) {
195 JsonKeyValue key_values[] = {
196 {"name", name, IS_EQUAL},
197 {"ph", phase, IS_EQUAL},
198 {key, value, IS_EQUAL},
199 {0, 0, IS_EQUAL}
200 };
201 return FindMatchingTraceEntry(key_values);
202}
203
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900204bool TraceEventTestFixture::FindMatchingValue(const char* key,
205 const char* value) {
206 JsonKeyValue key_values[] = {
207 {key, value, IS_EQUAL},
208 {0, 0, IS_EQUAL}
209 };
210 return FindMatchingTraceEntry(key_values);
211}
212
213bool TraceEventTestFixture::FindNonMatchingValue(const char* key,
214 const char* value) {
215 JsonKeyValue key_values[] = {
216 {key, value, IS_NOT_EQUAL},
217 {0, 0, IS_EQUAL}
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900218 };
219 return FindMatchingTraceEntry(key_values);
220}
221
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900222bool IsStringInDict(const char* string_to_match, DictionaryValue* dict) {
223 for (DictionaryValue::key_iterator ikey = dict->begin_keys();
224 ikey != dict->end_keys(); ++ikey) {
225 Value* child = NULL;
226 if (!dict->GetWithoutPathExpansion(*ikey, &child))
227 continue;
228
229 if ((*ikey).find(string_to_match) != std::string::npos)
230 return true;
231
232 std::string value_str;
233 child->GetAsString(&value_str);
234 if (value_str.find(string_to_match) != std::string::npos)
235 return true;
236 }
237
238 // Recurse to test arguments
239 DictionaryValue* args_dict = NULL;
240 dict->GetDictionary("args", &args_dict);
241 if (args_dict)
242 return IsStringInDict(string_to_match, args_dict);
243
244 return false;
245}
246
247DictionaryValue* FindTraceEntry(const ListValue& trace_parsed,
nduca@chromium.org6d048772011-08-10 00:16:25 +0900248 const char* string_to_match,
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900249 DictionaryValue* match_after_this_item = NULL) {
250 // Scan all items
251 size_t trace_parsed_count = trace_parsed.GetSize();
252 for (size_t i = 0; i < trace_parsed_count; i++) {
253 Value* value = NULL;
254 trace_parsed.Get(i, &value);
255 if (match_after_this_item) {
256 if (value == match_after_this_item)
257 match_after_this_item = NULL;
258 continue;
259 }
260 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
261 continue;
262 DictionaryValue* dict = static_cast<DictionaryValue*>(value);
263
264 if (IsStringInDict(string_to_match, dict))
265 return dict;
266 }
267 return NULL;
268}
269
nduca@chromium.org6d048772011-08-10 00:16:25 +0900270std::vector<DictionaryValue*> FindTraceEntries(
271 const ListValue& trace_parsed,
272 const char* string_to_match) {
273 std::vector<DictionaryValue*> hits;
274 size_t trace_parsed_count = trace_parsed.GetSize();
275 for (size_t i = 0; i < trace_parsed_count; i++) {
276 Value* value = NULL;
277 trace_parsed.Get(i, &value);
278 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
279 continue;
280 DictionaryValue* dict = static_cast<DictionaryValue*>(value);
281
282 if (IsStringInDict(string_to_match, dict))
283 hits.push_back(dict);
284 }
285 return hits;
286}
287
288void TraceWithAllMacroVariants(WaitableEvent* task_complete_event) {
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900289 {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900290 TRACE_EVENT_BEGIN_ETW("TRACE_EVENT_BEGIN_ETW call", 0x1122, "extrastring1");
291 TRACE_EVENT_END_ETW("TRACE_EVENT_END_ETW call", 0x3344, "extrastring2");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900292 TRACE_EVENT_INSTANT_ETW("TRACE_EVENT_INSTANT_ETW call",
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900293 0x5566, "extrastring3");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900294
295 TRACE_EVENT0("all", "TRACE_EVENT0 call");
296 TRACE_EVENT1("all", "TRACE_EVENT1 call", "name1", "value1");
297 TRACE_EVENT2("all", "TRACE_EVENT2 call",
jbates@chromium.org788d5a12011-09-07 09:43:11 +0900298 "name1", "\"value1\"",
299 "name2", "value\\2");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900300
301 TRACE_EVENT_INSTANT0("all", "TRACE_EVENT_INSTANT0 call");
302 TRACE_EVENT_INSTANT1("all", "TRACE_EVENT_INSTANT1 call", "name1", "value1");
303 TRACE_EVENT_INSTANT2("all", "TRACE_EVENT_INSTANT2 call",
304 "name1", "value1",
305 "name2", "value2");
306
307 TRACE_EVENT_BEGIN0("all", "TRACE_EVENT_BEGIN0 call");
308 TRACE_EVENT_BEGIN1("all", "TRACE_EVENT_BEGIN1 call", "name1", "value1");
309 TRACE_EVENT_BEGIN2("all", "TRACE_EVENT_BEGIN2 call",
310 "name1", "value1",
311 "name2", "value2");
312
313 TRACE_EVENT_END0("all", "TRACE_EVENT_END0 call");
314 TRACE_EVENT_END1("all", "TRACE_EVENT_END1 call", "name1", "value1");
315 TRACE_EVENT_END2("all", "TRACE_EVENT_END2 call",
316 "name1", "value1",
317 "name2", "value2");
nduca@chromium.org62210b02011-11-18 18:36:36 +0900318
jbates@chromium.org59c27602012-01-13 12:12:44 +0900319 TRACE_EVENT_IF_LONGER_THAN0(0, "all", "TRACE_EVENT_IF_LONGER_THAN0 call");
320 TRACE_EVENT_IF_LONGER_THAN1(0, "all", "TRACE_EVENT_IF_LONGER_THAN1 call",
321 "name1", "value1");
322 TRACE_EVENT_IF_LONGER_THAN2(0, "all", "TRACE_EVENT_IF_LONGER_THAN2 call",
323 "name1", "value1",
324 "name2", "value2");
325
jbates@chromium.org88295f92012-03-01 12:04:59 +0900326 TRACE_EVENT_ASYNC_BEGIN0("all", "TRACE_EVENT_ASYNC_BEGIN0 call", 5);
327 TRACE_EVENT_ASYNC_BEGIN1("all", "TRACE_EVENT_ASYNC_BEGIN1 call", 5,
328 "name1", "value1");
329 TRACE_EVENT_ASYNC_BEGIN2("all", "TRACE_EVENT_ASYNC_BEGIN2 call", 5,
330 "name1", "value1",
331 "name2", "value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900332
jbates@chromium.org88295f92012-03-01 12:04:59 +0900333 TRACE_EVENT_ASYNC_STEP0("all", "TRACE_EVENT_ASYNC_STEP0 call", 5);
334 TRACE_EVENT_ASYNC_STEP1("all", "TRACE_EVENT_ASYNC_STEP1 call", 5,
335 "name1", "value1");
336 TRACE_EVENT_ASYNC_STEP2("all", "TRACE_EVENT_ASYNC_STEP2 call", 5,
337 "name1", "value1",
338 "name2", "value2");
339
340 TRACE_EVENT_ASYNC_END0("all", "TRACE_EVENT_ASYNC_END0 call", 5);
341 TRACE_EVENT_ASYNC_END1("all", "TRACE_EVENT_ASYNC_END1 call", 5,
342 "name1", "value1");
343 TRACE_EVENT_ASYNC_END2("all", "TRACE_EVENT_ASYNC_END2 call", 5,
344 "name1", "value1",
345 "name2", "value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900346
347 TRACE_EVENT_BEGIN_ETW("TRACE_EVENT_BEGIN_ETW0 call", 5, NULL);
348 TRACE_EVENT_BEGIN_ETW("TRACE_EVENT_BEGIN_ETW1 call", 5, "value");
349 TRACE_EVENT_END_ETW("TRACE_EVENT_END_ETW0 call", 5, NULL);
350 TRACE_EVENT_END_ETW("TRACE_EVENT_END_ETW1 call", 5, "value");
351 TRACE_EVENT_INSTANT_ETW("TRACE_EVENT_INSTANT_ETW0 call", 5, NULL);
352 TRACE_EVENT_INSTANT_ETW("TRACE_EVENT_INSTANT_ETW1 call", 5, "value");
353
nduca@chromium.org62210b02011-11-18 18:36:36 +0900354 TRACE_COUNTER1("all", "TRACE_COUNTER1 call", 31415);
355 TRACE_COUNTER2("all", "TRACE_COUNTER2 call",
356 "a", 30000,
357 "b", 1415);
piman@chromium.org902b2952011-12-16 10:19:06 +0900358
359 TRACE_COUNTER_ID1("all", "TRACE_COUNTER_ID1 call", 0x319009, 31415);
360 TRACE_COUNTER_ID2("all", "TRACE_COUNTER_ID2 call", 0x319009,
361 "a", 30000, "b", 1415);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900362 } // Scope close causes TRACE_EVENT0 etc to send their END events.
363
364 if (task_complete_event)
365 task_complete_event->Signal();
366}
367
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900368void ValidateAllTraceMacrosCreatedData(const ListValue& trace_parsed) {
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900369 DictionaryValue* item = NULL;
370
371#define EXPECT_FIND_(string) \
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900372 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, string)));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900373#define EXPECT_NOT_FIND_(string) \
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900374 EXPECT_FALSE((item = FindTraceEntry(trace_parsed, string)));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900375#define EXPECT_SUB_FIND_(string) \
jbates@chromium.orgb84db522011-10-04 02:51:25 +0900376 if (item) EXPECT_TRUE((IsStringInDict(string, item)));
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900377
378 EXPECT_FIND_("ETW Trace Event");
379 EXPECT_FIND_("all");
380 EXPECT_FIND_("TRACE_EVENT_BEGIN_ETW call");
381 {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900382 std::string str_val;
383 EXPECT_TRUE(item && item->GetString("args.id", &str_val));
384 EXPECT_STREQ("1122", str_val.c_str());
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900385 }
386 EXPECT_SUB_FIND_("extrastring1");
387 EXPECT_FIND_("TRACE_EVENT_END_ETW call");
388 EXPECT_FIND_("TRACE_EVENT_INSTANT_ETW call");
389 EXPECT_FIND_("TRACE_EVENT0 call");
390 {
391 std::string ph_begin;
392 std::string ph_end;
393 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, "TRACE_EVENT0 call")));
394 EXPECT_TRUE((item && item->GetString("ph", &ph_begin)));
395 EXPECT_TRUE((item = FindTraceEntry(trace_parsed, "TRACE_EVENT0 call",
396 item)));
397 EXPECT_TRUE((item && item->GetString("ph", &ph_end)));
398 EXPECT_EQ("B", ph_begin);
399 EXPECT_EQ("E", ph_end);
400 }
401 EXPECT_FIND_("TRACE_EVENT1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900402 EXPECT_SUB_FIND_("name1");
403 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900404 EXPECT_FIND_("TRACE_EVENT2 call");
405 EXPECT_SUB_FIND_("name1");
jbates@chromium.org788d5a12011-09-07 09:43:11 +0900406 EXPECT_SUB_FIND_("\"value1\"");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900407 EXPECT_SUB_FIND_("name2");
jbates@chromium.org788d5a12011-09-07 09:43:11 +0900408 EXPECT_SUB_FIND_("value\\2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900409
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900410 EXPECT_FIND_("TRACE_EVENT_INSTANT0 call");
411 EXPECT_FIND_("TRACE_EVENT_INSTANT1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900412 EXPECT_SUB_FIND_("name1");
413 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900414 EXPECT_FIND_("TRACE_EVENT_INSTANT2 call");
415 EXPECT_SUB_FIND_("name1");
416 EXPECT_SUB_FIND_("value1");
417 EXPECT_SUB_FIND_("name2");
418 EXPECT_SUB_FIND_("value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900419
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900420 EXPECT_FIND_("TRACE_EVENT_BEGIN0 call");
421 EXPECT_FIND_("TRACE_EVENT_BEGIN1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900422 EXPECT_SUB_FIND_("name1");
423 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900424 EXPECT_FIND_("TRACE_EVENT_BEGIN2 call");
425 EXPECT_SUB_FIND_("name1");
426 EXPECT_SUB_FIND_("value1");
427 EXPECT_SUB_FIND_("name2");
428 EXPECT_SUB_FIND_("value2");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900429
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900430 EXPECT_FIND_("TRACE_EVENT_END0 call");
431 EXPECT_FIND_("TRACE_EVENT_END1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900432 EXPECT_SUB_FIND_("name1");
433 EXPECT_SUB_FIND_("value1");
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900434 EXPECT_FIND_("TRACE_EVENT_END2 call");
435 EXPECT_SUB_FIND_("name1");
436 EXPECT_SUB_FIND_("value1");
437 EXPECT_SUB_FIND_("name2");
438 EXPECT_SUB_FIND_("value2");
nduca@chromium.org62210b02011-11-18 18:36:36 +0900439
jbates@chromium.org59c27602012-01-13 12:12:44 +0900440 EXPECT_FIND_("TRACE_EVENT_IF_LONGER_THAN0 call");
441 EXPECT_FIND_("TRACE_EVENT_IF_LONGER_THAN1 call");
442 EXPECT_SUB_FIND_("name1");
443 EXPECT_SUB_FIND_("value1");
444 EXPECT_FIND_("TRACE_EVENT_IF_LONGER_THAN2 call");
445 EXPECT_SUB_FIND_("name1");
446 EXPECT_SUB_FIND_("value1");
447 EXPECT_SUB_FIND_("name2");
448 EXPECT_SUB_FIND_("value2");
449
jbates@chromium.org88295f92012-03-01 12:04:59 +0900450 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN0 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900451 EXPECT_SUB_FIND_("id");
452 EXPECT_SUB_FIND_("5");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900453 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900454 EXPECT_SUB_FIND_("id");
455 EXPECT_SUB_FIND_("5");
456 EXPECT_SUB_FIND_("name1");
457 EXPECT_SUB_FIND_("value1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900458 EXPECT_FIND_("TRACE_EVENT_ASYNC_BEGIN2 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900459 EXPECT_SUB_FIND_("id");
460 EXPECT_SUB_FIND_("5");
461 EXPECT_SUB_FIND_("name1");
462 EXPECT_SUB_FIND_("value1");
463 EXPECT_SUB_FIND_("name2");
464 EXPECT_SUB_FIND_("value2");
465
jbates@chromium.org88295f92012-03-01 12:04:59 +0900466 EXPECT_FIND_("TRACE_EVENT_ASYNC_STEP0 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900467 EXPECT_SUB_FIND_("id");
468 EXPECT_SUB_FIND_("5");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900469 EXPECT_FIND_("TRACE_EVENT_ASYNC_STEP1 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900470 EXPECT_SUB_FIND_("id");
471 EXPECT_SUB_FIND_("5");
472 EXPECT_SUB_FIND_("name1");
473 EXPECT_SUB_FIND_("value1");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900474 EXPECT_FIND_("TRACE_EVENT_ASYNC_STEP2 call");
475 EXPECT_SUB_FIND_("id");
476 EXPECT_SUB_FIND_("5");
477 EXPECT_SUB_FIND_("name1");
478 EXPECT_SUB_FIND_("value1");
479 EXPECT_SUB_FIND_("name2");
480 EXPECT_SUB_FIND_("value2");
481
482 EXPECT_FIND_("TRACE_EVENT_ASYNC_END0 call");
483 EXPECT_SUB_FIND_("id");
484 EXPECT_SUB_FIND_("5");
485 EXPECT_FIND_("TRACE_EVENT_ASYNC_END1 call");
486 EXPECT_SUB_FIND_("id");
487 EXPECT_SUB_FIND_("5");
488 EXPECT_SUB_FIND_("name1");
489 EXPECT_SUB_FIND_("value1");
490 EXPECT_FIND_("TRACE_EVENT_ASYNC_END2 call");
jbates@chromium.org59c27602012-01-13 12:12:44 +0900491 EXPECT_SUB_FIND_("id");
492 EXPECT_SUB_FIND_("5");
493 EXPECT_SUB_FIND_("name1");
494 EXPECT_SUB_FIND_("value1");
495 EXPECT_SUB_FIND_("name2");
496 EXPECT_SUB_FIND_("value2");
497
498 EXPECT_FIND_("TRACE_EVENT_BEGIN_ETW0 call");
499 EXPECT_SUB_FIND_("id");
500 EXPECT_SUB_FIND_("5");
501 EXPECT_SUB_FIND_("extra");
502 EXPECT_SUB_FIND_("NULL");
503 EXPECT_FIND_("TRACE_EVENT_BEGIN_ETW1 call");
504 EXPECT_SUB_FIND_("id");
505 EXPECT_SUB_FIND_("5");
506 EXPECT_SUB_FIND_("extra");
507 EXPECT_SUB_FIND_("value");
508 EXPECT_FIND_("TRACE_EVENT_END_ETW0 call");
509 EXPECT_SUB_FIND_("id");
510 EXPECT_SUB_FIND_("5");
511 EXPECT_SUB_FIND_("extra");
512 EXPECT_SUB_FIND_("NULL");
513 EXPECT_FIND_("TRACE_EVENT_END_ETW1 call");
514 EXPECT_SUB_FIND_("id");
515 EXPECT_SUB_FIND_("5");
516 EXPECT_SUB_FIND_("extra");
517 EXPECT_SUB_FIND_("value");
518 EXPECT_FIND_("TRACE_EVENT_INSTANT_ETW0 call");
519 EXPECT_SUB_FIND_("id");
520 EXPECT_SUB_FIND_("5");
521 EXPECT_SUB_FIND_("extra");
522 EXPECT_SUB_FIND_("NULL");
523 EXPECT_FIND_("TRACE_EVENT_INSTANT_ETW1 call");
524 EXPECT_SUB_FIND_("id");
525 EXPECT_SUB_FIND_("5");
526 EXPECT_SUB_FIND_("extra");
527 EXPECT_SUB_FIND_("value");
528
nduca@chromium.org62210b02011-11-18 18:36:36 +0900529 EXPECT_FIND_("TRACE_COUNTER1 call");
530 {
531 std::string ph;
532 EXPECT_TRUE((item && item->GetString("ph", &ph)));
533 EXPECT_EQ("C", ph);
534
535 int value;
536 EXPECT_TRUE((item && item->GetInteger("args.value", &value)));
537 EXPECT_EQ(31415, value);
538 }
539
540 EXPECT_FIND_("TRACE_COUNTER2 call");
541 {
542 std::string ph;
543 EXPECT_TRUE((item && item->GetString("ph", &ph)));
544 EXPECT_EQ("C", ph);
545
546 int value;
547 EXPECT_TRUE((item && item->GetInteger("args.a", &value)));
548 EXPECT_EQ(30000, value);
549
550 EXPECT_TRUE((item && item->GetInteger("args.b", &value)));
551 EXPECT_EQ(1415, value);
552 }
553
piman@chromium.org902b2952011-12-16 10:19:06 +0900554 EXPECT_FIND_("TRACE_COUNTER_ID1 call");
555 {
556 std::string id;
557 EXPECT_TRUE((item && item->GetString("id", &id)));
558 EXPECT_EQ("319009", id);
559
560 std::string ph;
561 EXPECT_TRUE((item && item->GetString("ph", &ph)));
562 EXPECT_EQ("C", ph);
563
564 int value;
565 EXPECT_TRUE((item && item->GetInteger("args.value", &value)));
566 EXPECT_EQ(31415, value);
567 }
568
569 EXPECT_FIND_("TRACE_COUNTER_ID2 call");
570 {
571 std::string id;
572 EXPECT_TRUE((item && item->GetString("id", &id)));
573 EXPECT_EQ("319009", id);
574
575 std::string ph;
576 EXPECT_TRUE((item && item->GetString("ph", &ph)));
577 EXPECT_EQ("C", ph);
578
579 int value;
580 EXPECT_TRUE((item && item->GetInteger("args.a", &value)));
581 EXPECT_EQ(30000, value);
582
583 EXPECT_TRUE((item && item->GetInteger("args.b", &value)));
584 EXPECT_EQ(1415, value);
585 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900586}
587
nduca@chromium.org6d048772011-08-10 00:16:25 +0900588void TraceManyInstantEvents(int thread_id, int num_events,
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900589 WaitableEvent* task_complete_event) {
nduca@chromium.org6d048772011-08-10 00:16:25 +0900590 for (int i = 0; i < num_events; i++) {
591 TRACE_EVENT_INSTANT2("all", "multi thread event",
592 "thread", thread_id,
593 "event", i);
594 }
595
596 if (task_complete_event)
597 task_complete_event->Signal();
598}
599
600void ValidateInstantEventPresentOnEveryThread(const ListValue& trace_parsed,
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900601 int num_threads,
602 int num_events) {
nduca@chromium.org6d048772011-08-10 00:16:25 +0900603 std::map<int, std::map<int, bool> > results;
604
605 size_t trace_parsed_count = trace_parsed.GetSize();
606 for (size_t i = 0; i < trace_parsed_count; i++) {
607 Value* value = NULL;
608 trace_parsed.Get(i, &value);
609 if (!value || value->GetType() != Value::TYPE_DICTIONARY)
610 continue;
611 DictionaryValue* dict = static_cast<DictionaryValue*>(value);
612 std::string name;
613 dict->GetString("name", &name);
614 if (name != "multi thread event")
615 continue;
616
617 int thread = 0;
618 int event = 0;
619 EXPECT_TRUE(dict->GetInteger("args.thread", &thread));
620 EXPECT_TRUE(dict->GetInteger("args.event", &event));
621 results[thread][event] = true;
622 }
623
624 EXPECT_FALSE(results[-1][-1]);
625 for (int thread = 0; thread < num_threads; thread++) {
626 for (int event = 0; event < num_events; event++) {
627 EXPECT_TRUE(results[thread][event]);
628 }
629 }
630}
631
632void TraceCallsWithCachedCategoryPointersPointers(const char* name_str) {
633 TRACE_EVENT0("category name1", name_str);
634 TRACE_EVENT_INSTANT0("category name2", name_str);
635 TRACE_EVENT_BEGIN0("category name3", name_str);
636 TRACE_EVENT_END0("category name4", name_str);
637}
638
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900639} // namespace
640
641// Simple Test for emitting data and validating it was received.
642TEST_F(TraceEventTestFixture, DataCaptured) {
643 ManualTestSetUp();
644 TraceLog::GetInstance()->SetEnabled(true);
645
nduca@chromium.org6d048772011-08-10 00:16:25 +0900646 TraceWithAllMacroVariants(NULL);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900647
648 TraceLog::GetInstance()->SetEnabled(false);
649
jbates@chromium.org6a092d72011-10-25 01:34:08 +0900650 ValidateAllTraceMacrosCreatedData(trace_parsed_);
scheib@chromium.org603f46e2011-05-10 11:23:58 +0900651}
652
nduca@chromium.org6a7360c2012-02-20 15:35:15 +0900653class MockEnabledStateChangedObserver :
654 public base::debug::TraceLog::EnabledStateChangedObserver {
655 public:
656 MOCK_METHOD0(OnTraceLogWillEnable, void());
657 MOCK_METHOD0(OnTraceLogWillDisable, void());
658};
659
660TEST_F(TraceEventTestFixture, EnabledObserverFiresOnEnable) {
661 ManualTestSetUp();
662
663 MockEnabledStateChangedObserver observer;
664 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
665
666 EXPECT_CALL(observer, OnTraceLogWillEnable())
667 .Times(1);
668 TraceLog::GetInstance()->SetEnabled(true);
669 testing::Mock::VerifyAndClear(&observer);
670
671 // Cleanup.
672 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
673 TraceLog::GetInstance()->SetEnabled(false);
674}
675
676TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnSecondEnable) {
677 ManualTestSetUp();
678
679 TraceLog::GetInstance()->SetEnabled(true);
680
681 testing::StrictMock<MockEnabledStateChangedObserver> observer;
682 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
683
684 EXPECT_CALL(observer, OnTraceLogWillEnable())
685 .Times(0);
686 EXPECT_CALL(observer, OnTraceLogWillDisable())
687 .Times(0);
688 TraceLog::GetInstance()->SetEnabled(true);
689 testing::Mock::VerifyAndClear(&observer);
690
691 // Cleanup.
692 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
693 TraceLog::GetInstance()->SetEnabled(false);
694}
695
696TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnUselessDisable) {
697 ManualTestSetUp();
698
699
700 testing::StrictMock<MockEnabledStateChangedObserver> observer;
701 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
702
703 EXPECT_CALL(observer, OnTraceLogWillEnable())
704 .Times(0);
705 EXPECT_CALL(observer, OnTraceLogWillDisable())
706 .Times(0);
707 TraceLog::GetInstance()->SetEnabled(false);
708 testing::Mock::VerifyAndClear(&observer);
709
710 // Cleanup.
711 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
712}
713
714TEST_F(TraceEventTestFixture, EnabledObserverFiresOnDisable) {
715 ManualTestSetUp();
716
717 TraceLog::GetInstance()->SetEnabled(true);
718
719 MockEnabledStateChangedObserver observer;
720 TraceLog::GetInstance()->AddEnabledStateObserver(&observer);
721
722 EXPECT_CALL(observer, OnTraceLogWillDisable())
723 .Times(1);
724 TraceLog::GetInstance()->SetEnabled(false);
725 testing::Mock::VerifyAndClear(&observer);
726
727 // Cleanup.
728 TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer);
729}
730
jbates@chromium.org11d4c362011-09-13 07:03:41 +0900731// Test that categories work.
732TEST_F(TraceEventTestFixture, Categories) {
733 ManualTestSetUp();
734
735 // Test that categories that are used can be retrieved whether trace was
736 // enabled or disabled when the trace event was encountered.
737 TRACE_EVENT_INSTANT0("c1", "name");
738 TRACE_EVENT_INSTANT0("c2", "name");
739 TraceLog::GetInstance()->SetEnabled(true);
740 TRACE_EVENT_INSTANT0("c3", "name");
741 TRACE_EVENT_INSTANT0("c4", "name");
742 TraceLog::GetInstance()->SetEnabled(false);
743 std::vector<std::string> cats;
744 TraceLog::GetInstance()->GetKnownCategories(&cats);
745 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c1") != cats.end());
746 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c2") != cats.end());
747 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c3") != cats.end());
748 EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c4") != cats.end());
749
750 const std::vector<std::string> empty_categories;
751 std::vector<std::string> included_categories;
752 std::vector<std::string> excluded_categories;
753
754 // Test that category filtering works.
755
756 // Include nonexistent category -> no events
757 Clear();
758 included_categories.clear();
759 included_categories.push_back("not_found823564786");
760 TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories);
761 TRACE_EVENT_INSTANT0("cat1", "name");
762 TRACE_EVENT_INSTANT0("cat2", "name");
763 TraceLog::GetInstance()->SetDisabled();
764 EXPECT_TRUE(trace_parsed_.empty());
765
766 // Include existent category -> only events of that category
767 Clear();
768 included_categories.clear();
769 included_categories.push_back("inc");
770 TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories);
771 TRACE_EVENT_INSTANT0("inc", "name");
772 TRACE_EVENT_INSTANT0("inc2", "name");
773 TraceLog::GetInstance()->SetDisabled();
774 EXPECT_TRUE(FindMatchingValue("cat", "inc"));
775 EXPECT_FALSE(FindNonMatchingValue("cat", "inc"));
776
777 // Include existent wildcard -> all categories matching wildcard
778 Clear();
779 included_categories.clear();
780 included_categories.push_back("inc_wildcard_*");
781 included_categories.push_back("inc_wildchar_?_end");
782 TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories);
783 TRACE_EVENT_INSTANT0("inc_wildcard_abc", "included");
784 TRACE_EVENT_INSTANT0("inc_wildcard_", "included");
785 TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "included");
786 TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "not_inc");
787 TRACE_EVENT_INSTANT0("cat1", "not_inc");
788 TRACE_EVENT_INSTANT0("cat2", "not_inc");
789 TraceLog::GetInstance()->SetDisabled();
790 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_abc"));
791 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_"));
792 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildchar_x_end"));
793 EXPECT_FALSE(FindMatchingValue("name", "not_inc"));
794
795 included_categories.clear();
796
797 // Exclude nonexistent category -> all events
798 Clear();
799 excluded_categories.clear();
800 excluded_categories.push_back("not_found823564786");
801 TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories);
802 TRACE_EVENT_INSTANT0("cat1", "name");
803 TRACE_EVENT_INSTANT0("cat2", "name");
804 TraceLog::GetInstance()->SetDisabled();
805 EXPECT_TRUE(FindMatchingValue("cat", "cat1"));
806 EXPECT_TRUE(FindMatchingValue("cat", "cat2"));
807
808 // Exclude existent category -> only events of other categories
809 Clear();
810 excluded_categories.clear();
811 excluded_categories.push_back("inc");
812 TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories);
813 TRACE_EVENT_INSTANT0("inc", "name");
814 TRACE_EVENT_INSTANT0("inc2", "name");
815 TraceLog::GetInstance()->SetDisabled();
816 EXPECT_TRUE(FindMatchingValue("cat", "inc2"));
817 EXPECT_FALSE(FindMatchingValue("cat", "inc"));
818
819 // Exclude existent wildcard -> all categories not matching wildcard
820 Clear();
821 excluded_categories.clear();
822 excluded_categories.push_back("inc_wildcard_*");
823 excluded_categories.push_back("inc_wildchar_?_end");
824 TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories);
825 TRACE_EVENT_INSTANT0("inc_wildcard_abc", "not_inc");
826 TRACE_EVENT_INSTANT0("inc_wildcard_", "not_inc");
827 TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "not_inc");
828 TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "included");
829 TRACE_EVENT_INSTANT0("cat1", "included");
830 TRACE_EVENT_INSTANT0("cat2", "included");
831 TraceLog::GetInstance()->SetDisabled();
832 EXPECT_TRUE(FindMatchingValue("cat", "inc_wildchar_bla_end"));
833 EXPECT_TRUE(FindMatchingValue("cat", "cat1"));
834 EXPECT_TRUE(FindMatchingValue("cat", "cat2"));
835 EXPECT_FALSE(FindMatchingValue("name", "not_inc"));
836}
837
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900838// Simple Test for time threshold events.
839TEST_F(TraceEventTestFixture, DataCapturedThreshold) {
840 ManualTestSetUp();
841 TraceLog::GetInstance()->SetEnabled(true);
842
843 // Test that events at the same level are properly filtered by threshold.
844 {
845 TRACE_EVENT_IF_LONGER_THAN0(100, "time", "threshold 100");
846 TRACE_EVENT_IF_LONGER_THAN0(1000, "time", "threshold 1000");
847 TRACE_EVENT_IF_LONGER_THAN0(10000, "time", "threshold 10000");
848 // 100+ seconds to avoid flakiness.
849 TRACE_EVENT_IF_LONGER_THAN0(100000000, "time", "threshold long1");
850 TRACE_EVENT_IF_LONGER_THAN0(200000000, "time", "threshold long2");
tedvessenes@gmail.comaaa63032012-01-01 07:53:51 +0900851 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900852 }
853
854 // Test that a normal nested event remains after it's parent event is dropped.
855 {
856 TRACE_EVENT_IF_LONGER_THAN0(1000000, "time", "2threshold10000");
857 {
858 TRACE_EVENT0("time", "nonthreshold1");
859 }
860 }
861
862 // Test that parent thresholded events are dropped while some nested events
863 // remain.
864 {
865 TRACE_EVENT0("time", "nonthreshold3");
866 {
867 TRACE_EVENT_IF_LONGER_THAN0(200000000, "time", "3thresholdlong2");
868 {
869 TRACE_EVENT_IF_LONGER_THAN0(100000000, "time", "3thresholdlong1");
870 {
871 TRACE_EVENT_IF_LONGER_THAN0(10000, "time", "3threshold10000");
872 {
873 TRACE_EVENT_IF_LONGER_THAN0(1000, "time", "3threshold1000");
874 {
875 TRACE_EVENT_IF_LONGER_THAN0(100, "time", "3threshold100");
tedvessenes@gmail.comaaa63032012-01-01 07:53:51 +0900876 base::PlatformThread::Sleep(
877 base::TimeDelta::FromMilliseconds(20));
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900878 }
879 }
880 }
881 }
882 }
883 }
884
885 // Test that child thresholded events are dropped while some parent events
886 // remain.
887 {
888 TRACE_EVENT0("time", "nonthreshold4");
889 {
890 TRACE_EVENT_IF_LONGER_THAN0(100, "time", "4threshold100");
891 {
892 TRACE_EVENT_IF_LONGER_THAN0(1000, "time", "4threshold1000");
893 {
894 TRACE_EVENT_IF_LONGER_THAN0(10000, "time", "4threshold10000");
895 {
896 TRACE_EVENT_IF_LONGER_THAN0(100000000, "time",
897 "4thresholdlong1");
898 {
899 TRACE_EVENT_IF_LONGER_THAN0(200000000, "time",
900 "4thresholdlong2");
tedvessenes@gmail.comaaa63032012-01-01 07:53:51 +0900901 base::PlatformThread::Sleep(
902 base::TimeDelta::FromMilliseconds(20));
jbates@chromium.orgb3cab862011-05-14 08:30:35 +0900903 }
904 }
905 }
906 }
907 }
908 }
909
910 TraceLog::GetInstance()->SetEnabled(false);
911
912#define EXPECT_FIND_BE_(str) \
913 EXPECT_TRUE(FindNamePhase(str, "B")); \
914 EXPECT_TRUE(FindNamePhase(str, "E"))
915#define EXPECT_NOT_FIND_BE_(str) \
916 EXPECT_FALSE(FindNamePhase(str, "B")); \
917 EXPECT_FALSE(FindNamePhase(str, "E"))
918
919 EXPECT_FIND_BE_("threshold 100");
920 EXPECT_FIND_BE_("threshold 1000");
921 EXPECT_FIND_BE_("threshold 10000");
922 EXPECT_NOT_FIND_BE_("threshold long1");
923 EXPECT_NOT_FIND_BE_("threshold long2");
924
925 EXPECT_NOT_FIND_BE_("2threshold10000");
926 EXPECT_FIND_BE_("nonthreshold1");
927
928 EXPECT_FIND_BE_("nonthreshold3");
929 EXPECT_FIND_BE_("3threshold100");
930 EXPECT_FIND_BE_("3threshold1000");
931 EXPECT_FIND_BE_("3threshold10000");
932 EXPECT_NOT_FIND_BE_("3thresholdlong1");
933 EXPECT_NOT_FIND_BE_("3thresholdlong2");
934
935 EXPECT_FIND_BE_("nonthreshold4");
936 EXPECT_FIND_BE_("4threshold100");
937 EXPECT_FIND_BE_("4threshold1000");
938 EXPECT_FIND_BE_("4threshold10000");
939 EXPECT_NOT_FIND_BE_("4thresholdlong1");
940 EXPECT_NOT_FIND_BE_("4thresholdlong2");
941}
942
jbates@chromium.org88295f92012-03-01 12:04:59 +0900943// Test ASYNC_BEGIN/END events
944TEST_F(TraceEventTestFixture, AsyncBeginEndEvents) {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900945 ManualTestSetUp();
946 TraceLog::GetInstance()->SetEnabled(true);
947
948 unsigned long long id = 0xfeedbeeffeedbeefull;
jbates@chromium.org88295f92012-03-01 12:04:59 +0900949 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name1", id);
950 TRACE_EVENT_ASYNC_STEP0( "cat", "name1", id);
951 TRACE_EVENT_ASYNC_END0("cat", "name1", id);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900952 TRACE_EVENT_BEGIN0( "cat", "name2");
jbates@chromium.org88295f92012-03-01 12:04:59 +0900953 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name3", 0);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900954
955 TraceLog::GetInstance()->SetEnabled(false);
956
957 EXPECT_TRUE(FindNamePhase("name1", "S"));
jbates@chromium.org88295f92012-03-01 12:04:59 +0900958 EXPECT_TRUE(FindNamePhase("name1", "T"));
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900959 EXPECT_TRUE(FindNamePhase("name1", "F"));
960
961 std::string id_str;
962 StringAppendF(&id_str, "%llx", id);
963
964 EXPECT_TRUE(FindNamePhaseKeyValue("name1", "S", "id", id_str.c_str()));
jbates@chromium.org88295f92012-03-01 12:04:59 +0900965 EXPECT_TRUE(FindNamePhaseKeyValue("name1", "T", "id", id_str.c_str()));
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900966 EXPECT_TRUE(FindNamePhaseKeyValue("name1", "F", "id", id_str.c_str()));
967 EXPECT_TRUE(FindNamePhaseKeyValue("name3", "S", "id", "0"));
968
969 // BEGIN events should not have id
970 EXPECT_FALSE(FindNamePhaseKeyValue("name2", "B", "id", "0"));
971}
972
jbates@chromium.org88295f92012-03-01 12:04:59 +0900973// Test ASYNC_BEGIN/END events
974TEST_F(TraceEventTestFixture, AsyncBeginEndPointerMangling) {
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900975 ManualTestSetUp();
976
977 void* ptr = this;
978
979 TraceLog::GetInstance()->SetProcessID(100);
980 TraceLog::GetInstance()->SetEnabled(true);
jbates@chromium.org88295f92012-03-01 12:04:59 +0900981 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name1", ptr);
982 TRACE_EVENT_ASYNC_BEGIN0( "cat", "name2", ptr);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900983 TraceLog::GetInstance()->SetEnabled(false);
984
985 TraceLog::GetInstance()->SetProcessID(200);
986 TraceLog::GetInstance()->SetEnabled(true);
jbates@chromium.org88295f92012-03-01 12:04:59 +0900987 TRACE_EVENT_ASYNC_END0( "cat", "name1", ptr);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900988 TraceLog::GetInstance()->SetEnabled(false);
989
jbates@chromium.org88295f92012-03-01 12:04:59 +0900990 DictionaryValue* async_begin = FindNamePhase("name1", "S");
991 DictionaryValue* async_begin2 = FindNamePhase("name2", "S");
992 DictionaryValue* async_end = FindNamePhase("name1", "F");
993 EXPECT_TRUE(async_begin);
994 EXPECT_TRUE(async_begin2);
995 EXPECT_TRUE(async_end);
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +0900996
997 Value* value = NULL;
jbates@chromium.org88295f92012-03-01 12:04:59 +0900998 std::string async_begin_id_str;
999 std::string async_begin2_id_str;
1000 std::string async_end_id_str;
1001 ASSERT_TRUE(async_begin->Get("id", &value));
1002 ASSERT_TRUE(value->GetAsString(&async_begin_id_str));
1003 ASSERT_TRUE(async_begin2->Get("id", &value));
1004 ASSERT_TRUE(value->GetAsString(&async_begin2_id_str));
1005 ASSERT_TRUE(async_end->Get("id", &value));
1006 ASSERT_TRUE(value->GetAsString(&async_end_id_str));
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001007
jbates@chromium.org88295f92012-03-01 12:04:59 +09001008 EXPECT_STREQ(async_begin_id_str.c_str(), async_begin2_id_str.c_str());
1009 EXPECT_STRNE(async_begin_id_str.c_str(), async_end_id_str.c_str());
jbates@chromium.org8bb0ee62011-12-03 02:17:38 +09001010}
1011
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001012// Test that static strings are not copied.
1013TEST_F(TraceEventTestFixture, StaticStringVsString) {
1014 ManualTestSetUp();
1015 TraceLog* tracer = TraceLog::GetInstance();
1016 // Make sure old events are flushed:
1017 tracer->SetEnabled(false);
1018 EXPECT_EQ(0u, tracer->GetEventsSize());
1019
1020 {
1021 tracer->SetEnabled(true);
1022 // Test that string arguments are copied.
1023 TRACE_EVENT2("cat", "name1",
1024 "arg1", std::string("argval"), "arg2", std::string("argval"));
1025 // Test that static TRACE_STR_COPY string arguments are copied.
1026 TRACE_EVENT2("cat", "name2",
1027 "arg1", TRACE_STR_COPY("argval"),
1028 "arg2", TRACE_STR_COPY("argval"));
1029 size_t num_events = tracer->GetEventsSize();
1030 EXPECT_GT(num_events, 1u);
1031 const TraceEvent& event1 = tracer->GetEventAt(num_events - 2);
1032 const TraceEvent& event2 = tracer->GetEventAt(num_events - 1);
1033 EXPECT_STREQ("name1", event1.name());
1034 EXPECT_STREQ("name2", event2.name());
1035 EXPECT_TRUE(event1.parameter_copy_storage() != NULL);
1036 EXPECT_TRUE(event2.parameter_copy_storage() != NULL);
1037 EXPECT_GT(event1.parameter_copy_storage()->size(), 0u);
1038 EXPECT_GT(event2.parameter_copy_storage()->size(), 0u);
1039 tracer->SetEnabled(false);
1040 }
1041
1042 {
1043 tracer->SetEnabled(true);
1044 // Test that static literal string arguments are not copied.
1045 TRACE_EVENT2("cat", "name1",
1046 "arg1", "argval", "arg2", "argval");
1047 // Test that static TRACE_STR_COPY NULL string arguments are not copied.
1048 const char* str1 = NULL;
1049 const char* str2 = NULL;
1050 TRACE_EVENT2("cat", "name2",
1051 "arg1", TRACE_STR_COPY(str1),
1052 "arg2", TRACE_STR_COPY(str2));
1053 size_t num_events = tracer->GetEventsSize();
1054 EXPECT_GT(num_events, 1u);
1055 const TraceEvent& event1 = tracer->GetEventAt(num_events - 2);
1056 const TraceEvent& event2 = tracer->GetEventAt(num_events - 1);
1057 EXPECT_STREQ("name1", event1.name());
1058 EXPECT_STREQ("name2", event2.name());
1059 EXPECT_TRUE(event1.parameter_copy_storage() == NULL);
1060 EXPECT_TRUE(event2.parameter_copy_storage() == NULL);
1061 tracer->SetEnabled(false);
1062 }
1063}
1064
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001065// Test that data sent from other threads is gathered
1066TEST_F(TraceEventTestFixture, DataCapturedOnThread) {
1067 ManualTestSetUp();
1068 TraceLog::GetInstance()->SetEnabled(true);
1069
1070 Thread thread("1");
1071 WaitableEvent task_complete_event(false, false);
1072 thread.Start();
1073
1074 thread.message_loop()->PostTask(
jbates@chromium.org0b837e42011-10-06 01:58:20 +09001075 FROM_HERE, base::Bind(&TraceWithAllMacroVariants, &task_complete_event));
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001076 task_complete_event.Wait();
jbates@chromium.orgb84db522011-10-04 02:51:25 +09001077 thread.Stop();
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001078
1079 TraceLog::GetInstance()->SetEnabled(false);
jbates@chromium.org6a092d72011-10-25 01:34:08 +09001080 ValidateAllTraceMacrosCreatedData(trace_parsed_);
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001081}
1082
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001083// Test that data sent from multiple threads is gathered
1084TEST_F(TraceEventTestFixture, DataCapturedManyThreads) {
1085 ManualTestSetUp();
1086 TraceLog::GetInstance()->SetEnabled(true);
1087
1088 const int num_threads = 4;
1089 const int num_events = 4000;
1090 Thread* threads[num_threads];
1091 WaitableEvent* task_complete_events[num_threads];
1092 for (int i = 0; i < num_threads; i++) {
1093 threads[i] = new Thread(StringPrintf("Thread %d", i).c_str());
1094 task_complete_events[i] = new WaitableEvent(false, false);
1095 threads[i]->Start();
1096 threads[i]->message_loop()->PostTask(
jbates@chromium.org0b837e42011-10-06 01:58:20 +09001097 FROM_HERE, base::Bind(&TraceManyInstantEvents,
1098 i, num_events, task_complete_events[i]));
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001099 }
1100
1101 for (int i = 0; i < num_threads; i++) {
1102 task_complete_events[i]->Wait();
1103 }
1104
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001105 for (int i = 0; i < num_threads; i++) {
1106 threads[i]->Stop();
1107 delete threads[i];
1108 delete task_complete_events[i];
1109 }
1110
jbates@chromium.orgb84db522011-10-04 02:51:25 +09001111 TraceLog::GetInstance()->SetEnabled(false);
1112
jbates@chromium.org6a092d72011-10-25 01:34:08 +09001113 ValidateInstantEventPresentOnEveryThread(trace_parsed_,
nduca@chromium.org6d048772011-08-10 00:16:25 +09001114 num_threads, num_events);
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001115}
1116
nduca@chromium.org6d048772011-08-10 00:16:25 +09001117// Test that thread and process names show up in the trace
1118TEST_F(TraceEventTestFixture, ThreadNames) {
1119 ManualTestSetUp();
1120
1121 // Create threads before we enable tracing to make sure
1122 // that tracelog still captures them.
1123 const int num_threads = 4;
1124 const int num_events = 10;
1125 Thread* threads[num_threads];
1126 PlatformThreadId thread_ids[num_threads];
1127 for (int i = 0; i < num_threads; i++)
1128 threads[i] = new Thread(StringPrintf("Thread %d", i).c_str());
1129
1130 // Enable tracing.
1131 TraceLog::GetInstance()->SetEnabled(true);
1132
1133 // Now run some trace code on these threads.
1134 WaitableEvent* task_complete_events[num_threads];
1135 for (int i = 0; i < num_threads; i++) {
1136 task_complete_events[i] = new WaitableEvent(false, false);
1137 threads[i]->Start();
1138 thread_ids[i] = threads[i]->thread_id();
1139 threads[i]->message_loop()->PostTask(
jbates@chromium.org0b837e42011-10-06 01:58:20 +09001140 FROM_HERE, base::Bind(&TraceManyInstantEvents,
1141 i, num_events, task_complete_events[i]));
nduca@chromium.org6d048772011-08-10 00:16:25 +09001142 }
1143 for (int i = 0; i < num_threads; i++) {
1144 task_complete_events[i]->Wait();
1145 }
1146
1147 // Shut things down.
nduca@chromium.org6d048772011-08-10 00:16:25 +09001148 for (int i = 0; i < num_threads; i++) {
1149 threads[i]->Stop();
1150 delete threads[i];
1151 delete task_complete_events[i];
1152 }
1153
jbates@chromium.orgb84db522011-10-04 02:51:25 +09001154 TraceLog::GetInstance()->SetEnabled(false);
1155
nduca@chromium.org6d048772011-08-10 00:16:25 +09001156 std::string tmp;
1157 int tmp_int;
1158 DictionaryValue* item;
1159
1160 // Make sure we get thread name metadata.
1161 // Note, the test suite may have created a ton of threads.
1162 // So, we'll have thread names for threads we didn't create.
1163 std::vector<DictionaryValue*> items =
1164 FindTraceEntries(trace_parsed_, "thread_name");
1165 for (int i = 0; i < static_cast<int>(items.size()); i++) {
1166 item = items[i];
joth@chromium.org088ae012011-11-11 01:26:23 +09001167 ASSERT_TRUE(item);
nduca@chromium.org6d048772011-08-10 00:16:25 +09001168 EXPECT_TRUE(item->GetInteger("tid", &tmp_int));
1169
1170 // See if this thread name is one of the threads we just created
1171 for (int j = 0; j < num_threads; j++) {
1172 if(static_cast<int>(thread_ids[j]) != tmp_int)
1173 continue;
1174
jbates@chromium.org62a16662012-02-04 08:18:06 +09001175 std::string expected_name = StringPrintf("Thread %d", j);
nduca@chromium.org6d048772011-08-10 00:16:25 +09001176 EXPECT_TRUE(item->GetString("ph", &tmp) && tmp == "M");
1177 EXPECT_TRUE(item->GetInteger("pid", &tmp_int) &&
1178 tmp_int == static_cast<int>(base::GetCurrentProcId()));
jbates@chromium.org62a16662012-02-04 08:18:06 +09001179 // If the thread name changes or the tid gets reused, the name will be
1180 // a comma-separated list of thread names, so look for a substring.
nduca@chromium.org6d048772011-08-10 00:16:25 +09001181 EXPECT_TRUE(item->GetString("args.name", &tmp) &&
jbates@chromium.org62a16662012-02-04 08:18:06 +09001182 tmp.find(expected_name) != std::string::npos);
nduca@chromium.org6d048772011-08-10 00:16:25 +09001183 }
1184 }
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001185}
1186
joth@chromium.org088ae012011-11-11 01:26:23 +09001187TEST_F(TraceEventTestFixture, ThreadNameChanges) {
1188 ManualTestSetUp();
1189
1190 TraceLog::GetInstance()->SetEnabled(true);
1191
1192 PlatformThread::SetName("");
1193 TRACE_EVENT_INSTANT0("drink", "water");
1194
1195 PlatformThread::SetName("cafe");
1196 TRACE_EVENT_INSTANT0("drink", "coffee");
1197
1198 PlatformThread::SetName("shop");
1199 // No event here, so won't appear in combined name.
1200
1201 PlatformThread::SetName("pub");
1202 TRACE_EVENT_INSTANT0("drink", "beer");
1203 TRACE_EVENT_INSTANT0("drink", "wine");
1204
1205 PlatformThread::SetName(" bar");
1206 TRACE_EVENT_INSTANT0("drink", "whisky");
1207
1208 TraceLog::GetInstance()->SetEnabled(false);
1209
1210 std::vector<DictionaryValue*> items =
1211 FindTraceEntries(trace_parsed_, "thread_name");
1212 EXPECT_EQ(1u, items.size());
1213 ASSERT_GT(items.size(), 0u);
1214 DictionaryValue* item = items[0];
1215 ASSERT_TRUE(item);
1216 int tid;
1217 EXPECT_TRUE(item->GetInteger("tid", &tid));
1218 EXPECT_EQ(PlatformThread::CurrentId(), static_cast<PlatformThreadId>(tid));
1219
1220 std::string expected_name = "cafe,pub, bar";
1221 std::string tmp;
1222 EXPECT_TRUE(item->GetString("args.name", &tmp));
1223 EXPECT_EQ(expected_name, tmp);
1224}
nduca@chromium.org6d048772011-08-10 00:16:25 +09001225
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001226// Test trace calls made after tracing singleton shut down.
1227//
1228// The singleton is destroyed by our base::AtExitManager, but there can be
1229// code still executing as the C++ static objects are destroyed. This test
1230// forces the singleton to destroy early, and intentinally makes trace calls
1231// afterwards.
1232TEST_F(TraceEventTestFixture, AtExit) {
1233 // Repeat this test a few times. Besides just showing robustness, it also
1234 // allows us to test that events at shutdown do not appear with valid events
1235 // recorded after the system is started again.
1236 for (int i = 0; i < 4; i++) {
1237 // Scope to contain the then destroy the TraceLog singleton.
1238 {
1239 base::ShadowingAtExitManager exit_manager_will_destroy_singletons;
1240
1241 // Setup TraceLog singleton inside this test's exit manager scope
1242 // so that it will be destroyed when this scope closes.
1243 ManualTestSetUp();
1244
1245 TRACE_EVENT_INSTANT0("all", "not recorded; system not enabled");
1246
1247 TraceLog::GetInstance()->SetEnabled(true);
1248
1249 TRACE_EVENT_INSTANT0("all", "is recorded 1; system has been enabled");
1250 // Trace calls that will cache pointers to categories; they're valid here
1251 TraceCallsWithCachedCategoryPointersPointers(
1252 "is recorded 2; system has been enabled");
1253
1254 TraceLog::GetInstance()->SetEnabled(false);
1255 } // scope to destroy singleton
1256 ASSERT_FALSE(TraceLog::GetInstance());
1257
1258 // Now that singleton is destroyed, check what trace events were recorded
1259 DictionaryValue* item = NULL;
1260 ListValue& trace_parsed = trace_parsed_;
1261 EXPECT_FIND_("is recorded 1");
1262 EXPECT_FIND_("is recorded 2");
1263 EXPECT_NOT_FIND_("not recorded");
1264
1265 // Make additional trace event calls on the shutdown system. They should
1266 // all pass cleanly, but the data not be recorded. We'll verify that next
1267 // time around the loop (the only way to flush the trace buffers).
1268 TRACE_EVENT_BEGIN_ETW("not recorded; system shutdown", 0, NULL);
1269 TRACE_EVENT_END_ETW("not recorded; system shutdown", 0, NULL);
1270 TRACE_EVENT_INSTANT_ETW("not recorded; system shutdown", 0, NULL);
1271 TRACE_EVENT0("all", "not recorded; system shutdown");
1272 TRACE_EVENT_INSTANT0("all", "not recorded; system shutdown");
1273 TRACE_EVENT_BEGIN0("all", "not recorded; system shutdown");
1274 TRACE_EVENT_END0("all", "not recorded; system shutdown");
1275
1276 TRACE_EVENT0("new category 0!", "not recorded; system shutdown");
1277 TRACE_EVENT_INSTANT0("new category 1!", "not recorded; system shutdown");
1278 TRACE_EVENT_BEGIN0("new category 2!", "not recorded; system shutdown");
1279 TRACE_EVENT_END0("new category 3!", "not recorded; system shutdown");
1280
1281 // Cached categories should be safe to check, and still disable traces
1282 TraceCallsWithCachedCategoryPointersPointers(
1283 "not recorded; system shutdown");
1284 }
1285}
1286
joth@chromium.org113de992011-07-21 21:28:59 +09001287TEST_F(TraceEventTestFixture, NormallyNoDeepCopy) {
1288 // Test that the TRACE_EVENT macros do not deep-copy their string. If they
1289 // do so it may indicate a performance regression, but more-over it would
1290 // make the DEEP_COPY overloads redundant.
1291 ManualTestSetUp();
1292
1293 std::string name_string("event name");
1294
1295 TraceLog::GetInstance()->SetEnabled(true);
1296 TRACE_EVENT_INSTANT0("category", name_string.c_str());
1297
1298 // Modify the string in place (a wholesale reassignment may leave the old
1299 // string intact on the heap).
1300 name_string[0] = '@';
1301
1302 TraceLog::GetInstance()->SetEnabled(false);
1303
1304 EXPECT_FALSE(FindTraceEntry(trace_parsed_, "event name"));
1305 EXPECT_TRUE(FindTraceEntry(trace_parsed_, name_string.c_str()));
1306}
1307
1308TEST_F(TraceEventTestFixture, DeepCopy) {
1309 ManualTestSetUp();
1310
1311 static const char kOriginalName1[] = "name1";
1312 static const char kOriginalName2[] = "name2";
1313 static const char kOriginalName3[] = "name3";
1314 std::string name1(kOriginalName1);
1315 std::string name2(kOriginalName2);
1316 std::string name3(kOriginalName3);
1317 std::string arg1("arg1");
1318 std::string arg2("arg2");
1319 std::string val1("val1");
1320 std::string val2("val2");
1321
1322 TraceLog::GetInstance()->SetEnabled(true);
1323 TRACE_EVENT_COPY_INSTANT0("category", name1.c_str());
1324 TRACE_EVENT_COPY_BEGIN1("category", name2.c_str(),
1325 arg1.c_str(), 5);
1326 TRACE_EVENT_COPY_END2("category", name3.c_str(),
jbates@chromium.org1f18e462011-09-07 02:56:24 +09001327 arg1.c_str(), val1,
1328 arg2.c_str(), val2);
joth@chromium.org113de992011-07-21 21:28:59 +09001329
1330 // As per NormallyNoDeepCopy, modify the strings in place.
1331 name1[0] = name2[0] = name3[0] = arg1[0] = arg2[0] = val1[0] = val2[0] = '@';
1332
1333 TraceLog::GetInstance()->SetEnabled(false);
1334
1335 EXPECT_FALSE(FindTraceEntry(trace_parsed_, name1.c_str()));
1336 EXPECT_FALSE(FindTraceEntry(trace_parsed_, name2.c_str()));
1337 EXPECT_FALSE(FindTraceEntry(trace_parsed_, name3.c_str()));
1338
1339 DictionaryValue* entry1 = FindTraceEntry(trace_parsed_, kOriginalName1);
1340 DictionaryValue* entry2 = FindTraceEntry(trace_parsed_, kOriginalName2);
1341 DictionaryValue* entry3 = FindTraceEntry(trace_parsed_, kOriginalName3);
1342 ASSERT_TRUE(entry1);
1343 ASSERT_TRUE(entry2);
1344 ASSERT_TRUE(entry3);
1345
1346 int i;
1347 EXPECT_FALSE(entry2->GetInteger("args.@rg1", &i));
1348 EXPECT_TRUE(entry2->GetInteger("args.arg1", &i));
1349 EXPECT_EQ(5, i);
1350
1351 std::string s;
1352 EXPECT_TRUE(entry3->GetString("args.arg1", &s));
1353 EXPECT_EQ("val1", s);
1354 EXPECT_TRUE(entry3->GetString("args.arg2", &s));
1355 EXPECT_EQ("val2", s);
1356}
1357
jbates@chromium.org6a092d72011-10-25 01:34:08 +09001358// Test that TraceResultBuffer outputs the correct result whether it is added
1359// in chunks or added all at once.
1360TEST_F(TraceEventTestFixture, TraceResultBuffer) {
1361 ManualTestSetUp();
1362
1363 Clear();
1364
1365 trace_buffer_.Start();
1366 trace_buffer_.AddFragment("bla1");
1367 trace_buffer_.AddFragment("bla2");
1368 trace_buffer_.AddFragment("bla3,bla4");
1369 trace_buffer_.Finish();
1370 EXPECT_STREQ(json_output_.json_output.c_str(), "[bla1,bla2,bla3,bla4]");
1371
1372 Clear();
1373
1374 trace_buffer_.Start();
1375 trace_buffer_.AddFragment("bla1,bla2,bla3,bla4");
1376 trace_buffer_.Finish();
1377 EXPECT_STREQ(json_output_.json_output.c_str(), "[bla1,bla2,bla3,bla4]");
1378}
1379
scheib@chromium.org603f46e2011-05-10 11:23:58 +09001380} // namespace debug
1381} // namespace base