• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(const std::vector<char> & raw_trace)76 absl::Status TestTraceProcessorImpl::ParseTrace(
77     const std::vector<char>& raw_trace) {
78   auto status =
79       trace_processor_->Parse(perfetto::trace_processor::TraceBlobView(
80           perfetto::trace_processor::TraceBlob::CopyFrom(raw_trace.data(),
81                                                          raw_trace.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   if (!status.ok()) {
86     return absl::UnknownError(status.message());
87   }
88 
89   status = trace_processor_->NotifyEndOfFile();
90   return status.ok() ? absl::OkStatus() : absl::UnknownError(status.message());
91 }
92 
OverrideSqlModule(const std::string & module_name,const TestTraceProcessorImpl::PerfettoSQLModule & module)93 absl::Status TestTraceProcessorImpl::OverrideSqlModule(
94     const std::string& module_name,
95     const TestTraceProcessorImpl::PerfettoSQLModule& module) {
96   auto status =
97       trace_processor_->RegisterSqlModule({module_name, module, true});
98   return status.ok() ? absl::OkStatus() : absl::UnknownError(status.message());
99 }
100 
101 }  // namespace base::test
102