1 // Copyright 2023 The Chromium Authors
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 "test_trace_processor_impl.h"
6 #include <sstream>
7 #include "third_party/perfetto/include/perfetto/trace_processor/trace_processor.h"
8
9 namespace base::test {
10
QueryResultOrError(const QueryResult & result)11 QueryResultOrError::QueryResultOrError(const QueryResult& result)
12 : result_(result) {}
QueryResultOrError(const std::string & error)13 QueryResultOrError::QueryResultOrError(const std::string& error)
14 : error_(error) {}
15 QueryResultOrError::~QueryResultOrError() = default;
16
TestTraceProcessorImpl()17 TestTraceProcessorImpl::TestTraceProcessorImpl() {
18 config_ = std::make_unique<perfetto::trace_processor::Config>();
19 trace_processor_ =
20 perfetto::trace_processor::TraceProcessor::CreateInstance(*config_);
21 }
22
23 TestTraceProcessorImpl::~TestTraceProcessorImpl() = default;
24
25 TestTraceProcessorImpl::TestTraceProcessorImpl(TestTraceProcessorImpl&& other) =
26 default;
27 TestTraceProcessorImpl& TestTraceProcessorImpl::operator=(
28 TestTraceProcessorImpl&& other) = default;
29
ExecuteQuery(const std::string & sql) const30 QueryResultOrError TestTraceProcessorImpl::ExecuteQuery(
31 const std::string& sql) const {
32 QueryResultOrError::QueryResult result;
33 auto it = trace_processor_->ExecuteQuery(sql);
34 // Write column names.
35 std::vector<std::string> column_names;
36 for (uint32_t c = 0; c < it.ColumnCount(); ++c) {
37 column_names.push_back(it.GetColumnName(c));
38 }
39 result.push_back(column_names);
40 // Write rows.
41 while (it.Next()) {
42 std::vector<std::string> row;
43 for (uint32_t c = 0; c < it.ColumnCount(); ++c) {
44 perfetto::trace_processor::SqlValue sql_value = it.Get(c);
45 std::ostringstream ss;
46 switch (sql_value.type) {
47 case perfetto::trace_processor::SqlValue::Type::kLong:
48 ss << sql_value.AsLong();
49 row.push_back(ss.str());
50 break;
51 case perfetto::trace_processor::SqlValue::Type::kDouble:
52 ss << sql_value.AsDouble();
53 row.push_back(ss.str());
54 break;
55 case perfetto::trace_processor::SqlValue::Type::kString:
56 row.push_back(sql_value.AsString());
57 break;
58 case perfetto::trace_processor::SqlValue::Type::kBytes:
59 row.push_back("<raw bytes>");
60 break;
61 case perfetto::trace_processor::SqlValue::Type::kNull:
62 row.push_back("[NULL]");
63 break;
64 default:
65 row.push_back("unknown");
66 }
67 }
68 result.push_back(row);
69 }
70 if (!it.Status().ok()) {
71 return QueryResultOrError(it.Status().message());
72 }
73 return QueryResultOrError(result);
74 }
75
ParseTrace(std::unique_ptr<uint8_t[]> buf,size_t size)76 absl::Status TestTraceProcessorImpl::ParseTrace(std::unique_ptr<uint8_t[]> buf,
77 size_t size) {
78 auto status =
79 trace_processor_->Parse(perfetto::trace_processor::TraceBlobView(
80 perfetto::trace_processor::TraceBlob::TakeOwnership(std::move(buf),
81 size)));
82 // TODO(rasikan): Add DCHECK that the trace is well-formed and parsing doesn't
83 // have any errors (e.g. to catch the cases when someone emits overlapping
84 // trace events on the same track).
85 trace_processor_->NotifyEndOfFile();
86 return status.ok() ? absl::OkStatus() : absl::UnknownError(status.message());
87 }
88
ParseTrace(const std::vector<char> & raw_trace)89 absl::Status TestTraceProcessorImpl::ParseTrace(
90 const std::vector<char>& raw_trace) {
91 auto size = raw_trace.size();
92 std::unique_ptr<uint8_t[]> data_copy(new uint8_t[size]);
93 std::copy(raw_trace.begin(), raw_trace.end(), data_copy.get());
94 return ParseTrace(std::move(data_copy), size);
95 }
96
OverrideSqlModule(const std::string & module_name,const TestTraceProcessorImpl::PerfettoSQLModule & module)97 absl::Status TestTraceProcessorImpl::OverrideSqlModule(
98 const std::string& module_name,
99 const TestTraceProcessorImpl::PerfettoSQLModule& module) {
100 auto status =
101 trace_processor_->RegisterSqlModule({module_name, module, true});
102 return status.ok() ? absl::OkStatus() : absl::UnknownError(status.message());
103 }
104
105 } // namespace base::test
106