• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <cinttypes>
18 #include <string>
19 
20 #include "perfetto/base/logging.h"
21 #include "perfetto/tracing/core/data_source_config.h"
22 
23 #include "src/base/test/test_task_runner.h"
24 #include "test/android_test_utils.h"
25 #include "test/cts/heapprofd_test_helper.h"
26 #include "test/gtest_and_gmock.h"
27 #include "test/test_helper.h"
28 
29 #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
30 #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
31 
32 namespace perfetto {
33 namespace {
34 
35 // Size of individual (repeated) allocations done by the test apps (must be kept
36 // in sync with their sources).
37 constexpr uint64_t kTestSamplingInterval = 4096;
38 constexpr uint64_t kExpectedIndividualAllocSz = 4153;
39 // Tests rely on the sampling behaviour where allocations larger than the
40 // sampling interval are recorded at their actual size.
41 static_assert(kExpectedIndividualAllocSz > kTestSamplingInterval,
42               "kTestSamplingInterval invalid");
43 
44 // Activity that runs a JNI thread that repeatedly calls
45 // malloc(kExpectedIndividualAllocSz).
46 static char kMallocActivity[] = "MainActivity";
47 
TEST(HeapprofdCtsTest,DebuggableAppRuntime)48 TEST(HeapprofdCtsTest, DebuggableAppRuntime) {
49   std::string app_name = "android.perfetto.cts.app.debuggable";
50   const auto& packets = ProfileRuntime(
51       app_name, kMallocActivity, kTestSamplingInterval, /*heap_names=*/{});
52   AssertExpectedMallocsPresent(kExpectedIndividualAllocSz, packets);
53   StopApp(app_name);
54 }
55 
TEST(HeapprofdCtsTest,DebuggableAppStartup)56 TEST(HeapprofdCtsTest, DebuggableAppStartup) {
57   std::string app_name = "android.perfetto.cts.app.debuggable";
58   const auto& packets = ProfileStartup(
59       app_name, kMallocActivity, kTestSamplingInterval, /*heap_names=*/{});
60   AssertExpectedMallocsPresent(kExpectedIndividualAllocSz, packets);
61   StopApp(app_name);
62 }
63 
TEST(HeapprofdCtsTest,ProfileableAppRuntime)64 TEST(HeapprofdCtsTest, ProfileableAppRuntime) {
65   std::string app_name = "android.perfetto.cts.app.profileable";
66   const auto& packets = ProfileRuntime(
67       app_name, kMallocActivity, kTestSamplingInterval, /*heap_names=*/{});
68   AssertExpectedMallocsPresent(kExpectedIndividualAllocSz, packets);
69   StopApp(app_name);
70 }
71 
TEST(HeapprofdCtsTest,ProfileableAppStartup)72 TEST(HeapprofdCtsTest, ProfileableAppStartup) {
73   std::string app_name = "android.perfetto.cts.app.profileable";
74   const auto& packets = ProfileStartup(
75       app_name, kMallocActivity, kTestSamplingInterval, /*heap_names=*/{});
76   AssertExpectedMallocsPresent(kExpectedIndividualAllocSz, packets);
77   StopApp(app_name);
78 }
79 
TEST(HeapprofdCtsTest,ReleaseAppRuntime)80 TEST(HeapprofdCtsTest, ReleaseAppRuntime) {
81   std::string app_name = "android.perfetto.cts.app.release";
82   const auto& packets = ProfileRuntime(
83       app_name, kMallocActivity, kTestSamplingInterval, /*heap_names=*/{});
84 
85   if (IsUserBuild())
86     AssertNoProfileContents(packets);
87   else
88     AssertExpectedMallocsPresent(kExpectedIndividualAllocSz, packets);
89   StopApp(app_name);
90 }
91 
TEST(HeapprofdCtsTest,ReleaseAppStartup)92 TEST(HeapprofdCtsTest, ReleaseAppStartup) {
93   std::string app_name = "android.perfetto.cts.app.release";
94   const auto& packets = ProfileStartup(
95       app_name, kMallocActivity, kTestSamplingInterval, /*heap_names=*/{});
96 
97   if (IsUserBuild())
98     AssertNoProfileContents(packets);
99   else
100     AssertExpectedMallocsPresent(kExpectedIndividualAllocSz, packets);
101   StopApp(app_name);
102 }
103 
TEST(HeapprofdCtsTest,NonProfileableAppRuntime)104 TEST(HeapprofdCtsTest, NonProfileableAppRuntime) {
105   std::string app_name = "android.perfetto.cts.app.nonprofileable";
106   const auto& packets = ProfileRuntime(
107       app_name, kMallocActivity, kTestSamplingInterval, /*heap_names=*/{});
108   if (IsUserBuild())
109     AssertNoProfileContents(packets);
110   else
111     AssertExpectedMallocsPresent(kExpectedIndividualAllocSz, packets);
112   StopApp(app_name);
113 }
114 
TEST(HeapprofdCtsTest,NonProfileableAppStartup)115 TEST(HeapprofdCtsTest, NonProfileableAppStartup) {
116   std::string app_name = "android.perfetto.cts.app.nonprofileable";
117   const auto& packets = ProfileStartup(
118       app_name, kMallocActivity, kTestSamplingInterval, /*heap_names=*/{});
119   if (IsUserBuild())
120     AssertNoProfileContents(packets);
121   else
122     AssertExpectedMallocsPresent(kExpectedIndividualAllocSz, packets);
123   StopApp(app_name);
124 }
125 
TEST(HeapprofdCtsTest,ProfilePlatformProcess)126 TEST(HeapprofdCtsTest, ProfilePlatformProcess) {
127   int target_pid = PidForProcessName("/system/bin/traced_probes");
128   ASSERT_GT(target_pid, 0) << "failed to find pid for target process";
129 
130   // Construct config.
131   TraceConfig trace_config;
132   trace_config.add_buffers()->set_size_kb(20 * 1024);
133   trace_config.set_duration_ms(3000);
134   trace_config.set_data_source_stop_timeout_ms(8000);
135   trace_config.set_unique_session_name(RandomSessionName().c_str());
136 
137   // process.stats to cause work in traced_probes
138   protos::gen::ProcessStatsConfig ps_config;
139   ps_config.set_proc_stats_poll_ms(100);
140   ps_config.set_record_thread_names(true);
141 
142   auto* ds_config = trace_config.add_data_sources()->mutable_config();
143   ds_config->set_name("linux.process_stats");
144   ds_config->set_process_stats_config_raw(ps_config.SerializeAsString());
145 
146   // profile native heap of traced_probes
147   protos::gen::HeapprofdConfig heapprofd_config;
148   heapprofd_config.set_sampling_interval_bytes(kTestSamplingInterval);
149   heapprofd_config.add_pid(static_cast<uint64_t>(target_pid));
150   heapprofd_config.set_block_client(true);
151 
152   ds_config = trace_config.add_data_sources()->mutable_config();
153   ds_config->set_name("android.heapprofd");
154   ds_config->set_heapprofd_config_raw(heapprofd_config.SerializeAsString());
155 
156   // Collect trace.
157   base::TestTaskRunner task_runner;
158   TestHelper helper(&task_runner);
159   helper.ConnectConsumer();
160   helper.WaitForConsumerConnect();
161 
162   helper.StartTracing(trace_config);
163   helper.WaitForTracingDisabled(15000 /*ms*/);
164   helper.ReadData();
165   helper.WaitForReadData();
166   auto packets = helper.trace();
167 
168   int target_pid_after = PidForProcessName("/system/bin/traced_probes");
169   ASSERT_EQ(target_pid, target_pid_after) << "traced_probes died during test";
170 
171   if (IsUserBuild())
172     AssertNoProfileContents(packets);
173   else
174     AssertHasSampledAllocs(packets);
175 }
176 
177 }  // namespace
178 }  // namespace perfetto
179