• 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 "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 "test/gtest_and_gmock.h"
26 
27 namespace perfetto {
28 namespace profiling {
29 
30 using ::testing::Contains;
31 using ::testing::Eq;
32 using ::testing::Pair;
33 using ::testing::Property;
34 
35 class MockProducerEndpoint : public TracingService::ProducerEndpoint {
36  public:
37   MOCK_METHOD1(UnregisterDataSource, void(const std::string&));
38   MOCK_METHOD1(NotifyFlushComplete, void(FlushRequestID));
39   MOCK_METHOD1(NotifyDataSourceStarted, void(DataSourceInstanceID));
40   MOCK_METHOD1(NotifyDataSourceStopped, void(DataSourceInstanceID));
41 
42   MOCK_CONST_METHOD0(shared_memory, SharedMemory*());
43   MOCK_CONST_METHOD0(shared_buffer_page_size_kb, size_t());
44   MOCK_METHOD2(CreateTraceWriter,
45                std::unique_ptr<TraceWriter>(BufferID, BufferExhaustedPolicy));
46   MOCK_METHOD0(MaybeSharedMemoryArbiter, SharedMemoryArbiter*());
47   MOCK_CONST_METHOD0(IsShmemProvidedByProducer, bool());
48   MOCK_METHOD1(ActivateTriggers, void(const std::vector<std::string>&));
49 
50   MOCK_METHOD1(RegisterDataSource, void(const DataSourceDescriptor&));
51   MOCK_METHOD1(UpdateDataSource, void(const DataSourceDescriptor&));
52   MOCK_METHOD2(CommitData, void(const CommitDataRequest&, CommitDataCallback));
53   MOCK_METHOD2(RegisterTraceWriter, void(uint32_t, uint32_t));
54   MOCK_METHOD1(UnregisterTraceWriter, void(uint32_t));
55   MOCK_METHOD1(Sync, void(std::function<void()>));
56 };
57 
TEST(LogHistogramTest,Simple)58 TEST(LogHistogramTest, Simple) {
59   LogHistogram h;
60   h.Add(1);
61   h.Add(0);
62   EXPECT_THAT(h.GetData(), Contains(Pair(2, 1)));
63   EXPECT_THAT(h.GetData(), Contains(Pair(1, 1)));
64 }
65 
TEST(LogHistogramTest,Overflow)66 TEST(LogHistogramTest, Overflow) {
67   LogHistogram h;
68   h.Add(std::numeric_limits<uint64_t>::max());
69   EXPECT_THAT(h.GetData(), Contains(Pair(LogHistogram::kMaxBucket, 1)));
70 }
71 
TEST(HeapprofdProducerTest,ExposesDataSource)72 TEST(HeapprofdProducerTest, ExposesDataSource) {
73   base::TestTaskRunner task_runner;
74   HeapprofdProducer producer(HeapprofdMode::kCentral, &task_runner,
75                              /* exit_when_done= */ false);
76 
77   std::unique_ptr<MockProducerEndpoint> endpoint(new MockProducerEndpoint());
78   EXPECT_CALL(*endpoint,
79               RegisterDataSource(Property(&DataSourceDescriptor::name,
80                                           Eq("android.heapprofd"))))
81       .Times(1);
82   producer.SetProducerEndpoint(std::move(endpoint));
83   producer.OnConnect();
84 }
85 
TEST(HeapprofdConfigToClientConfigurationTest,Smoke)86 TEST(HeapprofdConfigToClientConfigurationTest, Smoke) {
87   HeapprofdConfig cfg;
88   cfg.add_heaps("foo");
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, 1u);
93   EXPECT_STREQ(cli_config.heaps[0].name, "foo");
94   EXPECT_EQ(cli_config.heaps[0].interval, 4096u);
95 }
96 
TEST(HeapprofdConfigToClientConfigurationTest,DefaultHeap)97 TEST(HeapprofdConfigToClientConfigurationTest, DefaultHeap) {
98   HeapprofdConfig cfg;
99   cfg.set_sampling_interval_bytes(4096);
100   ClientConfiguration cli_config;
101   ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
102   EXPECT_EQ(cli_config.num_heaps, 1u);
103   EXPECT_STREQ(cli_config.heaps[0].name, "libc.malloc");
104   EXPECT_EQ(cli_config.heaps[0].interval, 4096u);
105 }
106 
TEST(HeapprofdConfigToClientConfigurationTest,TwoHeaps)107 TEST(HeapprofdConfigToClientConfigurationTest, TwoHeaps) {
108   HeapprofdConfig cfg;
109   cfg.add_heaps("foo");
110   cfg.add_heaps("bar");
111   cfg.set_sampling_interval_bytes(4096);
112   ClientConfiguration cli_config;
113   ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
114   EXPECT_EQ(cli_config.num_heaps, 2u);
115   EXPECT_STREQ(cli_config.heaps[0].name, "foo");
116   EXPECT_STREQ(cli_config.heaps[1].name, "bar");
117   EXPECT_EQ(cli_config.heaps[0].interval, 4096u);
118   EXPECT_EQ(cli_config.heaps[1].interval, 4096u);
119 }
120 
TEST(HeapprofdConfigToClientConfigurationTest,TwoHeapsIntervals)121 TEST(HeapprofdConfigToClientConfigurationTest, TwoHeapsIntervals) {
122   HeapprofdConfig cfg;
123   cfg.add_heaps("foo");
124   cfg.add_heap_sampling_intervals(4096u);
125   cfg.add_heaps("bar");
126   cfg.add_heap_sampling_intervals(1u);
127   ClientConfiguration cli_config;
128   ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
129   EXPECT_EQ(cli_config.num_heaps, 2u);
130   EXPECT_STREQ(cli_config.heaps[0].name, "foo");
131   EXPECT_STREQ(cli_config.heaps[1].name, "bar");
132   EXPECT_EQ(cli_config.heaps[0].interval, 4096u);
133   EXPECT_EQ(cli_config.heaps[1].interval, 1u);
134 }
135 
TEST(HeapprofdConfigToClientConfigurationTest,OverflowHeapName)136 TEST(HeapprofdConfigToClientConfigurationTest, OverflowHeapName) {
137   std::string large_name(100, 'a');
138   HeapprofdConfig cfg;
139   cfg.add_heaps(large_name);
140   cfg.set_sampling_interval_bytes(1);
141   ClientConfiguration cli_config;
142   ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
143   EXPECT_EQ(cli_config.num_heaps, 0u);
144 }
145 
TEST(HeapprofdConfigToClientConfigurationTest,OverflowHeapNameAndValid)146 TEST(HeapprofdConfigToClientConfigurationTest, OverflowHeapNameAndValid) {
147   std::string large_name(100, 'a');
148   HeapprofdConfig cfg;
149   cfg.add_heaps(large_name);
150   cfg.add_heaps("foo");
151   cfg.set_sampling_interval_bytes(1);
152   ClientConfiguration cli_config;
153   ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
154   EXPECT_EQ(cli_config.num_heaps, 1u);
155   EXPECT_STREQ(cli_config.heaps[0].name, "foo");
156 }
157 
TEST(HeapprofdConfigToClientConfigurationTest,ZeroSampling)158 TEST(HeapprofdConfigToClientConfigurationTest, ZeroSampling) {
159   HeapprofdConfig cfg;
160   cfg.add_heaps("foo");
161   cfg.set_sampling_interval_bytes(0);
162   ClientConfiguration cli_config;
163   EXPECT_FALSE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
164 }
165 
TEST(HeapprofdConfigToClientConfigurationTest,ZeroSamplingMultiple)166 TEST(HeapprofdConfigToClientConfigurationTest, ZeroSamplingMultiple) {
167   HeapprofdConfig cfg;
168   cfg.add_heaps("foo");
169   cfg.add_heap_sampling_intervals(4096u);
170   cfg.add_heaps("bar");
171   cfg.add_heap_sampling_intervals(0);
172   ClientConfiguration cli_config;
173   EXPECT_FALSE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
174 }
175 
TEST(HeapprofdConfigToClientConfigurationTest,AdaptiveSampling)176 TEST(HeapprofdConfigToClientConfigurationTest, AdaptiveSampling) {
177   HeapprofdConfig cfg;
178   cfg.add_heaps("foo");
179   cfg.set_sampling_interval_bytes(4096);
180   cfg.set_adaptive_sampling_shmem_threshold(1024u);
181   ClientConfiguration cli_config;
182   ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
183   EXPECT_EQ(cli_config.num_heaps, 1u);
184   EXPECT_STREQ(cli_config.heaps[0].name, "foo");
185   EXPECT_EQ(cli_config.heaps[0].interval, 4096u);
186   EXPECT_EQ(cli_config.adaptive_sampling_shmem_threshold, 1024u);
187   EXPECT_EQ(cli_config.adaptive_sampling_max_sampling_interval_bytes, 0u);
188 }
189 
TEST(HeapprofdConfigToClientConfigurationTest,AdaptiveSamplingWithMax)190 TEST(HeapprofdConfigToClientConfigurationTest, AdaptiveSamplingWithMax) {
191   HeapprofdConfig cfg;
192   cfg.add_heaps("foo");
193   cfg.set_sampling_interval_bytes(4096);
194   cfg.set_adaptive_sampling_shmem_threshold(1024u);
195   cfg.set_adaptive_sampling_max_sampling_interval_bytes(4 * 4096u);
196   ClientConfiguration cli_config;
197   ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
198   EXPECT_EQ(cli_config.num_heaps, 1u);
199   EXPECT_STREQ(cli_config.heaps[0].name, "foo");
200   EXPECT_EQ(cli_config.heaps[0].interval, 4096u);
201   EXPECT_EQ(cli_config.adaptive_sampling_shmem_threshold, 1024u);
202   EXPECT_EQ(cli_config.adaptive_sampling_max_sampling_interval_bytes,
203             4 * 4096u);
204 }
205 
TEST(HeapprofdConfigToClientConfigurationTest,AllHeaps)206 TEST(HeapprofdConfigToClientConfigurationTest, AllHeaps) {
207   HeapprofdConfig cfg;
208   cfg.set_all_heaps(true);
209   cfg.set_sampling_interval_bytes(4096);
210   ClientConfiguration cli_config;
211   ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
212   EXPECT_EQ(cli_config.num_heaps, 0u);
213   EXPECT_EQ(cli_config.default_interval, 4096u);
214 }
215 
TEST(HeapprofdConfigToClientConfigurationTest,AllHeapsAndExplicit)216 TEST(HeapprofdConfigToClientConfigurationTest, AllHeapsAndExplicit) {
217   HeapprofdConfig cfg;
218   cfg.set_all_heaps(true);
219   cfg.set_sampling_interval_bytes(4096);
220   cfg.add_heaps("foo");
221   cfg.add_heap_sampling_intervals(1024u);
222   ClientConfiguration cli_config;
223   ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
224   EXPECT_EQ(cli_config.num_heaps, 1u);
225   EXPECT_STREQ(cli_config.heaps[0].name, "foo");
226   EXPECT_EQ(cli_config.heaps[0].interval, 1024u);
227   EXPECT_EQ(cli_config.default_interval, 4096u);
228 }
229 
TEST(HeapprofdConfigToClientConfigurationTest,AllHeapsAndDisabled)230 TEST(HeapprofdConfigToClientConfigurationTest, AllHeapsAndDisabled) {
231   HeapprofdConfig cfg;
232   cfg.set_all_heaps(true);
233   cfg.set_sampling_interval_bytes(4096);
234   cfg.add_exclude_heaps("foo");
235   ClientConfiguration cli_config;
236   ASSERT_TRUE(HeapprofdConfigToClientConfiguration(cfg, &cli_config));
237   EXPECT_EQ(cli_config.num_heaps, 1u);
238   EXPECT_STREQ(cli_config.heaps[0].name, "foo");
239   EXPECT_EQ(cli_config.heaps[0].interval, 0u);
240   EXPECT_EQ(cli_config.default_interval, 4096u);
241 }
242 
243 }  // namespace profiling
244 }  // namespace perfetto
245