blob: ac11ddff5d29c9993ecc6d5b9e8a7811425504a1 [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
Hector Dearmancdfd85b2019-05-31 16:49:14 +010021#include <gmock/gmock.h>
22#include <gtest/gtest.h>
Primiano Tucci2c5488f2019-06-01 03:27:28 +010023#include "perfetto/ext/base/file_utils.h"
24#include "perfetto/ext/base/temp_file.h"
25#include "perfetto/ext/base/utils.h"
26#include "perfetto/ext/tracing/core/consumer.h"
Primiano Tucci2c5488f2019-06-01 03:27:28 +010027#include "perfetto/ext/tracing/core/producer.h"
28#include "perfetto/ext/tracing/core/shared_memory.h"
29#include "perfetto/ext/tracing/core/trace_packet.h"
30#include "perfetto/ext/tracing/core/trace_writer.h"
Primiano Tucci0f9e0222019-06-05 09:36:41 +010031#include "perfetto/tracing/core/data_source_config.h"
32#include "perfetto/tracing/core/data_source_descriptor.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;
Stephen Nusko1393ffd2019-03-22 13:54:58 +000062
63::testing::AssertionResult HasTriggerModeInternal(
64 const std::vector<protos::TracePacket>& packets,
65 protos::TraceConfig::TriggerConfig::TriggerMode mode) {
66 ::testing::StringMatchResultListener matcher_result_string;
67 bool contains = ::testing::ExplainMatchResult(
68 Contains(Property(
69 &protos::TracePacket::trace_config,
70 Property(&protos::TraceConfig::trigger_config,
71 Property(&protos::TraceConfig::TriggerConfig::trigger_mode,
72 Eq(mode))))),
73 packets, &matcher_result_string);
74 if (contains) {
75 return ::testing::AssertionSuccess();
76 }
77 return ::testing::AssertionFailure() << matcher_result_string.str();
78}
79
80MATCHER_P(HasTriggerMode, mode, "") {
81 return HasTriggerModeInternal(arg, mode);
82}
83
Primiano Tucci1a1951d2018-04-04 21:08:16 +020084} // namespace
85
Florian Mayer6a1a4d52018-06-08 16:47:07 +010086class TracingServiceImplTest : public testing::Test {
Sami Kyostila06487a22018-02-27 13:48:38 +000087 public:
Eric Seckler4ff03e52019-03-15 10:10:30 +000088 using DataSourceInstanceState =
89 TracingServiceImpl::DataSourceInstance::DataSourceInstanceState;
90
Florian Mayer6a1a4d52018-06-08 16:47:07 +010091 TracingServiceImplTest() {
Sami Kyostila06487a22018-02-27 13:48:38 +000092 auto shm_factory =
93 std::unique_ptr<SharedMemory::Factory>(new TestSharedMemory::Factory());
Florian Mayer6a1a4d52018-06-08 16:47:07 +010094 svc.reset(static_cast<TracingServiceImpl*>(
95 TracingService::CreateInstance(std::move(shm_factory), &task_runner)
Sami Kyostila06487a22018-02-27 13:48:38 +000096 .release()));
Primiano Tucci9754d0d2018-09-15 12:41:46 +010097 svc->min_write_period_ms_ = 1;
Sami Kyostila06487a22018-02-27 13:48:38 +000098 }
99
Primiano Tuccidca727d2018-04-04 11:31:55 +0200100 std::unique_ptr<MockProducer> CreateMockProducer() {
101 return std::unique_ptr<MockProducer>(
102 new StrictMock<MockProducer>(&task_runner));
103 }
104
105 std::unique_ptr<MockConsumer> CreateMockConsumer() {
106 return std::unique_ptr<MockConsumer>(
107 new StrictMock<MockConsumer>(&task_runner));
108 }
109
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200110 ProducerID* last_producer_id() { return &svc->last_producer_id_; }
111
112 uid_t GetProducerUid(ProducerID producer_id) {
113 return svc->GetProducer(producer_id)->uid_;
114 }
115
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000116 TracingServiceImpl::TracingSession* GetTracingSession(TracingSessionID tsid) {
117 auto* session = svc->GetTracingSession(tsid);
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100118 EXPECT_NE(nullptr, session);
119 return session;
120 }
121
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000122 TracingServiceImpl::TracingSession* tracing_session() {
123 return GetTracingSession(GetTracingSessionID());
124 }
125
126 TracingSessionID GetTracingSessionID() {
127 return svc->last_tracing_session_id_;
128 }
129
Eric Seckler6dc23592018-11-30 10:59:06 +0000130 const std::set<BufferID>& GetAllowedTargetBuffers(ProducerID producer_id) {
131 return svc->GetProducer(producer_id)->allowed_target_buffers_;
132 }
133
Eric Secklerf3f524b2018-12-13 09:09:34 +0000134 const std::map<WriterID, BufferID>& GetWriters(ProducerID producer_id) {
135 return svc->GetProducer(producer_id)->writers_;
136 }
137
Eric Secklera01e28a2019-01-08 11:21:04 +0000138 std::unique_ptr<SharedMemoryArbiterImpl> TakeShmemArbiterForProducer(
139 ProducerID producer_id) {
140 return std::move(svc->GetProducer(producer_id)->inproc_shmem_arbiter_);
141 }
142
Primiano Tuccid52e6272018-04-06 19:06:53 +0200143 size_t GetNumPendingFlushes() {
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100144 return tracing_session()->pending_flushes.size();
145 }
146
147 void WaitForNextSyncMarker() {
148 tracing_session()->last_snapshot_time = base::TimeMillis(0);
149 static int attempt = 0;
150 while (tracing_session()->last_snapshot_time == base::TimeMillis(0)) {
151 auto checkpoint_name = "wait_snapshot_" + std::to_string(attempt++);
152 auto timer_expired = task_runner.CreateCheckpoint(checkpoint_name);
153 task_runner.PostDelayedTask([timer_expired] { timer_expired(); }, 1);
154 task_runner.RunUntilCheckpoint(checkpoint_name);
155 }
Primiano Tuccid52e6272018-04-06 19:06:53 +0200156 }
157
Eric Secklerf3f524b2018-12-13 09:09:34 +0000158 void WaitForTraceWritersChanged(ProducerID producer_id) {
159 static int i = 0;
160 auto checkpoint_name = "writers_changed_" + std::to_string(producer_id) +
161 "_" + std::to_string(i++);
162 auto writers_changed = task_runner.CreateCheckpoint(checkpoint_name);
163 auto writers = GetWriters(producer_id);
164 std::function<void()> task;
165 task = [&task, writers, writers_changed, producer_id, this]() {
166 if (writers != GetWriters(producer_id)) {
167 writers_changed();
168 return;
169 }
170 task_runner.PostDelayedTask(task, 1);
171 };
172 task_runner.PostDelayedTask(task, 1);
173 task_runner.RunUntilCheckpoint(checkpoint_name);
174 }
175
Eric Seckler4ff03e52019-03-15 10:10:30 +0000176 DataSourceInstanceState GetDataSourceInstanceState(const std::string& name) {
177 for (const auto& kv : tracing_session()->data_source_instances) {
178 if (kv.second.data_source_name == name)
179 return kv.second.state;
180 }
181 PERFETTO_FATAL("Can't find data source instance with name %s",
182 name.c_str());
183 }
184
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000185 base::TestTaskRunner task_runner;
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100186 std::unique_ptr<TracingServiceImpl> svc;
Sami Kyostila06487a22018-02-27 13:48:38 +0000187};
188
Hector Dearmanfb4d0732019-05-19 15:44:56 +0100189TEST_F(TracingServiceImplTest, AtMostOneConfig) {
190 std::unique_ptr<MockConsumer> consumer_a = CreateMockConsumer();
191 std::unique_ptr<MockConsumer> consumer_b = CreateMockConsumer();
192
193 consumer_a->Connect(svc.get());
194 consumer_b->Connect(svc.get());
195
196 TraceConfig trace_config_a;
197 trace_config_a.add_buffers()->set_size_kb(128);
198 trace_config_a.set_duration_ms(0);
199 trace_config_a.set_unique_session_name("foo");
200
201 TraceConfig trace_config_b;
202 trace_config_b.add_buffers()->set_size_kb(128);
203 trace_config_b.set_duration_ms(0);
204 trace_config_b.set_unique_session_name("foo");
205
206 consumer_a->EnableTracing(trace_config_a);
207 consumer_b->EnableTracing(trace_config_b);
208
209 // This will stop immediately since it has the same unique session name.
210 consumer_b->WaitForTracingDisabled();
211
212 consumer_a->DisableTracing();
213 consumer_a->WaitForTracingDisabled();
214}
215
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100216TEST_F(TracingServiceImplTest, RegisterAndUnregister) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200217 std::unique_ptr<MockProducer> mock_producer_1 = CreateMockProducer();
218 std::unique_ptr<MockProducer> mock_producer_2 = CreateMockProducer();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000219
Primiano Tuccidca727d2018-04-04 11:31:55 +0200220 mock_producer_1->Connect(svc.get(), "mock_producer_1", 123u /* uid */);
221 mock_producer_2->Connect(svc.get(), "mock_producer_2", 456u /* uid */);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000222
223 ASSERT_EQ(2u, svc->num_producers());
Primiano Tuccidca727d2018-04-04 11:31:55 +0200224 ASSERT_EQ(mock_producer_1->endpoint(), svc->GetProducer(1));
225 ASSERT_EQ(mock_producer_2->endpoint(), svc->GetProducer(2));
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200226 ASSERT_EQ(123u, GetProducerUid(1));
227 ASSERT_EQ(456u, GetProducerUid(2));
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000228
Primiano Tuccidca727d2018-04-04 11:31:55 +0200229 mock_producer_1->RegisterDataSource("foo");
230 mock_producer_2->RegisterDataSource("bar");
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000231
Primiano Tuccidca727d2018-04-04 11:31:55 +0200232 mock_producer_1->UnregisterDataSource("foo");
233 mock_producer_2->UnregisterDataSource("bar");
Primiano Tucci9daa4832018-03-28 23:28:17 +0100234
Primiano Tuccidca727d2018-04-04 11:31:55 +0200235 mock_producer_1.reset();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000236 ASSERT_EQ(1u, svc->num_producers());
237 ASSERT_EQ(nullptr, svc->GetProducer(1));
238
Primiano Tuccidca727d2018-04-04 11:31:55 +0200239 mock_producer_2.reset();
240 ASSERT_EQ(nullptr, svc->GetProducer(2));
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000241
242 ASSERT_EQ(0u, svc->num_producers());
243}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100244
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100245TEST_F(TracingServiceImplTest, EnableAndDisableTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200246 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
247 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +0000248
Primiano Tuccidca727d2018-04-04 11:31:55 +0200249 std::unique_ptr<MockProducer> producer = CreateMockProducer();
250 producer->Connect(svc.get(), "mock_producer");
251 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000252
Sami Kyostila06487a22018-02-27 13:48:38 +0000253 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200254 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +0000255 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200256 ds_config->set_name("data_source");
257 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +0000258
Primiano Tuccidca727d2018-04-04 11:31:55 +0200259 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100260 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200261 producer->WaitForDataSourceStart("data_source");
262
Primiano Tucci674076d2018-10-01 10:41:09 +0100263 // Calling StartTracing() should be a noop (% a DLOG statement) because the
264 // trace config didn't have the |deferred_start| flag set.
265 consumer->StartTracing();
266
Primiano Tuccidca727d2018-04-04 11:31:55 +0200267 consumer->DisableTracing();
268 producer->WaitForDataSourceStop("data_source");
269 consumer->WaitForTracingDisabled();
Sami Kyostila06487a22018-02-27 13:48:38 +0000270}
271
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000272// Creates a tracing session with a START_TRACING trigger and checks that data
273// sources are started only after the service receives a trigger.
274TEST_F(TracingServiceImplTest, StartTracingTriggerDeferredStart) {
275 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
276 consumer->Connect(svc.get());
277
278 std::unique_ptr<MockProducer> producer = CreateMockProducer();
279 producer->Connect(svc.get(), "mock_producer");
280
281 // Create two data sources but enable only one of them.
282 producer->RegisterDataSource("ds_1");
283 producer->RegisterDataSource("ds_2");
284
285 TraceConfig trace_config;
286 trace_config.add_buffers()->set_size_kb(128);
287 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
288 auto* trigger_config = trace_config.mutable_trigger_config();
289 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
290 auto* trigger = trigger_config->add_triggers();
291 trigger->set_name("trigger_name");
292 trigger->set_stop_delay_ms(1);
293
294 trigger_config->set_trigger_timeout_ms(8.64e+7);
295
296 // Make sure we don't get unexpected DataSourceStart() notifications yet.
297 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
298
299 consumer->EnableTracing(trace_config);
300 producer->WaitForTracingSetup();
301
302 producer->WaitForDataSourceSetup("ds_1");
303
304 // The trace won't start until we send the trigger. since we have a
305 // START_TRACING trigger defined.
306 std::vector<std::string> req;
307 req.push_back("trigger_name");
308 producer->endpoint()->ActivateTriggers(req);
309
310 producer->WaitForDataSourceStart("ds_1");
311
312 auto writer1 = producer->CreateTraceWriter("ds_1");
313 producer->WaitForFlush(writer1.get());
314
315 producer->WaitForDataSourceStop("ds_1");
316 consumer->WaitForTracingDisabled();
317
318 ASSERT_EQ(1u, tracing_session()->received_triggers.size());
319 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100320 tracing_session()->received_triggers[0].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000321
322 EXPECT_THAT(
323 consumer->ReadBuffers(),
324 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
325}
326
327// Creates a tracing session with a START_TRACING trigger and checks that the
328// session is cleaned up when no trigger is received after |trigger_timeout_ms|.
329TEST_F(TracingServiceImplTest, StartTracingTriggerTimeOut) {
330 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
331 consumer->Connect(svc.get());
332
333 std::unique_ptr<MockProducer> producer = CreateMockProducer();
334 producer->Connect(svc.get(), "mock_producer");
335
336 // Create two data sources but enable only one of them.
337 producer->RegisterDataSource("ds_1");
338 producer->RegisterDataSource("ds_2");
339
340 TraceConfig trace_config;
341 trace_config.add_buffers()->set_size_kb(128);
342 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
343 auto* trigger_config = trace_config.mutable_trigger_config();
344 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
345 auto* trigger = trigger_config->add_triggers();
346 trigger->set_name("trigger_name");
347 trigger->set_stop_delay_ms(8.64e+7);
348
349 trigger_config->set_trigger_timeout_ms(1);
350
351 // Make sure we don't get unexpected DataSourceStart() notifications yet.
352 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
353
354 consumer->EnableTracing(trace_config);
355 producer->WaitForTracingSetup();
356
357 producer->WaitForDataSourceSetup("ds_1");
358
359 // The trace won't start until we send the trigger. since we have a
360 // START_TRACING trigger defined. This is where we'd expect to have an
361 // ActivateTriggers call to the producer->endpoint().
362
363 producer->WaitForDataSourceStop("ds_1");
364 consumer->WaitForTracingDisabled();
365 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
366}
367
368// Creates a tracing session with a START_TRACING trigger and checks that
369// the session is not started when the configured trigger producer is different
370// than the producer that sent the trigger.
371TEST_F(TracingServiceImplTest, StartTracingTriggerDifferentProducer) {
372 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
373 consumer->Connect(svc.get());
374
375 std::unique_ptr<MockProducer> producer = CreateMockProducer();
376 producer->Connect(svc.get(), "mock_producer");
377
378 // Create two data sources but enable only one of them.
379 producer->RegisterDataSource("ds_1");
380 producer->RegisterDataSource("ds_2");
381
382 TraceConfig trace_config;
383 trace_config.add_buffers()->set_size_kb(128);
384 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
385 auto* trigger_config = trace_config.mutable_trigger_config();
386 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
387 auto* trigger = trigger_config->add_triggers();
388 trigger->set_name("trigger_name");
389 trigger->set_stop_delay_ms(8.64e+7);
390 trigger->set_producer_name_regex("correct_name");
391
392 trigger_config->set_trigger_timeout_ms(1);
393
394 // Make sure we don't get unexpected DataSourceStart() notifications yet.
395 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
396
397 consumer->EnableTracing(trace_config);
398 producer->WaitForTracingSetup();
399
400 producer->WaitForDataSourceSetup("ds_1");
401
402 // The trace won't start until we send the trigger called "trigger_name"
403 // coming from a producer called "correct_name", since we have a
404 // START_TRACING trigger defined. This is where we'd expect to have an
405 // ActivateTriggers call to the producer->endpoint(), but we send the trigger
406 // from a different producer so it is ignored.
407 std::vector<std::string> req;
408 req.push_back("trigger_name");
409 producer->endpoint()->ActivateTriggers(req);
410
411 producer->WaitForDataSourceStop("ds_1");
412 consumer->WaitForTracingDisabled();
413 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
414}
415
416// Creates a tracing session with a START_TRACING trigger and checks that the
417// session is started when the trigger is received from the correct producer.
418TEST_F(TracingServiceImplTest, StartTracingTriggerCorrectProducer) {
419 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
420 consumer->Connect(svc.get());
421
422 std::unique_ptr<MockProducer> producer = CreateMockProducer();
423 producer->Connect(svc.get(), "mock_producer");
424
425 // Create two data sources but enable only one of them.
426 producer->RegisterDataSource("ds_1");
427 producer->RegisterDataSource("ds_2");
428
429 TraceConfig trace_config;
430 trace_config.add_buffers()->set_size_kb(128);
431 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
432 auto* trigger_config = trace_config.mutable_trigger_config();
433 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
434 auto* trigger = trigger_config->add_triggers();
435 trigger->set_name("trigger_name");
436 trigger->set_stop_delay_ms(1);
437 trigger->set_producer_name_regex("mock_produc[e-r]+");
438
439 trigger_config->set_trigger_timeout_ms(8.64e+7);
440
441 consumer->EnableTracing(trace_config);
442 producer->WaitForTracingSetup();
443
444 producer->WaitForDataSourceSetup("ds_1");
445
446 // Start the trace at this point with ActivateTriggers.
447 std::vector<std::string> req;
448 req.push_back("trigger_name");
449 producer->endpoint()->ActivateTriggers(req);
450
451 producer->WaitForDataSourceStart("ds_1");
452
453 auto writer = producer->CreateTraceWriter("ds_1");
454 producer->WaitForFlush(writer.get());
455
456 producer->WaitForDataSourceStop("ds_1");
457 consumer->WaitForTracingDisabled();
458 EXPECT_THAT(
459 consumer->ReadBuffers(),
460 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
461}
462
463// Creates a tracing session with a START_TRACING trigger and checks that the
464// session is cleaned up even when a different trigger is received.
465TEST_F(TracingServiceImplTest, StartTracingTriggerDifferentTrigger) {
466 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
467 consumer->Connect(svc.get());
468
469 std::unique_ptr<MockProducer> producer = CreateMockProducer();
470 producer->Connect(svc.get(), "mock_producer");
471
472 // Create two data sources but enable only one of them.
473 producer->RegisterDataSource("ds_1");
474 producer->RegisterDataSource("ds_2");
475
476 TraceConfig trace_config;
477 trace_config.add_buffers()->set_size_kb(128);
478 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
479 auto* trigger_config = trace_config.mutable_trigger_config();
480 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
481 auto* trigger = trigger_config->add_triggers();
482 trigger->set_name("trigger_name");
483 trigger->set_stop_delay_ms(8.64e+7);
484
485 trigger_config->set_trigger_timeout_ms(1);
486
487 // Make sure we don't get unexpected DataSourceStart() notifications yet.
488 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
489
490 consumer->EnableTracing(trace_config);
491 producer->WaitForTracingSetup();
492
493 producer->WaitForDataSourceSetup("ds_1");
494
495 // The trace won't start until we send the trigger called "trigger_name",
496 // since we have a START_TRACING trigger defined. This is where we'd expect to
497 // have an ActivateTriggers call to the producer->endpoint(), but we send a
498 // different trigger.
499 std::vector<std::string> req;
500 req.push_back("not_correct_trigger");
501 producer->endpoint()->ActivateTriggers(req);
502
503 producer->WaitForDataSourceStop("ds_1");
504 consumer->WaitForTracingDisabled();
505 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
506}
507
508// Creates a tracing session with a START_TRACING trigger and checks that any
509// trigger can start the TracingSession.
510TEST_F(TracingServiceImplTest, StartTracingTriggerMultipleTriggers) {
511 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
512 consumer->Connect(svc.get());
513
514 std::unique_ptr<MockProducer> producer = CreateMockProducer();
515 producer->Connect(svc.get(), "mock_producer");
516
517 // Create two data sources but enable only one of them.
518 producer->RegisterDataSource("ds_1");
519 producer->RegisterDataSource("ds_2");
520
521 TraceConfig trace_config;
522 trace_config.add_buffers()->set_size_kb(128);
523 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
524 auto* trigger_config = trace_config.mutable_trigger_config();
525 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
526 auto* trigger = trigger_config->add_triggers();
527 trigger->set_name("trigger_name");
528 trigger->set_stop_delay_ms(1);
529
530 trigger_config->set_trigger_timeout_ms(8.64e+7);
531
532 consumer->EnableTracing(trace_config);
533 producer->WaitForTracingSetup();
534
535 producer->WaitForDataSourceSetup("ds_1");
536
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000537 std::vector<std::string> req;
538 req.push_back("not_correct_trigger");
539 req.push_back("trigger_name");
540 producer->endpoint()->ActivateTriggers(req);
541
542 producer->WaitForDataSourceStart("ds_1");
543
544 auto writer = producer->CreateTraceWriter("ds_1");
545 producer->WaitForFlush(writer.get());
546
547 producer->WaitForDataSourceStop("ds_1");
548 consumer->WaitForTracingDisabled();
549 EXPECT_THAT(
550 consumer->ReadBuffers(),
551 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
552}
553
554// Creates two tracing sessions with a START_TRACING trigger and checks that
555// both are able to be triggered simultaneously.
556TEST_F(TracingServiceImplTest, StartTracingTriggerMultipleTraces) {
557 std::unique_ptr<MockConsumer> consumer_1 = CreateMockConsumer();
558 consumer_1->Connect(svc.get());
559 std::unique_ptr<MockConsumer> consumer_2 = CreateMockConsumer();
560 consumer_2->Connect(svc.get());
561
562 std::unique_ptr<MockProducer> producer = CreateMockProducer();
563 producer->Connect(svc.get(), "mock_producer");
564
565 // Create two data sources but each TracingSession will only enable one of
566 // them.
567 producer->RegisterDataSource("ds_1");
568 producer->RegisterDataSource("ds_2");
569
570 TraceConfig trace_config;
571 trace_config.add_buffers()->set_size_kb(128);
572 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
573 auto* trigger_config = trace_config.mutable_trigger_config();
574 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
575 auto* trigger = trigger_config->add_triggers();
576 trigger->set_name("trigger_name");
577 trigger->set_stop_delay_ms(1);
578
579 trigger_config->set_trigger_timeout_ms(8.64e+7);
580
581 consumer_1->EnableTracing(trace_config);
582 producer->WaitForTracingSetup();
583
584 producer->WaitForDataSourceSetup("ds_1");
585
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000586 auto tracing_session_1_id = GetTracingSessionID();
587
588 (*trace_config.mutable_data_sources())[0].mutable_config()->set_name("ds_2");
589 trigger = trace_config.mutable_trigger_config()->add_triggers();
590 trigger->set_name("trigger_name_2");
591 trigger->set_stop_delay_ms(8.64e+7);
592
593 consumer_2->EnableTracing(trace_config);
594
595 producer->WaitForDataSourceSetup("ds_2");
596
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000597 auto tracing_session_2_id = GetTracingSessionID();
598 EXPECT_NE(tracing_session_1_id, tracing_session_2_id);
599
600 const DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_1");
601 const DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_2");
602
603 std::vector<std::string> req;
604 req.push_back("not_correct_trigger");
605 req.push_back("trigger_name");
606 req.push_back("trigger_name_2");
607 producer->endpoint()->ActivateTriggers(req);
608
609 // The order has to be the same as the triggers or else we're incorrectly wait
610 // on the wrong checkpoint in the |task_runner|.
611 producer->WaitForDataSourceStart("ds_1");
612 producer->WaitForDataSourceStart("ds_2");
613
614 // Now that they've started we can check the triggers they've seen.
615 auto* tracing_session_1 = GetTracingSession(tracing_session_1_id);
616 ASSERT_EQ(1u, tracing_session_1->received_triggers.size());
617 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100618 tracing_session_1->received_triggers[0].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000619
620 // This is actually dependent on the order in which the triggers were received
621 // but there isn't really a better way than iteration order so probably not to
622 // brittle of a test. And this caught a real bug in implementation.
623 auto* tracing_session_2 = GetTracingSession(tracing_session_2_id);
624 ASSERT_EQ(2u, tracing_session_2->received_triggers.size());
625
626 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100627 tracing_session_2->received_triggers[0].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000628
629 EXPECT_EQ("trigger_name_2",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100630 tracing_session_2->received_triggers[1].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000631
632 auto writer1 = producer->CreateTraceWriter("ds_1");
633 auto writer2 = producer->CreateTraceWriter("ds_2");
634
635 // We can't use the standard WaitForX in the MockProducer and MockConsumer
636 // because they assume only a single trace is going on. So we perform our own
637 // expectations and wait at the end for the two consumers to receive
638 // OnTracingDisabled.
639 bool flushed_writer_1 = false;
640 bool flushed_writer_2 = false;
641 auto flush_correct_writer = [&](FlushRequestID flush_req_id,
642 const DataSourceInstanceID* id, size_t) {
643 if (*id == id1) {
644 flushed_writer_1 = true;
645 writer1->Flush();
646 producer->endpoint()->NotifyFlushComplete(flush_req_id);
647 } else if (*id == id2) {
648 flushed_writer_2 = true;
649 writer2->Flush();
650 producer->endpoint()->NotifyFlushComplete(flush_req_id);
651 }
652 };
653 EXPECT_CALL(*producer, Flush(_, _, _))
654 .WillOnce(Invoke(flush_correct_writer))
655 .WillOnce(Invoke(flush_correct_writer));
656
657 auto checkpoint_name = "on_tracing_disabled_consumer_1_and_2";
658 auto on_tracing_disabled = task_runner.CreateCheckpoint(checkpoint_name);
659 std::atomic<size_t> counter(0);
660 EXPECT_CALL(*consumer_1, OnTracingDisabled()).WillOnce(Invoke([&]() {
661 if (++counter == 2u) {
662 on_tracing_disabled();
663 }
664 }));
665 EXPECT_CALL(*consumer_2, OnTracingDisabled()).WillOnce(Invoke([&]() {
666 if (++counter == 2u) {
667 on_tracing_disabled();
668 }
669 }));
670
671 EXPECT_CALL(*producer, StopDataSource(id1));
672 EXPECT_CALL(*producer, StopDataSource(id2));
673
674 task_runner.RunUntilCheckpoint(checkpoint_name, 1000);
675
676 EXPECT_TRUE(flushed_writer_1);
677 EXPECT_TRUE(flushed_writer_2);
678 EXPECT_THAT(
679 consumer_1->ReadBuffers(),
680 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
681 EXPECT_THAT(
682 consumer_2->ReadBuffers(),
683 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
684}
685
Stephen Nusko70ea3302019-04-01 19:44:40 +0100686// Creates a tracing session with a START_TRACING trigger and checks that the
687// received_triggers are emitted as packets.
688TEST_F(TracingServiceImplTest, EmitTriggersWithStartTracingTrigger) {
689 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
690 consumer->Connect(svc.get());
691
692 std::unique_ptr<MockProducer> producer = CreateMockProducer();
693 producer->Connect(svc.get(), "mock_producer", /* uid = */ 123u);
694
695 producer->RegisterDataSource("ds_1");
696
697 TraceConfig trace_config;
698 trace_config.add_buffers()->set_size_kb(128);
699 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
700 auto* trigger_config = trace_config.mutable_trigger_config();
701 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
702 auto* trigger = trigger_config->add_triggers();
703 trigger->set_name("trigger_name");
704 trigger->set_stop_delay_ms(1);
705 trigger->set_producer_name_regex("mock_produc[e-r]+");
706
707 trigger_config->set_trigger_timeout_ms(30000);
708
709 consumer->EnableTracing(trace_config);
710 producer->WaitForTracingSetup();
711 producer->WaitForDataSourceSetup("ds_1");
712
713 // The trace won't start until we send the trigger since we have a
714 // START_TRACING trigger defined.
715 std::vector<std::string> req;
716 req.push_back("trigger_name");
717 req.push_back("trigger_name_2");
718 req.push_back("trigger_name_3");
719 producer->endpoint()->ActivateTriggers(req);
720
721 producer->WaitForDataSourceStart("ds_1");
722 auto writer1 = producer->CreateTraceWriter("ds_1");
723 producer->WaitForFlush(writer1.get());
724 producer->WaitForDataSourceStop("ds_1");
725 consumer->WaitForTracingDisabled();
726
727 ASSERT_EQ(1u, tracing_session()->received_triggers.size());
728 EXPECT_EQ("trigger_name",
729 tracing_session()->received_triggers[0].trigger_name);
730
731 auto packets = consumer->ReadBuffers();
732 EXPECT_THAT(
733 packets,
734 Contains(Property(
735 &protos::TracePacket::trace_config,
736 Property(
737 &protos::TraceConfig::trigger_config,
738 Property(
739 &protos::TraceConfig::TriggerConfig::trigger_mode,
740 Eq(protos::TraceConfig::TriggerConfig::START_TRACING))))));
741 auto expect_received_trigger = [&](const std::string& name) {
742 return Contains(AllOf(
743 Property(
744 &protos::TracePacket::trigger,
745 AllOf(Property(&protos::Trigger::trigger_name, Eq(name)),
Eric Secklerc4024b22019-04-02 15:37:08 +0000746 Property(&protos::Trigger::trusted_producer_uid, Eq(123)),
Stephen Nusko70ea3302019-04-01 19:44:40 +0100747 Property(&protos::Trigger::producer_name,
748 Eq("mock_producer")))),
749 Property(&protos::TracePacket::trusted_packet_sequence_id,
750 Eq(kServicePacketSequenceID))));
751 };
752 EXPECT_THAT(packets, expect_received_trigger("trigger_name"));
753 EXPECT_THAT(packets,
754 ::testing::Not(expect_received_trigger("trigger_name_2")));
755 EXPECT_THAT(packets,
756 ::testing::Not(expect_received_trigger("trigger_name_3")));
757}
758
759// Creates a tracing session with a START_TRACING trigger and checks that the
760// received_triggers are emitted as packets.
761TEST_F(TracingServiceImplTest, EmitTriggersWithStopTracingTrigger) {
762 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
763 consumer->Connect(svc.get());
764
765 std::unique_ptr<MockProducer> producer = CreateMockProducer();
766 producer->Connect(svc.get(), "mock_producer", /* uid = */ 321u);
767
768 producer->RegisterDataSource("ds_1");
769
770 TraceConfig trace_config;
771 trace_config.add_buffers()->set_size_kb(128);
772 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
773 auto* trigger_config = trace_config.mutable_trigger_config();
774 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
775 auto* trigger = trigger_config->add_triggers();
776 trigger->set_name("trigger_name");
777 trigger->set_stop_delay_ms(1);
778 trigger = trigger_config->add_triggers();
779 trigger->set_name("trigger_name_3");
780 trigger->set_stop_delay_ms(30000);
781
782 trigger_config->set_trigger_timeout_ms(30000);
783
784 consumer->EnableTracing(trace_config);
785 producer->WaitForTracingSetup();
786 producer->WaitForDataSourceSetup("ds_1");
787 producer->WaitForDataSourceStart("ds_1");
788
789 // The trace won't start until we send the trigger since we have a
790 // START_TRACING trigger defined.
791 std::vector<std::string> req;
792 req.push_back("trigger_name");
793 req.push_back("trigger_name_2");
794 req.push_back("trigger_name_3");
795 producer->endpoint()->ActivateTriggers(req);
796
797 auto writer1 = producer->CreateTraceWriter("ds_1");
798 producer->WaitForFlush(writer1.get());
799 producer->WaitForDataSourceStop("ds_1");
800 consumer->WaitForTracingDisabled();
801
802 ASSERT_EQ(2u, tracing_session()->received_triggers.size());
803 EXPECT_EQ("trigger_name",
804 tracing_session()->received_triggers[0].trigger_name);
805 EXPECT_EQ("trigger_name_3",
806 tracing_session()->received_triggers[1].trigger_name);
807
808 auto packets = consumer->ReadBuffers();
809 EXPECT_THAT(
810 packets,
811 Contains(Property(
812 &protos::TracePacket::trace_config,
813 Property(
814 &protos::TraceConfig::trigger_config,
815 Property(
816 &protos::TraceConfig::TriggerConfig::trigger_mode,
817 Eq(protos::TraceConfig::TriggerConfig::STOP_TRACING))))));
818
819 auto expect_received_trigger = [&](const std::string& name) {
820 return Contains(AllOf(
821 Property(
822 &protos::TracePacket::trigger,
823 AllOf(Property(&protos::Trigger::trigger_name, Eq(name)),
Eric Secklerc4024b22019-04-02 15:37:08 +0000824 Property(&protos::Trigger::trusted_producer_uid, Eq(321)),
Stephen Nusko70ea3302019-04-01 19:44:40 +0100825 Property(&protos::Trigger::producer_name,
826 Eq("mock_producer")))),
827 Property(&protos::TracePacket::trusted_packet_sequence_id,
828 Eq(kServicePacketSequenceID))));
829 };
830 EXPECT_THAT(packets, expect_received_trigger("trigger_name"));
831 EXPECT_THAT(packets,
832 ::testing::Not(expect_received_trigger("trigger_name_2")));
833 EXPECT_THAT(packets, expect_received_trigger("trigger_name_3"));
834}
835
836// Creates a tracing session with a START_TRACING trigger and checks that the
837// received_triggers are emitted as packets even ones after the initial
838// ReadBuffers() call.
839TEST_F(TracingServiceImplTest, EmitTriggersRepeatedly) {
840 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
841 consumer->Connect(svc.get());
842
843 std::unique_ptr<MockProducer> producer = CreateMockProducer();
844 producer->Connect(svc.get(), "mock_producer");
845
846 // Create two data sources but enable only one of them.
847 producer->RegisterDataSource("ds_1");
848 producer->RegisterDataSource("ds_2");
849
850 TraceConfig trace_config;
851 trace_config.add_buffers()->set_size_kb(128);
852 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
853 auto* trigger_config = trace_config.mutable_trigger_config();
854 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
855 auto* trigger = trigger_config->add_triggers();
856 trigger->set_name("trigger_name");
857 trigger->set_stop_delay_ms(1);
858 trigger = trigger_config->add_triggers();
859 trigger->set_name("trigger_name_2");
860 trigger->set_stop_delay_ms(1);
861
862 trigger_config->set_trigger_timeout_ms(30000);
863
864 auto expect_received_trigger = [&](const std::string& name) {
865 return Contains(
866 AllOf(Property(&protos::TracePacket::trigger,
867 AllOf(Property(&protos::Trigger::trigger_name, Eq(name)),
868 Property(&protos::Trigger::producer_name,
869 Eq("mock_producer")))),
870 Property(&protos::TracePacket::trusted_packet_sequence_id,
871 Eq(kServicePacketSequenceID))));
872 };
873
874 consumer->EnableTracing(trace_config);
875 producer->WaitForTracingSetup();
876 producer->WaitForDataSourceSetup("ds_1");
877 producer->WaitForDataSourceStart("ds_1");
878
879 // The trace won't start until we send the trigger. since we have a
880 // START_TRACING trigger defined.
881 producer->endpoint()->ActivateTriggers({"trigger_name"});
882
883 auto packets = consumer->ReadBuffers();
884 EXPECT_THAT(
885 packets,
886 Contains(Property(
887 &protos::TracePacket::trace_config,
888 Property(
889 &protos::TraceConfig::trigger_config,
890 Property(
891 &protos::TraceConfig::TriggerConfig::trigger_mode,
892 Eq(protos::TraceConfig::TriggerConfig::STOP_TRACING))))));
893 EXPECT_THAT(packets, expect_received_trigger("trigger_name"));
894 EXPECT_THAT(packets,
895 ::testing::Not(expect_received_trigger("trigger_name_2")));
896
897 // Send a new trigger.
898 producer->endpoint()->ActivateTriggers({"trigger_name_2"});
899
900 auto writer1 = producer->CreateTraceWriter("ds_1");
901 producer->WaitForFlush(writer1.get());
902 producer->WaitForDataSourceStop("ds_1");
903 consumer->WaitForTracingDisabled();
904
905 ASSERT_EQ(2u, tracing_session()->received_triggers.size());
906 EXPECT_EQ("trigger_name",
907 tracing_session()->received_triggers[0].trigger_name);
908 EXPECT_EQ("trigger_name_2",
909 tracing_session()->received_triggers[1].trigger_name);
910
911 packets = consumer->ReadBuffers();
912 // We don't rewrite the old trigger.
913 EXPECT_THAT(packets, ::testing::Not(expect_received_trigger("trigger_name")));
914 EXPECT_THAT(packets, expect_received_trigger("trigger_name_2"));
915}
916
Stephen Nuskod95a7512019-03-22 13:59:39 +0000917// Creates a tracing session with a STOP_TRACING trigger and checks that the
918// session is cleaned up after |trigger_timeout_ms|.
919TEST_F(TracingServiceImplTest, StopTracingTriggerTimeout) {
920 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
921 consumer->Connect(svc.get());
922
923 std::unique_ptr<MockProducer> producer = CreateMockProducer();
924 producer->Connect(svc.get(), "mock_producer");
925
926 // Create two data sources but enable only one of them.
927 producer->RegisterDataSource("ds_1");
928 producer->RegisterDataSource("ds_2");
929
930 TraceConfig trace_config;
931 trace_config.add_buffers()->set_size_kb(128);
932 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
933 auto* trigger_config = trace_config.mutable_trigger_config();
934 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
935 auto* trigger = trigger_config->add_triggers();
936 trigger->set_name("trigger_name");
937 trigger->set_stop_delay_ms(8.64e+7);
938
939 trigger_config->set_trigger_timeout_ms(1);
940
941 // Make sure we don't get unexpected DataSourceStart() notifications yet.
942 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
943
944 consumer->EnableTracing(trace_config);
945 producer->WaitForTracingSetup();
946
947 producer->WaitForDataSourceSetup("ds_1");
948 producer->WaitForDataSourceStart("ds_1");
949
950 // The trace won't return data until unless we send a trigger at this point.
951 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
952
953 auto writer = producer->CreateTraceWriter("ds_1");
954 producer->WaitForFlush(writer.get());
955
956 ASSERT_EQ(0u, tracing_session()->received_triggers.size());
957
958 producer->WaitForDataSourceStop("ds_1");
959 consumer->WaitForTracingDisabled();
960 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
961}
962
963// Creates a tracing session with a STOP_TRACING trigger and checks that the
964// session returns data after a trigger is received, but only what is currently
965// in the buffer.
966TEST_F(TracingServiceImplTest, StopTracingTriggerRingBuffer) {
967 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
968 consumer->Connect(svc.get());
969
970 std::unique_ptr<MockProducer> producer = CreateMockProducer();
971 producer->Connect(svc.get(), "mock_producer");
972
973 // Create two data sources but enable only one of them.
974 producer->RegisterDataSource("ds_1");
975 producer->RegisterDataSource("ds_2");
976
977 TraceConfig trace_config;
978 trace_config.add_buffers()->set_size_kb(128);
979 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
980 auto* trigger_config = trace_config.mutable_trigger_config();
981 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
982 auto* trigger = trigger_config->add_triggers();
983 trigger->set_name("trigger_name");
984 trigger->set_stop_delay_ms(1);
985
986 trigger_config->set_trigger_timeout_ms(8.64e+7);
987
988 consumer->EnableTracing(trace_config);
989 producer->WaitForTracingSetup();
990
991 producer->WaitForDataSourceSetup("ds_1");
992 producer->WaitForDataSourceStart("ds_1");
993
Stephen Nuskod95a7512019-03-22 13:59:39 +0000994 // The trace won't return data until unless we send a trigger at this point.
995 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
996
997 // We write into the buffer a large packet which takes up the whole buffer. We
998 // then add a bunch of smaller ones which causes the larger packet to be
999 // dropped. After we activate the session we should only see a bunch of the
1000 // smaller ones.
Eric Secklera883e5f2019-04-02 22:51:29 +00001001 static const size_t kNumTestPackets = 10;
Stephen Nuskod95a7512019-03-22 13:59:39 +00001002 static const char kPayload[] = "1234567890abcdef-";
1003
1004 auto writer = producer->CreateTraceWriter("ds_1");
1005 // Buffer is 1kb so we write a packet which is slightly smaller so it fits in
1006 // the buffer.
1007 const std::string large_payload(1024 * 128 - 20, 'a');
1008 {
1009 auto tp = writer->NewTracePacket();
1010 tp->set_for_testing()->set_str(large_payload.c_str(), large_payload.size());
1011 }
1012
1013 // Now we add a bunch of data before the trigger and after.
Eric Secklera883e5f2019-04-02 22:51:29 +00001014 for (size_t i = 0; i < kNumTestPackets; i++) {
Stephen Nuskod95a7512019-03-22 13:59:39 +00001015 if (i == kNumTestPackets / 2) {
1016 std::vector<std::string> req;
1017 req.push_back("trigger_name");
1018 producer->endpoint()->ActivateTriggers(req);
1019 }
1020 auto tp = writer->NewTracePacket();
1021 std::string payload(kPayload);
1022 payload.append(std::to_string(i));
1023 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
1024 }
1025 producer->WaitForFlush(writer.get());
1026
1027 ASSERT_EQ(1u, tracing_session()->received_triggers.size());
1028 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +01001029 tracing_session()->received_triggers[0].trigger_name);
Stephen Nuskod95a7512019-03-22 13:59:39 +00001030
1031 producer->WaitForDataSourceStop("ds_1");
1032 consumer->WaitForTracingDisabled();
Stephen Nusko70ea3302019-04-01 19:44:40 +01001033
Stephen Nuskod95a7512019-03-22 13:59:39 +00001034 auto packets = consumer->ReadBuffers();
Stephen Nusko70ea3302019-04-01 19:44:40 +01001035 EXPECT_LT(kNumTestPackets, packets.size());
Stephen Nuskod95a7512019-03-22 13:59:39 +00001036 // We expect for the TraceConfig preamble packet to be there correctly and
1037 // then we expect each payload to be there, but not the |large_payload|
1038 // packet.
1039 EXPECT_THAT(packets,
1040 HasTriggerMode(protos::TraceConfig::TriggerConfig::STOP_TRACING));
Eric Secklera883e5f2019-04-02 22:51:29 +00001041 for (size_t i = 0; i < kNumTestPackets; i++) {
Stephen Nuskod95a7512019-03-22 13:59:39 +00001042 std::string payload = kPayload;
1043 payload += std::to_string(i);
1044 EXPECT_THAT(packets, Contains(Property(
1045 &protos::TracePacket::for_testing,
1046 Property(&protos::TestEvent::str, Eq(payload)))));
1047 }
1048
1049 // The large payload was overwritten before we trigger and ReadBuffers so it
1050 // should not be in the returned data.
1051 EXPECT_THAT(packets,
1052 ::testing::Not(Contains(Property(
1053 &protos::TracePacket::for_testing,
1054 Property(&protos::TestEvent::str, Eq(large_payload))))));
1055}
1056
1057// Creates a tracing session with a STOP_TRACING trigger and checks that the
1058// session only cleans up once even with multiple triggers.
1059TEST_F(TracingServiceImplTest, StopTracingTriggerMultipleTriggers) {
1060 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1061 consumer->Connect(svc.get());
1062
1063 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1064 producer->Connect(svc.get(), "mock_producer");
1065
1066 // Create two data sources but enable only one of them.
1067 producer->RegisterDataSource("ds_1");
1068 producer->RegisterDataSource("ds_2");
1069
1070 TraceConfig trace_config;
1071 trace_config.add_buffers()->set_size_kb(128);
1072 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
1073 auto* trigger_config = trace_config.mutable_trigger_config();
1074 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
1075 auto* trigger = trigger_config->add_triggers();
1076 trigger->set_name("trigger_name");
1077 trigger->set_stop_delay_ms(1);
1078 trigger = trigger_config->add_triggers();
1079 trigger->set_name("trigger_name_2");
1080 trigger->set_stop_delay_ms(8.64e+7);
1081
1082 trigger_config->set_trigger_timeout_ms(8.64e+7);
1083
1084 consumer->EnableTracing(trace_config);
1085 producer->WaitForTracingSetup();
1086
1087 producer->WaitForDataSourceSetup("ds_1");
1088 producer->WaitForDataSourceStart("ds_1");
1089
Stephen Nuskod95a7512019-03-22 13:59:39 +00001090 // The trace won't return data until unless we send a trigger at this point.
1091 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
1092
1093 std::vector<std::string> req;
1094 req.push_back("trigger_name");
1095 req.push_back("trigger_name_3");
1096 req.push_back("trigger_name_2");
1097 producer->endpoint()->ActivateTriggers(req);
1098
1099 auto writer = producer->CreateTraceWriter("ds_1");
1100 producer->WaitForFlush(writer.get());
1101
1102 ASSERT_EQ(2u, tracing_session()->received_triggers.size());
1103 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +01001104 tracing_session()->received_triggers[0].trigger_name);
Stephen Nuskod95a7512019-03-22 13:59:39 +00001105 EXPECT_EQ("trigger_name_2",
Stephen Nusko70ea3302019-04-01 19:44:40 +01001106 tracing_session()->received_triggers[1].trigger_name);
Stephen Nuskod95a7512019-03-22 13:59:39 +00001107
1108 producer->WaitForDataSourceStop("ds_1");
1109 consumer->WaitForTracingDisabled();
1110 EXPECT_THAT(consumer->ReadBuffers(),
1111 HasTriggerMode(protos::TraceConfig::TriggerConfig::STOP_TRACING));
1112}
1113
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001114TEST_F(TracingServiceImplTest, LockdownMode) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001115 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1116 consumer->Connect(svc.get());
1117
1118 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1119 producer->Connect(svc.get(), "mock_producer_sameuid", geteuid());
1120 producer->RegisterDataSource("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +00001121
1122 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001123 trace_config.add_buffers()->set_size_kb(128);
1124 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1125 ds_config->set_name("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +00001126 trace_config.set_lockdown_mode(
1127 TraceConfig::LockdownModeOperation::LOCKDOWN_SET);
Primiano Tuccidca727d2018-04-04 11:31:55 +02001128 consumer->EnableTracing(trace_config);
1129
1130 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001131 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001132 producer->WaitForDataSourceStart("data_source");
1133
1134 std::unique_ptr<MockProducer> producer_otheruid = CreateMockProducer();
1135 auto x = svc->ConnectProducer(producer_otheruid.get(), geteuid() + 1,
1136 "mock_producer_ouid");
1137 EXPECT_CALL(*producer_otheruid, OnConnect()).Times(0);
Florian Mayer61c55482018-03-06 14:43:54 +00001138 task_runner.RunUntilIdle();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001139 Mock::VerifyAndClearExpectations(producer_otheruid.get());
Florian Mayer61c55482018-03-06 14:43:54 +00001140
Primiano Tuccidca727d2018-04-04 11:31:55 +02001141 consumer->DisableTracing();
1142 consumer->FreeBuffers();
1143 producer->WaitForDataSourceStop("data_source");
1144 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +00001145
1146 trace_config.set_lockdown_mode(
1147 TraceConfig::LockdownModeOperation::LOCKDOWN_CLEAR);
Primiano Tuccidca727d2018-04-04 11:31:55 +02001148 consumer->EnableTracing(trace_config);
Primiano Tucci674076d2018-10-01 10:41:09 +01001149 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001150 producer->WaitForDataSourceStart("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +00001151
Primiano Tuccidca727d2018-04-04 11:31:55 +02001152 std::unique_ptr<MockProducer> producer_otheruid2 = CreateMockProducer();
1153 producer_otheruid->Connect(svc.get(), "mock_producer_ouid2", geteuid() + 1);
Florian Mayer61c55482018-03-06 14:43:54 +00001154
Primiano Tuccidca727d2018-04-04 11:31:55 +02001155 consumer->DisableTracing();
1156 producer->WaitForDataSourceStop("data_source");
1157 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +00001158}
1159
Oystein Eftevaagcb6e4c82019-03-06 15:38:26 -08001160TEST_F(TracingServiceImplTest, ProducerNameFilterChange) {
1161 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1162 consumer->Connect(svc.get());
1163
1164 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1165 producer1->Connect(svc.get(), "mock_producer_1");
1166 producer1->RegisterDataSource("data_source");
1167
1168 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1169 producer2->Connect(svc.get(), "mock_producer_2");
1170 producer2->RegisterDataSource("data_source");
1171
1172 std::unique_ptr<MockProducer> producer3 = CreateMockProducer();
1173 producer3->Connect(svc.get(), "mock_producer_3");
1174 producer3->RegisterDataSource("data_source");
1175 producer3->RegisterDataSource("unused_data_source");
1176
1177 TraceConfig trace_config;
1178 trace_config.add_buffers()->set_size_kb(128);
1179 auto* data_source = trace_config.add_data_sources();
1180 data_source->mutable_config()->set_name("data_source");
1181 *data_source->add_producer_name_filter() = "mock_producer_1";
1182
1183 // Enable tracing with only mock_producer_1 enabled;
1184 // the rest should not start up.
1185 consumer->EnableTracing(trace_config);
1186
1187 producer1->WaitForTracingSetup();
1188 producer1->WaitForDataSourceSetup("data_source");
1189 producer1->WaitForDataSourceStart("data_source");
1190
1191 EXPECT_CALL(*producer2, OnConnect()).Times(0);
1192 EXPECT_CALL(*producer3, OnConnect()).Times(0);
1193 task_runner.RunUntilIdle();
1194 Mock::VerifyAndClearExpectations(producer2.get());
1195 Mock::VerifyAndClearExpectations(producer3.get());
1196
1197 // Enable mock_producer_2, the third one should still
1198 // not get connected.
1199 *data_source->add_producer_name_filter() = "mock_producer_2";
1200 consumer->ChangeTraceConfig(trace_config);
1201
1202 producer2->WaitForTracingSetup();
1203 producer2->WaitForDataSourceSetup("data_source");
1204 producer2->WaitForDataSourceStart("data_source");
1205
1206 // Enable mock_producer_3 but also try to do an
1207 // unsupported change (adding a new data source);
1208 // mock_producer_3 should get enabled but not
1209 // for the new data source.
1210 *data_source->add_producer_name_filter() = "mock_producer_3";
1211 auto* dummy_data_source = trace_config.add_data_sources();
1212 dummy_data_source->mutable_config()->set_name("unused_data_source");
1213 *dummy_data_source->add_producer_name_filter() = "mock_producer_3";
1214
1215 consumer->ChangeTraceConfig(trace_config);
1216
1217 producer3->WaitForTracingSetup();
1218 EXPECT_CALL(*producer3, SetupDataSource(_, _)).Times(1);
1219 EXPECT_CALL(*producer3, StartDataSource(_, _)).Times(1);
1220 task_runner.RunUntilIdle();
1221 Mock::VerifyAndClearExpectations(producer3.get());
1222
1223 consumer->DisableTracing();
1224 consumer->FreeBuffers();
1225 producer1->WaitForDataSourceStop("data_source");
1226 producer2->WaitForDataSourceStop("data_source");
1227
1228 EXPECT_CALL(*producer3, StopDataSource(_)).Times(1);
1229
1230 consumer->WaitForTracingDisabled();
1231
1232 task_runner.RunUntilIdle();
1233 Mock::VerifyAndClearExpectations(producer3.get());
1234}
1235
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001236TEST_F(TracingServiceImplTest, DisconnectConsumerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001237 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1238 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +00001239
Primiano Tuccidca727d2018-04-04 11:31:55 +02001240 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1241 producer->Connect(svc.get(), "mock_producer");
1242 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001243
Primiano Tuccidca727d2018-04-04 11:31:55 +02001244 TraceConfig trace_config;
1245 trace_config.add_buffers()->set_size_kb(128);
1246 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1247 ds_config->set_name("data_source");
1248 consumer->EnableTracing(trace_config);
1249
1250 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001251 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001252 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001253
1254 // Disconnecting the consumer while tracing should trigger data source
1255 // teardown.
Primiano Tuccidca727d2018-04-04 11:31:55 +02001256 consumer.reset();
1257 producer->WaitForDataSourceStop("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001258}
1259
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001260TEST_F(TracingServiceImplTest, ReconnectProducerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001261 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1262 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +00001263
Primiano Tuccidca727d2018-04-04 11:31:55 +02001264 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1265 producer->Connect(svc.get(), "mock_producer");
1266 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001267
Sami Kyostila06487a22018-02-27 13:48:38 +00001268 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001269 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +00001270 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001271 ds_config->set_name("data_source");
1272 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +00001273
Primiano Tuccidca727d2018-04-04 11:31:55 +02001274 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001275 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001276 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001277
Primiano Tuccidca727d2018-04-04 11:31:55 +02001278 // Disconnecting and reconnecting a producer with a matching data source.
1279 // The Producer should see that data source getting enabled again.
1280 producer.reset();
1281 producer = CreateMockProducer();
1282 producer->Connect(svc.get(), "mock_producer_2");
1283 producer->RegisterDataSource("data_source");
1284 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001285 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001286 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001287}
1288
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001289TEST_F(TracingServiceImplTest, ProducerIDWrapping) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001290 std::vector<std::unique_ptr<MockProducer>> producers;
1291 producers.push_back(nullptr);
Primiano Tucci081d46a2018-02-28 11:09:43 +00001292
Primiano Tuccidca727d2018-04-04 11:31:55 +02001293 auto connect_producer_and_get_id = [&producers,
1294 this](const std::string& name) {
1295 producers.emplace_back(CreateMockProducer());
1296 producers.back()->Connect(svc.get(), "mock_producer_" + name);
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001297 return *last_producer_id();
Primiano Tucci081d46a2018-02-28 11:09:43 +00001298 };
1299
1300 // Connect producers 1-4.
1301 for (ProducerID i = 1; i <= 4; i++)
Primiano Tuccidca727d2018-04-04 11:31:55 +02001302 ASSERT_EQ(i, connect_producer_and_get_id(std::to_string(i)));
Primiano Tucci081d46a2018-02-28 11:09:43 +00001303
1304 // Disconnect producers 1,3.
Primiano Tuccidca727d2018-04-04 11:31:55 +02001305 producers[1].reset();
1306 producers[3].reset();
Primiano Tucci081d46a2018-02-28 11:09:43 +00001307
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001308 *last_producer_id() = kMaxProducerID - 1;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001309 ASSERT_EQ(kMaxProducerID, connect_producer_and_get_id("maxid"));
1310 ASSERT_EQ(1u, connect_producer_and_get_id("1_again"));
1311 ASSERT_EQ(3u, connect_producer_and_get_id("3_again"));
1312 ASSERT_EQ(5u, connect_producer_and_get_id("5"));
1313 ASSERT_EQ(6u, connect_producer_and_get_id("6"));
Primiano Tucci081d46a2018-02-28 11:09:43 +00001314}
1315
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001316// Note: file_write_period_ms is set to a large enough to have exactly one flush
1317// of the tracing buffers (and therefore at most one synchronization section),
1318// unless the test runs unrealistically slowly, or the implementation of the
1319// tracing snapshot packets changes.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001320TEST_F(TracingServiceImplTest, WriteIntoFileAndStopOnMaxSize) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001321 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1322 consumer->Connect(svc.get());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001323
Primiano Tuccidca727d2018-04-04 11:31:55 +02001324 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1325 producer->Connect(svc.get(), "mock_producer");
1326 producer->RegisterDataSource("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001327
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001328 TraceConfig trace_config;
1329 trace_config.add_buffers()->set_size_kb(4096);
1330 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001331 ds_config->set_name("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001332 ds_config->set_target_buffer(0);
1333 trace_config.set_write_into_file(true);
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001334 trace_config.set_file_write_period_ms(100000); // 100s
1335 const uint64_t kMaxFileSize = 1024;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001336 trace_config.set_max_file_size_bytes(kMaxFileSize);
1337 base::TempFile tmp_file = base::TempFile::Create();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001338 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
1339
1340 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001341 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001342 producer->WaitForDataSourceStart("data_source");
1343
Hector Dearman685f7522019-03-12 14:28:56 +00001344 // The preamble packets are:
Hector Dearmane004a572019-05-13 17:51:43 +01001345 // Trace start clocksnapshot
Hector Dearman685f7522019-03-12 14:28:56 +00001346 // Config
1347 // SystemInfo
Hector Dearmane004a572019-05-13 17:51:43 +01001348 // Trace read clocksnapshot
1349 // Trace synchronisation
Eric Seckler667e0852019-06-06 14:56:07 +01001350 static const int kNumPreamblePackets = 5;
Hector Dearmane004a572019-05-13 17:51:43 +01001351 static const int kNumTestPackets = 9;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001352 static const char kPayload[] = "1234567890abcdef-";
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001353
1354 std::unique_ptr<TraceWriter> writer =
Primiano Tuccidca727d2018-04-04 11:31:55 +02001355 producer->CreateTraceWriter("data_source");
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001356 // Tracing service will emit a preamble of packets (a synchronization section,
1357 // followed by a tracing config packet). The preamble and these test packets
1358 // should fit within kMaxFileSize.
1359 for (int i = 0; i < kNumTestPackets; i++) {
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001360 auto tp = writer->NewTracePacket();
1361 std::string payload(kPayload);
1362 payload.append(std::to_string(i));
1363 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
1364 }
1365
1366 // Finally add a packet that overflows kMaxFileSize. This should cause the
1367 // implicit stop of the trace and should *not* be written in the trace.
1368 {
1369 auto tp = writer->NewTracePacket();
1370 char big_payload[kMaxFileSize] = "BIG!";
1371 tp->set_for_testing()->set_str(big_payload, sizeof(big_payload));
1372 }
1373 writer->Flush();
1374 writer.reset();
1375
Primiano Tuccidca727d2018-04-04 11:31:55 +02001376 consumer->DisableTracing();
1377 producer->WaitForDataSourceStop("data_source");
1378 consumer->WaitForTracingDisabled();
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001379
1380 // Verify the contents of the file.
1381 std::string trace_raw;
1382 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
1383 protos::Trace trace;
1384 ASSERT_TRUE(trace.ParseFromString(trace_raw));
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001385
1386 ASSERT_EQ(trace.packet_size(), kNumPreamblePackets + kNumTestPackets);
1387 for (int i = 0; i < kNumTestPackets; i++) {
1388 const protos::TracePacket& tp = trace.packet(kNumPreamblePackets + i);
1389 ASSERT_EQ(kPayload + std::to_string(i++), tp.for_testing().str());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001390 }
Primiano Tuccidca727d2018-04-04 11:31:55 +02001391}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001392
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001393// Test the logic that allows the trace config to set the shm total size and
1394// page size from the trace config. Also check that, if the config doesn't
1395// specify a value we fall back on the hint provided by the producer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001396TEST_F(TracingServiceImplTest, ProducerShmAndPageSizeOverriddenByTraceConfig) {
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001397 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1398 consumer->Connect(svc.get());
1399 const size_t kConfigPageSizesKb[] = /****/ {16, 16, 4, 0, 16, 8, 3, 4096, 4};
1400 const size_t kExpectedPageSizesKb[] = /**/ {16, 16, 4, 4, 16, 8, 4, 64, 4};
1401
1402 const size_t kConfigSizesKb[] = /**/ {0, 16, 0, 20, 32, 7, 0, 96, 4096000};
1403 const size_t kHintSizesKb[] = /****/ {0, 0, 16, 32, 16, 0, 7, 96, 4096000};
1404 const size_t kExpectedSizesKb[] = {
1405 kDefaultShmSizeKb, // Both hint and config are 0, use default.
1406 16, // Hint is 0, use config.
1407 16, // Config is 0, use hint.
1408 20, // Hint is takes precedence over the config.
1409 32, // Ditto, even if config is higher than hint.
1410 kDefaultShmSizeKb, // Config is invalid and hint is 0, use default.
1411 kDefaultShmSizeKb, // Config is 0 and hint is invalid, use default.
1412 kDefaultShmSizeKb, // 96 KB isn't a multiple of the page size (64 KB).
1413 kMaxShmSizeKb // Too big, cap at kMaxShmSize.
1414 };
1415
1416 const size_t kNumProducers = base::ArraySize(kHintSizesKb);
1417 std::unique_ptr<MockProducer> producer[kNumProducers];
1418 for (size_t i = 0; i < kNumProducers; i++) {
1419 auto name = "mock_producer_" + std::to_string(i);
1420 producer[i] = CreateMockProducer();
1421 producer[i]->Connect(svc.get(), name, geteuid(), kHintSizesKb[i] * 1024);
1422 producer[i]->RegisterDataSource("data_source");
1423 }
1424
1425 TraceConfig trace_config;
1426 trace_config.add_buffers()->set_size_kb(128);
1427 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1428 ds_config->set_name("data_source");
1429 for (size_t i = 0; i < kNumProducers; i++) {
1430 auto* producer_config = trace_config.add_producers();
1431 producer_config->set_producer_name("mock_producer_" + std::to_string(i));
Primiano Tucci3cbb10a2018-04-10 17:52:40 +01001432 producer_config->set_shm_size_kb(static_cast<uint32_t>(kConfigSizesKb[i]));
1433 producer_config->set_page_size_kb(
1434 static_cast<uint32_t>(kConfigPageSizesKb[i]));
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001435 }
1436
1437 consumer->EnableTracing(trace_config);
1438 size_t actual_shm_sizes_kb[kNumProducers]{};
1439 size_t actual_page_sizes_kb[kNumProducers]{};
1440 for (size_t i = 0; i < kNumProducers; i++) {
1441 producer[i]->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001442 producer[i]->WaitForDataSourceSetup("data_source");
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001443 actual_shm_sizes_kb[i] =
1444 producer[i]->endpoint()->shared_memory()->size() / 1024;
1445 actual_page_sizes_kb[i] =
1446 producer[i]->endpoint()->shared_buffer_page_size_kb();
1447 }
Primiano Tucci674076d2018-10-01 10:41:09 +01001448 for (size_t i = 0; i < kNumProducers; i++) {
1449 producer[i]->WaitForDataSourceStart("data_source");
1450 }
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001451 ASSERT_THAT(actual_page_sizes_kb, ElementsAreArray(kExpectedPageSizesKb));
1452 ASSERT_THAT(actual_shm_sizes_kb, ElementsAreArray(kExpectedSizesKb));
1453}
1454
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001455TEST_F(TracingServiceImplTest, ExplicitFlush) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001456 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1457 consumer->Connect(svc.get());
1458
1459 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1460 producer->Connect(svc.get(), "mock_producer");
1461 producer->RegisterDataSource("data_source");
1462
1463 TraceConfig trace_config;
1464 trace_config.add_buffers()->set_size_kb(128);
1465 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1466 ds_config->set_name("data_source");
1467
1468 consumer->EnableTracing(trace_config);
1469 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001470 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001471 producer->WaitForDataSourceStart("data_source");
1472
1473 std::unique_ptr<TraceWriter> writer =
1474 producer->CreateTraceWriter("data_source");
1475 {
1476 auto tp = writer->NewTracePacket();
1477 tp->set_for_testing()->set_str("payload");
1478 }
1479
1480 auto flush_request = consumer->Flush();
1481 producer->WaitForFlush(writer.get());
1482 ASSERT_TRUE(flush_request.WaitForReply());
1483
1484 consumer->DisableTracing();
1485 producer->WaitForDataSourceStop("data_source");
1486 consumer->WaitForTracingDisabled();
1487 EXPECT_THAT(
1488 consumer->ReadBuffers(),
1489 Contains(Property(&protos::TracePacket::for_testing,
1490 Property(&protos::TestEvent::str, Eq("payload")))));
1491}
1492
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001493TEST_F(TracingServiceImplTest, ImplicitFlushOnTimedTraces) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001494 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1495 consumer->Connect(svc.get());
1496
1497 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1498 producer->Connect(svc.get(), "mock_producer");
1499 producer->RegisterDataSource("data_source");
1500
1501 TraceConfig trace_config;
1502 trace_config.add_buffers()->set_size_kb(128);
1503 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1504 ds_config->set_name("data_source");
1505 trace_config.set_duration_ms(1);
1506
1507 consumer->EnableTracing(trace_config);
1508 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001509 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001510 producer->WaitForDataSourceStart("data_source");
1511
1512 std::unique_ptr<TraceWriter> writer =
1513 producer->CreateTraceWriter("data_source");
1514 {
1515 auto tp = writer->NewTracePacket();
1516 tp->set_for_testing()->set_str("payload");
1517 }
1518
1519 producer->WaitForFlush(writer.get());
1520
1521 producer->WaitForDataSourceStop("data_source");
1522 consumer->WaitForTracingDisabled();
1523
1524 EXPECT_THAT(
1525 consumer->ReadBuffers(),
1526 Contains(Property(&protos::TracePacket::for_testing,
1527 Property(&protos::TestEvent::str, Eq("payload")))));
1528}
1529
1530// Tests the monotonic semantic of flush request IDs, i.e., once a producer
1531// acks flush request N, all flush requests <= N are considered successful and
1532// acked to the consumer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001533TEST_F(TracingServiceImplTest, BatchFlushes) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001534 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1535 consumer->Connect(svc.get());
1536
1537 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1538 producer->Connect(svc.get(), "mock_producer");
1539 producer->RegisterDataSource("data_source");
1540
1541 TraceConfig trace_config;
1542 trace_config.add_buffers()->set_size_kb(128);
1543 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1544 ds_config->set_name("data_source");
1545
1546 consumer->EnableTracing(trace_config);
1547 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001548 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001549 producer->WaitForDataSourceStart("data_source");
1550
1551 std::unique_ptr<TraceWriter> writer =
1552 producer->CreateTraceWriter("data_source");
1553 {
1554 auto tp = writer->NewTracePacket();
1555 tp->set_for_testing()->set_str("payload");
1556 }
1557
1558 auto flush_req_1 = consumer->Flush();
1559 auto flush_req_2 = consumer->Flush();
1560 auto flush_req_3 = consumer->Flush();
1561
1562 // We'll deliberately let the 4th flush request timeout. Use a lower timeout
1563 // to keep test time short.
1564 auto flush_req_4 = consumer->Flush(/*timeout_ms=*/10);
1565 ASSERT_EQ(4u, GetNumPendingFlushes());
1566
1567 // Make the producer reply only to the 3rd flush request.
1568 testing::InSequence seq;
Eric Secklera01e28a2019-01-08 11:21:04 +00001569 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 1.
1570 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 2.
1571 producer->WaitForFlush(writer.get()); // Reply only to flush 3.
1572 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 4.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001573
1574 // Even if the producer explicily replied only to flush ID == 3, all the
1575 // previous flushed < 3 should be implicitly acked.
1576 ASSERT_TRUE(flush_req_1.WaitForReply());
1577 ASSERT_TRUE(flush_req_2.WaitForReply());
1578 ASSERT_TRUE(flush_req_3.WaitForReply());
1579
1580 // At this point flush id == 4 should still be pending and should fail because
1581 // of reaching its timeout.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001582 ASSERT_FALSE(flush_req_4.WaitForReply());
1583
1584 consumer->DisableTracing();
1585 producer->WaitForDataSourceStop("data_source");
1586 consumer->WaitForTracingDisabled();
1587 EXPECT_THAT(
1588 consumer->ReadBuffers(),
1589 Contains(Property(&protos::TracePacket::for_testing,
1590 Property(&protos::TestEvent::str, Eq("payload")))));
1591}
1592
Primiano Tuccicaa57802018-11-25 11:07:07 +00001593TEST_F(TracingServiceImplTest, PeriodicFlush) {
1594 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1595 consumer->Connect(svc.get());
1596
1597 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1598 producer->Connect(svc.get(), "mock_producer");
1599 producer->RegisterDataSource("data_source");
1600
1601 TraceConfig trace_config;
1602 trace_config.add_buffers()->set_size_kb(128);
1603 trace_config.set_flush_period_ms(1);
1604 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1605 ds_config->set_name("data_source");
1606
1607 consumer->EnableTracing(trace_config);
1608 producer->WaitForTracingSetup();
1609 producer->WaitForDataSourceSetup("data_source");
1610 producer->WaitForDataSourceStart("data_source");
1611
1612 std::unique_ptr<TraceWriter> writer =
1613 producer->CreateTraceWriter("data_source");
1614
1615 const int kNumFlushes = 3;
1616 auto checkpoint = task_runner.CreateCheckpoint("all_flushes_done");
1617 int flushes_seen = 0;
1618 EXPECT_CALL(*producer, Flush(_, _, _))
1619 .WillRepeatedly(Invoke([&producer, &writer, &flushes_seen, checkpoint](
1620 FlushRequestID flush_req_id,
1621 const DataSourceInstanceID*, size_t) {
1622 {
1623 auto tp = writer->NewTracePacket();
1624 char payload[32];
1625 sprintf(payload, "f_%d", flushes_seen);
1626 tp->set_for_testing()->set_str(payload);
1627 }
1628 writer->Flush();
1629 producer->endpoint()->NotifyFlushComplete(flush_req_id);
1630 if (++flushes_seen == kNumFlushes)
1631 checkpoint();
1632 }));
1633 task_runner.RunUntilCheckpoint("all_flushes_done");
1634
1635 consumer->DisableTracing();
1636 producer->WaitForDataSourceStop("data_source");
1637 consumer->WaitForTracingDisabled();
1638 auto trace_packets = consumer->ReadBuffers();
1639 for (int i = 0; i < kNumFlushes; i++) {
1640 EXPECT_THAT(trace_packets,
1641 Contains(Property(&protos::TracePacket::for_testing,
1642 Property(&protos::TestEvent::str,
1643 Eq("f_" + std::to_string(i))))));
1644 }
1645}
1646
Ryan Savitski33868d52019-05-13 10:56:14 +01001647TEST_F(TracingServiceImplTest, PeriodicClearIncrementalState) {
1648 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1649 consumer->Connect(svc.get());
1650 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1651 producer->Connect(svc.get(), "mock_producer");
1652
1653 // Incremental data source that expects to receive the clear.
1654 producer->RegisterDataSource("ds_incremental1", false, false,
1655 /*handles_incremental_state_clear=*/true);
1656
1657 // Incremental data source that expects to receive the clear.
1658 producer->RegisterDataSource("ds_incremental2", false, false,
1659 /*handles_incremental_state_clear=*/true);
1660
Ryan Savitski0b4008a2019-05-13 17:55:53 +01001661 // Data source that does *not* advertise itself as supporting incremental
1662 // state clears.
Ryan Savitski33868d52019-05-13 10:56:14 +01001663 producer->RegisterDataSource("ds_selfcontained", false, false,
1664 /*handles_incremental_state_clear=*/false);
1665
1666 // Incremental data source that is registered, but won't be active within the
1667 // test's tracing session.
1668 producer->RegisterDataSource("ds_inactive", false, false,
1669 /*handles_incremental_state_clear=*/true);
1670
1671 TraceConfig trace_config;
1672 trace_config.add_buffers()->set_size_kb(128);
1673 trace_config.mutable_incremental_state_config()->set_clear_period_ms(1);
1674 trace_config.add_data_sources()->mutable_config()->set_name(
1675 "ds_selfcontained");
1676 trace_config.add_data_sources()->mutable_config()->set_name(
1677 "ds_incremental1");
1678 trace_config.add_data_sources()->mutable_config()->set_name(
1679 "ds_incremental2");
1680
1681 // note: the mocking is very brittle, and has to assume a specific order of
1682 // the data sources' setup/start.
1683 consumer->EnableTracing(trace_config);
1684 producer->WaitForTracingSetup();
1685 producer->WaitForDataSourceSetup("ds_selfcontained");
1686 producer->WaitForDataSourceSetup("ds_incremental1");
1687 producer->WaitForDataSourceSetup("ds_incremental2");
1688 producer->WaitForDataSourceStart("ds_selfcontained");
1689 producer->WaitForDataSourceStart("ds_incremental1");
1690 producer->WaitForDataSourceStart("ds_incremental2");
1691
1692 DataSourceInstanceID ds_incremental1 =
1693 producer->GetDataSourceInstanceId("ds_incremental1");
1694 DataSourceInstanceID ds_incremental2 =
1695 producer->GetDataSourceInstanceId("ds_incremental2");
1696
Ryan Savitskiba8a5f52019-05-14 11:58:21 +01001697 const size_t kNumClears = 3;
Ryan Savitski33868d52019-05-13 10:56:14 +01001698 std::function<void()> checkpoint =
1699 task_runner.CreateCheckpoint("clears_received");
1700 std::vector<std::vector<DataSourceInstanceID>> clears_seen;
1701 EXPECT_CALL(*producer, ClearIncrementalState(_, _))
1702 .WillRepeatedly(Invoke([&clears_seen, &checkpoint](
1703 const DataSourceInstanceID* data_source_ids,
1704 size_t num_data_sources) {
1705 std::vector<DataSourceInstanceID> ds_ids;
1706 for (size_t i = 0; i < num_data_sources; i++) {
1707 ds_ids.push_back(*data_source_ids++);
1708 }
1709 clears_seen.push_back(ds_ids);
1710 if (clears_seen.size() >= kNumClears)
1711 checkpoint();
1712 }));
1713 task_runner.RunUntilCheckpoint("clears_received");
1714
1715 consumer->DisableTracing();
1716
1717 // Assert that the clears were only for the active incremental data sources.
1718 ASSERT_EQ(clears_seen.size(), kNumClears);
1719 for (const std::vector<DataSourceInstanceID>& ds_ids : clears_seen) {
1720 ASSERT_THAT(ds_ids, ElementsAreArray({ds_incremental1, ds_incremental2}));
1721 }
1722}
1723
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001724// Creates a tracing session where some of the data sources set the
1725// |will_notify_on_stop| flag and checks that the OnTracingDisabled notification
1726// to the consumer is delayed until the acks are received.
1727TEST_F(TracingServiceImplTest, OnTracingDisabledWaitsForDataSourceStopAcks) {
1728 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1729 consumer->Connect(svc.get());
1730
1731 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1732 producer->Connect(svc.get(), "mock_producer");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001733 producer->RegisterDataSource("ds_will_ack_1", /*ack_stop=*/true,
1734 /*ack_start=*/true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001735 producer->RegisterDataSource("ds_wont_ack");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001736 producer->RegisterDataSource("ds_will_ack_2", /*ack_stop=*/true,
1737 /*ack_start=*/false);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001738
1739 TraceConfig trace_config;
1740 trace_config.add_buffers()->set_size_kb(128);
1741 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_1");
1742 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1743 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_2");
1744 trace_config.set_duration_ms(1);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001745 trace_config.set_deferred_start(true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001746
1747 consumer->EnableTracing(trace_config);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001748
1749 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1750 DataSourceInstanceState::CONFIGURED);
1751 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1752 DataSourceInstanceState::CONFIGURED);
1753 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1754 DataSourceInstanceState::CONFIGURED);
1755
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001756 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001757
1758 producer->WaitForDataSourceSetup("ds_will_ack_1");
1759 producer->WaitForDataSourceSetup("ds_wont_ack");
1760 producer->WaitForDataSourceSetup("ds_will_ack_2");
1761
Eric Seckler4ff03e52019-03-15 10:10:30 +00001762 DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_will_ack_1");
1763 DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_will_ack_2");
1764
1765 consumer->StartTracing();
1766
1767 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1768 DataSourceInstanceState::STARTING);
1769 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1770 DataSourceInstanceState::STARTED);
1771 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1772 DataSourceInstanceState::STARTED);
1773
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001774 producer->WaitForDataSourceStart("ds_will_ack_1");
1775 producer->WaitForDataSourceStart("ds_wont_ack");
1776 producer->WaitForDataSourceStart("ds_will_ack_2");
1777
Eric Seckler4ff03e52019-03-15 10:10:30 +00001778 producer->endpoint()->NotifyDataSourceStarted(id1);
1779
1780 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1781 DataSourceInstanceState::STARTED);
1782
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001783 std::unique_ptr<TraceWriter> writer =
1784 producer->CreateTraceWriter("ds_wont_ack");
1785 producer->WaitForFlush(writer.get());
1786
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001787 producer->WaitForDataSourceStop("ds_will_ack_1");
1788 producer->WaitForDataSourceStop("ds_wont_ack");
1789 producer->WaitForDataSourceStop("ds_will_ack_2");
1790
Eric Seckler4ff03e52019-03-15 10:10:30 +00001791 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1792 DataSourceInstanceState::STOPPING);
1793 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1794 DataSourceInstanceState::STOPPED);
1795 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1796 DataSourceInstanceState::STOPPING);
1797
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001798 producer->endpoint()->NotifyDataSourceStopped(id1);
1799 producer->endpoint()->NotifyDataSourceStopped(id2);
1800
Eric Seckler4ff03e52019-03-15 10:10:30 +00001801 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1802 DataSourceInstanceState::STOPPED);
1803 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1804 DataSourceInstanceState::STOPPED);
1805
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001806 // Wait for at most half of the service timeout, so that this test fails if
1807 // the service falls back on calling the OnTracingDisabled() because some of
1808 // the expected acks weren't received.
1809 consumer->WaitForTracingDisabled(
1810 TracingServiceImpl::kDataSourceStopTimeoutMs / 2);
1811}
1812
Oystein Eftevaagf250e1c2018-08-23 16:10:52 -07001813// Creates a tracing session where a second data source
1814// is added while the service is waiting for DisableTracing
1815// acks; the service should not enable the new datasource
1816// and should not hit any asserts when the consumer is
1817// subsequently destroyed.
1818TEST_F(TracingServiceImplTest, OnDataSourceAddedWhilePendingDisableAcks) {
1819 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1820 consumer->Connect(svc.get());
1821
1822 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1823 producer->Connect(svc.get(), "mock_producer");
1824 producer->RegisterDataSource("ds_will_ack", /*ack_stop=*/true);
1825
1826 TraceConfig trace_config;
1827 trace_config.add_buffers()->set_size_kb(128);
1828 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack");
1829 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1830
1831 consumer->EnableTracing(trace_config);
1832 producer->WaitForTracingSetup();
1833
1834 consumer->DisableTracing();
1835
1836 producer->RegisterDataSource("ds_wont_ack");
1837
1838 consumer.reset();
1839}
1840
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001841// Similar to OnTracingDisabledWaitsForDataSourceStopAcks, but deliberately
1842// skips the ack and checks that the service invokes the OnTracingDisabled()
1843// after the timeout.
1844TEST_F(TracingServiceImplTest, OnTracingDisabledCalledAnywaysInCaseOfTimeout) {
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001845 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1846 consumer->Connect(svc.get());
1847
1848 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1849 producer->Connect(svc.get(), "mock_producer");
1850 producer->RegisterDataSource("data_source", /*ack_stop=*/true);
1851
1852 TraceConfig trace_config;
1853 trace_config.add_buffers()->set_size_kb(128);
1854 trace_config.add_data_sources()->mutable_config()->set_name("data_source");
1855 trace_config.set_duration_ms(1);
Florian Mayer990e6d72019-06-03 11:34:52 +01001856 trace_config.set_data_source_stop_timeout_ms(1);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001857
1858 consumer->EnableTracing(trace_config);
1859 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001860 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001861 producer->WaitForDataSourceStart("data_source");
1862
1863 std::unique_ptr<TraceWriter> writer =
1864 producer->CreateTraceWriter("data_source");
1865 producer->WaitForFlush(writer.get());
1866
1867 producer->WaitForDataSourceStop("data_source");
1868 consumer->WaitForTracingDisabled();
1869}
1870
Primiano Tucci03de28f2018-08-01 11:29:46 +01001871// Tests the session_id logic. Two data sources in the same tracing session
1872// should see the same session id.
1873TEST_F(TracingServiceImplTest, SessionId) {
1874 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1875 consumer->Connect(svc.get());
1876
1877 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1878 producer1->Connect(svc.get(), "mock_producer1");
1879 producer1->RegisterDataSource("ds_1A");
1880 producer1->RegisterDataSource("ds_1B");
1881
1882 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1883 producer2->Connect(svc.get(), "mock_producer2");
1884 producer2->RegisterDataSource("ds_2A");
1885
1886 testing::InSequence seq;
1887 TracingSessionID last_session_id = 0;
1888 for (int i = 0; i < 3; i++) {
1889 TraceConfig trace_config;
1890 trace_config.add_buffers()->set_size_kb(128);
1891 trace_config.add_data_sources()->mutable_config()->set_name("ds_1A");
1892 trace_config.add_data_sources()->mutable_config()->set_name("ds_1B");
1893 trace_config.add_data_sources()->mutable_config()->set_name("ds_2A");
1894 trace_config.set_duration_ms(1);
1895
1896 consumer->EnableTracing(trace_config);
1897
1898 if (i == 0)
1899 producer1->WaitForTracingSetup();
Primiano Tucci03de28f2018-08-01 11:29:46 +01001900
Primiano Tucci674076d2018-10-01 10:41:09 +01001901 producer1->WaitForDataSourceSetup("ds_1A");
1902 producer1->WaitForDataSourceSetup("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001903 if (i == 0)
1904 producer2->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001905 producer2->WaitForDataSourceSetup("ds_2A");
1906
1907 producer1->WaitForDataSourceStart("ds_1A");
1908 producer1->WaitForDataSourceStart("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001909 producer2->WaitForDataSourceStart("ds_2A");
1910
1911 auto* ds1 = producer1->GetDataSourceInstance("ds_1A");
1912 auto* ds2 = producer1->GetDataSourceInstance("ds_1B");
1913 auto* ds3 = producer2->GetDataSourceInstance("ds_2A");
1914 ASSERT_EQ(ds1->session_id, ds2->session_id);
1915 ASSERT_EQ(ds1->session_id, ds3->session_id);
1916 ASSERT_NE(ds1->session_id, last_session_id);
1917 last_session_id = ds1->session_id;
1918
1919 auto writer1 = producer1->CreateTraceWriter("ds_1A");
1920 producer1->WaitForFlush(writer1.get());
1921
1922 auto writer2 = producer2->CreateTraceWriter("ds_2A");
1923 producer2->WaitForFlush(writer2.get());
1924
1925 producer1->WaitForDataSourceStop("ds_1A");
1926 producer1->WaitForDataSourceStop("ds_1B");
1927 producer2->WaitForDataSourceStop("ds_2A");
1928 consumer->WaitForTracingDisabled();
1929 consumer->FreeBuffers();
1930 }
1931}
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001932
1933// Writes a long trace and then tests that the trace parsed in partitions
1934// derived by the synchronization markers is identical to the whole trace parsed
1935// in one go.
1936TEST_F(TracingServiceImplTest, ResynchronizeTraceStreamUsingSyncMarker) {
1937 // Setup tracing.
1938 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1939 consumer->Connect(svc.get());
1940 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1941 producer->Connect(svc.get(), "mock_producer");
1942 producer->RegisterDataSource("data_source");
1943 TraceConfig trace_config;
1944 trace_config.add_buffers()->set_size_kb(4096);
1945 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1946 ds_config->set_name("data_source");
1947 trace_config.set_write_into_file(true);
1948 trace_config.set_file_write_period_ms(1);
1949 base::TempFile tmp_file = base::TempFile::Create();
1950 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
1951 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001952 producer->WaitForDataSourceSetup("data_source");
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001953 producer->WaitForDataSourceStart("data_source");
1954
1955 // Write some variable length payload, waiting for sync markers every now
1956 // and then.
1957 const int kNumMarkers = 5;
1958 auto writer = producer->CreateTraceWriter("data_source");
1959 for (int i = 1; i <= 100; i++) {
Florian Mayereff98042018-12-10 17:44:44 +00001960 std::string payload(static_cast<size_t>(i), 'A' + (i % 25));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001961 writer->NewTracePacket()->set_for_testing()->set_str(payload.c_str());
1962 if (i % (100 / kNumMarkers) == 0) {
1963 writer->Flush();
1964 WaitForNextSyncMarker();
1965 }
1966 }
1967 writer->Flush();
1968 writer.reset();
1969 consumer->DisableTracing();
1970 producer->WaitForDataSourceStop("data_source");
1971 consumer->WaitForTracingDisabled();
1972
1973 std::string trace_raw;
1974 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
1975
1976 const auto kMarkerSize = sizeof(TracingServiceImpl::kSyncMarker);
1977 const std::string kSyncMarkerStr(
1978 reinterpret_cast<const char*>(TracingServiceImpl::kSyncMarker),
1979 kMarkerSize);
1980
1981 // Read back the trace in partitions derived from the marker.
1982 // The trace should look like this:
1983 // [uid, marker] [event] [event] [uid, marker] [event] [event]
1984 size_t num_markers = 0;
1985 size_t start = 0;
1986 size_t end = 0;
1987 protos::Trace merged_trace;
1988 for (size_t pos = 0; pos != std::string::npos; start = end) {
1989 pos = trace_raw.find(kSyncMarkerStr, pos + 1);
1990 num_markers++;
1991 end = (pos == std::string::npos) ? trace_raw.size() : pos + kMarkerSize;
1992 int size = static_cast<int>(end - start);
1993 ASSERT_GT(size, 0);
1994 protos::Trace trace_partition;
1995 ASSERT_TRUE(trace_partition.ParseFromArray(trace_raw.data() + start, size));
1996 merged_trace.MergeFrom(trace_partition);
1997 }
Lalit Maganti9bdc7ce2018-09-17 15:25:11 +01001998 EXPECT_GE(num_markers, static_cast<size_t>(kNumMarkers));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001999
2000 protos::Trace whole_trace;
2001 ASSERT_TRUE(whole_trace.ParseFromString(trace_raw));
2002
2003 ASSERT_EQ(whole_trace.packet_size(), merged_trace.packet_size());
2004 EXPECT_EQ(whole_trace.SerializeAsString(), merged_trace.SerializeAsString());
2005}
2006
Primiano Tucci674076d2018-10-01 10:41:09 +01002007// Creates a tracing session with |deferred_start| and checks that data sources
2008// are started only after calling StartTracing().
2009TEST_F(TracingServiceImplTest, DeferredStart) {
2010 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2011 consumer->Connect(svc.get());
2012
2013 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2014 producer->Connect(svc.get(), "mock_producer");
2015
2016 // Create two data sources but enable only one of them.
2017 producer->RegisterDataSource("ds_1");
2018 producer->RegisterDataSource("ds_2");
2019
2020 TraceConfig trace_config;
2021 trace_config.add_buffers()->set_size_kb(128);
2022 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
2023 trace_config.set_deferred_start(true);
2024 trace_config.set_duration_ms(1);
2025
2026 consumer->EnableTracing(trace_config);
2027 producer->WaitForTracingSetup();
2028
2029 producer->WaitForDataSourceSetup("ds_1");
2030
2031 // Make sure we don't get unexpected DataSourceStart() notifications yet.
2032 task_runner.RunUntilIdle();
2033
2034 consumer->StartTracing();
2035
2036 producer->WaitForDataSourceStart("ds_1");
2037
Stephen Nusko1393ffd2019-03-22 13:54:58 +00002038 auto writer = producer->CreateTraceWriter("ds_1");
2039 producer->WaitForFlush(writer.get());
Primiano Tucci674076d2018-10-01 10:41:09 +01002040
2041 producer->WaitForDataSourceStop("ds_1");
2042 consumer->WaitForTracingDisabled();
2043}
2044
Eric Secklerd0ac7ca2019-02-06 09:13:45 +00002045TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
2046 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2047 consumer->Connect(svc.get());
2048
2049 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2050 producer1->Connect(svc.get(), "mock_producer1", 123u /* uid */);
2051 producer1->RegisterDataSource("data_source");
2052
2053 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2054 producer2->Connect(svc.get(), "mock_producer2", 456u /* uid */);
2055 producer2->RegisterDataSource("data_source");
2056
2057 TraceConfig trace_config;
2058 trace_config.add_buffers()->set_size_kb(128);
2059 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2060 ds_config->set_name("data_source");
2061
2062 consumer->EnableTracing(trace_config);
2063 producer1->WaitForTracingSetup();
2064 producer1->WaitForDataSourceSetup("data_source");
2065 producer2->WaitForTracingSetup();
2066 producer2->WaitForDataSourceSetup("data_source");
2067 producer1->WaitForDataSourceStart("data_source");
2068 producer2->WaitForDataSourceStart("data_source");
2069
2070 std::unique_ptr<TraceWriter> writer1a =
2071 producer1->CreateTraceWriter("data_source");
2072 std::unique_ptr<TraceWriter> writer1b =
2073 producer1->CreateTraceWriter("data_source");
2074 std::unique_ptr<TraceWriter> writer2a =
2075 producer2->CreateTraceWriter("data_source");
2076 {
2077 auto tp = writer1a->NewTracePacket();
2078 tp->set_for_testing()->set_str("payload1a1");
2079 tp = writer1b->NewTracePacket();
2080 tp->set_for_testing()->set_str("payload1b1");
2081 tp = writer1a->NewTracePacket();
2082 tp->set_for_testing()->set_str("payload1a2");
2083 tp = writer2a->NewTracePacket();
2084 tp->set_for_testing()->set_str("payload2a1");
2085 tp = writer1b->NewTracePacket();
2086 tp->set_for_testing()->set_str("payload1b2");
2087 }
2088
2089 auto flush_request = consumer->Flush();
2090 producer1->WaitForFlush({writer1a.get(), writer1b.get()});
2091 producer2->WaitForFlush(writer2a.get());
2092 ASSERT_TRUE(flush_request.WaitForReply());
2093
2094 consumer->DisableTracing();
2095 producer1->WaitForDataSourceStop("data_source");
2096 producer2->WaitForDataSourceStop("data_source");
2097 consumer->WaitForTracingDisabled();
2098 auto packets = consumer->ReadBuffers();
2099 EXPECT_THAT(
2100 packets,
2101 Contains(AllOf(
2102 Property(&protos::TracePacket::for_testing,
2103 Property(&protos::TestEvent::str, Eq("payload1a1"))),
2104 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2105 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
2106 EXPECT_THAT(
2107 packets,
2108 Contains(AllOf(
2109 Property(&protos::TracePacket::for_testing,
2110 Property(&protos::TestEvent::str, Eq("payload1a2"))),
2111 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2112 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
2113 EXPECT_THAT(
2114 packets,
2115 Contains(AllOf(
2116 Property(&protos::TracePacket::for_testing,
2117 Property(&protos::TestEvent::str, Eq("payload1b1"))),
2118 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2119 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
2120 EXPECT_THAT(
2121 packets,
2122 Contains(AllOf(
2123 Property(&protos::TracePacket::for_testing,
2124 Property(&protos::TestEvent::str, Eq("payload1b2"))),
2125 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2126 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
2127 EXPECT_THAT(
2128 packets,
2129 Contains(AllOf(
2130 Property(&protos::TracePacket::for_testing,
2131 Property(&protos::TestEvent::str, Eq("payload2a1"))),
2132 Property(&protos::TracePacket::trusted_uid, Eq(456)),
2133 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(4u)))));
2134}
2135
Eric Seckler6dc23592018-11-30 10:59:06 +00002136TEST_F(TracingServiceImplTest, AllowedBuffers) {
2137 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2138 consumer->Connect(svc.get());
2139
2140 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2141 producer1->Connect(svc.get(), "mock_producer1");
2142 ProducerID producer1_id = *last_producer_id();
2143 producer1->RegisterDataSource("data_source1");
2144 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2145 producer2->Connect(svc.get(), "mock_producer2");
2146 ProducerID producer2_id = *last_producer_id();
2147 producer2->RegisterDataSource("data_source2.1");
2148 producer2->RegisterDataSource("data_source2.2");
2149 producer2->RegisterDataSource("data_source2.3");
2150
2151 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
2152 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
2153
2154 TraceConfig trace_config;
2155 trace_config.add_buffers()->set_size_kb(128);
2156 trace_config.add_buffers()->set_size_kb(128);
2157 trace_config.add_buffers()->set_size_kb(128);
2158 auto* ds_config1 = trace_config.add_data_sources()->mutable_config();
2159 ds_config1->set_name("data_source1");
2160 ds_config1->set_target_buffer(0);
2161 auto* ds_config21 = trace_config.add_data_sources()->mutable_config();
2162 ds_config21->set_name("data_source2.1");
2163 ds_config21->set_target_buffer(1);
2164 auto* ds_config22 = trace_config.add_data_sources()->mutable_config();
2165 ds_config22->set_name("data_source2.2");
2166 ds_config22->set_target_buffer(2);
2167 auto* ds_config23 = trace_config.add_data_sources()->mutable_config();
2168 ds_config23->set_name("data_source2.3");
2169 ds_config23->set_target_buffer(2); // same buffer as data_source2.2.
2170 consumer->EnableTracing(trace_config);
2171
Primiano Tucci2abd1152018-12-03 17:00:02 +01002172 ASSERT_EQ(3u, tracing_session()->num_buffers());
Eric Seckler6dc23592018-11-30 10:59:06 +00002173 std::set<BufferID> expected_buffers_producer1 = {
2174 tracing_session()->buffers_index[0]};
2175 std::set<BufferID> expected_buffers_producer2 = {
2176 tracing_session()->buffers_index[1], tracing_session()->buffers_index[2]};
2177 EXPECT_EQ(expected_buffers_producer1, GetAllowedTargetBuffers(producer1_id));
2178 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
2179
2180 producer1->WaitForTracingSetup();
2181 producer1->WaitForDataSourceSetup("data_source1");
2182
2183 producer2->WaitForTracingSetup();
2184 producer2->WaitForDataSourceSetup("data_source2.1");
2185 producer2->WaitForDataSourceSetup("data_source2.2");
2186 producer2->WaitForDataSourceSetup("data_source2.3");
2187
2188 producer1->WaitForDataSourceStart("data_source1");
2189 producer2->WaitForDataSourceStart("data_source2.1");
2190 producer2->WaitForDataSourceStart("data_source2.2");
2191 producer2->WaitForDataSourceStart("data_source2.3");
2192
2193 producer2->UnregisterDataSource("data_source2.3");
2194 producer2->WaitForDataSourceStop("data_source2.3");
2195
2196 // Should still be allowed to write to buffers 1 (data_source2.1) and 2
2197 // (data_source2.2).
2198 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
2199
2200 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2201 // trace config didn't have the |deferred_start| flag set.
2202 consumer->StartTracing();
2203
2204 consumer->DisableTracing();
2205 producer1->WaitForDataSourceStop("data_source1");
2206 producer2->WaitForDataSourceStop("data_source2.1");
2207 producer2->WaitForDataSourceStop("data_source2.2");
2208 consumer->WaitForTracingDisabled();
2209
2210 consumer->FreeBuffers();
2211 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
2212 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
2213}
2214
Eric Seckler6aa9ece2018-12-06 16:40:12 +00002215#if !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00002216TEST_F(TracingServiceImplTest, CommitToForbiddenBufferIsDiscarded) {
2217 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2218 consumer->Connect(svc.get());
2219
2220 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2221 producer->Connect(svc.get(), "mock_producer");
2222 ProducerID producer_id = *last_producer_id();
2223 producer->RegisterDataSource("data_source");
2224
2225 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
2226
2227 TraceConfig trace_config;
2228 trace_config.add_buffers()->set_size_kb(128);
2229 trace_config.add_buffers()->set_size_kb(128);
2230 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2231 ds_config->set_name("data_source");
2232 ds_config->set_target_buffer(0);
2233 consumer->EnableTracing(trace_config);
2234
2235 ASSERT_EQ(2u, tracing_session()->num_buffers());
2236 std::set<BufferID> expected_buffers = {tracing_session()->buffers_index[0]};
2237 EXPECT_EQ(expected_buffers, GetAllowedTargetBuffers(producer_id));
2238
2239 producer->WaitForTracingSetup();
2240 producer->WaitForDataSourceSetup("data_source");
2241 producer->WaitForDataSourceStart("data_source");
2242
2243 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2244 // trace config didn't have the |deferred_start| flag set.
2245 consumer->StartTracing();
2246
2247 // Try to write to the correct buffer.
2248 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2249 tracing_session()->buffers_index[0]);
2250 {
2251 auto tp = writer->NewTracePacket();
2252 tp->set_for_testing()->set_str("good_payload");
2253 }
2254
2255 auto flush_request = consumer->Flush();
2256 producer->WaitForFlush(writer.get());
2257 ASSERT_TRUE(flush_request.WaitForReply());
2258
2259 // Try to write to the wrong buffer.
2260 writer = producer->endpoint()->CreateTraceWriter(
2261 tracing_session()->buffers_index[1]);
2262 {
2263 auto tp = writer->NewTracePacket();
2264 tp->set_for_testing()->set_str("bad_payload");
2265 }
2266
2267 flush_request = consumer->Flush();
2268 producer->WaitForFlush(writer.get());
2269 ASSERT_TRUE(flush_request.WaitForReply());
2270
2271 consumer->DisableTracing();
2272 producer->WaitForDataSourceStop("data_source");
2273 consumer->WaitForTracingDisabled();
2274
2275 auto packets = consumer->ReadBuffers();
2276 EXPECT_THAT(packets, Contains(Property(&protos::TracePacket::for_testing,
2277 Property(&protos::TestEvent::str,
2278 Eq("good_payload")))));
2279 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2280 Property(&protos::TestEvent::str,
2281 Eq("bad_payload"))))));
2282
2283 consumer->FreeBuffers();
2284 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
2285}
Eric Seckler6aa9ece2018-12-06 16:40:12 +00002286#endif // !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00002287
Eric Secklerf3f524b2018-12-13 09:09:34 +00002288TEST_F(TracingServiceImplTest, RegisterAndUnregisterTraceWriter) {
2289 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2290 consumer->Connect(svc.get());
2291
2292 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2293 producer->Connect(svc.get(), "mock_producer");
2294 ProducerID producer_id = *last_producer_id();
2295 producer->RegisterDataSource("data_source");
2296
2297 EXPECT_TRUE(GetWriters(producer_id).empty());
2298
2299 TraceConfig trace_config;
2300 trace_config.add_buffers()->set_size_kb(128);
2301 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2302 ds_config->set_name("data_source");
2303 ds_config->set_target_buffer(0);
2304 consumer->EnableTracing(trace_config);
2305
2306 producer->WaitForTracingSetup();
2307 producer->WaitForDataSourceSetup("data_source");
2308 producer->WaitForDataSourceStart("data_source");
2309
2310 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2311 // trace config didn't have the |deferred_start| flag set.
2312 consumer->StartTracing();
2313
2314 // Creating the trace writer should register it with the service.
2315 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2316 tracing_session()->buffers_index[0]);
2317
2318 WaitForTraceWritersChanged(producer_id);
2319
2320 std::map<WriterID, BufferID> expected_writers;
2321 expected_writers[writer->writer_id()] = tracing_session()->buffers_index[0];
2322 EXPECT_EQ(expected_writers, GetWriters(producer_id));
2323
2324 // Verify writing works.
2325 {
2326 auto tp = writer->NewTracePacket();
2327 tp->set_for_testing()->set_str("payload");
2328 }
2329
2330 auto flush_request = consumer->Flush();
2331 producer->WaitForFlush(writer.get());
2332 ASSERT_TRUE(flush_request.WaitForReply());
2333
2334 // Destroying the writer should unregister it.
2335 writer.reset();
2336 WaitForTraceWritersChanged(producer_id);
2337 EXPECT_TRUE(GetWriters(producer_id).empty());
2338
2339 consumer->DisableTracing();
2340 producer->WaitForDataSourceStop("data_source");
2341 consumer->WaitForTracingDisabled();
2342
2343 auto packets = consumer->ReadBuffers();
2344 EXPECT_THAT(packets, Contains(Property(
2345 &protos::TracePacket::for_testing,
2346 Property(&protos::TestEvent::str, Eq("payload")))));
2347}
2348
Eric Secklera01e28a2019-01-08 11:21:04 +00002349TEST_F(TracingServiceImplTest, ScrapeBuffersOnFlush) {
2350 svc->SetSMBScrapingEnabled(true);
2351
2352 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2353 consumer->Connect(svc.get());
2354
2355 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2356 producer->Connect(svc.get(), "mock_producer");
2357 ProducerID producer_id = *last_producer_id();
2358 producer->RegisterDataSource("data_source");
2359
2360 TraceConfig trace_config;
2361 trace_config.add_buffers()->set_size_kb(128);
2362 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2363 ds_config->set_name("data_source");
2364 ds_config->set_target_buffer(0);
2365 consumer->EnableTracing(trace_config);
2366
2367 producer->WaitForTracingSetup();
2368 producer->WaitForDataSourceSetup("data_source");
2369 producer->WaitForDataSourceStart("data_source");
2370
2371 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2372 // trace config didn't have the |deferred_start| flag set.
2373 consumer->StartTracing();
2374
2375 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2376 tracing_session()->buffers_index[0]);
2377 WaitForTraceWritersChanged(producer_id);
2378
2379 // Write a few trace packets.
2380 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2381 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2382 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2383
2384 // Flush but don't actually flush the chunk from TraceWriter.
2385 auto flush_request = consumer->Flush();
2386 producer->WaitForFlush(nullptr, /*reply=*/true);
2387 ASSERT_TRUE(flush_request.WaitForReply());
2388
2389 // Chunk with the packets should have been scraped. The service can't know
2390 // whether the last packet was completed, so shouldn't read it.
2391 auto packets = consumer->ReadBuffers();
2392 EXPECT_THAT(packets, Contains(Property(
2393 &protos::TracePacket::for_testing,
2394 Property(&protos::TestEvent::str, Eq("payload1")))));
2395 EXPECT_THAT(packets, Contains(Property(
2396 &protos::TracePacket::for_testing,
2397 Property(&protos::TestEvent::str, Eq("payload2")))));
2398 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2399 Property(&protos::TestEvent::str,
2400 Eq("payload3"))))));
2401
2402 // Write some more packets.
2403 writer->NewTracePacket()->set_for_testing()->set_str("payload4");
2404 writer->NewTracePacket()->set_for_testing()->set_str("payload5");
2405
2406 // Don't reply to flush, causing a timeout. This should scrape again.
2407 flush_request = consumer->Flush(/*timeout=*/100);
2408 producer->WaitForFlush(nullptr, /*reply=*/false);
2409 ASSERT_FALSE(flush_request.WaitForReply());
2410
2411 // Chunk with the packets should have been scraped again, overriding the
2412 // original one. Again, the last packet should be ignored and the first two
2413 // should not be read twice.
2414 packets = consumer->ReadBuffers();
2415 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2416 Property(&protos::TestEvent::str,
2417 Eq("payload1"))))));
2418 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2419 Property(&protos::TestEvent::str,
2420 Eq("payload2"))))));
2421 EXPECT_THAT(packets, Contains(Property(
2422 &protos::TracePacket::for_testing,
2423 Property(&protos::TestEvent::str, Eq("payload3")))));
2424 EXPECT_THAT(packets, Contains(Property(
2425 &protos::TracePacket::for_testing,
2426 Property(&protos::TestEvent::str, Eq("payload4")))));
2427 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2428 Property(&protos::TestEvent::str,
2429 Eq("payload5"))))));
2430
2431 consumer->DisableTracing();
2432 producer->WaitForDataSourceStop("data_source");
2433 consumer->WaitForTracingDisabled();
2434}
2435
Sami Kyostilaf5ad4642019-05-16 10:46:15 +01002436TEST_F(TracingServiceImplTest, ScrapeBuffersFromAnotherThread) {
2437 // This test verifies that there are no reported TSAN races while scraping
2438 // buffers from a producer which is actively writing more trace data
2439 // concurrently.
2440 svc->SetSMBScrapingEnabled(true);
2441
2442 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2443 consumer->Connect(svc.get());
2444
2445 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2446 producer->Connect(svc.get(), "mock_producer");
2447 ProducerID producer_id = *last_producer_id();
2448 producer->RegisterDataSource("data_source");
2449
2450 TraceConfig trace_config;
2451 trace_config.add_buffers()->set_size_kb(128);
2452 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2453 ds_config->set_name("data_source");
2454 ds_config->set_target_buffer(0);
2455 consumer->EnableTracing(trace_config);
2456
2457 producer->WaitForTracingSetup();
2458 producer->WaitForDataSourceSetup("data_source");
2459 producer->WaitForDataSourceStart("data_source");
2460 consumer->StartTracing();
2461
2462 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2463 tracing_session()->buffers_index[0]);
2464 WaitForTraceWritersChanged(producer_id);
2465
2466 constexpr int kPacketCount = 10;
2467 std::atomic<int> packets_written{};
2468 std::thread writer_thread([&] {
2469 for (int i = 0; i < kPacketCount; i++) {
2470 writer->NewTracePacket()->set_for_testing()->set_str("payload");
2471 packets_written.store(i, std::memory_order_relaxed);
2472 }
2473 });
2474
2475 // Wait until the thread has had some time to write some packets.
2476 while (packets_written.load(std::memory_order_relaxed) < kPacketCount / 2)
2477 base::SleepMicroseconds(5000);
2478
2479 // Disabling tracing will trigger scraping.
2480 consumer->DisableTracing();
2481 writer_thread.join();
2482
2483 // Because we don't synchronize with the producer thread, we can't make any
2484 // guarantees about the number of packets we will successfully read. We just
2485 // verify that no TSAN races are reported.
2486 consumer->ReadBuffers();
2487
2488 producer->WaitForDataSourceStop("data_source");
2489 consumer->WaitForTracingDisabled();
2490}
2491
Eric Secklera01e28a2019-01-08 11:21:04 +00002492// Test scraping on producer disconnect.
2493TEST_F(TracingServiceImplTest, ScrapeBuffersOnProducerDisconnect) {
2494 svc->SetSMBScrapingEnabled(true);
2495
2496 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2497 consumer->Connect(svc.get());
2498
2499 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2500 producer->Connect(svc.get(), "mock_producer");
2501 ProducerID producer_id = *last_producer_id();
2502 producer->RegisterDataSource("data_source");
2503
2504 TraceConfig trace_config;
2505 trace_config.add_buffers()->set_size_kb(128);
2506 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2507 ds_config->set_name("data_source");
2508 ds_config->set_target_buffer(0);
2509 consumer->EnableTracing(trace_config);
2510
2511 producer->WaitForTracingSetup();
2512 producer->WaitForDataSourceSetup("data_source");
2513 producer->WaitForDataSourceStart("data_source");
2514
2515 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2516 // trace config didn't have the |deferred_start| flag set.
2517 consumer->StartTracing();
2518
2519 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2520 tracing_session()->buffers_index[0]);
2521 WaitForTraceWritersChanged(producer_id);
2522
2523 // Write a few trace packets.
2524 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2525 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2526 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2527
2528 // Disconnect the producer without committing the chunk. This should cause a
2529 // scrape of the SMB. Avoid destroying the ShmemArbiter until writer is
2530 // destroyed.
2531 auto shmem_arbiter = TakeShmemArbiterForProducer(producer_id);
2532 producer.reset();
2533
2534 // Chunk with the packets should have been scraped. The service can't know
2535 // whether the last packet was completed, so shouldn't read it.
2536 auto packets = consumer->ReadBuffers();
2537 EXPECT_THAT(packets, Contains(Property(
2538 &protos::TracePacket::for_testing,
2539 Property(&protos::TestEvent::str, Eq("payload1")))));
2540 EXPECT_THAT(packets, Contains(Property(
2541 &protos::TracePacket::for_testing,
2542 Property(&protos::TestEvent::str, Eq("payload2")))));
2543 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2544 Property(&protos::TestEvent::str,
2545 Eq("payload3"))))));
2546
2547 // Cleanup writer without causing a crash because the producer already went
2548 // away.
2549 static_cast<TraceWriterImpl*>(writer.get())->ResetChunkForTesting();
2550 writer.reset();
2551 shmem_arbiter.reset();
2552
2553 consumer->DisableTracing();
2554 consumer->WaitForTracingDisabled();
2555}
2556
2557TEST_F(TracingServiceImplTest, ScrapeBuffersOnDisable) {
2558 svc->SetSMBScrapingEnabled(true);
2559
2560 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2561 consumer->Connect(svc.get());
2562
2563 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2564 producer->Connect(svc.get(), "mock_producer");
2565 ProducerID producer_id = *last_producer_id();
2566 producer->RegisterDataSource("data_source");
2567
2568 TraceConfig trace_config;
2569 trace_config.add_buffers()->set_size_kb(128);
2570 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2571 ds_config->set_name("data_source");
2572 ds_config->set_target_buffer(0);
2573 consumer->EnableTracing(trace_config);
2574
2575 producer->WaitForTracingSetup();
2576 producer->WaitForDataSourceSetup("data_source");
2577 producer->WaitForDataSourceStart("data_source");
2578
2579 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2580 // trace config didn't have the |deferred_start| flag set.
2581 consumer->StartTracing();
2582
2583 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2584 tracing_session()->buffers_index[0]);
2585 WaitForTraceWritersChanged(producer_id);
2586
2587 // Write a few trace packets.
2588 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2589 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2590 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2591
2592 consumer->DisableTracing();
2593 producer->WaitForDataSourceStop("data_source");
2594 consumer->WaitForTracingDisabled();
2595
2596 // Chunk with the packets should have been scraped. The service can't know
2597 // whether the last packet was completed, so shouldn't read it.
2598 auto packets = consumer->ReadBuffers();
2599 EXPECT_THAT(packets, Contains(Property(
2600 &protos::TracePacket::for_testing,
2601 Property(&protos::TestEvent::str, Eq("payload1")))));
2602 EXPECT_THAT(packets, Contains(Property(
2603 &protos::TracePacket::for_testing,
2604 Property(&protos::TestEvent::str, Eq("payload2")))));
2605 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2606 Property(&protos::TestEvent::str,
2607 Eq("payload3"))))));
2608}
2609
Primiano Tucciff7beab2019-01-09 21:49:20 +00002610TEST_F(TracingServiceImplTest, AbortIfTraceDurationIsTooLong) {
2611 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2612 consumer->Connect(svc.get());
2613
2614 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2615 producer->Connect(svc.get(), "mock_producer");
2616 producer->RegisterDataSource("datasource");
2617
2618 TraceConfig trace_config;
2619 trace_config.add_buffers()->set_size_kb(128);
2620 trace_config.add_data_sources()->mutable_config()->set_name("datasource");
2621 trace_config.set_duration_ms(0x7fffffff);
2622
2623 EXPECT_CALL(*producer, SetupDataSource(_, _)).Times(0);
2624 consumer->EnableTracing(trace_config);
2625
2626 // The trace is aborted immediately, 5s here is just some slack for the thread
2627 // ping-pongs for slow devices.
2628 consumer->WaitForTracingDisabled(5000);
2629}
2630
Eric Secklereaf29ed2019-01-23 09:53:55 +00002631TEST_F(TracingServiceImplTest, GetTraceStats) {
2632 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2633 consumer->Connect(svc.get());
2634
2635 consumer->GetTraceStats();
2636 consumer->WaitForTraceStats(false);
2637
2638 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2639 producer->Connect(svc.get(), "mock_producer");
2640 producer->RegisterDataSource("data_source");
2641
2642 TraceConfig trace_config;
2643 trace_config.add_buffers()->set_size_kb(128);
2644 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2645 ds_config->set_name("data_source");
2646
2647 consumer->EnableTracing(trace_config);
2648 producer->WaitForTracingSetup();
2649 producer->WaitForDataSourceSetup("data_source");
2650 producer->WaitForDataSourceStart("data_source");
2651
2652 consumer->GetTraceStats();
2653 consumer->WaitForTraceStats(true);
2654
2655 consumer->DisableTracing();
2656 producer->WaitForDataSourceStop("data_source");
2657 consumer->WaitForTracingDisabled();
2658}
2659
Eric Seckler7b0c9452019-03-18 13:14:36 +00002660TEST_F(TracingServiceImplTest, ObserveEventsDataSourceInstances) {
2661 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2662 consumer->Connect(svc.get());
2663
2664 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2665 producer->Connect(svc.get(), "mock_producer");
2666 producer->RegisterDataSource("data_source");
2667
2668 TraceConfig trace_config;
2669 trace_config.add_buffers()->set_size_kb(128);
2670 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2671 ds_config->set_name("data_source");
2672
2673 // Start tracing before the consumer is interested in events. The consumer's
2674 // OnObservableEvents() should not be called yet.
2675 consumer->EnableTracing(trace_config);
2676 producer->WaitForTracingSetup();
2677 producer->WaitForDataSourceSetup("data_source");
2678 producer->WaitForDataSourceStart("data_source");
2679
2680 // Calling ObserveEvents should cause an event for the initial instance state.
2681 consumer->ObserveEvents(TracingService::ConsumerEndpoint::
2682 ObservableEventType::kDataSourceInstances);
2683 {
2684 auto events = consumer->WaitForObservableEvents();
2685
2686 ObservableEvents::DataSourceInstanceStateChange change;
2687 change.set_producer_name("mock_producer");
2688 change.set_data_source_name("data_source");
2689 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2690 DATA_SOURCE_INSTANCE_STATE_STARTED);
2691 EXPECT_EQ(events.instance_state_changes_size(), 1);
2692 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2693 }
2694
2695 // Disabling should cause an instance state change to STOPPED.
2696 consumer->DisableTracing();
2697
2698 {
2699 auto events = consumer->WaitForObservableEvents();
2700
2701 ObservableEvents::DataSourceInstanceStateChange change;
2702 change.set_producer_name("mock_producer");
2703 change.set_data_source_name("data_source");
2704 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2705 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2706 EXPECT_EQ(events.instance_state_changes_size(), 1);
2707 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2708 }
2709
2710 producer->WaitForDataSourceStop("data_source");
2711 consumer->WaitForTracingDisabled();
2712 consumer->FreeBuffers();
2713
2714 // Enable again, this should cause a state change for a new instance to
2715 // its initial state STOPPED.
2716 trace_config.set_deferred_start(true);
2717 consumer->EnableTracing(trace_config);
2718
2719 {
2720 auto events = consumer->WaitForObservableEvents();
2721
2722 ObservableEvents::DataSourceInstanceStateChange change;
2723 change.set_producer_name("mock_producer");
2724 change.set_data_source_name("data_source");
2725 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2726 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2727 EXPECT_EQ(events.instance_state_changes_size(), 1);
2728 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2729 }
2730
2731 producer->WaitForDataSourceSetup("data_source");
2732
2733 // Should move the instance into STARTED state and thus cause an event.
2734 consumer->StartTracing();
2735
2736 {
2737 auto events = consumer->WaitForObservableEvents();
2738
2739 ObservableEvents::DataSourceInstanceStateChange change;
2740 change.set_producer_name("mock_producer");
2741 change.set_data_source_name("data_source");
2742 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2743 DATA_SOURCE_INSTANCE_STATE_STARTED);
2744 EXPECT_EQ(events.instance_state_changes_size(), 1);
2745 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2746 }
2747
2748 producer->WaitForDataSourceStart("data_source");
2749
2750 // Stop observing events.
2751 consumer->ObserveEvents(
2752 TracingService::ConsumerEndpoint::ObservableEventType::kNone);
2753
2754 // Disabling should now no longer cause events to be sent to the consumer.
2755 consumer->DisableTracing();
2756 producer->WaitForDataSourceStop("data_source");
2757 consumer->WaitForTracingDisabled();
2758}
2759
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002760TEST_F(TracingServiceImplTest, QueryServiceState) {
2761 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2762 consumer->Connect(svc.get());
2763
2764 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2765 producer1->Connect(svc.get(), "producer1");
2766
2767 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2768 producer2->Connect(svc.get(), "producer2");
2769
2770 producer1->RegisterDataSource("common_ds");
2771 producer2->RegisterDataSource("common_ds");
2772
2773 producer1->RegisterDataSource("p1_ds");
2774 producer2->RegisterDataSource("p2_ds");
2775
2776 TracingServiceState svc_state = consumer->QueryServiceState();
2777
Eric Seckler4ffe6c22019-06-05 09:07:16 +01002778 EXPECT_EQ(svc_state.producers_size(), 2);
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002779 EXPECT_EQ(svc_state.producers().at(0).id(), 1);
2780 EXPECT_EQ(svc_state.producers().at(0).name(), "producer1");
2781 EXPECT_EQ(svc_state.producers().at(1).id(), 2);
2782 EXPECT_EQ(svc_state.producers().at(1).name(), "producer2");
2783
Eric Seckler4ffe6c22019-06-05 09:07:16 +01002784 EXPECT_EQ(svc_state.data_sources_size(), 4);
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002785
2786 EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 1);
2787 EXPECT_EQ(svc_state.data_sources().at(0).descriptor().name(), "common_ds");
2788
2789 EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
2790 EXPECT_EQ(svc_state.data_sources().at(1).descriptor().name(), "common_ds");
2791
2792 EXPECT_EQ(svc_state.data_sources().at(2).producer_id(), 1);
2793 EXPECT_EQ(svc_state.data_sources().at(2).descriptor().name(), "p1_ds");
2794
2795 EXPECT_EQ(svc_state.data_sources().at(3).producer_id(), 2);
2796 EXPECT_EQ(svc_state.data_sources().at(3).descriptor().name(), "p2_ds");
2797
2798 // Test that descriptors are cleared when a producer disconnects.
2799 producer1.reset();
2800 svc_state = consumer->QueryServiceState();
2801
Eric Seckler4ffe6c22019-06-05 09:07:16 +01002802 EXPECT_EQ(svc_state.producers_size(), 1);
2803 EXPECT_EQ(svc_state.data_sources_size(), 2);
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002804
2805 EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 2);
2806 EXPECT_EQ(svc_state.data_sources().at(0).descriptor().name(), "common_ds");
2807 EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
2808 EXPECT_EQ(svc_state.data_sources().at(1).descriptor().name(), "p2_ds");
2809}
2810
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00002811} // namespace perfetto