Merge changes from topics "norootintegrationtest", "profileshelltestdatafile"
* changes:
Assert correct callsite name using TP.
Run perfetto_integrationtests from /data/local/tests.
Do not require root for integrationtest.
diff --git a/Android.bp b/Android.bp
index 3352769..657752a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1639,12 +1639,17 @@
":perfetto_include_perfetto_base_base",
":perfetto_include_perfetto_ext_base_base",
":perfetto_include_perfetto_ext_ipc_ipc",
+ ":perfetto_include_perfetto_ext_trace_processor_export_json",
+ ":perfetto_include_perfetto_ext_trace_processor_importers_memory_tracker_memory_tracker",
":perfetto_include_perfetto_ext_traced_sys_stats_counters",
":perfetto_include_perfetto_ext_traced_traced",
":perfetto_include_perfetto_ext_tracing_core_core",
":perfetto_include_perfetto_ext_tracing_ipc_ipc",
":perfetto_include_perfetto_profiling_normalize",
":perfetto_include_perfetto_protozero_protozero",
+ ":perfetto_include_perfetto_trace_processor_basic_types",
+ ":perfetto_include_perfetto_trace_processor_storage",
+ ":perfetto_include_perfetto_trace_processor_trace_processor",
":perfetto_include_perfetto_tracing_core_core",
":perfetto_include_perfetto_tracing_core_forward_decls",
":perfetto_include_perfetto_tracing_tracing",
@@ -1695,6 +1700,8 @@
":perfetto_protos_perfetto_trace_perfetto_zero_gen",
":perfetto_protos_perfetto_trace_power_cpp_gen",
":perfetto_protos_perfetto_trace_power_zero_gen",
+ ":perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen",
+ ":perfetto_protos_perfetto_trace_processor_zero_gen",
":perfetto_protos_perfetto_trace_profiling_cpp_gen",
":perfetto_protos_perfetto_trace_profiling_zero_gen",
":perfetto_protos_perfetto_trace_ps_cpp_gen",
@@ -1731,6 +1738,25 @@
":perfetto_src_profiling_memory_scoped_spinlock",
":perfetto_src_profiling_memory_wire_protocol",
":perfetto_src_protozero_protozero",
+ ":perfetto_src_trace_processor_analysis_analysis",
+ ":perfetto_src_trace_processor_containers_containers",
+ ":perfetto_src_trace_processor_db_lib",
+ ":perfetto_src_trace_processor_export_json",
+ ":perfetto_src_trace_processor_ftrace_descriptors",
+ ":perfetto_src_trace_processor_importers_common",
+ ":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
+ ":perfetto_src_trace_processor_lib",
+ ":perfetto_src_trace_processor_metatrace",
+ ":perfetto_src_trace_processor_metrics_lib",
+ ":perfetto_src_trace_processor_sqlite_sqlite",
+ ":perfetto_src_trace_processor_storage_full",
+ ":perfetto_src_trace_processor_storage_minimal",
+ ":perfetto_src_trace_processor_storage_storage",
+ ":perfetto_src_trace_processor_tables_tables",
+ ":perfetto_src_trace_processor_types_types",
+ ":perfetto_src_trace_processor_util_descriptors",
+ ":perfetto_src_trace_processor_util_protozero_to_text",
+ ":perfetto_src_trace_processor_util_util",
":perfetto_src_traced_probes_android_log_android_log",
":perfetto_src_traced_probes_common_common",
":perfetto_src_traced_probes_data_source",
@@ -1767,10 +1793,14 @@
],
shared_libs: [
"heapprofd_client_api",
+ "libandroidicu",
"libbase",
"liblog",
"libprocinfo",
+ "libsqlite",
"libunwindstack",
+ "libutils",
+ "libz",
],
static_libs: [
"libgmock",
@@ -1828,6 +1858,8 @@
"perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
"perfetto_protos_perfetto_trace_power_cpp_gen_headers",
"perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_processor_zero_gen_headers",
"perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
"perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
"perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
@@ -1839,6 +1871,12 @@
"perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
"perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
"perfetto_src_base_version_gen_h",
+ "perfetto_src_trace_processor_importers_gen_cc_chrome_track_event_descriptor",
+ "perfetto_src_trace_processor_importers_gen_cc_config_descriptor",
+ "perfetto_src_trace_processor_importers_gen_cc_track_event_descriptor",
+ "perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
+ "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
+ "perfetto_src_trace_processor_metrics_gen_merged_sql_metrics",
],
defaults: [
"perfetto_defaults",
@@ -1846,14 +1884,15 @@
cflags: [
"-DGOOGLE_PROTOBUF_NO_RTTI",
"-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_HIDDEN",
],
header_libs: [
"bionic_libc_platform_headers",
],
- require_root: true,
test_suites: [
"general-tests",
],
+ test_config: "PerfettoIntegrationTests.xml",
}
// GN: //protos/perfetto/common:cpp
diff --git a/PerfettoIntegrationTests.xml b/PerfettoIntegrationTests.xml
new file mode 100644
index 0000000..97e7c3a
--- /dev/null
+++ b/PerfettoIntegrationTests.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs perfetto_integrationtests.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push"
+ value="perfetto_integrationtests->/data/local/tests/unrestricted/perfetto_integrationtests" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path"
+ value="/data/local/tests/unrestricted" />
+ <option name="module-name" value="perfetto_integrationtests" />
+ </test>
+</configuration>
\ No newline at end of file
diff --git a/src/profiling/memory/BUILD.gn b/src/profiling/memory/BUILD.gn
index c1b9623..32e049b 100644
--- a/src/profiling/memory/BUILD.gn
+++ b/src/profiling/memory/BUILD.gn
@@ -346,6 +346,7 @@
"../../../test:test_helper",
"../../base",
"../../base:test_support",
+ "../../trace_processor:lib",
]
sources = [ "heapprofd_end_to_end_test.cc" ]
if (perfetto_build_with_android) {
diff --git a/src/profiling/memory/heapprofd_end_to_end_test.cc b/src/profiling/memory/heapprofd_end_to_end_test.cc
index 1a898df..50d87df 100644
--- a/src/profiling/memory/heapprofd_end_to_end_test.cc
+++ b/src/profiling/memory/heapprofd_end_to_end_test.cc
@@ -16,8 +16,10 @@
#include <atomic>
#include <string>
+#include <vector>
#include <fcntl.h>
+#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -26,11 +28,13 @@
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/pipe.h"
#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/subprocess.h"
#include "perfetto/ext/tracing/ipc/default_socket.h"
#include "perfetto/profiling/memory/heap_profile.h"
+#include "perfetto/trace_processor/trace_processor.h"
#include "protos/perfetto/trace/trace.gen.h"
#include "protos/perfetto/trace/trace.pbzero.h"
#include "src/base/test/test_task_runner.h"
@@ -62,11 +66,63 @@
enum class TestMode { kCentral, kStatic };
enum class AllocatorMode { kMalloc, kCustom };
+using ::testing::AllOf;
using ::testing::AnyOf;
using ::testing::Bool;
+using ::testing::Contains;
using ::testing::Eq;
+using ::testing::Field;
+using ::testing::HasSubstr;
using ::testing::Values;
+constexpr const char* kOnlyFlamegraph =
+ "SELECT id, name, map_name, count, cumulative_count, size, "
+ "cumulative_size, "
+ "alloc_count, cumulative_alloc_count, alloc_size, cumulative_alloc_size, "
+ "parent_id "
+ "FROM experimental_flamegraph WHERE "
+ "(ts, upid) IN (SELECT distinct ts, upid from heap_profile_allocation) AND "
+ "profile_type = 'native' order by abs(cumulative_size) desc;";
+
+struct FlamegraphNode {
+ int64_t id;
+ std::string name;
+ std::string map_name;
+ int64_t count;
+ int64_t cumulative_count;
+ int64_t size;
+ int64_t cumulative_size;
+ int64_t alloc_count;
+ int64_t cumulative_alloc_count;
+ int64_t alloc_size;
+ int64_t cumulative_alloc_size;
+ base::Optional<int64_t> parent_id;
+};
+
+std::vector<FlamegraphNode> GetFlamegraph(trace_processor::TraceProcessor* tp) {
+ std::vector<FlamegraphNode> result;
+ auto it = tp->ExecuteQuery(kOnlyFlamegraph);
+ while (it.Next()) {
+ result.push_back({
+ it.Get(0).AsLong(),
+ it.Get(1).AsString(),
+ it.Get(2).AsString(),
+ it.Get(3).AsLong(),
+ it.Get(4).AsLong(),
+ it.Get(5).AsLong(),
+ it.Get(6).AsLong(),
+ it.Get(7).AsLong(),
+ it.Get(8).AsLong(),
+ it.Get(9).AsLong(),
+ it.Get(10).AsLong(),
+ it.Get(11).is_null() ? base::nullopt
+ : base::Optional<int64_t>(it.Get(11).AsLong()),
+ });
+ }
+ PERFETTO_CHECK(it.Status().ok());
+ return result;
+}
+
std::string AllocatorName(AllocatorMode mode) {
switch (mode) {
case AllocatorMode::kMalloc:
@@ -382,8 +438,38 @@
}
}
-std::unique_ptr<TestHelper> GetHelper(base::TestTaskRunner* task_runner) {
- std::unique_ptr<TestHelper> helper(new TestHelper(task_runner));
+class TraceProcessorTestHelper : public TestHelper {
+ public:
+ explicit TraceProcessorTestHelper(base::TestTaskRunner* task_runner)
+ : TestHelper(task_runner),
+ tp_(trace_processor::TraceProcessor::CreateInstance({})) {}
+
+ void ReadTraceData(std::vector<TracePacket> packets) override {
+ for (auto& packet : packets) {
+ auto preamble = packet.GetProtoPreamble();
+ std::string payload = packet.GetRawBytesForTesting();
+ char* preamble_payload = std::get<0>(preamble);
+ size_t preamble_size = std::get<1>(preamble);
+ size_t buf_size = preamble_size + payload.size();
+ std::unique_ptr<uint8_t[]> buf =
+ std::unique_ptr<uint8_t[]>(new uint8_t[buf_size]);
+ memcpy(&buf[0], preamble_payload, preamble_size);
+ memcpy(&buf[preamble_size], payload.data(), payload.size());
+ PERFETTO_CHECK(tp_->Parse(std::move(buf), buf_size).ok());
+ }
+ TestHelper::ReadTraceData(std::move(packets));
+ }
+
+ trace_processor::TraceProcessor& tp() { return *tp_; }
+
+ private:
+ std::unique_ptr<trace_processor::TraceProcessor> tp_;
+};
+
+std::unique_ptr<TraceProcessorTestHelper> GetHelper(
+ base::TestTaskRunner* task_runner) {
+ std::unique_ptr<TraceProcessorTestHelper> helper(
+ new TraceProcessorTestHelper(task_runner));
helper->StartServiceIfRequired();
helper->ConnectConsumer();
@@ -391,6 +477,13 @@
return helper;
}
+void ReadAndWait(TraceProcessorTestHelper* helper) {
+ helper->WaitForTracingDisabled(kTracingDisabledTimeoutMs);
+ helper->ReadData();
+ helper->WaitForReadData(0, kWaitForReadDataTimeoutMs);
+ helper->tp().NotifyEndOfFile();
+}
+
std::string ToTraceString(
const std::vector<protos::gen::TracePacket>& packets) {
protos::gen::Trace trace;
@@ -484,18 +577,18 @@
base::WriteAll(*fd, trace_string.data(), trace_string.size()) >= 0);
}
- std::unique_ptr<TestHelper> Trace(const TraceConfig& trace_config) {
+ std::unique_ptr<TraceProcessorTestHelper> Trace(
+ const TraceConfig& trace_config) {
auto helper = GetHelper(&task_runner);
helper->StartTracing(trace_config);
- helper->WaitForTracingDisabled(kTracingDisabledTimeoutMs);
- helper->ReadData();
- helper->WaitForReadData(0, kWaitForReadDataTimeoutMs);
+ ReadAndWait(helper.get());
return helper;
}
- std::vector<std::string> GetUnwindingErrors(TestHelper* helper) {
+ std::vector<std::string> GetUnwindingErrors(
+ TraceProcessorTestHelper* helper) {
std::vector<std::string> out;
const auto& packets = helper->trace();
for (const protos::gen::TracePacket& packet : packets) {
@@ -509,7 +602,7 @@
return out;
}
- void PrintStats(TestHelper* helper) {
+ void PrintStats(TraceProcessorTestHelper* helper) {
const auto& packets = helper->trace();
for (const protos::gen::TracePacket& packet : packets) {
for (const auto& dump : packet.profile_packet().process_dumps()) {
@@ -524,7 +617,7 @@
}
}
- void ValidateSampleSizes(TestHelper* helper,
+ void ValidateSampleSizes(TraceProcessorTestHelper* helper,
uint64_t pid,
uint64_t alloc_size,
const std::string& heap_name = "") {
@@ -545,7 +638,7 @@
}
}
- void ValidateFromStartup(TestHelper* helper,
+ void ValidateFromStartup(TraceProcessorTestHelper* helper,
uint64_t pid,
bool from_startup) {
const auto& packets = helper->trace();
@@ -558,7 +651,7 @@
}
}
- void ValidateRejectedConcurrent(TestHelper* helper,
+ void ValidateRejectedConcurrent(TraceProcessorTestHelper* helper,
uint64_t pid,
bool rejected_concurrent) {
const auto& packets = helper->trace();
@@ -571,7 +664,7 @@
}
}
- void ValidateNoSamples(TestHelper* helper, uint64_t pid) {
+ void ValidateNoSamples(TraceProcessorTestHelper* helper, uint64_t pid) {
const auto& packets = helper->trace();
size_t samples = 0;
for (const protos::gen::TracePacket& packet : packets) {
@@ -584,7 +677,7 @@
EXPECT_EQ(samples, 0u);
}
- void ValidateHasSamples(TestHelper* helper,
+ void ValidateHasSamples(TraceProcessorTestHelper* helper,
uint64_t pid,
const std::string& heap_name,
uint64_t sampling_interval) {
@@ -613,7 +706,7 @@
EXPECT_GT(last_freed, 0u) << heap_name;
}
- void ValidateOnlyPID(TestHelper* helper, uint64_t pid) {
+ void ValidateOnlyPID(TraceProcessorTestHelper* helper, uint64_t pid) {
size_t dumps = 0;
const auto& packets = helper->trace();
for (const protos::gen::TracePacket& packet : packets) {
@@ -760,6 +853,13 @@
PrintStats(helper.get());
KillAssertRunning(&child);
+ auto flamegraph = GetFlamegraph(&helper->tp());
+ EXPECT_THAT(flamegraph,
+ Contains(AllOf(
+ Field(&FlamegraphNode::name, HasSubstr("RunAccurateMalloc")),
+ Field(&FlamegraphNode::cumulative_size, Eq(15)),
+ Field(&FlamegraphNode::cumulative_alloc_size, Eq(40)))));
+
ValidateOnlyPID(helper.get(), pid);
size_t total_alloc = 0;
@@ -986,10 +1086,7 @@
std::string("0"));
StartAndWaitForHandshake(&child);
- helper->WaitForTracingDisabled(kTracingDisabledTimeoutMs);
-
- helper->ReadData();
- helper->WaitForReadData(0, kWaitForReadDataTimeoutMs);
+ ReadAndWait(helper.get());
WRITE_TRACE(helper->full_trace());
KillAssertRunning(&child);
@@ -1056,10 +1153,7 @@
StartAndWaitForHandshake(&child);
- helper->WaitForTracingDisabled(kTracingDisabledTimeoutMs);
-
- helper->ReadData();
- helper->WaitForReadData(0, kWaitForReadDataTimeoutMs);
+ ReadAndWait(helper.get());
WRITE_TRACE(helper->full_trace());
KillAssertRunning(&child);
@@ -1119,10 +1213,7 @@
trace_config.set_duration_ms(5000);
helper->StartTracing(trace_config);
- helper->WaitForTracingDisabled(kTracingDisabledTimeoutMs);
-
- helper->ReadData();
- helper->WaitForReadData(0, kWaitForReadDataTimeoutMs);
+ ReadAndWait(helper.get());
WRITE_TRACE(helper->full_trace());
KillAssertRunning(&child);
@@ -1183,10 +1274,7 @@
trace_config.set_duration_ms(5000);
helper->StartTracing(trace_config);
- helper->WaitForTracingDisabled(kTracingDisabledTimeoutMs);
-
- helper->ReadData();
- helper->WaitForReadData(0, kWaitForReadDataTimeoutMs);
+ ReadAndWait(helper.get());
WRITE_TRACE(helper->full_trace());
KillAssertRunning(&child);
@@ -1285,16 +1373,14 @@
PERFETTO_LOG("HeapprofdEndToEnd::Reinit: Starting second");
// We must keep alive the original helper because it owns the service thread.
- std::unique_ptr<TestHelper> helper2 =
- std::unique_ptr<TestHelper>(new TestHelper(&task_runner));
+ std::unique_ptr<TraceProcessorTestHelper> helper2 =
+ std::unique_ptr<TraceProcessorTestHelper>(
+ new TraceProcessorTestHelper(&task_runner));
helper2->ConnectConsumer();
helper2->WaitForConsumerConnect();
helper2->StartTracing(trace_config);
- helper2->WaitForTracingDisabled(kTracingDisabledTimeoutMs);
-
- helper2->ReadData();
- helper2->WaitForReadData(0, kWaitForReadDataTimeoutMs);
+ ReadAndWait(helper2.get());
WRITE_TRACE(helper2->trace());
PrintStats(helper2.get());
@@ -1372,16 +1458,15 @@
PERFETTO_LOG("HeapprofdEndToEnd::Reinit: Starting second");
// We must keep alive the original helper because it owns the service thread.
- std::unique_ptr<TestHelper> helper2 =
- std::unique_ptr<TestHelper>(new TestHelper(&task_runner));
+ std::unique_ptr<TraceProcessorTestHelper> helper2 =
+ std::unique_ptr<TraceProcessorTestHelper>(
+ new TraceProcessorTestHelper(&task_runner));
helper2->ConnectConsumer();
helper2->WaitForConsumerConnect();
helper2->StartTracing(trace_config);
- helper2->WaitForTracingDisabled(kTracingDisabledTimeoutMs);
+ ReadAndWait(helper2.get());
- helper2->ReadData();
- helper2->WaitForReadData(0, kWaitForReadDataTimeoutMs);
WRITE_TRACE(helper2->trace());
PrintStats(helper2.get());
@@ -1412,20 +1497,17 @@
sleep(1);
PERFETTO_LOG("Starting concurrent.");
- std::unique_ptr<TestHelper> helper_concurrent(new TestHelper(&task_runner));
+ std::unique_ptr<TraceProcessorTestHelper> helper_concurrent(
+ new TraceProcessorTestHelper(&task_runner));
helper_concurrent->ConnectConsumer();
helper_concurrent->WaitForConsumerConnect();
helper_concurrent->StartTracing(trace_config);
- helper->WaitForTracingDisabled(kTracingDisabledTimeoutMs);
- helper->ReadData();
- helper->WaitForReadData(0, kWaitForReadDataTimeoutMs);
+ ReadAndWait(helper.get());
WRITE_TRACE(helper->full_trace());
PrintStats(helper.get());
- helper_concurrent->WaitForTracingDisabled(kTracingDisabledTimeoutMs);
- helper_concurrent->ReadData();
- helper_concurrent->WaitForReadData(0, kWaitForReadDataTimeoutMs);
+ ReadAndWait(helper_concurrent.get());
WRITE_TRACE(helper_concurrent->trace());
PrintStats(helper_concurrent.get());
KillAssertRunning(&child);
@@ -1493,9 +1575,7 @@
// Assert that we did profile the process.
helper->FlushAndWait(2000);
helper->DisableTracing();
- helper->WaitForTracingDisabled(kTracingDisabledTimeoutMs);
- helper->ReadData();
- helper->WaitForReadData(0, kWaitForReadDataTimeoutMs);
+ ReadAndWait(helper.get());
WRITE_TRACE(helper->full_trace());
const auto& packets = helper->trace();
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index 9401a5a..38c7cca 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -199,9 +199,8 @@
('include_dirs', {'bionic/libc/kernel'}),
],
'perfetto_integrationtests': [
- # api_end_to_end_test needs root to create a socket.
- ('require_root', True),
('test_suites', {'general-tests'}),
+ ('test_config', 'PerfettoIntegrationTests.xml'),
],
'traced_probes': [
('required', {'libperfetto_android_internal',
@@ -457,8 +456,8 @@
self.genrule_srcs = set()
self.genrule_shared_libs = set()
self.version_script = None
- self.require_root = None
self.test_suites = set()
+ self.test_config = None
self.stubs = {}
def to_string(self, output):
@@ -490,8 +489,8 @@
self._output_field(output, 'stl')
self._output_field(output, 'apex_available')
self._output_field(output, 'version_script')
- self._output_field(output, 'require_root')
self._output_field(output, 'test_suites')
+ self._output_field(output, 'test_config')
self._output_field(output, 'stubs')
target_out = []