xref: /aosp_15_r20/external/cronet/base/test/test_trace_processor_impl.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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