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_METHOD2(SetAndroidProperty,
43                bool(const std::string&, const std::string&));
44 };
45 
TEST(BuiltinProducerTest,LazyHeapprofdSimple)46 TEST(BuiltinProducerTest, LazyHeapprofdSimple) {
47   DataSourceConfig cfg;
48   cfg.set_name(kHeapprofdDataSourceName);
49   base::TestTaskRunner task_runner;
50   auto done = task_runner.CreateCheckpoint("done");
51   StrictMock<MockBuiltinProducer> p(&task_runner);
52   testing::InSequence s;
53   EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, "1"))
54       .WillOnce(Return(true));
55   EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, ""))
56       .WillOnce(InvokeWithoutArgs([&done]() {
57         done();
58         return true;
59       }));
60   p.SetupDataSource(1, cfg);
61   p.StopDataSource(1);
62   task_runner.RunUntilCheckpoint("done");
63 }
64 
TEST(BuiltinProducerTest,LazyTracedPerfSimple)65 TEST(BuiltinProducerTest, LazyTracedPerfSimple) {
66   DataSourceConfig cfg;
67   cfg.set_name(kTracedPerfDataSourceName);
68   base::TestTaskRunner task_runner;
69   auto done = task_runner.CreateCheckpoint("done");
70   StrictMock<MockBuiltinProducer> p(&task_runner);
71   testing::InSequence s;
72   EXPECT_CALL(p, SetAndroidProperty(kLazyTracedPerfPropertyName, "1"))
73       .WillOnce(Return(true));
74   EXPECT_CALL(p, SetAndroidProperty(kLazyTracedPerfPropertyName, ""))
75       .WillOnce(InvokeWithoutArgs([&done]() {
76         done();
77         return true;
78       }));
79   p.SetupDataSource(1, cfg);
80   p.StopDataSource(1);
81   task_runner.RunUntilCheckpoint("done");
82 }
83 
TEST(BuiltinProducerTest,LazyHeapprofdRefCount)84 TEST(BuiltinProducerTest, LazyHeapprofdRefCount) {
85   DataSourceConfig cfg;
86   cfg.set_name(kHeapprofdDataSourceName);
87   base::TestTaskRunner task_runner;
88   auto done = task_runner.CreateCheckpoint("done");
89   StrictMock<MockBuiltinProducer> p(&task_runner);
90   testing::InSequence s;
91   EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, "1"))
92       .WillRepeatedly(Return(true));
93   p.SetupDataSource(1, cfg);
94   p.SetupDataSource(2, cfg);
95   p.StopDataSource(2);
96   task_runner.RunUntilIdle();
97   EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, ""))
98       .WillOnce(InvokeWithoutArgs([&done]() {
99         done();
100         return true;
101       }));
102   p.StopDataSource(1);
103   task_runner.RunUntilCheckpoint("done");
104 }
105 
TEST(BuiltinProducerTest,LazyHeapprofdNoFlap)106 TEST(BuiltinProducerTest, LazyHeapprofdNoFlap) {
107   DataSourceConfig cfg;
108   cfg.set_name(kHeapprofdDataSourceName);
109   base::TestTaskRunner task_runner;
110   auto done = task_runner.CreateCheckpoint("done");
111   StrictMock<MockBuiltinProducer> p(&task_runner);
112   testing::InSequence s;
113   EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, "1"))
114       .WillRepeatedly(Return(true));
115   p.SetupDataSource(1, cfg);
116   p.StopDataSource(1);
117   p.SetupDataSource(2, cfg);
118   task_runner.RunUntilIdle();
119   p.StopDataSource(2);
120   EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, ""))
121       .WillOnce(InvokeWithoutArgs([&done]() {
122         done();
123         return true;
124       }));
125   task_runner.RunUntilCheckpoint("done");
126 }
127 
TEST(BuiltinProducerTest,LazyRefCountsIndependent)128 TEST(BuiltinProducerTest, LazyRefCountsIndependent) {
129   DataSourceConfig cfg_perf;
130   cfg_perf.set_name(kTracedPerfDataSourceName);
131   DataSourceConfig cfg_heap;
132   cfg_heap.set_name(kHeapprofdDataSourceName);
133 
134   base::TestTaskRunner task_runner;
135   StrictMock<MockBuiltinProducer> p(&task_runner);
136   testing::InSequence s;
137 
138   // start one instance of both types of sources
139   EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, "1"))
140       .WillOnce(Return(true));
141   EXPECT_CALL(p, SetAndroidProperty(kLazyTracedPerfPropertyName, "1"))
142       .WillOnce(Return(true));
143   p.SetupDataSource(1, cfg_heap);
144   p.SetupDataSource(2, cfg_perf);
145   task_runner.RunUntilIdle();
146   Mock::VerifyAndClearExpectations(&p);
147 
148   // stop heapprofd source
149   EXPECT_CALL(p, SetAndroidProperty(kLazyHeapprofdPropertyName, ""))
150       .WillOnce(Return(true));
151   p.StopDataSource(1);
152   task_runner.RunUntilIdle();
153   Mock::VerifyAndClearExpectations(&p);
154 
155   // stop traced_perf source
156   EXPECT_CALL(p, SetAndroidProperty(kLazyTracedPerfPropertyName, ""))
157       .WillOnce(Return(true));
158   p.StopDataSource(2);
159   task_runner.RunUntilIdle();
160   Mock::VerifyAndClearExpectations(&p);
161 }
162 
163 }  // namespace
164 }  // namespace perfetto
165