blob: 3ab0b11add5ebb67b760f7e71d759e84ecb9fa15 [file] [log] [blame]
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00001/*
2 * Copyright (C) 2017 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/tracing/core/service_impl.h"
18
19#include <string.h>
20
21#include "gmock/gmock.h"
22#include "gtest/gtest.h"
Sami Kyostila06487a22018-02-27 13:48:38 +000023#include "perfetto/tracing/core/consumer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000024#include "perfetto/tracing/core/data_source_config.h"
25#include "perfetto/tracing/core/data_source_descriptor.h"
26#include "perfetto/tracing/core/producer.h"
27#include "perfetto/tracing/core/shared_memory.h"
Sami Kyostila06487a22018-02-27 13:48:38 +000028#include "perfetto/tracing/core/trace_packet.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000029#include "src/base/test/test_task_runner.h"
30#include "src/tracing/test/test_shared_memory.h"
31
32namespace perfetto {
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000033using ::testing::_;
34using ::testing::InSequence;
35using ::testing::Mock;
36
Sami Kyostila32e0b542018-02-14 08:55:43 +000037namespace {
38
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000039class MockProducer : public Producer {
40 public:
41 ~MockProducer() override {}
42
43 // Producer implementation.
44 MOCK_METHOD0(OnConnect, void());
45 MOCK_METHOD0(OnDisconnect, void());
46 MOCK_METHOD2(CreateDataSourceInstance,
47 void(DataSourceInstanceID, const DataSourceConfig&));
48 MOCK_METHOD1(TearDownDataSourceInstance, void(DataSourceInstanceID));
49};
50
Sami Kyostila06487a22018-02-27 13:48:38 +000051class MockConsumer : public Consumer {
52 public:
53 ~MockConsumer() override {}
54
55 // Consumer implementation.
56 MOCK_METHOD0(OnConnect, void());
57 MOCK_METHOD0(OnDisconnect, void());
58
59 void OnTraceData(std::vector<TracePacket> packets, bool has_more) override {}
60};
61
Sami Kyostila32e0b542018-02-14 08:55:43 +000062} // namespace
63
Sami Kyostila06487a22018-02-27 13:48:38 +000064class ServiceImplTest : public testing::Test {
65 public:
66 ServiceImplTest() {
67 auto shm_factory =
68 std::unique_ptr<SharedMemory::Factory>(new TestSharedMemory::Factory());
69 svc.reset(static_cast<ServiceImpl*>(
70 Service::CreateInstance(std::move(shm_factory), &task_runner)
71 .release()));
72 }
73
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000074 base::TestTaskRunner task_runner;
Sami Kyostila06487a22018-02-27 13:48:38 +000075 std::unique_ptr<ServiceImpl> svc;
76};
77
78TEST_F(ServiceImplTest, RegisterAndUnregister) {
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000079 MockProducer mock_producer_1;
80 MockProducer mock_producer_2;
81 std::unique_ptr<Service::ProducerEndpoint> producer_endpoint_1 =
Sami Kyostila32e0b542018-02-14 08:55:43 +000082 svc->ConnectProducer(&mock_producer_1, 123u /* uid */);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000083 std::unique_ptr<Service::ProducerEndpoint> producer_endpoint_2 =
Sami Kyostila32e0b542018-02-14 08:55:43 +000084 svc->ConnectProducer(&mock_producer_2, 456u /* uid */);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000085
86 ASSERT_TRUE(producer_endpoint_1);
87 ASSERT_TRUE(producer_endpoint_2);
88
89 InSequence seq;
90 EXPECT_CALL(mock_producer_1, OnConnect());
91 EXPECT_CALL(mock_producer_2, OnConnect());
92 task_runner.RunUntilIdle();
93
94 ASSERT_EQ(2u, svc->num_producers());
95 ASSERT_EQ(producer_endpoint_1.get(), svc->GetProducer(1));
96 ASSERT_EQ(producer_endpoint_2.get(), svc->GetProducer(2));
Sami Kyostila32e0b542018-02-14 08:55:43 +000097 ASSERT_EQ(123u, svc->GetProducer(1)->uid_);
98 ASSERT_EQ(456u, svc->GetProducer(2)->uid_);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000099
Primiano Tucci114b6492017-12-11 23:09:45 +0000100 DataSourceDescriptor ds_desc1;
101 ds_desc1.set_name("foo");
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000102 producer_endpoint_1->RegisterDataSource(
Sami Kyostila06487a22018-02-27 13:48:38 +0000103 ds_desc1, [this, &producer_endpoint_1](DataSourceID id) {
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000104 EXPECT_EQ(1u, id);
105 task_runner.PostTask(
106 std::bind(&Service::ProducerEndpoint::UnregisterDataSource,
107 producer_endpoint_1.get(), id));
108 });
109
Primiano Tucci114b6492017-12-11 23:09:45 +0000110 DataSourceDescriptor ds_desc2;
111 ds_desc2.set_name("bar");
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000112 producer_endpoint_2->RegisterDataSource(
Sami Kyostila06487a22018-02-27 13:48:38 +0000113 ds_desc2, [this, &producer_endpoint_2](DataSourceID id) {
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000114 EXPECT_EQ(1u, id);
115 task_runner.PostTask(
116 std::bind(&Service::ProducerEndpoint::UnregisterDataSource,
117 producer_endpoint_2.get(), id));
118 });
119
120 task_runner.RunUntilIdle();
121
122 EXPECT_CALL(mock_producer_1, OnDisconnect());
123 producer_endpoint_1.reset();
124 task_runner.RunUntilIdle();
125 Mock::VerifyAndClearExpectations(&mock_producer_1);
126
127 ASSERT_EQ(1u, svc->num_producers());
128 ASSERT_EQ(nullptr, svc->GetProducer(1));
129
130 EXPECT_CALL(mock_producer_2, OnDisconnect());
131 producer_endpoint_2.reset();
132 task_runner.RunUntilIdle();
133 Mock::VerifyAndClearExpectations(&mock_producer_2);
134
135 ASSERT_EQ(0u, svc->num_producers());
136}
137
Sami Kyostila06487a22018-02-27 13:48:38 +0000138TEST_F(ServiceImplTest, EnableAndDisableTracing) {
139 MockProducer mock_producer;
140 std::unique_ptr<Service::ProducerEndpoint> producer_endpoint =
141 svc->ConnectProducer(&mock_producer, 123u /* uid */);
142 MockConsumer mock_consumer;
143 std::unique_ptr<Service::ConsumerEndpoint> consumer_endpoint =
144 svc->ConnectConsumer(&mock_consumer);
145
146 InSequence seq;
147 EXPECT_CALL(mock_producer, OnConnect());
148 EXPECT_CALL(mock_consumer, OnConnect());
149 task_runner.RunUntilIdle();
150
151 DataSourceDescriptor ds_desc;
152 ds_desc.set_name("foo");
153 producer_endpoint->RegisterDataSource(ds_desc, [](DataSourceID) {});
154
155 task_runner.RunUntilIdle();
156
157 EXPECT_CALL(mock_producer, CreateDataSourceInstance(_, _));
158 EXPECT_CALL(mock_producer, TearDownDataSourceInstance(_));
159 TraceConfig trace_config;
160 trace_config.add_buffers()->set_size_kb(4096 * 10);
161 auto* ds_config = trace_config.add_data_sources()->mutable_config();
162 ds_config->set_name("foo");
163 ds_config->set_target_buffer(0);
164 consumer_endpoint->EnableTracing(trace_config);
165 task_runner.RunUntilIdle();
166
167 EXPECT_CALL(mock_producer, OnDisconnect());
168 EXPECT_CALL(mock_consumer, OnDisconnect());
169 consumer_endpoint->DisableTracing();
170 producer_endpoint.reset();
171 consumer_endpoint.reset();
172 task_runner.RunUntilIdle();
173 Mock::VerifyAndClearExpectations(&mock_producer);
174 Mock::VerifyAndClearExpectations(&mock_consumer);
175}
176
177TEST_F(ServiceImplTest, DisconnectConsumerWhileTracing) {
178 MockProducer mock_producer;
179 std::unique_ptr<Service::ProducerEndpoint> producer_endpoint =
180 svc->ConnectProducer(&mock_producer, 123u /* uid */);
181 MockConsumer mock_consumer;
182 std::unique_ptr<Service::ConsumerEndpoint> consumer_endpoint =
183 svc->ConnectConsumer(&mock_consumer);
184
185 InSequence seq;
186 EXPECT_CALL(mock_producer, OnConnect());
187 EXPECT_CALL(mock_consumer, OnConnect());
188 task_runner.RunUntilIdle();
189
190 DataSourceDescriptor ds_desc;
191 ds_desc.set_name("foo");
192 producer_endpoint->RegisterDataSource(ds_desc, [](DataSourceID) {});
193 task_runner.RunUntilIdle();
194
195 // Disconnecting the consumer while tracing should trigger data source
196 // teardown.
197 EXPECT_CALL(mock_producer, CreateDataSourceInstance(_, _));
198 EXPECT_CALL(mock_producer, TearDownDataSourceInstance(_));
199 TraceConfig trace_config;
200 trace_config.add_buffers()->set_size_kb(4096 * 10);
201 auto* ds_config = trace_config.add_data_sources()->mutable_config();
202 ds_config->set_name("foo");
203 ds_config->set_target_buffer(0);
204 consumer_endpoint->EnableTracing(trace_config);
205 task_runner.RunUntilIdle();
206
207 EXPECT_CALL(mock_consumer, OnDisconnect());
208 consumer_endpoint.reset();
209 task_runner.RunUntilIdle();
210
211 EXPECT_CALL(mock_producer, OnDisconnect());
212 producer_endpoint.reset();
213 Mock::VerifyAndClearExpectations(&mock_producer);
214 Mock::VerifyAndClearExpectations(&mock_consumer);
215}
216
217TEST_F(ServiceImplTest, ReconnectProducerWhileTracing) {
218 MockProducer mock_producer;
219 std::unique_ptr<Service::ProducerEndpoint> producer_endpoint =
220 svc->ConnectProducer(&mock_producer, 123u /* uid */);
221 MockConsumer mock_consumer;
222 std::unique_ptr<Service::ConsumerEndpoint> consumer_endpoint =
223 svc->ConnectConsumer(&mock_consumer);
224
225 InSequence seq;
226 EXPECT_CALL(mock_producer, OnConnect());
227 EXPECT_CALL(mock_consumer, OnConnect());
228 task_runner.RunUntilIdle();
229
230 DataSourceDescriptor ds_desc;
231 ds_desc.set_name("foo");
232 producer_endpoint->RegisterDataSource(ds_desc, [](DataSourceID) {});
233 task_runner.RunUntilIdle();
234
235 // Disconnecting the producer while tracing should trigger data source
236 // teardown.
237 EXPECT_CALL(mock_producer, CreateDataSourceInstance(_, _));
238 EXPECT_CALL(mock_producer, TearDownDataSourceInstance(_));
239 EXPECT_CALL(mock_producer, OnDisconnect());
240 TraceConfig trace_config;
241 trace_config.add_buffers()->set_size_kb(4096 * 10);
242 auto* ds_config = trace_config.add_data_sources()->mutable_config();
243 ds_config->set_name("foo");
244 ds_config->set_target_buffer(0);
245 consumer_endpoint->EnableTracing(trace_config);
246 producer_endpoint.reset();
247 task_runner.RunUntilIdle();
248
249 // Reconnecting a producer with a matching data source should see that data
250 // source getting enabled.
251 EXPECT_CALL(mock_producer, OnConnect());
252 producer_endpoint = svc->ConnectProducer(&mock_producer, 123u /* uid */);
253 task_runner.RunUntilIdle();
254 EXPECT_CALL(mock_producer, CreateDataSourceInstance(_, _));
255 EXPECT_CALL(mock_producer, TearDownDataSourceInstance(_));
256 producer_endpoint->RegisterDataSource(ds_desc, [](DataSourceID) {});
257 task_runner.RunUntilIdle();
258
259 EXPECT_CALL(mock_consumer, OnDisconnect());
260 consumer_endpoint->DisableTracing();
261 consumer_endpoint.reset();
262 task_runner.RunUntilIdle();
263
264 EXPECT_CALL(mock_producer, OnDisconnect());
265 producer_endpoint.reset();
266 Mock::VerifyAndClearExpectations(&mock_producer);
267 Mock::VerifyAndClearExpectations(&mock_consumer);
268}
269
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000270} // namespace perfetto