Make testing traces easier
We would like to add unit tests to make sure important trace events, that are
used in benchmarks, like the ones recently introduced in crrev/c/861389, are not
accidentally deleted.
This patch cleans up existing similar unit tests and makes writing new tests
easier.
TBR=oysteine@chromium.org,jam@chromium.org,hjd@chromium.org,skyostil@chromium.org,tdresser@chromium.org
BUG=none
Change-Id: Ieda04b3e5470b1b31b4140c2c9a6c51ea6e56202
Reviewed-on: https://chromium-review.googlesource.com/919144
Commit-Queue: Ehsan Chiniforooshan <chiniforooshan@chromium.org>
Reviewed-by: Ehsan Chiniforooshan <chiniforooshan@chromium.org>
Reviewed-by: Timothy Dresser <tdresser@chromium.org>
Reviewed-by: danakj <danakj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#536814}
CrOS-Libchrome-Original-Commit: b53a9c2f3acb0405b1b26f15fca5d059e8fd98ce
diff --git a/base/test/trace_event_analyzer.cc b/base/test/trace_event_analyzer.cc
index 5d6d081..a822aee 100644
--- a/base/test/trace_event_analyzer.cc
+++ b/base/test/trace_event_analyzer.cc
@@ -7,13 +7,29 @@
#include <math.h>
#include <algorithm>
-#include <memory>
#include <set>
#include "base/json/json_reader.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/run_loop.h"
#include "base/strings/pattern.h"
+#include "base/trace_event/trace_buffer.h"
+#include "base/trace_event/trace_config.h"
+#include "base/trace_event/trace_log.h"
#include "base/values.h"
+namespace {
+void OnTraceDataCollected(base::OnceClosure quit_closure,
+ base::trace_event::TraceResultBuffer* buffer,
+ const scoped_refptr<base::RefCountedString>& json,
+ bool has_more_events) {
+ buffer->AddFragment(json->data());
+ if (!has_more_events)
+ std::move(quit_closure).Run();
+}
+} // namespace
+
namespace trace_analyzer {
// TraceEvent
@@ -874,6 +890,34 @@
}
}
+// Utility functions for collecting process-local traces and creating a
+// |TraceAnalyzer| from the result.
+
+void Start(const std::string& category_filter_string) {
+ DCHECK(!base::trace_event::TraceLog::GetInstance()->IsEnabled());
+ base::trace_event::TraceLog::GetInstance()->SetEnabled(
+ base::trace_event::TraceConfig(category_filter_string, ""),
+ base::trace_event::TraceLog::RECORDING_MODE);
+}
+
+std::unique_ptr<TraceAnalyzer> Stop() {
+ DCHECK(base::trace_event::TraceLog::GetInstance()->IsEnabled());
+ base::trace_event::TraceLog::GetInstance()->SetDisabled();
+
+ base::trace_event::TraceResultBuffer buffer;
+ base::trace_event::TraceResultBuffer::SimpleOutput trace_output;
+ buffer.SetOutputCallback(trace_output.GetCallback());
+ base::RunLoop run_loop;
+ buffer.Start();
+ base::trace_event::TraceLog::GetInstance()->Flush(
+ base::BindRepeating(&OnTraceDataCollected, run_loop.QuitClosure(),
+ base::Unretained(&buffer)));
+ run_loop.Run();
+ buffer.Finish();
+
+ return base::WrapUnique(TraceAnalyzer::Create(trace_output.json_output));
+}
+
// TraceEventVector utility functions.
bool GetRateStats(const TraceEventVector& events,
diff --git a/base/test/trace_event_analyzer.h b/base/test/trace_event_analyzer.h
index 4e1d09d..ea716bc 100644
--- a/base/test/trace_event_analyzer.h
+++ b/base/test/trace_event_analyzer.h
@@ -71,7 +71,21 @@
// EXPECT_TRUE(events[i].GetAbsTimeToOtherEvent(&duration));
// EXPECT_LT(duration, 1000000.0/60.0); // expect less than 1/60 second.
// }
-
+//
+// There are two helper functions, Start(category_filter_string) and Stop(), for
+// facilitating the collection of process-local traces and building a
+// TraceAnalyzer from them. A typical test, that uses the helper functions,
+// looks like the following:
+//
+// TEST_F(...) {
+// Start("*");
+// [Invoke the functions you want to test their traces]
+// auto analyzer = Stop();
+//
+// [Use the analyzer to verify produced traces, as explained above]
+// }
+//
+// Note: The Stop() function needs a SingleThreadTaskRunner.
#ifndef BASE_TEST_TRACE_EVENT_ANALYZER_H_
#define BASE_TEST_TRACE_EVENT_ANALYZER_H_
@@ -80,6 +94,9 @@
#include <stdint.h>
#include <map>
+#include <memory>
+#include <string>
+#include <vector>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -743,6 +760,13 @@
DISALLOW_COPY_AND_ASSIGN(TraceAnalyzer);
};
+// Utility functions for collecting process-local traces and creating a
+// |TraceAnalyzer| from the result. Please see comments in trace_config.h to
+// understand how the |category_filter_string| works. Use "*" to enable all
+// default categories.
+void Start(const std::string& category_filter_string);
+std::unique_ptr<TraceAnalyzer> Stop();
+
// Utility functions for TraceEventVector.
struct RateStats {
diff --git a/base/trace_event/blame_context_unittest.cc b/base/trace_event/blame_context_unittest.cc
index bd999aa..12e7857 100644
--- a/base/trace_event/blame_context_unittest.cc
+++ b/base/trace_event/blame_context_unittest.cc
@@ -5,12 +5,8 @@
#include "base/trace_event/blame_context.h"
#include "base/json/json_writer.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/ref_counted_memory.h"
#include "base/message_loop/message_loop.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"
@@ -60,61 +56,21 @@
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();
- std::unique_ptr<trace_analyzer::TraceAnalyzer> CreateTraceAnalyzer();
protected:
MessageLoop loop_;
};
-void BlameContextTest::StartTracing() {
- trace_event::TraceLog::GetInstance()->SetEnabled(
- trace_event::TraceConfig("*"), trace_event::TraceLog::RECORDING_MODE);
-}
-
-void BlameContextTest::StopTracing() {
- trace_event::TraceLog::GetInstance()->SetDisabled();
-}
-
-std::unique_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 WrapUnique(
- trace_analyzer::TraceAnalyzer::Create(trace_output.json_output));
-}
-
TEST_F(BlameContextTest, EnterAndLeave) {
using trace_analyzer::Query;
- StartTracing();
+ trace_analyzer::Start("*");
{
TestBlameContext blame_context(0x1234);
blame_context.Initialize();
blame_context.Enter();
blame_context.Leave();
}
- StopTracing();
- std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer =
- CreateTraceAnalyzer();
+ auto analyzer = trace_analyzer::Stop();
trace_analyzer::TraceEventVector events;
Query q = Query::EventPhaseIs(TRACE_EVENT_PHASE_ENTER_CONTEXT) ||
@@ -136,7 +92,7 @@
// Ensure there is no cross talk between blame contexts from different
// categories.
using trace_analyzer::Query;
- StartTracing();
+ trace_analyzer::Start("*");
{
TestBlameContext blame_context(0x1234);
DisabledTestBlameContext disabled_blame_context(0x5678);
@@ -147,9 +103,7 @@
disabled_blame_context.Enter();
disabled_blame_context.Leave();
}
- StopTracing();
- std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer =
- CreateTraceAnalyzer();
+ auto analyzer = trace_analyzer::Stop();
trace_analyzer::TraceEventVector events;
Query q = Query::EventPhaseIs(TRACE_EVENT_PHASE_ENTER_CONTEXT) ||
@@ -170,7 +124,7 @@
TEST_F(BlameContextTest, TakeSnapshot) {
using trace_analyzer::Query;
- StartTracing();
+ trace_analyzer::Start("*");
{
TestBlameContext parent_blame_context(0x5678);
TestBlameContext blame_context(0x1234, parent_blame_context);
@@ -178,9 +132,7 @@
blame_context.Initialize();
blame_context.TakeSnapshot();
}
- StopTracing();
- std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer =
- CreateTraceAnalyzer();
+ auto analyzer = trace_analyzer::Stop();
trace_analyzer::TraceEventVector events;
Query q = Query::EventPhaseIs(TRACE_EVENT_PHASE_SNAPSHOT_OBJECT);