blob: 14bbc508ce320d9609cf6b1062a39d8703aede66 [file] [log] [blame]
// 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