1 /*
2 * Copyright (C) 2018 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/traced/service/builtin_producer.h"
18
19 #include "perfetto/tracing/core/data_source_config.h"
20 #include "src/base/test/test_task_runner.h"
21 #include "test/gtest_and_gmock.h"
22
23 namespace perfetto {
24 namespace {
25
26 constexpr char kHeapprofdDataSourceName[] = "android.heapprofd";
27 constexpr char kTracedPerfDataSourceName[] = "linux.perf";
28 constexpr char kLazyHeapprofdPropertyName[] = "traced.lazy.heapprofd";
29 constexpr char kLazyTracedPerfPropertyName[] = "traced.lazy.traced_perf";
30
31 using ::testing::_;
32 using ::testing::InvokeWithoutArgs;
33 using ::testing::Mock;
34 using ::testing::Return;
35 using ::testing::StrictMock;
36
37 class MockBuiltinProducer : public BuiltinProducer {
38 public:
MockBuiltinProducer(base::TaskRunner * task_runner)39 MockBuiltinProducer(base::TaskRunner* task_runner)
40 : BuiltinProducer(task_runner, /*lazy_stop_delay_ms=*/0) {}
41
42 MOCK_METHOD(bool,
43 SetAndroidProperty,
44 (const std::string&, const std::string&),
45 (override));
46 };
47
TEST(BuiltinProducerTest,LazyHeapprofdSimple)48 TEST(BuiltinProducerTest, LazyHeapprofdSimple) {
49 DataSourceConfig cfg;
50 cfg.set_name(kHeapprofdDataSourceName);
51 base::TestTaskRunner task_runner;
52 auto done = task_runner.CreateCheckpoint("done");
53 StrictMock<MockBuiltinProducer> p(&task_runner);
54 testing::InSequence s;
55 EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, "1"))
56 .WillOnce(Return(true));
57 EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, ""))
58 .WillOnce(InvokeWithoutArgs([&done]() {
59 done();
60 return true;
61 }));
62 p.SetupDataSource(1, cfg);
63 p.StopDataSource(1);
64 task_runner.RunUntilCheckpoint("done");
65 }
66
TEST(BuiltinProducerTest,LazyTracedPerfSimple)67 TEST(BuiltinProducerTest, LazyTracedPerfSimple) {
68 DataSourceConfig cfg;
69 cfg.set_name(kTracedPerfDataSourceName);
70 base::TestTaskRunner task_runner;
71 auto done = task_runner.CreateCheckpoint("done");
72 StrictMock<MockBuiltinProducer> p(&task_runner);
73 testing::InSequence s;
74 EXPECT_CALL(p, SetAndroidProperty(kLazyTracedPerfPropertyName, "1"))
75 .WillOnce(Return(true));
76 EXPECT_CALL(p, SetAndroidProperty(kLazyTracedPerfPropertyName, ""))
77 .WillOnce(InvokeWithoutArgs([&done]() {
78 done();
79 return true;
80 }));
81 p.SetupDataSource(1, cfg);
82 p.StopDataSource(1);
83 task_runner.RunUntilCheckpoint("done");
84 }
85
TEST(BuiltinProducerTest,LazyHeapprofdRefCount)86 TEST(BuiltinProducerTest, LazyHeapprofdRefCount) {
87 DataSourceConfig cfg;
88 cfg.set_name(kHeapprofdDataSourceName);
89 base::TestTaskRunner task_runner;
90 auto done = task_runner.CreateCheckpoint("done");
91 StrictMock<MockBuiltinProducer> p(&task_runner);
92 testing::InSequence s;
93 EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, "1"))
94 .WillRepeatedly(Return(true));
95 p.SetupDataSource(1, cfg);
96 p.SetupDataSource(2, cfg);
97 p.StopDataSource(2);
98 task_runner.RunUntilIdle();
99 EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, ""))
100 .WillOnce(InvokeWithoutArgs([&done]() {
101 done();
102 return true;
103 }));
104 p.StopDataSource(1);
105 task_runner.RunUntilCheckpoint("done");
106 }
107
TEST(BuiltinProducerTest,LazyHeapprofdNoFlap)108 TEST(BuiltinProducerTest, LazyHeapprofdNoFlap) {
109 DataSourceConfig cfg;
110 cfg.set_name(kHeapprofdDataSourceName);
111 base::TestTaskRunner task_runner;
112 auto done = task_runner.CreateCheckpoint("done");
113 StrictMock<MockBuiltinProducer> p(&task_runner);
114 testing::InSequence s;
115 EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, "1"))
116 .WillRepeatedly(Return(true));
117 p.SetupDataSource(1, cfg);
118 p.StopDataSource(1);
119 p.SetupDataSource(2, cfg);
120 task_runner.RunUntilIdle();
121 p.StopDataSource(2);
122 EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, ""))
123 .WillOnce(InvokeWithoutArgs([&done]() {
124 done();
125 return true;
126 }));
127 task_runner.RunUntilCheckpoint("done");
128 }
129
TEST(BuiltinProducerTest,LazyRefCountsIndependent)130 TEST(BuiltinProducerTest, LazyRefCountsIndependent) {
131 DataSourceConfig cfg_perf;
132 cfg_perf.set_name(kTracedPerfDataSourceName);
133 DataSourceConfig cfg_heap;
134 cfg_heap.set_name(kHeapprofdDataSourceName);
135
136 base::TestTaskRunner task_runner;
137 StrictMock<MockBuiltinProducer> p(&task_runner);
138 testing::InSequence s;
139
140 // start one instance of both types of sources
141 EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, "1"))
142 .WillOnce(Return(true));
143 EXPECT_CALL(p, SetAndroidProperty(kLazyTracedPerfPropertyName, "1"))
144 .WillOnce(Return(true));
145 p.SetupDataSource(1, cfg_heap);
146 p.SetupDataSource(2, cfg_perf);
147 task_runner.RunUntilIdle();
148 Mock::VerifyAndClearExpectations(&p);
149
150 // stop heapprofd source
151 EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, ""))
152 .WillOnce(Return(true));
153 p.StopDataSource(1);
154 task_runner.RunUntilIdle();
155 Mock::VerifyAndClearExpectations(&p);
156
157 // stop traced_perf source
158 EXPECT_CALL(p, SetAndroidProperty(kLazyTracedPerfPropertyName, ""))
159 .WillOnce(Return(true));
160 p.StopDataSource(2);
161 task_runner.RunUntilIdle();
162 Mock::VerifyAndClearExpectations(&p);
163 }
164
165 } // namespace
166 } // namespace perfetto
167