blob: 857efa680a7aeeaee7293b5cc107b91cfe6831b2 [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
Florian Mayer6a1a4d52018-06-08 16:47:07 +010017#include "src/tracing/core/tracing_service_impl.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000018
19#include <string.h>
20
21#include "gmock/gmock.h"
22#include "gtest/gtest.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010023#include "perfetto/base/file_utils.h"
24#include "perfetto/base/temp_file.h"
Primiano Tucci1a1951d2018-04-04 21:08:16 +020025#include "perfetto/base/utils.h"
Sami Kyostila06487a22018-02-27 13:48:38 +000026#include "perfetto/tracing/core/consumer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000027#include "perfetto/tracing/core/data_source_config.h"
28#include "perfetto/tracing/core/data_source_descriptor.h"
29#include "perfetto/tracing/core/producer.h"
30#include "perfetto/tracing/core/shared_memory.h"
Sami Kyostila06487a22018-02-27 13:48:38 +000031#include "perfetto/tracing/core/trace_packet.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010032#include "perfetto/tracing/core/trace_writer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000033#include "src/base/test/test_task_runner.h"
Eric Secklera01e28a2019-01-08 11:21:04 +000034#include "src/tracing/core/shared_memory_arbiter_impl.h"
Eric Secklerf3f524b2018-12-13 09:09:34 +000035#include "src/tracing/core/trace_writer_impl.h"
Primiano Tuccidca727d2018-04-04 11:31:55 +020036#include "src/tracing/test/mock_consumer.h"
37#include "src/tracing/test/mock_producer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000038#include "src/tracing/test/test_shared_memory.h"
39
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010040#include "perfetto/trace/test_event.pbzero.h"
41#include "perfetto/trace/trace.pb.h"
Primiano Tuccidca727d2018-04-04 11:31:55 +020042#include "perfetto/trace/trace_packet.pb.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010043#include "perfetto/trace/trace_packet.pbzero.h"
44
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000045using ::testing::_;
Primiano Tuccidca727d2018-04-04 11:31:55 +020046using ::testing::Contains;
Primiano Tucci1a1951d2018-04-04 21:08:16 +020047using ::testing::ElementsAreArray;
Primiano Tuccidca727d2018-04-04 11:31:55 +020048using ::testing::Eq;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000049using ::testing::InSequence;
Primiano Tucci081d46a2018-02-28 11:09:43 +000050using ::testing::Invoke;
Primiano Tuccidca727d2018-04-04 11:31:55 +020051using ::testing::InvokeWithoutArgs;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000052using ::testing::Mock;
Eric Secklerdd0ad102018-12-06 11:32:04 +000053using ::testing::Not;
Primiano Tuccidca727d2018-04-04 11:31:55 +020054using ::testing::Property;
55using ::testing::StrictMock;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000056
Primiano Tuccidca727d2018-04-04 11:31:55 +020057namespace perfetto {
Sami Kyostila32e0b542018-02-14 08:55:43 +000058
Primiano Tucci1a1951d2018-04-04 21:08:16 +020059namespace {
Florian Mayer6a1a4d52018-06-08 16:47:07 +010060constexpr size_t kDefaultShmSizeKb = TracingServiceImpl::kDefaultShmSize / 1024;
61constexpr size_t kMaxShmSizeKb = TracingServiceImpl::kMaxShmSize / 1024;
Primiano Tucci1a1951d2018-04-04 21:08:16 +020062} // namespace
63
Florian Mayer6a1a4d52018-06-08 16:47:07 +010064class TracingServiceImplTest : public testing::Test {
Sami Kyostila06487a22018-02-27 13:48:38 +000065 public:
Eric Seckler4ff03e52019-03-15 10:10:30 +000066 using DataSourceInstanceState =
67 TracingServiceImpl::DataSourceInstance::DataSourceInstanceState;
68
Florian Mayer6a1a4d52018-06-08 16:47:07 +010069 TracingServiceImplTest() {
Sami Kyostila06487a22018-02-27 13:48:38 +000070 auto shm_factory =
71 std::unique_ptr<SharedMemory::Factory>(new TestSharedMemory::Factory());
Florian Mayer6a1a4d52018-06-08 16:47:07 +010072 svc.reset(static_cast<TracingServiceImpl*>(
73 TracingService::CreateInstance(std::move(shm_factory), &task_runner)
Sami Kyostila06487a22018-02-27 13:48:38 +000074 .release()));
Primiano Tucci9754d0d2018-09-15 12:41:46 +010075 svc->min_write_period_ms_ = 1;
Sami Kyostila06487a22018-02-27 13:48:38 +000076 }
77
Primiano Tuccidca727d2018-04-04 11:31:55 +020078 std::unique_ptr<MockProducer> CreateMockProducer() {
79 return std::unique_ptr<MockProducer>(
80 new StrictMock<MockProducer>(&task_runner));
81 }
82
83 std::unique_ptr<MockConsumer> CreateMockConsumer() {
84 return std::unique_ptr<MockConsumer>(
85 new StrictMock<MockConsumer>(&task_runner));
86 }
87
Primiano Tucci1a1951d2018-04-04 21:08:16 +020088 ProducerID* last_producer_id() { return &svc->last_producer_id_; }
89
90 uid_t GetProducerUid(ProducerID producer_id) {
91 return svc->GetProducer(producer_id)->uid_;
92 }
93
Primiano Tucci9754d0d2018-09-15 12:41:46 +010094 TracingServiceImpl::TracingSession* tracing_session() {
95 auto* session = svc->GetTracingSession(svc->last_tracing_session_id_);
96 EXPECT_NE(nullptr, session);
97 return session;
98 }
99
Eric Seckler6dc23592018-11-30 10:59:06 +0000100 const std::set<BufferID>& GetAllowedTargetBuffers(ProducerID producer_id) {
101 return svc->GetProducer(producer_id)->allowed_target_buffers_;
102 }
103
Eric Secklerf3f524b2018-12-13 09:09:34 +0000104 const std::map<WriterID, BufferID>& GetWriters(ProducerID producer_id) {
105 return svc->GetProducer(producer_id)->writers_;
106 }
107
Eric Secklera01e28a2019-01-08 11:21:04 +0000108 std::unique_ptr<SharedMemoryArbiterImpl> TakeShmemArbiterForProducer(
109 ProducerID producer_id) {
110 return std::move(svc->GetProducer(producer_id)->inproc_shmem_arbiter_);
111 }
112
Primiano Tuccid52e6272018-04-06 19:06:53 +0200113 size_t GetNumPendingFlushes() {
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100114 return tracing_session()->pending_flushes.size();
115 }
116
117 void WaitForNextSyncMarker() {
118 tracing_session()->last_snapshot_time = base::TimeMillis(0);
119 static int attempt = 0;
120 while (tracing_session()->last_snapshot_time == base::TimeMillis(0)) {
121 auto checkpoint_name = "wait_snapshot_" + std::to_string(attempt++);
122 auto timer_expired = task_runner.CreateCheckpoint(checkpoint_name);
123 task_runner.PostDelayedTask([timer_expired] { timer_expired(); }, 1);
124 task_runner.RunUntilCheckpoint(checkpoint_name);
125 }
Primiano Tuccid52e6272018-04-06 19:06:53 +0200126 }
127
Eric Secklerf3f524b2018-12-13 09:09:34 +0000128 void WaitForTraceWritersChanged(ProducerID producer_id) {
129 static int i = 0;
130 auto checkpoint_name = "writers_changed_" + std::to_string(producer_id) +
131 "_" + std::to_string(i++);
132 auto writers_changed = task_runner.CreateCheckpoint(checkpoint_name);
133 auto writers = GetWriters(producer_id);
134 std::function<void()> task;
135 task = [&task, writers, writers_changed, producer_id, this]() {
136 if (writers != GetWriters(producer_id)) {
137 writers_changed();
138 return;
139 }
140 task_runner.PostDelayedTask(task, 1);
141 };
142 task_runner.PostDelayedTask(task, 1);
143 task_runner.RunUntilCheckpoint(checkpoint_name);
144 }
145
Eric Seckler4ff03e52019-03-15 10:10:30 +0000146 DataSourceInstanceState GetDataSourceInstanceState(const std::string& name) {
147 for (const auto& kv : tracing_session()->data_source_instances) {
148 if (kv.second.data_source_name == name)
149 return kv.second.state;
150 }
151 PERFETTO_FATAL("Can't find data source instance with name %s",
152 name.c_str());
153 }
154
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000155 base::TestTaskRunner task_runner;
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100156 std::unique_ptr<TracingServiceImpl> svc;
Sami Kyostila06487a22018-02-27 13:48:38 +0000157};
158
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100159TEST_F(TracingServiceImplTest, RegisterAndUnregister) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200160 std::unique_ptr<MockProducer> mock_producer_1 = CreateMockProducer();
161 std::unique_ptr<MockProducer> mock_producer_2 = CreateMockProducer();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000162
Primiano Tuccidca727d2018-04-04 11:31:55 +0200163 mock_producer_1->Connect(svc.get(), "mock_producer_1", 123u /* uid */);
164 mock_producer_2->Connect(svc.get(), "mock_producer_2", 456u /* uid */);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000165
166 ASSERT_EQ(2u, svc->num_producers());
Primiano Tuccidca727d2018-04-04 11:31:55 +0200167 ASSERT_EQ(mock_producer_1->endpoint(), svc->GetProducer(1));
168 ASSERT_EQ(mock_producer_2->endpoint(), svc->GetProducer(2));
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200169 ASSERT_EQ(123u, GetProducerUid(1));
170 ASSERT_EQ(456u, GetProducerUid(2));
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000171
Primiano Tuccidca727d2018-04-04 11:31:55 +0200172 mock_producer_1->RegisterDataSource("foo");
173 mock_producer_2->RegisterDataSource("bar");
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000174
Primiano Tuccidca727d2018-04-04 11:31:55 +0200175 mock_producer_1->UnregisterDataSource("foo");
176 mock_producer_2->UnregisterDataSource("bar");
Primiano Tucci9daa4832018-03-28 23:28:17 +0100177
Primiano Tuccidca727d2018-04-04 11:31:55 +0200178 mock_producer_1.reset();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000179 ASSERT_EQ(1u, svc->num_producers());
180 ASSERT_EQ(nullptr, svc->GetProducer(1));
181
Primiano Tuccidca727d2018-04-04 11:31:55 +0200182 mock_producer_2.reset();
183 ASSERT_EQ(nullptr, svc->GetProducer(2));
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000184
185 ASSERT_EQ(0u, svc->num_producers());
186}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100187
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100188TEST_F(TracingServiceImplTest, EnableAndDisableTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200189 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
190 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +0000191
Primiano Tuccidca727d2018-04-04 11:31:55 +0200192 std::unique_ptr<MockProducer> producer = CreateMockProducer();
193 producer->Connect(svc.get(), "mock_producer");
194 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000195
Sami Kyostila06487a22018-02-27 13:48:38 +0000196 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200197 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +0000198 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200199 ds_config->set_name("data_source");
200 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +0000201
Primiano Tuccidca727d2018-04-04 11:31:55 +0200202 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100203 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200204 producer->WaitForDataSourceStart("data_source");
205
Primiano Tucci674076d2018-10-01 10:41:09 +0100206 // Calling StartTracing() should be a noop (% a DLOG statement) because the
207 // trace config didn't have the |deferred_start| flag set.
208 consumer->StartTracing();
209
Primiano Tuccidca727d2018-04-04 11:31:55 +0200210 consumer->DisableTracing();
211 producer->WaitForDataSourceStop("data_source");
212 consumer->WaitForTracingDisabled();
Sami Kyostila06487a22018-02-27 13:48:38 +0000213}
214
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100215TEST_F(TracingServiceImplTest, LockdownMode) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200216 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
217 consumer->Connect(svc.get());
218
219 std::unique_ptr<MockProducer> producer = CreateMockProducer();
220 producer->Connect(svc.get(), "mock_producer_sameuid", geteuid());
221 producer->RegisterDataSource("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +0000222
223 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200224 trace_config.add_buffers()->set_size_kb(128);
225 auto* ds_config = trace_config.add_data_sources()->mutable_config();
226 ds_config->set_name("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +0000227 trace_config.set_lockdown_mode(
228 TraceConfig::LockdownModeOperation::LOCKDOWN_SET);
Primiano Tuccidca727d2018-04-04 11:31:55 +0200229 consumer->EnableTracing(trace_config);
230
231 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100232 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200233 producer->WaitForDataSourceStart("data_source");
234
235 std::unique_ptr<MockProducer> producer_otheruid = CreateMockProducer();
236 auto x = svc->ConnectProducer(producer_otheruid.get(), geteuid() + 1,
237 "mock_producer_ouid");
238 EXPECT_CALL(*producer_otheruid, OnConnect()).Times(0);
Florian Mayer61c55482018-03-06 14:43:54 +0000239 task_runner.RunUntilIdle();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200240 Mock::VerifyAndClearExpectations(producer_otheruid.get());
Florian Mayer61c55482018-03-06 14:43:54 +0000241
Primiano Tuccidca727d2018-04-04 11:31:55 +0200242 consumer->DisableTracing();
243 consumer->FreeBuffers();
244 producer->WaitForDataSourceStop("data_source");
245 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +0000246
247 trace_config.set_lockdown_mode(
248 TraceConfig::LockdownModeOperation::LOCKDOWN_CLEAR);
Primiano Tuccidca727d2018-04-04 11:31:55 +0200249 consumer->EnableTracing(trace_config);
Primiano Tucci674076d2018-10-01 10:41:09 +0100250 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200251 producer->WaitForDataSourceStart("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +0000252
Primiano Tuccidca727d2018-04-04 11:31:55 +0200253 std::unique_ptr<MockProducer> producer_otheruid2 = CreateMockProducer();
254 producer_otheruid->Connect(svc.get(), "mock_producer_ouid2", geteuid() + 1);
Florian Mayer61c55482018-03-06 14:43:54 +0000255
Primiano Tuccidca727d2018-04-04 11:31:55 +0200256 consumer->DisableTracing();
257 producer->WaitForDataSourceStop("data_source");
258 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +0000259}
260
Oystein Eftevaagcb6e4c82019-03-06 15:38:26 -0800261TEST_F(TracingServiceImplTest, ProducerNameFilterChange) {
262 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
263 consumer->Connect(svc.get());
264
265 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
266 producer1->Connect(svc.get(), "mock_producer_1");
267 producer1->RegisterDataSource("data_source");
268
269 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
270 producer2->Connect(svc.get(), "mock_producer_2");
271 producer2->RegisterDataSource("data_source");
272
273 std::unique_ptr<MockProducer> producer3 = CreateMockProducer();
274 producer3->Connect(svc.get(), "mock_producer_3");
275 producer3->RegisterDataSource("data_source");
276 producer3->RegisterDataSource("unused_data_source");
277
278 TraceConfig trace_config;
279 trace_config.add_buffers()->set_size_kb(128);
280 auto* data_source = trace_config.add_data_sources();
281 data_source->mutable_config()->set_name("data_source");
282 *data_source->add_producer_name_filter() = "mock_producer_1";
283
284 // Enable tracing with only mock_producer_1 enabled;
285 // the rest should not start up.
286 consumer->EnableTracing(trace_config);
287
288 producer1->WaitForTracingSetup();
289 producer1->WaitForDataSourceSetup("data_source");
290 producer1->WaitForDataSourceStart("data_source");
291
292 EXPECT_CALL(*producer2, OnConnect()).Times(0);
293 EXPECT_CALL(*producer3, OnConnect()).Times(0);
294 task_runner.RunUntilIdle();
295 Mock::VerifyAndClearExpectations(producer2.get());
296 Mock::VerifyAndClearExpectations(producer3.get());
297
298 // Enable mock_producer_2, the third one should still
299 // not get connected.
300 *data_source->add_producer_name_filter() = "mock_producer_2";
301 consumer->ChangeTraceConfig(trace_config);
302
303 producer2->WaitForTracingSetup();
304 producer2->WaitForDataSourceSetup("data_source");
305 producer2->WaitForDataSourceStart("data_source");
306
307 // Enable mock_producer_3 but also try to do an
308 // unsupported change (adding a new data source);
309 // mock_producer_3 should get enabled but not
310 // for the new data source.
311 *data_source->add_producer_name_filter() = "mock_producer_3";
312 auto* dummy_data_source = trace_config.add_data_sources();
313 dummy_data_source->mutable_config()->set_name("unused_data_source");
314 *dummy_data_source->add_producer_name_filter() = "mock_producer_3";
315
316 consumer->ChangeTraceConfig(trace_config);
317
318 producer3->WaitForTracingSetup();
319 EXPECT_CALL(*producer3, SetupDataSource(_, _)).Times(1);
320 EXPECT_CALL(*producer3, StartDataSource(_, _)).Times(1);
321 task_runner.RunUntilIdle();
322 Mock::VerifyAndClearExpectations(producer3.get());
323
324 consumer->DisableTracing();
325 consumer->FreeBuffers();
326 producer1->WaitForDataSourceStop("data_source");
327 producer2->WaitForDataSourceStop("data_source");
328
329 EXPECT_CALL(*producer3, StopDataSource(_)).Times(1);
330
331 consumer->WaitForTracingDisabled();
332
333 task_runner.RunUntilIdle();
334 Mock::VerifyAndClearExpectations(producer3.get());
335}
336
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100337TEST_F(TracingServiceImplTest, DisconnectConsumerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200338 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
339 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +0000340
Primiano Tuccidca727d2018-04-04 11:31:55 +0200341 std::unique_ptr<MockProducer> producer = CreateMockProducer();
342 producer->Connect(svc.get(), "mock_producer");
343 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000344
Primiano Tuccidca727d2018-04-04 11:31:55 +0200345 TraceConfig trace_config;
346 trace_config.add_buffers()->set_size_kb(128);
347 auto* ds_config = trace_config.add_data_sources()->mutable_config();
348 ds_config->set_name("data_source");
349 consumer->EnableTracing(trace_config);
350
351 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100352 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200353 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000354
355 // Disconnecting the consumer while tracing should trigger data source
356 // teardown.
Primiano Tuccidca727d2018-04-04 11:31:55 +0200357 consumer.reset();
358 producer->WaitForDataSourceStop("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000359}
360
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100361TEST_F(TracingServiceImplTest, ReconnectProducerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200362 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
363 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +0000364
Primiano Tuccidca727d2018-04-04 11:31:55 +0200365 std::unique_ptr<MockProducer> producer = CreateMockProducer();
366 producer->Connect(svc.get(), "mock_producer");
367 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000368
Sami Kyostila06487a22018-02-27 13:48:38 +0000369 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200370 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +0000371 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200372 ds_config->set_name("data_source");
373 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +0000374
Primiano Tuccidca727d2018-04-04 11:31:55 +0200375 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100376 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200377 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000378
Primiano Tuccidca727d2018-04-04 11:31:55 +0200379 // Disconnecting and reconnecting a producer with a matching data source.
380 // The Producer should see that data source getting enabled again.
381 producer.reset();
382 producer = CreateMockProducer();
383 producer->Connect(svc.get(), "mock_producer_2");
384 producer->RegisterDataSource("data_source");
385 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100386 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200387 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000388}
389
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100390TEST_F(TracingServiceImplTest, ProducerIDWrapping) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200391 std::vector<std::unique_ptr<MockProducer>> producers;
392 producers.push_back(nullptr);
Primiano Tucci081d46a2018-02-28 11:09:43 +0000393
Primiano Tuccidca727d2018-04-04 11:31:55 +0200394 auto connect_producer_and_get_id = [&producers,
395 this](const std::string& name) {
396 producers.emplace_back(CreateMockProducer());
397 producers.back()->Connect(svc.get(), "mock_producer_" + name);
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200398 return *last_producer_id();
Primiano Tucci081d46a2018-02-28 11:09:43 +0000399 };
400
401 // Connect producers 1-4.
402 for (ProducerID i = 1; i <= 4; i++)
Primiano Tuccidca727d2018-04-04 11:31:55 +0200403 ASSERT_EQ(i, connect_producer_and_get_id(std::to_string(i)));
Primiano Tucci081d46a2018-02-28 11:09:43 +0000404
405 // Disconnect producers 1,3.
Primiano Tuccidca727d2018-04-04 11:31:55 +0200406 producers[1].reset();
407 producers[3].reset();
Primiano Tucci081d46a2018-02-28 11:09:43 +0000408
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200409 *last_producer_id() = kMaxProducerID - 1;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200410 ASSERT_EQ(kMaxProducerID, connect_producer_and_get_id("maxid"));
411 ASSERT_EQ(1u, connect_producer_and_get_id("1_again"));
412 ASSERT_EQ(3u, connect_producer_and_get_id("3_again"));
413 ASSERT_EQ(5u, connect_producer_and_get_id("5"));
414 ASSERT_EQ(6u, connect_producer_and_get_id("6"));
Primiano Tucci081d46a2018-02-28 11:09:43 +0000415}
416
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000417// Note: file_write_period_ms is set to a large enough to have exactly one flush
418// of the tracing buffers (and therefore at most one synchronization section),
419// unless the test runs unrealistically slowly, or the implementation of the
420// tracing snapshot packets changes.
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100421TEST_F(TracingServiceImplTest, WriteIntoFileAndStopOnMaxSize) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200422 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
423 consumer->Connect(svc.get());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100424
Primiano Tuccidca727d2018-04-04 11:31:55 +0200425 std::unique_ptr<MockProducer> producer = CreateMockProducer();
426 producer->Connect(svc.get(), "mock_producer");
427 producer->RegisterDataSource("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100428
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100429 TraceConfig trace_config;
430 trace_config.add_buffers()->set_size_kb(4096);
431 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200432 ds_config->set_name("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100433 ds_config->set_target_buffer(0);
434 trace_config.set_write_into_file(true);
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000435 trace_config.set_file_write_period_ms(100000); // 100s
436 const uint64_t kMaxFileSize = 1024;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100437 trace_config.set_max_file_size_bytes(kMaxFileSize);
438 base::TempFile tmp_file = base::TempFile::Create();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200439 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
440
441 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100442 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200443 producer->WaitForDataSourceStart("data_source");
444
Hector Dearman685f7522019-03-12 14:28:56 +0000445 // The preamble packets are:
446 // Config
447 // SystemInfo
448 // 3x unknown
449 static const int kNumPreamblePackets = 5;
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000450 static const int kNumTestPackets = 10;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200451 static const char kPayload[] = "1234567890abcdef-";
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100452
453 std::unique_ptr<TraceWriter> writer =
Primiano Tuccidca727d2018-04-04 11:31:55 +0200454 producer->CreateTraceWriter("data_source");
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000455 // Tracing service will emit a preamble of packets (a synchronization section,
456 // followed by a tracing config packet). The preamble and these test packets
457 // should fit within kMaxFileSize.
458 for (int i = 0; i < kNumTestPackets; i++) {
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100459 auto tp = writer->NewTracePacket();
460 std::string payload(kPayload);
461 payload.append(std::to_string(i));
462 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
463 }
464
465 // Finally add a packet that overflows kMaxFileSize. This should cause the
466 // implicit stop of the trace and should *not* be written in the trace.
467 {
468 auto tp = writer->NewTracePacket();
469 char big_payload[kMaxFileSize] = "BIG!";
470 tp->set_for_testing()->set_str(big_payload, sizeof(big_payload));
471 }
472 writer->Flush();
473 writer.reset();
474
Primiano Tuccidca727d2018-04-04 11:31:55 +0200475 consumer->DisableTracing();
476 producer->WaitForDataSourceStop("data_source");
477 consumer->WaitForTracingDisabled();
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100478
479 // Verify the contents of the file.
480 std::string trace_raw;
481 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
482 protos::Trace trace;
483 ASSERT_TRUE(trace.ParseFromString(trace_raw));
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000484
485 ASSERT_EQ(trace.packet_size(), kNumPreamblePackets + kNumTestPackets);
486 for (int i = 0; i < kNumTestPackets; i++) {
487 const protos::TracePacket& tp = trace.packet(kNumPreamblePackets + i);
488 ASSERT_EQ(kPayload + std::to_string(i++), tp.for_testing().str());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100489 }
Primiano Tuccidca727d2018-04-04 11:31:55 +0200490}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100491
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200492// Test the logic that allows the trace config to set the shm total size and
493// page size from the trace config. Also check that, if the config doesn't
494// specify a value we fall back on the hint provided by the producer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100495TEST_F(TracingServiceImplTest, ProducerShmAndPageSizeOverriddenByTraceConfig) {
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200496 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
497 consumer->Connect(svc.get());
498 const size_t kConfigPageSizesKb[] = /****/ {16, 16, 4, 0, 16, 8, 3, 4096, 4};
499 const size_t kExpectedPageSizesKb[] = /**/ {16, 16, 4, 4, 16, 8, 4, 64, 4};
500
501 const size_t kConfigSizesKb[] = /**/ {0, 16, 0, 20, 32, 7, 0, 96, 4096000};
502 const size_t kHintSizesKb[] = /****/ {0, 0, 16, 32, 16, 0, 7, 96, 4096000};
503 const size_t kExpectedSizesKb[] = {
504 kDefaultShmSizeKb, // Both hint and config are 0, use default.
505 16, // Hint is 0, use config.
506 16, // Config is 0, use hint.
507 20, // Hint is takes precedence over the config.
508 32, // Ditto, even if config is higher than hint.
509 kDefaultShmSizeKb, // Config is invalid and hint is 0, use default.
510 kDefaultShmSizeKb, // Config is 0 and hint is invalid, use default.
511 kDefaultShmSizeKb, // 96 KB isn't a multiple of the page size (64 KB).
512 kMaxShmSizeKb // Too big, cap at kMaxShmSize.
513 };
514
515 const size_t kNumProducers = base::ArraySize(kHintSizesKb);
516 std::unique_ptr<MockProducer> producer[kNumProducers];
517 for (size_t i = 0; i < kNumProducers; i++) {
518 auto name = "mock_producer_" + std::to_string(i);
519 producer[i] = CreateMockProducer();
520 producer[i]->Connect(svc.get(), name, geteuid(), kHintSizesKb[i] * 1024);
521 producer[i]->RegisterDataSource("data_source");
522 }
523
524 TraceConfig trace_config;
525 trace_config.add_buffers()->set_size_kb(128);
526 auto* ds_config = trace_config.add_data_sources()->mutable_config();
527 ds_config->set_name("data_source");
528 for (size_t i = 0; i < kNumProducers; i++) {
529 auto* producer_config = trace_config.add_producers();
530 producer_config->set_producer_name("mock_producer_" + std::to_string(i));
Primiano Tucci3cbb10a2018-04-10 17:52:40 +0100531 producer_config->set_shm_size_kb(static_cast<uint32_t>(kConfigSizesKb[i]));
532 producer_config->set_page_size_kb(
533 static_cast<uint32_t>(kConfigPageSizesKb[i]));
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200534 }
535
536 consumer->EnableTracing(trace_config);
537 size_t actual_shm_sizes_kb[kNumProducers]{};
538 size_t actual_page_sizes_kb[kNumProducers]{};
539 for (size_t i = 0; i < kNumProducers; i++) {
540 producer[i]->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100541 producer[i]->WaitForDataSourceSetup("data_source");
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200542 actual_shm_sizes_kb[i] =
543 producer[i]->endpoint()->shared_memory()->size() / 1024;
544 actual_page_sizes_kb[i] =
545 producer[i]->endpoint()->shared_buffer_page_size_kb();
546 }
Primiano Tucci674076d2018-10-01 10:41:09 +0100547 for (size_t i = 0; i < kNumProducers; i++) {
548 producer[i]->WaitForDataSourceStart("data_source");
549 }
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200550 ASSERT_THAT(actual_page_sizes_kb, ElementsAreArray(kExpectedPageSizesKb));
551 ASSERT_THAT(actual_shm_sizes_kb, ElementsAreArray(kExpectedSizesKb));
552}
553
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100554TEST_F(TracingServiceImplTest, ExplicitFlush) {
Primiano Tuccid52e6272018-04-06 19:06:53 +0200555 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
556 consumer->Connect(svc.get());
557
558 std::unique_ptr<MockProducer> producer = CreateMockProducer();
559 producer->Connect(svc.get(), "mock_producer");
560 producer->RegisterDataSource("data_source");
561
562 TraceConfig trace_config;
563 trace_config.add_buffers()->set_size_kb(128);
564 auto* ds_config = trace_config.add_data_sources()->mutable_config();
565 ds_config->set_name("data_source");
566
567 consumer->EnableTracing(trace_config);
568 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100569 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +0200570 producer->WaitForDataSourceStart("data_source");
571
572 std::unique_ptr<TraceWriter> writer =
573 producer->CreateTraceWriter("data_source");
574 {
575 auto tp = writer->NewTracePacket();
576 tp->set_for_testing()->set_str("payload");
577 }
578
579 auto flush_request = consumer->Flush();
580 producer->WaitForFlush(writer.get());
581 ASSERT_TRUE(flush_request.WaitForReply());
582
583 consumer->DisableTracing();
584 producer->WaitForDataSourceStop("data_source");
585 consumer->WaitForTracingDisabled();
586 EXPECT_THAT(
587 consumer->ReadBuffers(),
588 Contains(Property(&protos::TracePacket::for_testing,
589 Property(&protos::TestEvent::str, Eq("payload")))));
590}
591
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100592TEST_F(TracingServiceImplTest, ImplicitFlushOnTimedTraces) {
Primiano Tuccid52e6272018-04-06 19:06:53 +0200593 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
594 consumer->Connect(svc.get());
595
596 std::unique_ptr<MockProducer> producer = CreateMockProducer();
597 producer->Connect(svc.get(), "mock_producer");
598 producer->RegisterDataSource("data_source");
599
600 TraceConfig trace_config;
601 trace_config.add_buffers()->set_size_kb(128);
602 auto* ds_config = trace_config.add_data_sources()->mutable_config();
603 ds_config->set_name("data_source");
604 trace_config.set_duration_ms(1);
605
606 consumer->EnableTracing(trace_config);
607 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100608 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +0200609 producer->WaitForDataSourceStart("data_source");
610
611 std::unique_ptr<TraceWriter> writer =
612 producer->CreateTraceWriter("data_source");
613 {
614 auto tp = writer->NewTracePacket();
615 tp->set_for_testing()->set_str("payload");
616 }
617
618 producer->WaitForFlush(writer.get());
619
620 producer->WaitForDataSourceStop("data_source");
621 consumer->WaitForTracingDisabled();
622
623 EXPECT_THAT(
624 consumer->ReadBuffers(),
625 Contains(Property(&protos::TracePacket::for_testing,
626 Property(&protos::TestEvent::str, Eq("payload")))));
627}
628
629// Tests the monotonic semantic of flush request IDs, i.e., once a producer
630// acks flush request N, all flush requests <= N are considered successful and
631// acked to the consumer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100632TEST_F(TracingServiceImplTest, BatchFlushes) {
Primiano Tuccid52e6272018-04-06 19:06:53 +0200633 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
634 consumer->Connect(svc.get());
635
636 std::unique_ptr<MockProducer> producer = CreateMockProducer();
637 producer->Connect(svc.get(), "mock_producer");
638 producer->RegisterDataSource("data_source");
639
640 TraceConfig trace_config;
641 trace_config.add_buffers()->set_size_kb(128);
642 auto* ds_config = trace_config.add_data_sources()->mutable_config();
643 ds_config->set_name("data_source");
644
645 consumer->EnableTracing(trace_config);
646 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100647 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +0200648 producer->WaitForDataSourceStart("data_source");
649
650 std::unique_ptr<TraceWriter> writer =
651 producer->CreateTraceWriter("data_source");
652 {
653 auto tp = writer->NewTracePacket();
654 tp->set_for_testing()->set_str("payload");
655 }
656
657 auto flush_req_1 = consumer->Flush();
658 auto flush_req_2 = consumer->Flush();
659 auto flush_req_3 = consumer->Flush();
660
661 // We'll deliberately let the 4th flush request timeout. Use a lower timeout
662 // to keep test time short.
663 auto flush_req_4 = consumer->Flush(/*timeout_ms=*/10);
664 ASSERT_EQ(4u, GetNumPendingFlushes());
665
666 // Make the producer reply only to the 3rd flush request.
667 testing::InSequence seq;
Eric Secklera01e28a2019-01-08 11:21:04 +0000668 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 1.
669 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 2.
670 producer->WaitForFlush(writer.get()); // Reply only to flush 3.
671 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 4.
Primiano Tuccid52e6272018-04-06 19:06:53 +0200672
673 // Even if the producer explicily replied only to flush ID == 3, all the
674 // previous flushed < 3 should be implicitly acked.
675 ASSERT_TRUE(flush_req_1.WaitForReply());
676 ASSERT_TRUE(flush_req_2.WaitForReply());
677 ASSERT_TRUE(flush_req_3.WaitForReply());
678
679 // At this point flush id == 4 should still be pending and should fail because
680 // of reaching its timeout.
Primiano Tuccid52e6272018-04-06 19:06:53 +0200681 ASSERT_FALSE(flush_req_4.WaitForReply());
682
683 consumer->DisableTracing();
684 producer->WaitForDataSourceStop("data_source");
685 consumer->WaitForTracingDisabled();
686 EXPECT_THAT(
687 consumer->ReadBuffers(),
688 Contains(Property(&protos::TracePacket::for_testing,
689 Property(&protos::TestEvent::str, Eq("payload")))));
690}
691
Primiano Tuccicaa57802018-11-25 11:07:07 +0000692TEST_F(TracingServiceImplTest, PeriodicFlush) {
693 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
694 consumer->Connect(svc.get());
695
696 std::unique_ptr<MockProducer> producer = CreateMockProducer();
697 producer->Connect(svc.get(), "mock_producer");
698 producer->RegisterDataSource("data_source");
699
700 TraceConfig trace_config;
701 trace_config.add_buffers()->set_size_kb(128);
702 trace_config.set_flush_period_ms(1);
703 auto* ds_config = trace_config.add_data_sources()->mutable_config();
704 ds_config->set_name("data_source");
705
706 consumer->EnableTracing(trace_config);
707 producer->WaitForTracingSetup();
708 producer->WaitForDataSourceSetup("data_source");
709 producer->WaitForDataSourceStart("data_source");
710
711 std::unique_ptr<TraceWriter> writer =
712 producer->CreateTraceWriter("data_source");
713
714 const int kNumFlushes = 3;
715 auto checkpoint = task_runner.CreateCheckpoint("all_flushes_done");
716 int flushes_seen = 0;
717 EXPECT_CALL(*producer, Flush(_, _, _))
718 .WillRepeatedly(Invoke([&producer, &writer, &flushes_seen, checkpoint](
719 FlushRequestID flush_req_id,
720 const DataSourceInstanceID*, size_t) {
721 {
722 auto tp = writer->NewTracePacket();
723 char payload[32];
724 sprintf(payload, "f_%d", flushes_seen);
725 tp->set_for_testing()->set_str(payload);
726 }
727 writer->Flush();
728 producer->endpoint()->NotifyFlushComplete(flush_req_id);
729 if (++flushes_seen == kNumFlushes)
730 checkpoint();
731 }));
732 task_runner.RunUntilCheckpoint("all_flushes_done");
733
734 consumer->DisableTracing();
735 producer->WaitForDataSourceStop("data_source");
736 consumer->WaitForTracingDisabled();
737 auto trace_packets = consumer->ReadBuffers();
738 for (int i = 0; i < kNumFlushes; i++) {
739 EXPECT_THAT(trace_packets,
740 Contains(Property(&protos::TracePacket::for_testing,
741 Property(&protos::TestEvent::str,
742 Eq("f_" + std::to_string(i))))));
743 }
744}
745
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100746// Creates a tracing session where some of the data sources set the
747// |will_notify_on_stop| flag and checks that the OnTracingDisabled notification
748// to the consumer is delayed until the acks are received.
749TEST_F(TracingServiceImplTest, OnTracingDisabledWaitsForDataSourceStopAcks) {
750 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
751 consumer->Connect(svc.get());
752
753 std::unique_ptr<MockProducer> producer = CreateMockProducer();
754 producer->Connect(svc.get(), "mock_producer");
Eric Seckler4ff03e52019-03-15 10:10:30 +0000755 producer->RegisterDataSource("ds_will_ack_1", /*ack_stop=*/true,
756 /*ack_start=*/true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100757 producer->RegisterDataSource("ds_wont_ack");
Eric Seckler4ff03e52019-03-15 10:10:30 +0000758 producer->RegisterDataSource("ds_will_ack_2", /*ack_stop=*/true,
759 /*ack_start=*/false);
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100760
761 TraceConfig trace_config;
762 trace_config.add_buffers()->set_size_kb(128);
763 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_1");
764 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
765 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_2");
766 trace_config.set_duration_ms(1);
Eric Seckler4ff03e52019-03-15 10:10:30 +0000767 trace_config.set_deferred_start(true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100768
769 consumer->EnableTracing(trace_config);
Eric Seckler4ff03e52019-03-15 10:10:30 +0000770
771 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
772 DataSourceInstanceState::CONFIGURED);
773 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
774 DataSourceInstanceState::CONFIGURED);
775 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
776 DataSourceInstanceState::CONFIGURED);
777
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100778 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100779
780 producer->WaitForDataSourceSetup("ds_will_ack_1");
781 producer->WaitForDataSourceSetup("ds_wont_ack");
782 producer->WaitForDataSourceSetup("ds_will_ack_2");
783
Eric Seckler4ff03e52019-03-15 10:10:30 +0000784 DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_will_ack_1");
785 DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_will_ack_2");
786
787 consumer->StartTracing();
788
789 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
790 DataSourceInstanceState::STARTING);
791 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
792 DataSourceInstanceState::STARTED);
793 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
794 DataSourceInstanceState::STARTED);
795
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100796 producer->WaitForDataSourceStart("ds_will_ack_1");
797 producer->WaitForDataSourceStart("ds_wont_ack");
798 producer->WaitForDataSourceStart("ds_will_ack_2");
799
Eric Seckler4ff03e52019-03-15 10:10:30 +0000800 producer->endpoint()->NotifyDataSourceStarted(id1);
801
802 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
803 DataSourceInstanceState::STARTED);
804
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100805 std::unique_ptr<TraceWriter> writer =
806 producer->CreateTraceWriter("ds_wont_ack");
807 producer->WaitForFlush(writer.get());
808
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100809 producer->WaitForDataSourceStop("ds_will_ack_1");
810 producer->WaitForDataSourceStop("ds_wont_ack");
811 producer->WaitForDataSourceStop("ds_will_ack_2");
812
Eric Seckler4ff03e52019-03-15 10:10:30 +0000813 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
814 DataSourceInstanceState::STOPPING);
815 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
816 DataSourceInstanceState::STOPPED);
817 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
818 DataSourceInstanceState::STOPPING);
819
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100820 producer->endpoint()->NotifyDataSourceStopped(id1);
821 producer->endpoint()->NotifyDataSourceStopped(id2);
822
Eric Seckler4ff03e52019-03-15 10:10:30 +0000823 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
824 DataSourceInstanceState::STOPPED);
825 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
826 DataSourceInstanceState::STOPPED);
827
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100828 // Wait for at most half of the service timeout, so that this test fails if
829 // the service falls back on calling the OnTracingDisabled() because some of
830 // the expected acks weren't received.
831 consumer->WaitForTracingDisabled(
832 TracingServiceImpl::kDataSourceStopTimeoutMs / 2);
833}
834
Oystein Eftevaagf250e1c2018-08-23 16:10:52 -0700835// Creates a tracing session where a second data source
836// is added while the service is waiting for DisableTracing
837// acks; the service should not enable the new datasource
838// and should not hit any asserts when the consumer is
839// subsequently destroyed.
840TEST_F(TracingServiceImplTest, OnDataSourceAddedWhilePendingDisableAcks) {
841 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
842 consumer->Connect(svc.get());
843
844 std::unique_ptr<MockProducer> producer = CreateMockProducer();
845 producer->Connect(svc.get(), "mock_producer");
846 producer->RegisterDataSource("ds_will_ack", /*ack_stop=*/true);
847
848 TraceConfig trace_config;
849 trace_config.add_buffers()->set_size_kb(128);
850 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack");
851 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
852
853 consumer->EnableTracing(trace_config);
854 producer->WaitForTracingSetup();
855
856 consumer->DisableTracing();
857
858 producer->RegisterDataSource("ds_wont_ack");
859
860 consumer.reset();
861}
862
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100863// Similar to OnTracingDisabledWaitsForDataSourceStopAcks, but deliberately
864// skips the ack and checks that the service invokes the OnTracingDisabled()
865// after the timeout.
866TEST_F(TracingServiceImplTest, OnTracingDisabledCalledAnywaysInCaseOfTimeout) {
867 svc->override_data_source_test_timeout_ms_for_testing = 1;
868 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
869 consumer->Connect(svc.get());
870
871 std::unique_ptr<MockProducer> producer = CreateMockProducer();
872 producer->Connect(svc.get(), "mock_producer");
873 producer->RegisterDataSource("data_source", /*ack_stop=*/true);
874
875 TraceConfig trace_config;
876 trace_config.add_buffers()->set_size_kb(128);
877 trace_config.add_data_sources()->mutable_config()->set_name("data_source");
878 trace_config.set_duration_ms(1);
879
880 consumer->EnableTracing(trace_config);
881 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100882 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100883 producer->WaitForDataSourceStart("data_source");
884
885 std::unique_ptr<TraceWriter> writer =
886 producer->CreateTraceWriter("data_source");
887 producer->WaitForFlush(writer.get());
888
889 producer->WaitForDataSourceStop("data_source");
890 consumer->WaitForTracingDisabled();
891}
892
Primiano Tucci03de28f2018-08-01 11:29:46 +0100893// Tests the session_id logic. Two data sources in the same tracing session
894// should see the same session id.
895TEST_F(TracingServiceImplTest, SessionId) {
896 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
897 consumer->Connect(svc.get());
898
899 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
900 producer1->Connect(svc.get(), "mock_producer1");
901 producer1->RegisterDataSource("ds_1A");
902 producer1->RegisterDataSource("ds_1B");
903
904 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
905 producer2->Connect(svc.get(), "mock_producer2");
906 producer2->RegisterDataSource("ds_2A");
907
908 testing::InSequence seq;
909 TracingSessionID last_session_id = 0;
910 for (int i = 0; i < 3; i++) {
911 TraceConfig trace_config;
912 trace_config.add_buffers()->set_size_kb(128);
913 trace_config.add_data_sources()->mutable_config()->set_name("ds_1A");
914 trace_config.add_data_sources()->mutable_config()->set_name("ds_1B");
915 trace_config.add_data_sources()->mutable_config()->set_name("ds_2A");
916 trace_config.set_duration_ms(1);
917
918 consumer->EnableTracing(trace_config);
919
920 if (i == 0)
921 producer1->WaitForTracingSetup();
Primiano Tucci03de28f2018-08-01 11:29:46 +0100922
Primiano Tucci674076d2018-10-01 10:41:09 +0100923 producer1->WaitForDataSourceSetup("ds_1A");
924 producer1->WaitForDataSourceSetup("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +0100925 if (i == 0)
926 producer2->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100927 producer2->WaitForDataSourceSetup("ds_2A");
928
929 producer1->WaitForDataSourceStart("ds_1A");
930 producer1->WaitForDataSourceStart("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +0100931 producer2->WaitForDataSourceStart("ds_2A");
932
933 auto* ds1 = producer1->GetDataSourceInstance("ds_1A");
934 auto* ds2 = producer1->GetDataSourceInstance("ds_1B");
935 auto* ds3 = producer2->GetDataSourceInstance("ds_2A");
936 ASSERT_EQ(ds1->session_id, ds2->session_id);
937 ASSERT_EQ(ds1->session_id, ds3->session_id);
938 ASSERT_NE(ds1->session_id, last_session_id);
939 last_session_id = ds1->session_id;
940
941 auto writer1 = producer1->CreateTraceWriter("ds_1A");
942 producer1->WaitForFlush(writer1.get());
943
944 auto writer2 = producer2->CreateTraceWriter("ds_2A");
945 producer2->WaitForFlush(writer2.get());
946
947 producer1->WaitForDataSourceStop("ds_1A");
948 producer1->WaitForDataSourceStop("ds_1B");
949 producer2->WaitForDataSourceStop("ds_2A");
950 consumer->WaitForTracingDisabled();
951 consumer->FreeBuffers();
952 }
953}
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100954
955// Writes a long trace and then tests that the trace parsed in partitions
956// derived by the synchronization markers is identical to the whole trace parsed
957// in one go.
958TEST_F(TracingServiceImplTest, ResynchronizeTraceStreamUsingSyncMarker) {
959 // Setup tracing.
960 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
961 consumer->Connect(svc.get());
962 std::unique_ptr<MockProducer> producer = CreateMockProducer();
963 producer->Connect(svc.get(), "mock_producer");
964 producer->RegisterDataSource("data_source");
965 TraceConfig trace_config;
966 trace_config.add_buffers()->set_size_kb(4096);
967 auto* ds_config = trace_config.add_data_sources()->mutable_config();
968 ds_config->set_name("data_source");
969 trace_config.set_write_into_file(true);
970 trace_config.set_file_write_period_ms(1);
971 base::TempFile tmp_file = base::TempFile::Create();
972 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
973 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100974 producer->WaitForDataSourceSetup("data_source");
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100975 producer->WaitForDataSourceStart("data_source");
976
977 // Write some variable length payload, waiting for sync markers every now
978 // and then.
979 const int kNumMarkers = 5;
980 auto writer = producer->CreateTraceWriter("data_source");
981 for (int i = 1; i <= 100; i++) {
Florian Mayereff98042018-12-10 17:44:44 +0000982 std::string payload(static_cast<size_t>(i), 'A' + (i % 25));
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100983 writer->NewTracePacket()->set_for_testing()->set_str(payload.c_str());
984 if (i % (100 / kNumMarkers) == 0) {
985 writer->Flush();
986 WaitForNextSyncMarker();
987 }
988 }
989 writer->Flush();
990 writer.reset();
991 consumer->DisableTracing();
992 producer->WaitForDataSourceStop("data_source");
993 consumer->WaitForTracingDisabled();
994
995 std::string trace_raw;
996 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
997
998 const auto kMarkerSize = sizeof(TracingServiceImpl::kSyncMarker);
999 const std::string kSyncMarkerStr(
1000 reinterpret_cast<const char*>(TracingServiceImpl::kSyncMarker),
1001 kMarkerSize);
1002
1003 // Read back the trace in partitions derived from the marker.
1004 // The trace should look like this:
1005 // [uid, marker] [event] [event] [uid, marker] [event] [event]
1006 size_t num_markers = 0;
1007 size_t start = 0;
1008 size_t end = 0;
1009 protos::Trace merged_trace;
1010 for (size_t pos = 0; pos != std::string::npos; start = end) {
1011 pos = trace_raw.find(kSyncMarkerStr, pos + 1);
1012 num_markers++;
1013 end = (pos == std::string::npos) ? trace_raw.size() : pos + kMarkerSize;
1014 int size = static_cast<int>(end - start);
1015 ASSERT_GT(size, 0);
1016 protos::Trace trace_partition;
1017 ASSERT_TRUE(trace_partition.ParseFromArray(trace_raw.data() + start, size));
1018 merged_trace.MergeFrom(trace_partition);
1019 }
Lalit Maganti9bdc7ce2018-09-17 15:25:11 +01001020 EXPECT_GE(num_markers, static_cast<size_t>(kNumMarkers));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001021
1022 protos::Trace whole_trace;
1023 ASSERT_TRUE(whole_trace.ParseFromString(trace_raw));
1024
1025 ASSERT_EQ(whole_trace.packet_size(), merged_trace.packet_size());
1026 EXPECT_EQ(whole_trace.SerializeAsString(), merged_trace.SerializeAsString());
1027}
1028
Primiano Tucci674076d2018-10-01 10:41:09 +01001029// Creates a tracing session with |deferred_start| and checks that data sources
1030// are started only after calling StartTracing().
1031TEST_F(TracingServiceImplTest, DeferredStart) {
1032 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1033 consumer->Connect(svc.get());
1034
1035 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1036 producer->Connect(svc.get(), "mock_producer");
1037
1038 // Create two data sources but enable only one of them.
1039 producer->RegisterDataSource("ds_1");
1040 producer->RegisterDataSource("ds_2");
1041
1042 TraceConfig trace_config;
1043 trace_config.add_buffers()->set_size_kb(128);
1044 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
1045 trace_config.set_deferred_start(true);
1046 trace_config.set_duration_ms(1);
1047
1048 consumer->EnableTracing(trace_config);
1049 producer->WaitForTracingSetup();
1050
1051 producer->WaitForDataSourceSetup("ds_1");
1052
1053 // Make sure we don't get unexpected DataSourceStart() notifications yet.
1054 task_runner.RunUntilIdle();
1055
1056 consumer->StartTracing();
1057
1058 producer->WaitForDataSourceStart("ds_1");
1059
1060 auto writer1 = producer->CreateTraceWriter("ds_1");
1061 producer->WaitForFlush(writer1.get());
1062
1063 producer->WaitForDataSourceStop("ds_1");
1064 consumer->WaitForTracingDisabled();
1065}
1066
Eric Secklerd0ac7ca2019-02-06 09:13:45 +00001067TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
1068 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1069 consumer->Connect(svc.get());
1070
1071 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1072 producer1->Connect(svc.get(), "mock_producer1", 123u /* uid */);
1073 producer1->RegisterDataSource("data_source");
1074
1075 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1076 producer2->Connect(svc.get(), "mock_producer2", 456u /* uid */);
1077 producer2->RegisterDataSource("data_source");
1078
1079 TraceConfig trace_config;
1080 trace_config.add_buffers()->set_size_kb(128);
1081 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1082 ds_config->set_name("data_source");
1083
1084 consumer->EnableTracing(trace_config);
1085 producer1->WaitForTracingSetup();
1086 producer1->WaitForDataSourceSetup("data_source");
1087 producer2->WaitForTracingSetup();
1088 producer2->WaitForDataSourceSetup("data_source");
1089 producer1->WaitForDataSourceStart("data_source");
1090 producer2->WaitForDataSourceStart("data_source");
1091
1092 std::unique_ptr<TraceWriter> writer1a =
1093 producer1->CreateTraceWriter("data_source");
1094 std::unique_ptr<TraceWriter> writer1b =
1095 producer1->CreateTraceWriter("data_source");
1096 std::unique_ptr<TraceWriter> writer2a =
1097 producer2->CreateTraceWriter("data_source");
1098 {
1099 auto tp = writer1a->NewTracePacket();
1100 tp->set_for_testing()->set_str("payload1a1");
1101 tp = writer1b->NewTracePacket();
1102 tp->set_for_testing()->set_str("payload1b1");
1103 tp = writer1a->NewTracePacket();
1104 tp->set_for_testing()->set_str("payload1a2");
1105 tp = writer2a->NewTracePacket();
1106 tp->set_for_testing()->set_str("payload2a1");
1107 tp = writer1b->NewTracePacket();
1108 tp->set_for_testing()->set_str("payload1b2");
1109 }
1110
1111 auto flush_request = consumer->Flush();
1112 producer1->WaitForFlush({writer1a.get(), writer1b.get()});
1113 producer2->WaitForFlush(writer2a.get());
1114 ASSERT_TRUE(flush_request.WaitForReply());
1115
1116 consumer->DisableTracing();
1117 producer1->WaitForDataSourceStop("data_source");
1118 producer2->WaitForDataSourceStop("data_source");
1119 consumer->WaitForTracingDisabled();
1120 auto packets = consumer->ReadBuffers();
1121 EXPECT_THAT(
1122 packets,
1123 Contains(AllOf(
1124 Property(&protos::TracePacket::for_testing,
1125 Property(&protos::TestEvent::str, Eq("payload1a1"))),
1126 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1127 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
1128 EXPECT_THAT(
1129 packets,
1130 Contains(AllOf(
1131 Property(&protos::TracePacket::for_testing,
1132 Property(&protos::TestEvent::str, Eq("payload1a2"))),
1133 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1134 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
1135 EXPECT_THAT(
1136 packets,
1137 Contains(AllOf(
1138 Property(&protos::TracePacket::for_testing,
1139 Property(&protos::TestEvent::str, Eq("payload1b1"))),
1140 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1141 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
1142 EXPECT_THAT(
1143 packets,
1144 Contains(AllOf(
1145 Property(&protos::TracePacket::for_testing,
1146 Property(&protos::TestEvent::str, Eq("payload1b2"))),
1147 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1148 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
1149 EXPECT_THAT(
1150 packets,
1151 Contains(AllOf(
1152 Property(&protos::TracePacket::for_testing,
1153 Property(&protos::TestEvent::str, Eq("payload2a1"))),
1154 Property(&protos::TracePacket::trusted_uid, Eq(456)),
1155 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(4u)))));
1156}
1157
Eric Seckler6dc23592018-11-30 10:59:06 +00001158TEST_F(TracingServiceImplTest, AllowedBuffers) {
1159 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1160 consumer->Connect(svc.get());
1161
1162 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1163 producer1->Connect(svc.get(), "mock_producer1");
1164 ProducerID producer1_id = *last_producer_id();
1165 producer1->RegisterDataSource("data_source1");
1166 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1167 producer2->Connect(svc.get(), "mock_producer2");
1168 ProducerID producer2_id = *last_producer_id();
1169 producer2->RegisterDataSource("data_source2.1");
1170 producer2->RegisterDataSource("data_source2.2");
1171 producer2->RegisterDataSource("data_source2.3");
1172
1173 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
1174 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
1175
1176 TraceConfig trace_config;
1177 trace_config.add_buffers()->set_size_kb(128);
1178 trace_config.add_buffers()->set_size_kb(128);
1179 trace_config.add_buffers()->set_size_kb(128);
1180 auto* ds_config1 = trace_config.add_data_sources()->mutable_config();
1181 ds_config1->set_name("data_source1");
1182 ds_config1->set_target_buffer(0);
1183 auto* ds_config21 = trace_config.add_data_sources()->mutable_config();
1184 ds_config21->set_name("data_source2.1");
1185 ds_config21->set_target_buffer(1);
1186 auto* ds_config22 = trace_config.add_data_sources()->mutable_config();
1187 ds_config22->set_name("data_source2.2");
1188 ds_config22->set_target_buffer(2);
1189 auto* ds_config23 = trace_config.add_data_sources()->mutable_config();
1190 ds_config23->set_name("data_source2.3");
1191 ds_config23->set_target_buffer(2); // same buffer as data_source2.2.
1192 consumer->EnableTracing(trace_config);
1193
Primiano Tucci2abd1152018-12-03 17:00:02 +01001194 ASSERT_EQ(3u, tracing_session()->num_buffers());
Eric Seckler6dc23592018-11-30 10:59:06 +00001195 std::set<BufferID> expected_buffers_producer1 = {
1196 tracing_session()->buffers_index[0]};
1197 std::set<BufferID> expected_buffers_producer2 = {
1198 tracing_session()->buffers_index[1], tracing_session()->buffers_index[2]};
1199 EXPECT_EQ(expected_buffers_producer1, GetAllowedTargetBuffers(producer1_id));
1200 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
1201
1202 producer1->WaitForTracingSetup();
1203 producer1->WaitForDataSourceSetup("data_source1");
1204
1205 producer2->WaitForTracingSetup();
1206 producer2->WaitForDataSourceSetup("data_source2.1");
1207 producer2->WaitForDataSourceSetup("data_source2.2");
1208 producer2->WaitForDataSourceSetup("data_source2.3");
1209
1210 producer1->WaitForDataSourceStart("data_source1");
1211 producer2->WaitForDataSourceStart("data_source2.1");
1212 producer2->WaitForDataSourceStart("data_source2.2");
1213 producer2->WaitForDataSourceStart("data_source2.3");
1214
1215 producer2->UnregisterDataSource("data_source2.3");
1216 producer2->WaitForDataSourceStop("data_source2.3");
1217
1218 // Should still be allowed to write to buffers 1 (data_source2.1) and 2
1219 // (data_source2.2).
1220 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
1221
1222 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1223 // trace config didn't have the |deferred_start| flag set.
1224 consumer->StartTracing();
1225
1226 consumer->DisableTracing();
1227 producer1->WaitForDataSourceStop("data_source1");
1228 producer2->WaitForDataSourceStop("data_source2.1");
1229 producer2->WaitForDataSourceStop("data_source2.2");
1230 consumer->WaitForTracingDisabled();
1231
1232 consumer->FreeBuffers();
1233 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
1234 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
1235}
1236
Eric Seckler6aa9ece2018-12-06 16:40:12 +00001237#if !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00001238TEST_F(TracingServiceImplTest, CommitToForbiddenBufferIsDiscarded) {
1239 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1240 consumer->Connect(svc.get());
1241
1242 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1243 producer->Connect(svc.get(), "mock_producer");
1244 ProducerID producer_id = *last_producer_id();
1245 producer->RegisterDataSource("data_source");
1246
1247 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
1248
1249 TraceConfig trace_config;
1250 trace_config.add_buffers()->set_size_kb(128);
1251 trace_config.add_buffers()->set_size_kb(128);
1252 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1253 ds_config->set_name("data_source");
1254 ds_config->set_target_buffer(0);
1255 consumer->EnableTracing(trace_config);
1256
1257 ASSERT_EQ(2u, tracing_session()->num_buffers());
1258 std::set<BufferID> expected_buffers = {tracing_session()->buffers_index[0]};
1259 EXPECT_EQ(expected_buffers, GetAllowedTargetBuffers(producer_id));
1260
1261 producer->WaitForTracingSetup();
1262 producer->WaitForDataSourceSetup("data_source");
1263 producer->WaitForDataSourceStart("data_source");
1264
1265 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1266 // trace config didn't have the |deferred_start| flag set.
1267 consumer->StartTracing();
1268
1269 // Try to write to the correct buffer.
1270 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1271 tracing_session()->buffers_index[0]);
1272 {
1273 auto tp = writer->NewTracePacket();
1274 tp->set_for_testing()->set_str("good_payload");
1275 }
1276
1277 auto flush_request = consumer->Flush();
1278 producer->WaitForFlush(writer.get());
1279 ASSERT_TRUE(flush_request.WaitForReply());
1280
1281 // Try to write to the wrong buffer.
1282 writer = producer->endpoint()->CreateTraceWriter(
1283 tracing_session()->buffers_index[1]);
1284 {
1285 auto tp = writer->NewTracePacket();
1286 tp->set_for_testing()->set_str("bad_payload");
1287 }
1288
1289 flush_request = consumer->Flush();
1290 producer->WaitForFlush(writer.get());
1291 ASSERT_TRUE(flush_request.WaitForReply());
1292
1293 consumer->DisableTracing();
1294 producer->WaitForDataSourceStop("data_source");
1295 consumer->WaitForTracingDisabled();
1296
1297 auto packets = consumer->ReadBuffers();
1298 EXPECT_THAT(packets, Contains(Property(&protos::TracePacket::for_testing,
1299 Property(&protos::TestEvent::str,
1300 Eq("good_payload")))));
1301 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1302 Property(&protos::TestEvent::str,
1303 Eq("bad_payload"))))));
1304
1305 consumer->FreeBuffers();
1306 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
1307}
Eric Seckler6aa9ece2018-12-06 16:40:12 +00001308#endif // !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00001309
Eric Secklerf3f524b2018-12-13 09:09:34 +00001310TEST_F(TracingServiceImplTest, RegisterAndUnregisterTraceWriter) {
1311 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1312 consumer->Connect(svc.get());
1313
1314 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1315 producer->Connect(svc.get(), "mock_producer");
1316 ProducerID producer_id = *last_producer_id();
1317 producer->RegisterDataSource("data_source");
1318
1319 EXPECT_TRUE(GetWriters(producer_id).empty());
1320
1321 TraceConfig trace_config;
1322 trace_config.add_buffers()->set_size_kb(128);
1323 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1324 ds_config->set_name("data_source");
1325 ds_config->set_target_buffer(0);
1326 consumer->EnableTracing(trace_config);
1327
1328 producer->WaitForTracingSetup();
1329 producer->WaitForDataSourceSetup("data_source");
1330 producer->WaitForDataSourceStart("data_source");
1331
1332 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1333 // trace config didn't have the |deferred_start| flag set.
1334 consumer->StartTracing();
1335
1336 // Creating the trace writer should register it with the service.
1337 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1338 tracing_session()->buffers_index[0]);
1339
1340 WaitForTraceWritersChanged(producer_id);
1341
1342 std::map<WriterID, BufferID> expected_writers;
1343 expected_writers[writer->writer_id()] = tracing_session()->buffers_index[0];
1344 EXPECT_EQ(expected_writers, GetWriters(producer_id));
1345
1346 // Verify writing works.
1347 {
1348 auto tp = writer->NewTracePacket();
1349 tp->set_for_testing()->set_str("payload");
1350 }
1351
1352 auto flush_request = consumer->Flush();
1353 producer->WaitForFlush(writer.get());
1354 ASSERT_TRUE(flush_request.WaitForReply());
1355
1356 // Destroying the writer should unregister it.
1357 writer.reset();
1358 WaitForTraceWritersChanged(producer_id);
1359 EXPECT_TRUE(GetWriters(producer_id).empty());
1360
1361 consumer->DisableTracing();
1362 producer->WaitForDataSourceStop("data_source");
1363 consumer->WaitForTracingDisabled();
1364
1365 auto packets = consumer->ReadBuffers();
1366 EXPECT_THAT(packets, Contains(Property(
1367 &protos::TracePacket::for_testing,
1368 Property(&protos::TestEvent::str, Eq("payload")))));
1369}
1370
Eric Secklera01e28a2019-01-08 11:21:04 +00001371TEST_F(TracingServiceImplTest, ScrapeBuffersOnFlush) {
1372 svc->SetSMBScrapingEnabled(true);
1373
1374 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1375 consumer->Connect(svc.get());
1376
1377 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1378 producer->Connect(svc.get(), "mock_producer");
1379 ProducerID producer_id = *last_producer_id();
1380 producer->RegisterDataSource("data_source");
1381
1382 TraceConfig trace_config;
1383 trace_config.add_buffers()->set_size_kb(128);
1384 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1385 ds_config->set_name("data_source");
1386 ds_config->set_target_buffer(0);
1387 consumer->EnableTracing(trace_config);
1388
1389 producer->WaitForTracingSetup();
1390 producer->WaitForDataSourceSetup("data_source");
1391 producer->WaitForDataSourceStart("data_source");
1392
1393 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1394 // trace config didn't have the |deferred_start| flag set.
1395 consumer->StartTracing();
1396
1397 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1398 tracing_session()->buffers_index[0]);
1399 WaitForTraceWritersChanged(producer_id);
1400
1401 // Write a few trace packets.
1402 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
1403 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
1404 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
1405
1406 // Flush but don't actually flush the chunk from TraceWriter.
1407 auto flush_request = consumer->Flush();
1408 producer->WaitForFlush(nullptr, /*reply=*/true);
1409 ASSERT_TRUE(flush_request.WaitForReply());
1410
1411 // Chunk with the packets should have been scraped. The service can't know
1412 // whether the last packet was completed, so shouldn't read it.
1413 auto packets = consumer->ReadBuffers();
1414 EXPECT_THAT(packets, Contains(Property(
1415 &protos::TracePacket::for_testing,
1416 Property(&protos::TestEvent::str, Eq("payload1")))));
1417 EXPECT_THAT(packets, Contains(Property(
1418 &protos::TracePacket::for_testing,
1419 Property(&protos::TestEvent::str, Eq("payload2")))));
1420 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1421 Property(&protos::TestEvent::str,
1422 Eq("payload3"))))));
1423
1424 // Write some more packets.
1425 writer->NewTracePacket()->set_for_testing()->set_str("payload4");
1426 writer->NewTracePacket()->set_for_testing()->set_str("payload5");
1427
1428 // Don't reply to flush, causing a timeout. This should scrape again.
1429 flush_request = consumer->Flush(/*timeout=*/100);
1430 producer->WaitForFlush(nullptr, /*reply=*/false);
1431 ASSERT_FALSE(flush_request.WaitForReply());
1432
1433 // Chunk with the packets should have been scraped again, overriding the
1434 // original one. Again, the last packet should be ignored and the first two
1435 // should not be read twice.
1436 packets = consumer->ReadBuffers();
1437 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1438 Property(&protos::TestEvent::str,
1439 Eq("payload1"))))));
1440 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1441 Property(&protos::TestEvent::str,
1442 Eq("payload2"))))));
1443 EXPECT_THAT(packets, Contains(Property(
1444 &protos::TracePacket::for_testing,
1445 Property(&protos::TestEvent::str, Eq("payload3")))));
1446 EXPECT_THAT(packets, Contains(Property(
1447 &protos::TracePacket::for_testing,
1448 Property(&protos::TestEvent::str, Eq("payload4")))));
1449 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1450 Property(&protos::TestEvent::str,
1451 Eq("payload5"))))));
1452
1453 consumer->DisableTracing();
1454 producer->WaitForDataSourceStop("data_source");
1455 consumer->WaitForTracingDisabled();
1456}
1457
1458// Test scraping on producer disconnect.
1459TEST_F(TracingServiceImplTest, ScrapeBuffersOnProducerDisconnect) {
1460 svc->SetSMBScrapingEnabled(true);
1461
1462 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1463 consumer->Connect(svc.get());
1464
1465 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1466 producer->Connect(svc.get(), "mock_producer");
1467 ProducerID producer_id = *last_producer_id();
1468 producer->RegisterDataSource("data_source");
1469
1470 TraceConfig trace_config;
1471 trace_config.add_buffers()->set_size_kb(128);
1472 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1473 ds_config->set_name("data_source");
1474 ds_config->set_target_buffer(0);
1475 consumer->EnableTracing(trace_config);
1476
1477 producer->WaitForTracingSetup();
1478 producer->WaitForDataSourceSetup("data_source");
1479 producer->WaitForDataSourceStart("data_source");
1480
1481 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1482 // trace config didn't have the |deferred_start| flag set.
1483 consumer->StartTracing();
1484
1485 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1486 tracing_session()->buffers_index[0]);
1487 WaitForTraceWritersChanged(producer_id);
1488
1489 // Write a few trace packets.
1490 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
1491 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
1492 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
1493
1494 // Disconnect the producer without committing the chunk. This should cause a
1495 // scrape of the SMB. Avoid destroying the ShmemArbiter until writer is
1496 // destroyed.
1497 auto shmem_arbiter = TakeShmemArbiterForProducer(producer_id);
1498 producer.reset();
1499
1500 // Chunk with the packets should have been scraped. The service can't know
1501 // whether the last packet was completed, so shouldn't read it.
1502 auto packets = consumer->ReadBuffers();
1503 EXPECT_THAT(packets, Contains(Property(
1504 &protos::TracePacket::for_testing,
1505 Property(&protos::TestEvent::str, Eq("payload1")))));
1506 EXPECT_THAT(packets, Contains(Property(
1507 &protos::TracePacket::for_testing,
1508 Property(&protos::TestEvent::str, Eq("payload2")))));
1509 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1510 Property(&protos::TestEvent::str,
1511 Eq("payload3"))))));
1512
1513 // Cleanup writer without causing a crash because the producer already went
1514 // away.
1515 static_cast<TraceWriterImpl*>(writer.get())->ResetChunkForTesting();
1516 writer.reset();
1517 shmem_arbiter.reset();
1518
1519 consumer->DisableTracing();
1520 consumer->WaitForTracingDisabled();
1521}
1522
1523TEST_F(TracingServiceImplTest, ScrapeBuffersOnDisable) {
1524 svc->SetSMBScrapingEnabled(true);
1525
1526 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1527 consumer->Connect(svc.get());
1528
1529 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1530 producer->Connect(svc.get(), "mock_producer");
1531 ProducerID producer_id = *last_producer_id();
1532 producer->RegisterDataSource("data_source");
1533
1534 TraceConfig trace_config;
1535 trace_config.add_buffers()->set_size_kb(128);
1536 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1537 ds_config->set_name("data_source");
1538 ds_config->set_target_buffer(0);
1539 consumer->EnableTracing(trace_config);
1540
1541 producer->WaitForTracingSetup();
1542 producer->WaitForDataSourceSetup("data_source");
1543 producer->WaitForDataSourceStart("data_source");
1544
1545 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1546 // trace config didn't have the |deferred_start| flag set.
1547 consumer->StartTracing();
1548
1549 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1550 tracing_session()->buffers_index[0]);
1551 WaitForTraceWritersChanged(producer_id);
1552
1553 // Write a few trace packets.
1554 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
1555 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
1556 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
1557
1558 consumer->DisableTracing();
1559 producer->WaitForDataSourceStop("data_source");
1560 consumer->WaitForTracingDisabled();
1561
1562 // Chunk with the packets should have been scraped. The service can't know
1563 // whether the last packet was completed, so shouldn't read it.
1564 auto packets = consumer->ReadBuffers();
1565 EXPECT_THAT(packets, Contains(Property(
1566 &protos::TracePacket::for_testing,
1567 Property(&protos::TestEvent::str, Eq("payload1")))));
1568 EXPECT_THAT(packets, Contains(Property(
1569 &protos::TracePacket::for_testing,
1570 Property(&protos::TestEvent::str, Eq("payload2")))));
1571 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1572 Property(&protos::TestEvent::str,
1573 Eq("payload3"))))));
1574}
1575
Primiano Tucciff7beab2019-01-09 21:49:20 +00001576TEST_F(TracingServiceImplTest, AbortIfTraceDurationIsTooLong) {
1577 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1578 consumer->Connect(svc.get());
1579
1580 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1581 producer->Connect(svc.get(), "mock_producer");
1582 producer->RegisterDataSource("datasource");
1583
1584 TraceConfig trace_config;
1585 trace_config.add_buffers()->set_size_kb(128);
1586 trace_config.add_data_sources()->mutable_config()->set_name("datasource");
1587 trace_config.set_duration_ms(0x7fffffff);
1588
1589 EXPECT_CALL(*producer, SetupDataSource(_, _)).Times(0);
1590 consumer->EnableTracing(trace_config);
1591
1592 // The trace is aborted immediately, 5s here is just some slack for the thread
1593 // ping-pongs for slow devices.
1594 consumer->WaitForTracingDisabled(5000);
1595}
1596
Eric Secklereaf29ed2019-01-23 09:53:55 +00001597TEST_F(TracingServiceImplTest, GetTraceStats) {
1598 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1599 consumer->Connect(svc.get());
1600
1601 consumer->GetTraceStats();
1602 consumer->WaitForTraceStats(false);
1603
1604 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1605 producer->Connect(svc.get(), "mock_producer");
1606 producer->RegisterDataSource("data_source");
1607
1608 TraceConfig trace_config;
1609 trace_config.add_buffers()->set_size_kb(128);
1610 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1611 ds_config->set_name("data_source");
1612
1613 consumer->EnableTracing(trace_config);
1614 producer->WaitForTracingSetup();
1615 producer->WaitForDataSourceSetup("data_source");
1616 producer->WaitForDataSourceStart("data_source");
1617
1618 consumer->GetTraceStats();
1619 consumer->WaitForTraceStats(true);
1620
1621 consumer->DisableTracing();
1622 producer->WaitForDataSourceStop("data_source");
1623 consumer->WaitForTracingDisabled();
1624}
1625
Eric Seckler7b0c9452019-03-18 13:14:36 +00001626TEST_F(TracingServiceImplTest, ObserveEventsDataSourceInstances) {
1627 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1628 consumer->Connect(svc.get());
1629
1630 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1631 producer->Connect(svc.get(), "mock_producer");
1632 producer->RegisterDataSource("data_source");
1633
1634 TraceConfig trace_config;
1635 trace_config.add_buffers()->set_size_kb(128);
1636 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1637 ds_config->set_name("data_source");
1638
1639 // Start tracing before the consumer is interested in events. The consumer's
1640 // OnObservableEvents() should not be called yet.
1641 consumer->EnableTracing(trace_config);
1642 producer->WaitForTracingSetup();
1643 producer->WaitForDataSourceSetup("data_source");
1644 producer->WaitForDataSourceStart("data_source");
1645
1646 // Calling ObserveEvents should cause an event for the initial instance state.
1647 consumer->ObserveEvents(TracingService::ConsumerEndpoint::
1648 ObservableEventType::kDataSourceInstances);
1649 {
1650 auto events = consumer->WaitForObservableEvents();
1651
1652 ObservableEvents::DataSourceInstanceStateChange change;
1653 change.set_producer_name("mock_producer");
1654 change.set_data_source_name("data_source");
1655 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
1656 DATA_SOURCE_INSTANCE_STATE_STARTED);
1657 EXPECT_EQ(events.instance_state_changes_size(), 1);
1658 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
1659 }
1660
1661 // Disabling should cause an instance state change to STOPPED.
1662 consumer->DisableTracing();
1663
1664 {
1665 auto events = consumer->WaitForObservableEvents();
1666
1667 ObservableEvents::DataSourceInstanceStateChange change;
1668 change.set_producer_name("mock_producer");
1669 change.set_data_source_name("data_source");
1670 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
1671 DATA_SOURCE_INSTANCE_STATE_STOPPED);
1672 EXPECT_EQ(events.instance_state_changes_size(), 1);
1673 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
1674 }
1675
1676 producer->WaitForDataSourceStop("data_source");
1677 consumer->WaitForTracingDisabled();
1678 consumer->FreeBuffers();
1679
1680 // Enable again, this should cause a state change for a new instance to
1681 // its initial state STOPPED.
1682 trace_config.set_deferred_start(true);
1683 consumer->EnableTracing(trace_config);
1684
1685 {
1686 auto events = consumer->WaitForObservableEvents();
1687
1688 ObservableEvents::DataSourceInstanceStateChange change;
1689 change.set_producer_name("mock_producer");
1690 change.set_data_source_name("data_source");
1691 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
1692 DATA_SOURCE_INSTANCE_STATE_STOPPED);
1693 EXPECT_EQ(events.instance_state_changes_size(), 1);
1694 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
1695 }
1696
1697 producer->WaitForDataSourceSetup("data_source");
1698
1699 // Should move the instance into STARTED state and thus cause an event.
1700 consumer->StartTracing();
1701
1702 {
1703 auto events = consumer->WaitForObservableEvents();
1704
1705 ObservableEvents::DataSourceInstanceStateChange change;
1706 change.set_producer_name("mock_producer");
1707 change.set_data_source_name("data_source");
1708 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
1709 DATA_SOURCE_INSTANCE_STATE_STARTED);
1710 EXPECT_EQ(events.instance_state_changes_size(), 1);
1711 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
1712 }
1713
1714 producer->WaitForDataSourceStart("data_source");
1715
1716 // Stop observing events.
1717 consumer->ObserveEvents(
1718 TracingService::ConsumerEndpoint::ObservableEventType::kNone);
1719
1720 // Disabling should now no longer cause events to be sent to the consumer.
1721 consumer->DisableTracing();
1722 producer->WaitForDataSourceStop("data_source");
1723 consumer->WaitForTracingDisabled();
1724}
1725
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00001726} // namespace perfetto