| Index: base/trace_event/blame_context_unittest.cc
|
| diff --git a/base/trace_event/blame_context_unittest.cc b/base/trace_event/blame_context_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7217d8fb1bb6e305621b0d475b72f1e2e63aa5b3
|
| --- /dev/null
|
| +++ b/base/trace_event/blame_context_unittest.cc
|
| @@ -0,0 +1,216 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "base/trace_event/blame_context.h"
|
| +
|
| +#include "base/json/json_writer.h"
|
| +#include "base/memory/ref_counted_memory.h"
|
| +#include "base/run_loop.h"
|
| +#include "base/test/trace_event_analyzer.h"
|
| +#include "base/trace_event/trace_buffer.h"
|
| +#include "base/trace_event/trace_event_argument.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace base {
|
| +namespace trace_event {
|
| +namespace {
|
| +
|
| +const char kTestBlameContextCategory[] = "test";
|
| +const char kDisabledTestBlameContextCategory[] = "disabled-by-default-test";
|
| +const char kTestBlameContextName[] = "TestBlameContext";
|
| +const char kTestBlameContextType[] = "TestBlameContextType";
|
| +const char kTestBlameContextScope[] = "TestBlameContextScope";
|
| +
|
| +class TestBlameContext : public BlameContext {
|
| + public:
|
| + explicit TestBlameContext(int id)
|
| + : BlameContext(kTestBlameContextCategory,
|
| + kTestBlameContextName,
|
| + kTestBlameContextType,
|
| + kTestBlameContextScope,
|
| + id,
|
| + nullptr) {}
|
| +
|
| + TestBlameContext(int id, const TestBlameContext& parent)
|
| + : BlameContext(kTestBlameContextCategory,
|
| + kTestBlameContextName,
|
| + kTestBlameContextType,
|
| + kTestBlameContextScope,
|
| + id,
|
| + &parent) {}
|
| +
|
| + protected:
|
| + void AsValueInto(trace_event::TracedValue* state) override {
|
| + BlameContext::AsValueInto(state);
|
| + state->SetBoolean("crossStreams", false);
|
| + }
|
| +};
|
| +
|
| +class DisabledTestBlameContext : public BlameContext {
|
| + public:
|
| + explicit DisabledTestBlameContext(int id)
|
| + : BlameContext(kDisabledTestBlameContextCategory,
|
| + kTestBlameContextName,
|
| + kTestBlameContextType,
|
| + kTestBlameContextScope,
|
| + id,
|
| + nullptr) {}
|
| +};
|
| +
|
| +void OnTraceDataCollected(Closure quit_closure,
|
| + trace_event::TraceResultBuffer* buffer,
|
| + const scoped_refptr<RefCountedString>& json,
|
| + bool has_more_events) {
|
| + buffer->AddFragment(json->data());
|
| + if (!has_more_events)
|
| + quit_closure.Run();
|
| +}
|
| +
|
| +class BlameContextTest : public testing::Test {
|
| + public:
|
| + void StartTracing();
|
| + void StopTracing();
|
| + scoped_ptr<trace_analyzer::TraceAnalyzer> CreateTraceAnalyzer();
|
| +};
|
| +
|
| +void BlameContextTest::StartTracing() {
|
| + trace_event::TraceLog::GetInstance()->SetEnabled(
|
| + trace_event::TraceConfig("*"), trace_event::TraceLog::RECORDING_MODE);
|
| +}
|
| +
|
| +void BlameContextTest::StopTracing() {
|
| + trace_event::TraceLog::GetInstance()->SetDisabled();
|
| +}
|
| +
|
| +scoped_ptr<trace_analyzer::TraceAnalyzer>
|
| +BlameContextTest::CreateTraceAnalyzer() {
|
| + trace_event::TraceResultBuffer buffer;
|
| + trace_event::TraceResultBuffer::SimpleOutput trace_output;
|
| + buffer.SetOutputCallback(trace_output.GetCallback());
|
| + RunLoop run_loop;
|
| + buffer.Start();
|
| + trace_event::TraceLog::GetInstance()->Flush(
|
| + Bind(&OnTraceDataCollected, run_loop.QuitClosure(), Unretained(&buffer)));
|
| + run_loop.Run();
|
| + buffer.Finish();
|
| +
|
| + return make_scoped_ptr(
|
| + trace_analyzer::TraceAnalyzer::Create(trace_output.json_output));
|
| +}
|
| +
|
| +TEST_F(BlameContextTest, EnterAndLeave) {
|
| + using trace_analyzer::Query;
|
| + StartTracing();
|
| + {
|
| + TestBlameContext blame_context(0x1234);
|
| + blame_context.Initialize();
|
| + blame_context.Enter();
|
| + blame_context.Leave();
|
| + }
|
| + StopTracing();
|
| + scoped_ptr<trace_analyzer::TraceAnalyzer> analyzer = CreateTraceAnalyzer();
|
| +
|
| + trace_analyzer::TraceEventVector events;
|
| + Query q = Query::EventPhaseIs(TRACE_EVENT_PHASE_ENTER_CONTEXT) ||
|
| + Query::EventPhaseIs(TRACE_EVENT_PHASE_LEAVE_CONTEXT);
|
| + analyzer->FindEvents(q, &events);
|
| +
|
| + EXPECT_EQ(2u, events.size());
|
| + EXPECT_EQ(TRACE_EVENT_PHASE_ENTER_CONTEXT, events[0]->phase);
|
| + EXPECT_EQ(kTestBlameContextCategory, events[0]->category);
|
| + EXPECT_EQ(kTestBlameContextName, events[0]->name);
|
| + EXPECT_EQ("0x1234", events[0]->id);
|
| + EXPECT_EQ(TRACE_EVENT_PHASE_LEAVE_CONTEXT, events[1]->phase);
|
| + EXPECT_EQ(kTestBlameContextCategory, events[1]->category);
|
| + EXPECT_EQ(kTestBlameContextName, events[1]->name);
|
| + EXPECT_EQ("0x1234", events[1]->id);
|
| +}
|
| +
|
| +TEST_F(BlameContextTest, DifferentCategories) {
|
| + // Ensure there is no cross talk between blame contexts from different
|
| + // categories.
|
| + using trace_analyzer::Query;
|
| + StartTracing();
|
| + {
|
| + TestBlameContext blame_context(0x1234);
|
| + DisabledTestBlameContext disabled_blame_context(0x5678);
|
| + blame_context.Initialize();
|
| + blame_context.Enter();
|
| + blame_context.Leave();
|
| + disabled_blame_context.Initialize();
|
| + disabled_blame_context.Enter();
|
| + disabled_blame_context.Leave();
|
| + }
|
| + StopTracing();
|
| + scoped_ptr<trace_analyzer::TraceAnalyzer> analyzer = CreateTraceAnalyzer();
|
| +
|
| + trace_analyzer::TraceEventVector events;
|
| + Query q = Query::EventPhaseIs(TRACE_EVENT_PHASE_ENTER_CONTEXT) ||
|
| + Query::EventPhaseIs(TRACE_EVENT_PHASE_LEAVE_CONTEXT);
|
| + analyzer->FindEvents(q, &events);
|
| +
|
| + // None of the events from the disabled-by-default category should show up.
|
| + EXPECT_EQ(2u, events.size());
|
| + EXPECT_EQ(TRACE_EVENT_PHASE_ENTER_CONTEXT, events[0]->phase);
|
| + EXPECT_EQ(kTestBlameContextCategory, events[0]->category);
|
| + EXPECT_EQ(kTestBlameContextName, events[0]->name);
|
| + EXPECT_EQ("0x1234", events[0]->id);
|
| + EXPECT_EQ(TRACE_EVENT_PHASE_LEAVE_CONTEXT, events[1]->phase);
|
| + EXPECT_EQ(kTestBlameContextCategory, events[1]->category);
|
| + EXPECT_EQ(kTestBlameContextName, events[1]->name);
|
| + EXPECT_EQ("0x1234", events[1]->id);
|
| +}
|
| +
|
| +TEST_F(BlameContextTest, TakeSnapshot) {
|
| + using trace_analyzer::Query;
|
| + StartTracing();
|
| + {
|
| + TestBlameContext parent_blame_context(0x5678);
|
| + TestBlameContext blame_context(0x1234, parent_blame_context);
|
| + parent_blame_context.Initialize();
|
| + blame_context.Initialize();
|
| + blame_context.TakeSnapshot();
|
| + }
|
| + StopTracing();
|
| + scoped_ptr<trace_analyzer::TraceAnalyzer> analyzer = CreateTraceAnalyzer();
|
| +
|
| + trace_analyzer::TraceEventVector events;
|
| + Query q = Query::EventPhaseIs(TRACE_EVENT_PHASE_SNAPSHOT_OBJECT);
|
| + analyzer->FindEvents(q, &events);
|
| +
|
| + // We should have 3 snapshots: one for both calls to Initialize() and one from
|
| + // the explicit call to TakeSnapshot().
|
| + EXPECT_EQ(3u, events.size());
|
| + EXPECT_EQ(kTestBlameContextCategory, events[0]->category);
|
| + EXPECT_EQ(kTestBlameContextType, events[0]->name);
|
| + EXPECT_EQ("0x5678", events[0]->id);
|
| + EXPECT_TRUE(events[0]->HasArg("snapshot"));
|
| +
|
| + EXPECT_EQ(kTestBlameContextCategory, events[1]->category);
|
| + EXPECT_EQ(kTestBlameContextType, events[1]->name);
|
| + EXPECT_EQ("0x1234", events[1]->id);
|
| + EXPECT_TRUE(events[0]->HasArg("snapshot"));
|
| +
|
| + EXPECT_EQ(kTestBlameContextCategory, events[2]->category);
|
| + EXPECT_EQ(kTestBlameContextType, events[2]->name);
|
| + EXPECT_EQ("0x1234", events[2]->id);
|
| + EXPECT_TRUE(events[0]->HasArg("snapshot"));
|
| +
|
| + const char kExpectedSnapshotJson[] =
|
| + "{"
|
| + "\"crossStreams\":false,"
|
| + "\"parent\":{"
|
| + "\"id_ref\":\"0x5678\","
|
| + "\"scope\":\"TestBlameContextScope\""
|
| + "}"
|
| + "}";
|
| +
|
| + std::string snapshot_json;
|
| + JSONWriter::Write(*events[2]->GetKnownArgAsValue("snapshot"), &snapshot_json);
|
| + EXPECT_EQ(kExpectedSnapshotJson, snapshot_json);
|
| +}
|
| +
|
| +} // namepace
|
| +} // namespace trace_event
|
| +} // namespace base
|
|
|