1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // 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/trace_event/blame_context.h"
6
7 #include "base/json/json_writer.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/test/trace_event_analyzer.h"
10 #include "base/trace_event/trace_event_argument.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace base {
14 namespace trace_event {
15 namespace {
16
17 const char kTestBlameContextCategory[] = "test";
18 const char kDisabledTestBlameContextCategory[] = "disabled-by-default-test";
19 const char kTestBlameContextName[] = "TestBlameContext";
20 const char kTestBlameContextType[] = "TestBlameContextType";
21 const char kTestBlameContextScope[] = "TestBlameContextScope";
22
23 class TestBlameContext : public BlameContext {
24 public:
TestBlameContext(int id)25 explicit TestBlameContext(int id)
26 : BlameContext(kTestBlameContextCategory,
27 kTestBlameContextName,
28 kTestBlameContextType,
29 kTestBlameContextScope,
30 id,
31 nullptr) {}
32
TestBlameContext(int id,const TestBlameContext & parent)33 TestBlameContext(int id, const TestBlameContext& parent)
34 : BlameContext(kTestBlameContextCategory,
35 kTestBlameContextName,
36 kTestBlameContextType,
37 kTestBlameContextScope,
38 id,
39 &parent) {}
40
41 protected:
AsValueInto(trace_event::TracedValue * state)42 void AsValueInto(trace_event::TracedValue* state) override {
43 BlameContext::AsValueInto(state);
44 state->SetBoolean("crossStreams", false);
45 }
46 };
47
48 class DisabledTestBlameContext : public BlameContext {
49 public:
DisabledTestBlameContext(int id)50 explicit DisabledTestBlameContext(int id)
51 : BlameContext(kDisabledTestBlameContextCategory,
52 kTestBlameContextName,
53 kTestBlameContextType,
54 kTestBlameContextScope,
55 id,
56 nullptr) {}
57 };
58
59 class BlameContextTest : public testing::Test {
60 protected:
61 MessageLoop loop_;
62 };
63
TEST_F(BlameContextTest,EnterAndLeave)64 TEST_F(BlameContextTest, EnterAndLeave) {
65 using trace_analyzer::Query;
66 trace_analyzer::Start("*");
67 {
68 TestBlameContext blame_context(0x1234);
69 blame_context.Initialize();
70 blame_context.Enter();
71 blame_context.Leave();
72 }
73 auto analyzer = trace_analyzer::Stop();
74
75 trace_analyzer::TraceEventVector events;
76 Query q = Query::EventPhaseIs(TRACE_EVENT_PHASE_ENTER_CONTEXT) ||
77 Query::EventPhaseIs(TRACE_EVENT_PHASE_LEAVE_CONTEXT);
78 analyzer->FindEvents(q, &events);
79
80 EXPECT_EQ(2u, events.size());
81 EXPECT_EQ(TRACE_EVENT_PHASE_ENTER_CONTEXT, events[0]->phase);
82 EXPECT_EQ(kTestBlameContextCategory, events[0]->category);
83 EXPECT_EQ(kTestBlameContextName, events[0]->name);
84 EXPECT_EQ("0x1234", events[0]->id);
85 EXPECT_EQ(TRACE_EVENT_PHASE_LEAVE_CONTEXT, events[1]->phase);
86 EXPECT_EQ(kTestBlameContextCategory, events[1]->category);
87 EXPECT_EQ(kTestBlameContextName, events[1]->name);
88 EXPECT_EQ("0x1234", events[1]->id);
89 }
90
TEST_F(BlameContextTest,DifferentCategories)91 TEST_F(BlameContextTest, DifferentCategories) {
92 // Ensure there is no cross talk between blame contexts from different
93 // categories.
94 using trace_analyzer::Query;
95 trace_analyzer::Start("*");
96 {
97 TestBlameContext blame_context(0x1234);
98 DisabledTestBlameContext disabled_blame_context(0x5678);
99 blame_context.Initialize();
100 blame_context.Enter();
101 blame_context.Leave();
102 disabled_blame_context.Initialize();
103 disabled_blame_context.Enter();
104 disabled_blame_context.Leave();
105 }
106 auto analyzer = trace_analyzer::Stop();
107
108 trace_analyzer::TraceEventVector events;
109 Query q = Query::EventPhaseIs(TRACE_EVENT_PHASE_ENTER_CONTEXT) ||
110 Query::EventPhaseIs(TRACE_EVENT_PHASE_LEAVE_CONTEXT);
111 analyzer->FindEvents(q, &events);
112
113 // None of the events from the disabled-by-default category should show up.
114 EXPECT_EQ(2u, events.size());
115 EXPECT_EQ(TRACE_EVENT_PHASE_ENTER_CONTEXT, events[0]->phase);
116 EXPECT_EQ(kTestBlameContextCategory, events[0]->category);
117 EXPECT_EQ(kTestBlameContextName, events[0]->name);
118 EXPECT_EQ("0x1234", events[0]->id);
119 EXPECT_EQ(TRACE_EVENT_PHASE_LEAVE_CONTEXT, events[1]->phase);
120 EXPECT_EQ(kTestBlameContextCategory, events[1]->category);
121 EXPECT_EQ(kTestBlameContextName, events[1]->name);
122 EXPECT_EQ("0x1234", events[1]->id);
123 }
124
TEST_F(BlameContextTest,TakeSnapshot)125 TEST_F(BlameContextTest, TakeSnapshot) {
126 using trace_analyzer::Query;
127 trace_analyzer::Start("*");
128 {
129 TestBlameContext parent_blame_context(0x5678);
130 TestBlameContext blame_context(0x1234, parent_blame_context);
131 parent_blame_context.Initialize();
132 blame_context.Initialize();
133 blame_context.TakeSnapshot();
134 }
135 auto analyzer = trace_analyzer::Stop();
136
137 trace_analyzer::TraceEventVector events;
138 Query q = Query::EventPhaseIs(TRACE_EVENT_PHASE_SNAPSHOT_OBJECT);
139 analyzer->FindEvents(q, &events);
140
141 // We should have 3 snapshots: one for both calls to Initialize() and one from
142 // the explicit call to TakeSnapshot().
143 EXPECT_EQ(3u, events.size());
144 EXPECT_EQ(kTestBlameContextCategory, events[0]->category);
145 EXPECT_EQ(kTestBlameContextType, events[0]->name);
146 EXPECT_EQ("0x5678", events[0]->id);
147 EXPECT_TRUE(events[0]->HasArg("snapshot"));
148
149 EXPECT_EQ(kTestBlameContextCategory, events[1]->category);
150 EXPECT_EQ(kTestBlameContextType, events[1]->name);
151 EXPECT_EQ("0x1234", events[1]->id);
152 EXPECT_TRUE(events[0]->HasArg("snapshot"));
153
154 EXPECT_EQ(kTestBlameContextCategory, events[2]->category);
155 EXPECT_EQ(kTestBlameContextType, events[2]->name);
156 EXPECT_EQ("0x1234", events[2]->id);
157 EXPECT_TRUE(events[0]->HasArg("snapshot"));
158
159 const char kExpectedSnapshotJson[] =
160 "{"
161 "\"crossStreams\":false,"
162 "\"parent\":{"
163 "\"id_ref\":\"0x5678\","
164 "\"scope\":\"TestBlameContextScope\""
165 "}"
166 "}";
167
168 std::string snapshot_json;
169 JSONWriter::Write(*events[2]->GetKnownArgAsValue("snapshot"), &snapshot_json);
170 EXPECT_EQ(kExpectedSnapshotJson, snapshot_json);
171 }
172
173 } // namepace
174 } // namespace trace_event
175 } // namespace base
176