84 lines
3.0 KiB
C++
84 lines
3.0 KiB
C++
|
|
// Copyright 2023 The Chromium Authors
|
||
|
|
// Use of this source code is governed by a BSD-style license that can be
|
||
|
|
// found in the LICENSE file.
|
||
|
|
|
||
|
|
#include "test_trace_processor.h"
|
||
|
|
#include <sstream>
|
||
|
|
#include "third_party/perfetto/include/perfetto/trace_processor/trace_processor.h"
|
||
|
|
|
||
|
|
namespace base::test {
|
||
|
|
|
||
|
|
TestTraceProcessor::TestTraceProcessor() {
|
||
|
|
config_ = std::make_unique<perfetto::trace_processor::Config>();
|
||
|
|
trace_processor_ =
|
||
|
|
perfetto::trace_processor::TraceProcessor::CreateInstance(*config_);
|
||
|
|
}
|
||
|
|
|
||
|
|
TestTraceProcessor::~TestTraceProcessor() = default;
|
||
|
|
|
||
|
|
std::vector<std::vector<std::string>> TestTraceProcessor::ExecuteQuery(
|
||
|
|
const std::string& sql) {
|
||
|
|
std::vector<std::vector<std::string>> result;
|
||
|
|
auto it = trace_processor_->ExecuteQuery(sql);
|
||
|
|
// Write column names.
|
||
|
|
std::vector<std::string> column_names;
|
||
|
|
for (uint32_t c = 0; c < it.ColumnCount(); ++c) {
|
||
|
|
column_names.push_back(it.GetColumnName(c));
|
||
|
|
}
|
||
|
|
result.push_back(column_names);
|
||
|
|
// Write rows.
|
||
|
|
while (it.Next()) {
|
||
|
|
std::vector<std::string> row;
|
||
|
|
for (uint32_t c = 0; c < it.ColumnCount(); ++c) {
|
||
|
|
perfetto::trace_processor::SqlValue sql_value = it.Get(c);
|
||
|
|
std::ostringstream ss;
|
||
|
|
switch (sql_value.type) {
|
||
|
|
case perfetto::trace_processor::SqlValue::Type::kLong:
|
||
|
|
ss << sql_value.AsLong();
|
||
|
|
row.push_back(ss.str());
|
||
|
|
break;
|
||
|
|
case perfetto::trace_processor::SqlValue::Type::kDouble:
|
||
|
|
ss << sql_value.AsDouble();
|
||
|
|
row.push_back(ss.str());
|
||
|
|
break;
|
||
|
|
case perfetto::trace_processor::SqlValue::Type::kString:
|
||
|
|
row.push_back(sql_value.AsString());
|
||
|
|
break;
|
||
|
|
case perfetto::trace_processor::SqlValue::Type::kBytes:
|
||
|
|
row.push_back("<raw bytes>");
|
||
|
|
break;
|
||
|
|
case perfetto::trace_processor::SqlValue::Type::kNull:
|
||
|
|
row.push_back("[NULL]");
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
row.push_back("unknown");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
result.push_back(row);
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
absl::Status TestTraceProcessor::ParseTrace(std::unique_ptr<uint8_t[]> buf,
|
||
|
|
size_t size) {
|
||
|
|
auto status =
|
||
|
|
trace_processor_->Parse(perfetto::trace_processor::TraceBlobView(
|
||
|
|
perfetto::trace_processor::TraceBlob::TakeOwnership(std::move(buf),
|
||
|
|
size)));
|
||
|
|
// TODO(rasikan): Add DCHECK that the trace is well-formed and parsing doesn't
|
||
|
|
// have any errors (e.g. to catch the cases when someone emits overlapping
|
||
|
|
// trace events on the same track).
|
||
|
|
trace_processor_->NotifyEndOfFile();
|
||
|
|
return status.ok() ? absl::OkStatus() : absl::UnknownError(status.message());
|
||
|
|
}
|
||
|
|
|
||
|
|
absl::Status TestTraceProcessor::ParseTrace(
|
||
|
|
const std::vector<char>& raw_trace) {
|
||
|
|
auto size = raw_trace.size();
|
||
|
|
std::unique_ptr<uint8_t[]> data_copy(new uint8_t[size]);
|
||
|
|
std::copy(raw_trace.begin(), raw_trace.end(), data_copy.get());
|
||
|
|
return ParseTrace(std::move(data_copy), size);
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace base::test
|