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 "src/profiling/memory/heapprofd_producer.h"
18
19 #include "perfetto/ext/base/file_utils.h"
20 #include "perfetto/ext/base/temp_file.h"
21 #include "perfetto/ext/tracing/core/basic_types.h"
22 #include "perfetto/ext/tracing/core/commit_data_request.h"
23 #include "perfetto/tracing/core/data_source_descriptor.h"
24 #include "src/base/test/test_task_runner.h"
25 #include "src/tracing/test/mock_producer_endpoint.h"
26 #include "test/gtest_and_gmock.h"
27
28 namespace perfetto {
29 namespace profiling {
30
31 using ::testing::Contains;
32 using ::testing::Eq;
33 using ::testing::Pair;
34 using ::testing::Property;
35
TEST(LogHistogramTest,Simple)36 TEST(LogHistogramTest, Simple) {
37 LogHistogram h;
38 h.Add(1);
39 h.Add(0);
40 EXPECT_THAT(h.GetData(), Contains(Pair(2, 1)));
41 EXPECT_THAT(h.GetData(), Contains(Pair(1, 1)));
42 }
43
TEST(LogHistogramTest,Overflow)44 TEST(LogHistogramTest, Overflow) {
45 LogHistogram h;
46 h.Add(std::numeric_limits<uint64_t>::max());
47 EXPECT_THAT(h.GetData(), Contains(Pair(LogHistogram::kMaxBucket, 1)));
48 }
49
TEST(HeapprofdProducerTest,ExposesDataSource)50 TEST(HeapprofdProducerTest, ExposesDataSource) {
51 base::TestTaskRunner task_runner;
52 HeapprofdProducer producer(HeapprofdMode::kCentral, &task_runner,
53 /* exit_when_done= */ false);
54
55 std::unique_ptr<MockProducerEndpoint> endpoint(new MockProducerEndpoint());
56 EXPECT_CALL(*endpoint,
57 RegisterDataSource(Property(&DataSourceDescriptor::name,
58 Eq("android.heapprofd"))))
59 .Times(1);
60 producer.SetProducerEndpoint(std::move(endpoint));
61 producer.OnConnect();
62 }
63
TEST(HeapprofdConfigToClientConfigurationTest,Smoke)64 TEST(HeapprofdConfigToClientConfigurationTest, Smoke) {
65 HeapprofdConfig cfg;
66 cfg.add_heaps("foo");
67 cfg.set_sampling_interval_bytes(4096);
68 ClientConfiguration cli_config;
69 ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
70 EXPECT_EQ(cli_config.num_heaps, 1u);
71 EXPECT_STREQ(cli_config.heaps[0].name, "foo");
72 EXPECT_EQ(cli_config.heaps[0].interval, 4096u);
73 }
74
TEST(HeapprofdConfigToClientConfigurationTest,DefaultHeap)75 TEST(HeapprofdConfigToClientConfigurationTest, DefaultHeap) {
76 HeapprofdConfig cfg;
77 cfg.set_sampling_interval_bytes(4096);
78 ClientConfiguration cli_config;
79 ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
80 EXPECT_EQ(cli_config.num_heaps, 1u);
81 EXPECT_STREQ(cli_config.heaps[0].name, "libc.malloc");
82 EXPECT_EQ(cli_config.heaps[0].interval, 4096u);
83 }
84
TEST(HeapprofdConfigToClientConfigurationTest,TwoHeaps)85 TEST(HeapprofdConfigToClientConfigurationTest, TwoHeaps) {
86 HeapprofdConfig cfg;
87 cfg.add_heaps("foo");
88 cfg.add_heaps("bar");
89 cfg.set_sampling_interval_bytes(4096);
90 ClientConfiguration cli_config;
91 ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
92 EXPECT_EQ(cli_config.num_heaps, 2u);
93 EXPECT_STREQ(cli_config.heaps[0].name, "foo");
94 EXPECT_STREQ(cli_config.heaps[1].name, "bar");
95 EXPECT_EQ(cli_config.heaps[0].interval, 4096u);
96 EXPECT_EQ(cli_config.heaps[1].interval, 4096u);
97 }
98
TEST(HeapprofdConfigToClientConfigurationTest,TwoHeapsIntervals)99 TEST(HeapprofdConfigToClientConfigurationTest, TwoHeapsIntervals) {
100 HeapprofdConfig cfg;
101 cfg.add_heaps("foo");
102 cfg.add_heap_sampling_intervals(4096u);
103 cfg.add_heaps("bar");
104 cfg.add_heap_sampling_intervals(1u);
105 ClientConfiguration cli_config;
106 ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
107 EXPECT_EQ(cli_config.num_heaps, 2u);
108 EXPECT_STREQ(cli_config.heaps[0].name, "foo");
109 EXPECT_STREQ(cli_config.heaps[1].name, "bar");
110 EXPECT_EQ(cli_config.heaps[0].interval, 4096u);
111 EXPECT_EQ(cli_config.heaps[1].interval, 1u);
112 }
113
TEST(HeapprofdConfigToClientConfigurationTest,OverflowHeapName)114 TEST(HeapprofdConfigToClientConfigurationTest, OverflowHeapName) {
115 std::string large_name(100, 'a');
116 HeapprofdConfig cfg;
117 cfg.add_heaps(large_name);
118 cfg.set_sampling_interval_bytes(1);
119 ClientConfiguration cli_config;
120 ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
121 EXPECT_EQ(cli_config.num_heaps, 0u);
122 }
123
TEST(HeapprofdConfigToClientConfigurationTest,OverflowHeapNameAndValid)124 TEST(HeapprofdConfigToClientConfigurationTest, OverflowHeapNameAndValid) {
125 std::string large_name(100, 'a');
126 HeapprofdConfig cfg;
127 cfg.add_heaps(large_name);
128 cfg.add_heaps("foo");
129 cfg.set_sampling_interval_bytes(1);
130 ClientConfiguration cli_config;
131 ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
132 EXPECT_EQ(cli_config.num_heaps, 1u);
133 EXPECT_STREQ(cli_config.heaps[0].name, "foo");
134 }
135
TEST(HeapprofdConfigToClientConfigurationTest,ZeroSampling)136 TEST(HeapprofdConfigToClientConfigurationTest, ZeroSampling) {
137 HeapprofdConfig cfg;
138 cfg.add_heaps("foo");
139 cfg.set_sampling_interval_bytes(0);
140 ClientConfiguration cli_config;
141 EXPECT_FALSE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
142 }
143
TEST(HeapprofdConfigToClientConfigurationTest,ZeroSamplingMultiple)144 TEST(HeapprofdConfigToClientConfigurationTest, ZeroSamplingMultiple) {
145 HeapprofdConfig cfg;
146 cfg.add_heaps("foo");
147 cfg.add_heap_sampling_intervals(4096u);
148 cfg.add_heaps("bar");
149 cfg.add_heap_sampling_intervals(0);
150 ClientConfiguration cli_config;
151 EXPECT_FALSE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
152 }
153
TEST(HeapprofdConfigToClientConfigurationTest,AdaptiveSampling)154 TEST(HeapprofdConfigToClientConfigurationTest, AdaptiveSampling) {
155 HeapprofdConfig cfg;
156 cfg.add_heaps("foo");
157 cfg.set_sampling_interval_bytes(4096);
158 cfg.set_adaptive_sampling_shmem_threshold(1024u);
159 ClientConfiguration cli_config;
160 ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
161 EXPECT_EQ(cli_config.num_heaps, 1u);
162 EXPECT_STREQ(cli_config.heaps[0].name, "foo");
163 EXPECT_EQ(cli_config.heaps[0].interval, 4096u);
164 EXPECT_EQ(cli_config.adaptive_sampling_shmem_threshold, 1024u);
165 EXPECT_EQ(cli_config.adaptive_sampling_max_sampling_interval_bytes, 0u);
166 }
167
TEST(HeapprofdConfigToClientConfigurationTest,AdaptiveSamplingWithMax)168 TEST(HeapprofdConfigToClientConfigurationTest, AdaptiveSamplingWithMax) {
169 HeapprofdConfig cfg;
170 cfg.add_heaps("foo");
171 cfg.set_sampling_interval_bytes(4096);
172 cfg.set_adaptive_sampling_shmem_threshold(1024u);
173 cfg.set_adaptive_sampling_max_sampling_interval_bytes(4 * 4096u);
174 ClientConfiguration cli_config;
175 ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
176 EXPECT_EQ(cli_config.num_heaps, 1u);
177 EXPECT_STREQ(cli_config.heaps[0].name, "foo");
178 EXPECT_EQ(cli_config.heaps[0].interval, 4096u);
179 EXPECT_EQ(cli_config.adaptive_sampling_shmem_threshold, 1024u);
180 EXPECT_EQ(cli_config.adaptive_sampling_max_sampling_interval_bytes,
181 4 * 4096u);
182 }
183
TEST(HeapprofdConfigToClientConfigurationTest,AllHeaps)184 TEST(HeapprofdConfigToClientConfigurationTest, AllHeaps) {
185 HeapprofdConfig cfg;
186 cfg.set_all_heaps(true);
187 cfg.set_sampling_interval_bytes(4096);
188 ClientConfiguration cli_config;
189 ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
190 EXPECT_EQ(cli_config.num_heaps, 0u);
191 EXPECT_EQ(cli_config.default_interval, 4096u);
192 }
193
TEST(HeapprofdConfigToClientConfigurationTest,AllHeapsAndExplicit)194 TEST(HeapprofdConfigToClientConfigurationTest, AllHeapsAndExplicit) {
195 HeapprofdConfig cfg;
196 cfg.set_all_heaps(true);
197 cfg.set_sampling_interval_bytes(4096);
198 cfg.add_heaps("foo");
199 cfg.add_heap_sampling_intervals(1024u);
200 ClientConfiguration cli_config;
201 ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
202 EXPECT_EQ(cli_config.num_heaps, 1u);
203 EXPECT_STREQ(cli_config.heaps[0].name, "foo");
204 EXPECT_EQ(cli_config.heaps[0].interval, 1024u);
205 EXPECT_EQ(cli_config.default_interval, 4096u);
206 }
207
TEST(HeapprofdConfigToClientConfigurationTest,AllHeapsAndDisabled)208 TEST(HeapprofdConfigToClientConfigurationTest, AllHeapsAndDisabled) {
209 HeapprofdConfig cfg;
210 cfg.set_all_heaps(true);
211 cfg.set_sampling_interval_bytes(4096);
212 cfg.add_exclude_heaps("foo");
213 ClientConfiguration cli_config;
214 ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
215 EXPECT_EQ(cli_config.num_heaps, 1u);
216 EXPECT_STREQ(cli_config.heaps[0].name, "foo");
217 EXPECT_EQ(cli_config.heaps[0].interval, 0u);
218 EXPECT_EQ(cli_config.default_interval, 4096u);
219 }
220
221 } // namespace profiling
222 } // namespace perfetto
223