blob: 006738497413dc65caffc0390d4d8e0688cdaf86 [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"
27#include "perfetto/ext/tracing/core/data_source_config.h"
28#include "perfetto/ext/tracing/core/data_source_descriptor.h"
29#include "perfetto/ext/tracing/core/producer.h"
30#include "perfetto/ext/tracing/core/shared_memory.h"
31#include "perfetto/ext/tracing/core/trace_packet.h"
32#include "perfetto/ext/tracing/core/trace_writer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000033#include "src/base/test/test_task_runner.h"
Eric Secklera01e28a2019-01-08 11:21:04 +000034#include "src/tracing/core/shared_memory_arbiter_impl.h"
Eric Secklerf3f524b2018-12-13 09:09:34 +000035#include "src/tracing/core/trace_writer_impl.h"
Primiano Tuccidca727d2018-04-04 11:31:55 +020036#include "src/tracing/test/mock_consumer.h"
37#include "src/tracing/test/mock_producer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000038#include "src/tracing/test/test_shared_memory.h"
39
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010040#include "perfetto/trace/test_event.pbzero.h"
41#include "perfetto/trace/trace.pb.h"
Primiano Tuccidca727d2018-04-04 11:31:55 +020042#include "perfetto/trace/trace_packet.pb.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010043#include "perfetto/trace/trace_packet.pbzero.h"
44
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000045using ::testing::_;
Primiano Tuccidca727d2018-04-04 11:31:55 +020046using ::testing::Contains;
Primiano Tucci1a1951d2018-04-04 21:08:16 +020047using ::testing::ElementsAreArray;
Primiano Tuccidca727d2018-04-04 11:31:55 +020048using ::testing::Eq;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000049using ::testing::InSequence;
Primiano Tucci081d46a2018-02-28 11:09:43 +000050using ::testing::Invoke;
Primiano Tuccidca727d2018-04-04 11:31:55 +020051using ::testing::InvokeWithoutArgs;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000052using ::testing::Mock;
Eric Secklerdd0ad102018-12-06 11:32:04 +000053using ::testing::Not;
Primiano Tuccidca727d2018-04-04 11:31:55 +020054using ::testing::Property;
55using ::testing::StrictMock;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000056
Primiano Tuccidca727d2018-04-04 11:31:55 +020057namespace perfetto {
Sami Kyostila32e0b542018-02-14 08:55:43 +000058
Primiano Tucci1a1951d2018-04-04 21:08:16 +020059namespace {
Florian Mayer6a1a4d52018-06-08 16:47:07 +010060constexpr size_t kDefaultShmSizeKb = TracingServiceImpl::kDefaultShmSize / 1024;
61constexpr size_t kMaxShmSizeKb = TracingServiceImpl::kMaxShmSize / 1024;
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
1350 // Trace stats
1351 static const int kNumPreamblePackets = 6;
1352 static const int kNumTestPackets = 9;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001353 static const char kPayload[] = "1234567890abcdef-";
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001354
1355 std::unique_ptr<TraceWriter> writer =
Primiano Tuccidca727d2018-04-04 11:31:55 +02001356 producer->CreateTraceWriter("data_source");
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001357 // Tracing service will emit a preamble of packets (a synchronization section,
1358 // followed by a tracing config packet). The preamble and these test packets
1359 // should fit within kMaxFileSize.
1360 for (int i = 0; i < kNumTestPackets; i++) {
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001361 auto tp = writer->NewTracePacket();
1362 std::string payload(kPayload);
1363 payload.append(std::to_string(i));
1364 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
1365 }
1366
1367 // Finally add a packet that overflows kMaxFileSize. This should cause the
1368 // implicit stop of the trace and should *not* be written in the trace.
1369 {
1370 auto tp = writer->NewTracePacket();
1371 char big_payload[kMaxFileSize] = "BIG!";
1372 tp->set_for_testing()->set_str(big_payload, sizeof(big_payload));
1373 }
1374 writer->Flush();
1375 writer.reset();
1376
Primiano Tuccidca727d2018-04-04 11:31:55 +02001377 consumer->DisableTracing();
1378 producer->WaitForDataSourceStop("data_source");
1379 consumer->WaitForTracingDisabled();
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001380
1381 // Verify the contents of the file.
1382 std::string trace_raw;
1383 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
1384 protos::Trace trace;
1385 ASSERT_TRUE(trace.ParseFromString(trace_raw));
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001386
1387 ASSERT_EQ(trace.packet_size(), kNumPreamblePackets + kNumTestPackets);
1388 for (int i = 0; i < kNumTestPackets; i++) {
1389 const protos::TracePacket& tp = trace.packet(kNumPreamblePackets + i);
1390 ASSERT_EQ(kPayload + std::to_string(i++), tp.for_testing().str());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001391 }
Primiano Tuccidca727d2018-04-04 11:31:55 +02001392}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001393
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001394// Test the logic that allows the trace config to set the shm total size and
1395// page size from the trace config. Also check that, if the config doesn't
1396// specify a value we fall back on the hint provided by the producer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001397TEST_F(TracingServiceImplTest, ProducerShmAndPageSizeOverriddenByTraceConfig) {
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001398 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1399 consumer->Connect(svc.get());
1400 const size_t kConfigPageSizesKb[] = /****/ {16, 16, 4, 0, 16, 8, 3, 4096, 4};
1401 const size_t kExpectedPageSizesKb[] = /**/ {16, 16, 4, 4, 16, 8, 4, 64, 4};
1402
1403 const size_t kConfigSizesKb[] = /**/ {0, 16, 0, 20, 32, 7, 0, 96, 4096000};
1404 const size_t kHintSizesKb[] = /****/ {0, 0, 16, 32, 16, 0, 7, 96, 4096000};
1405 const size_t kExpectedSizesKb[] = {
1406 kDefaultShmSizeKb, // Both hint and config are 0, use default.
1407 16, // Hint is 0, use config.
1408 16, // Config is 0, use hint.
1409 20, // Hint is takes precedence over the config.
1410 32, // Ditto, even if config is higher than hint.
1411 kDefaultShmSizeKb, // Config is invalid and hint is 0, use default.
1412 kDefaultShmSizeKb, // Config is 0 and hint is invalid, use default.
1413 kDefaultShmSizeKb, // 96 KB isn't a multiple of the page size (64 KB).
1414 kMaxShmSizeKb // Too big, cap at kMaxShmSize.
1415 };
1416
1417 const size_t kNumProducers = base::ArraySize(kHintSizesKb);
1418 std::unique_ptr<MockProducer> producer[kNumProducers];
1419 for (size_t i = 0; i < kNumProducers; i++) {
1420 auto name = "mock_producer_" + std::to_string(i);
1421 producer[i] = CreateMockProducer();
1422 producer[i]->Connect(svc.get(), name, geteuid(), kHintSizesKb[i] * 1024);
1423 producer[i]->RegisterDataSource("data_source");
1424 }
1425
1426 TraceConfig trace_config;
1427 trace_config.add_buffers()->set_size_kb(128);
1428 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1429 ds_config->set_name("data_source");
1430 for (size_t i = 0; i < kNumProducers; i++) {
1431 auto* producer_config = trace_config.add_producers();
1432 producer_config->set_producer_name("mock_producer_" + std::to_string(i));
Primiano Tucci3cbb10a2018-04-10 17:52:40 +01001433 producer_config->set_shm_size_kb(static_cast<uint32_t>(kConfigSizesKb[i]));
1434 producer_config->set_page_size_kb(
1435 static_cast<uint32_t>(kConfigPageSizesKb[i]));
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001436 }
1437
1438 consumer->EnableTracing(trace_config);
1439 size_t actual_shm_sizes_kb[kNumProducers]{};
1440 size_t actual_page_sizes_kb[kNumProducers]{};
1441 for (size_t i = 0; i < kNumProducers; i++) {
1442 producer[i]->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001443 producer[i]->WaitForDataSourceSetup("data_source");
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001444 actual_shm_sizes_kb[i] =
1445 producer[i]->endpoint()->shared_memory()->size() / 1024;
1446 actual_page_sizes_kb[i] =
1447 producer[i]->endpoint()->shared_buffer_page_size_kb();
1448 }
Primiano Tucci674076d2018-10-01 10:41:09 +01001449 for (size_t i = 0; i < kNumProducers; i++) {
1450 producer[i]->WaitForDataSourceStart("data_source");
1451 }
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001452 ASSERT_THAT(actual_page_sizes_kb, ElementsAreArray(kExpectedPageSizesKb));
1453 ASSERT_THAT(actual_shm_sizes_kb, ElementsAreArray(kExpectedSizesKb));
1454}
1455
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001456TEST_F(TracingServiceImplTest, ExplicitFlush) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001457 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1458 consumer->Connect(svc.get());
1459
1460 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1461 producer->Connect(svc.get(), "mock_producer");
1462 producer->RegisterDataSource("data_source");
1463
1464 TraceConfig trace_config;
1465 trace_config.add_buffers()->set_size_kb(128);
1466 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1467 ds_config->set_name("data_source");
1468
1469 consumer->EnableTracing(trace_config);
1470 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001471 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001472 producer->WaitForDataSourceStart("data_source");
1473
1474 std::unique_ptr<TraceWriter> writer =
1475 producer->CreateTraceWriter("data_source");
1476 {
1477 auto tp = writer->NewTracePacket();
1478 tp->set_for_testing()->set_str("payload");
1479 }
1480
1481 auto flush_request = consumer->Flush();
1482 producer->WaitForFlush(writer.get());
1483 ASSERT_TRUE(flush_request.WaitForReply());
1484
1485 consumer->DisableTracing();
1486 producer->WaitForDataSourceStop("data_source");
1487 consumer->WaitForTracingDisabled();
1488 EXPECT_THAT(
1489 consumer->ReadBuffers(),
1490 Contains(Property(&protos::TracePacket::for_testing,
1491 Property(&protos::TestEvent::str, Eq("payload")))));
1492}
1493
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001494TEST_F(TracingServiceImplTest, ImplicitFlushOnTimedTraces) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001495 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1496 consumer->Connect(svc.get());
1497
1498 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1499 producer->Connect(svc.get(), "mock_producer");
1500 producer->RegisterDataSource("data_source");
1501
1502 TraceConfig trace_config;
1503 trace_config.add_buffers()->set_size_kb(128);
1504 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1505 ds_config->set_name("data_source");
1506 trace_config.set_duration_ms(1);
1507
1508 consumer->EnableTracing(trace_config);
1509 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001510 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001511 producer->WaitForDataSourceStart("data_source");
1512
1513 std::unique_ptr<TraceWriter> writer =
1514 producer->CreateTraceWriter("data_source");
1515 {
1516 auto tp = writer->NewTracePacket();
1517 tp->set_for_testing()->set_str("payload");
1518 }
1519
1520 producer->WaitForFlush(writer.get());
1521
1522 producer->WaitForDataSourceStop("data_source");
1523 consumer->WaitForTracingDisabled();
1524
1525 EXPECT_THAT(
1526 consumer->ReadBuffers(),
1527 Contains(Property(&protos::TracePacket::for_testing,
1528 Property(&protos::TestEvent::str, Eq("payload")))));
1529}
1530
1531// Tests the monotonic semantic of flush request IDs, i.e., once a producer
1532// acks flush request N, all flush requests <= N are considered successful and
1533// acked to the consumer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001534TEST_F(TracingServiceImplTest, BatchFlushes) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001535 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1536 consumer->Connect(svc.get());
1537
1538 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1539 producer->Connect(svc.get(), "mock_producer");
1540 producer->RegisterDataSource("data_source");
1541
1542 TraceConfig trace_config;
1543 trace_config.add_buffers()->set_size_kb(128);
1544 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1545 ds_config->set_name("data_source");
1546
1547 consumer->EnableTracing(trace_config);
1548 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001549 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001550 producer->WaitForDataSourceStart("data_source");
1551
1552 std::unique_ptr<TraceWriter> writer =
1553 producer->CreateTraceWriter("data_source");
1554 {
1555 auto tp = writer->NewTracePacket();
1556 tp->set_for_testing()->set_str("payload");
1557 }
1558
1559 auto flush_req_1 = consumer->Flush();
1560 auto flush_req_2 = consumer->Flush();
1561 auto flush_req_3 = consumer->Flush();
1562
1563 // We'll deliberately let the 4th flush request timeout. Use a lower timeout
1564 // to keep test time short.
1565 auto flush_req_4 = consumer->Flush(/*timeout_ms=*/10);
1566 ASSERT_EQ(4u, GetNumPendingFlushes());
1567
1568 // Make the producer reply only to the 3rd flush request.
1569 testing::InSequence seq;
Eric Secklera01e28a2019-01-08 11:21:04 +00001570 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 1.
1571 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 2.
1572 producer->WaitForFlush(writer.get()); // Reply only to flush 3.
1573 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 4.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001574
1575 // Even if the producer explicily replied only to flush ID == 3, all the
1576 // previous flushed < 3 should be implicitly acked.
1577 ASSERT_TRUE(flush_req_1.WaitForReply());
1578 ASSERT_TRUE(flush_req_2.WaitForReply());
1579 ASSERT_TRUE(flush_req_3.WaitForReply());
1580
1581 // At this point flush id == 4 should still be pending and should fail because
1582 // of reaching its timeout.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001583 ASSERT_FALSE(flush_req_4.WaitForReply());
1584
1585 consumer->DisableTracing();
1586 producer->WaitForDataSourceStop("data_source");
1587 consumer->WaitForTracingDisabled();
1588 EXPECT_THAT(
1589 consumer->ReadBuffers(),
1590 Contains(Property(&protos::TracePacket::for_testing,
1591 Property(&protos::TestEvent::str, Eq("payload")))));
1592}
1593
Primiano Tuccicaa57802018-11-25 11:07:07 +00001594TEST_F(TracingServiceImplTest, PeriodicFlush) {
1595 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1596 consumer->Connect(svc.get());
1597
1598 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1599 producer->Connect(svc.get(), "mock_producer");
1600 producer->RegisterDataSource("data_source");
1601
1602 TraceConfig trace_config;
1603 trace_config.add_buffers()->set_size_kb(128);
1604 trace_config.set_flush_period_ms(1);
1605 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1606 ds_config->set_name("data_source");
1607
1608 consumer->EnableTracing(trace_config);
1609 producer->WaitForTracingSetup();
1610 producer->WaitForDataSourceSetup("data_source");
1611 producer->WaitForDataSourceStart("data_source");
1612
1613 std::unique_ptr<TraceWriter> writer =
1614 producer->CreateTraceWriter("data_source");
1615
1616 const int kNumFlushes = 3;
1617 auto checkpoint = task_runner.CreateCheckpoint("all_flushes_done");
1618 int flushes_seen = 0;
1619 EXPECT_CALL(*producer, Flush(_, _, _))
1620 .WillRepeatedly(Invoke([&producer, &writer, &flushes_seen, checkpoint](
1621 FlushRequestID flush_req_id,
1622 const DataSourceInstanceID*, size_t) {
1623 {
1624 auto tp = writer->NewTracePacket();
1625 char payload[32];
1626 sprintf(payload, "f_%d", flushes_seen);
1627 tp->set_for_testing()->set_str(payload);
1628 }
1629 writer->Flush();
1630 producer->endpoint()->NotifyFlushComplete(flush_req_id);
1631 if (++flushes_seen == kNumFlushes)
1632 checkpoint();
1633 }));
1634 task_runner.RunUntilCheckpoint("all_flushes_done");
1635
1636 consumer->DisableTracing();
1637 producer->WaitForDataSourceStop("data_source");
1638 consumer->WaitForTracingDisabled();
1639 auto trace_packets = consumer->ReadBuffers();
1640 for (int i = 0; i < kNumFlushes; i++) {
1641 EXPECT_THAT(trace_packets,
1642 Contains(Property(&protos::TracePacket::for_testing,
1643 Property(&protos::TestEvent::str,
1644 Eq("f_" + std::to_string(i))))));
1645 }
1646}
1647
Ryan Savitski33868d52019-05-13 10:56:14 +01001648TEST_F(TracingServiceImplTest, PeriodicClearIncrementalState) {
1649 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1650 consumer->Connect(svc.get());
1651 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1652 producer->Connect(svc.get(), "mock_producer");
1653
1654 // Incremental data source that expects to receive the clear.
1655 producer->RegisterDataSource("ds_incremental1", false, false,
1656 /*handles_incremental_state_clear=*/true);
1657
1658 // Incremental data source that expects to receive the clear.
1659 producer->RegisterDataSource("ds_incremental2", false, false,
1660 /*handles_incremental_state_clear=*/true);
1661
Ryan Savitski0b4008a2019-05-13 17:55:53 +01001662 // Data source that does *not* advertise itself as supporting incremental
1663 // state clears.
Ryan Savitski33868d52019-05-13 10:56:14 +01001664 producer->RegisterDataSource("ds_selfcontained", false, false,
1665 /*handles_incremental_state_clear=*/false);
1666
1667 // Incremental data source that is registered, but won't be active within the
1668 // test's tracing session.
1669 producer->RegisterDataSource("ds_inactive", false, false,
1670 /*handles_incremental_state_clear=*/true);
1671
1672 TraceConfig trace_config;
1673 trace_config.add_buffers()->set_size_kb(128);
1674 trace_config.mutable_incremental_state_config()->set_clear_period_ms(1);
1675 trace_config.add_data_sources()->mutable_config()->set_name(
1676 "ds_selfcontained");
1677 trace_config.add_data_sources()->mutable_config()->set_name(
1678 "ds_incremental1");
1679 trace_config.add_data_sources()->mutable_config()->set_name(
1680 "ds_incremental2");
1681
1682 // note: the mocking is very brittle, and has to assume a specific order of
1683 // the data sources' setup/start.
1684 consumer->EnableTracing(trace_config);
1685 producer->WaitForTracingSetup();
1686 producer->WaitForDataSourceSetup("ds_selfcontained");
1687 producer->WaitForDataSourceSetup("ds_incremental1");
1688 producer->WaitForDataSourceSetup("ds_incremental2");
1689 producer->WaitForDataSourceStart("ds_selfcontained");
1690 producer->WaitForDataSourceStart("ds_incremental1");
1691 producer->WaitForDataSourceStart("ds_incremental2");
1692
1693 DataSourceInstanceID ds_incremental1 =
1694 producer->GetDataSourceInstanceId("ds_incremental1");
1695 DataSourceInstanceID ds_incremental2 =
1696 producer->GetDataSourceInstanceId("ds_incremental2");
1697
Ryan Savitskiba8a5f52019-05-14 11:58:21 +01001698 const size_t kNumClears = 3;
Ryan Savitski33868d52019-05-13 10:56:14 +01001699 std::function<void()> checkpoint =
1700 task_runner.CreateCheckpoint("clears_received");
1701 std::vector<std::vector<DataSourceInstanceID>> clears_seen;
1702 EXPECT_CALL(*producer, ClearIncrementalState(_, _))
1703 .WillRepeatedly(Invoke([&clears_seen, &checkpoint](
1704 const DataSourceInstanceID* data_source_ids,
1705 size_t num_data_sources) {
1706 std::vector<DataSourceInstanceID> ds_ids;
1707 for (size_t i = 0; i < num_data_sources; i++) {
1708 ds_ids.push_back(*data_source_ids++);
1709 }
1710 clears_seen.push_back(ds_ids);
1711 if (clears_seen.size() >= kNumClears)
1712 checkpoint();
1713 }));
1714 task_runner.RunUntilCheckpoint("clears_received");
1715
1716 consumer->DisableTracing();
1717
1718 // Assert that the clears were only for the active incremental data sources.
1719 ASSERT_EQ(clears_seen.size(), kNumClears);
1720 for (const std::vector<DataSourceInstanceID>& ds_ids : clears_seen) {
1721 ASSERT_THAT(ds_ids, ElementsAreArray({ds_incremental1, ds_incremental2}));
1722 }
1723}
1724
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001725// Creates a tracing session where some of the data sources set the
1726// |will_notify_on_stop| flag and checks that the OnTracingDisabled notification
1727// to the consumer is delayed until the acks are received.
1728TEST_F(TracingServiceImplTest, OnTracingDisabledWaitsForDataSourceStopAcks) {
1729 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1730 consumer->Connect(svc.get());
1731
1732 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1733 producer->Connect(svc.get(), "mock_producer");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001734 producer->RegisterDataSource("ds_will_ack_1", /*ack_stop=*/true,
1735 /*ack_start=*/true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001736 producer->RegisterDataSource("ds_wont_ack");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001737 producer->RegisterDataSource("ds_will_ack_2", /*ack_stop=*/true,
1738 /*ack_start=*/false);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001739
1740 TraceConfig trace_config;
1741 trace_config.add_buffers()->set_size_kb(128);
1742 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_1");
1743 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1744 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_2");
1745 trace_config.set_duration_ms(1);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001746 trace_config.set_deferred_start(true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001747
1748 consumer->EnableTracing(trace_config);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001749
1750 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1751 DataSourceInstanceState::CONFIGURED);
1752 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1753 DataSourceInstanceState::CONFIGURED);
1754 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1755 DataSourceInstanceState::CONFIGURED);
1756
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001757 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001758
1759 producer->WaitForDataSourceSetup("ds_will_ack_1");
1760 producer->WaitForDataSourceSetup("ds_wont_ack");
1761 producer->WaitForDataSourceSetup("ds_will_ack_2");
1762
Eric Seckler4ff03e52019-03-15 10:10:30 +00001763 DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_will_ack_1");
1764 DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_will_ack_2");
1765
1766 consumer->StartTracing();
1767
1768 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1769 DataSourceInstanceState::STARTING);
1770 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1771 DataSourceInstanceState::STARTED);
1772 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1773 DataSourceInstanceState::STARTED);
1774
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001775 producer->WaitForDataSourceStart("ds_will_ack_1");
1776 producer->WaitForDataSourceStart("ds_wont_ack");
1777 producer->WaitForDataSourceStart("ds_will_ack_2");
1778
Eric Seckler4ff03e52019-03-15 10:10:30 +00001779 producer->endpoint()->NotifyDataSourceStarted(id1);
1780
1781 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1782 DataSourceInstanceState::STARTED);
1783
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001784 std::unique_ptr<TraceWriter> writer =
1785 producer->CreateTraceWriter("ds_wont_ack");
1786 producer->WaitForFlush(writer.get());
1787
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001788 producer->WaitForDataSourceStop("ds_will_ack_1");
1789 producer->WaitForDataSourceStop("ds_wont_ack");
1790 producer->WaitForDataSourceStop("ds_will_ack_2");
1791
Eric Seckler4ff03e52019-03-15 10:10:30 +00001792 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1793 DataSourceInstanceState::STOPPING);
1794 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1795 DataSourceInstanceState::STOPPED);
1796 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1797 DataSourceInstanceState::STOPPING);
1798
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001799 producer->endpoint()->NotifyDataSourceStopped(id1);
1800 producer->endpoint()->NotifyDataSourceStopped(id2);
1801
Eric Seckler4ff03e52019-03-15 10:10:30 +00001802 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1803 DataSourceInstanceState::STOPPED);
1804 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1805 DataSourceInstanceState::STOPPED);
1806
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001807 // Wait for at most half of the service timeout, so that this test fails if
1808 // the service falls back on calling the OnTracingDisabled() because some of
1809 // the expected acks weren't received.
1810 consumer->WaitForTracingDisabled(
1811 TracingServiceImpl::kDataSourceStopTimeoutMs / 2);
1812}
1813
Oystein Eftevaagf250e1c2018-08-23 16:10:52 -07001814// Creates a tracing session where a second data source
1815// is added while the service is waiting for DisableTracing
1816// acks; the service should not enable the new datasource
1817// and should not hit any asserts when the consumer is
1818// subsequently destroyed.
1819TEST_F(TracingServiceImplTest, OnDataSourceAddedWhilePendingDisableAcks) {
1820 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1821 consumer->Connect(svc.get());
1822
1823 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1824 producer->Connect(svc.get(), "mock_producer");
1825 producer->RegisterDataSource("ds_will_ack", /*ack_stop=*/true);
1826
1827 TraceConfig trace_config;
1828 trace_config.add_buffers()->set_size_kb(128);
1829 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack");
1830 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1831
1832 consumer->EnableTracing(trace_config);
1833 producer->WaitForTracingSetup();
1834
1835 consumer->DisableTracing();
1836
1837 producer->RegisterDataSource("ds_wont_ack");
1838
1839 consumer.reset();
1840}
1841
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001842// Similar to OnTracingDisabledWaitsForDataSourceStopAcks, but deliberately
1843// skips the ack and checks that the service invokes the OnTracingDisabled()
1844// after the timeout.
1845TEST_F(TracingServiceImplTest, OnTracingDisabledCalledAnywaysInCaseOfTimeout) {
1846 svc->override_data_source_test_timeout_ms_for_testing = 1;
1847 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1848 consumer->Connect(svc.get());
1849
1850 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1851 producer->Connect(svc.get(), "mock_producer");
1852 producer->RegisterDataSource("data_source", /*ack_stop=*/true);
1853
1854 TraceConfig trace_config;
1855 trace_config.add_buffers()->set_size_kb(128);
1856 trace_config.add_data_sources()->mutable_config()->set_name("data_source");
1857 trace_config.set_duration_ms(1);
1858
1859 consumer->EnableTracing(trace_config);
1860 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001861 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001862 producer->WaitForDataSourceStart("data_source");
1863
1864 std::unique_ptr<TraceWriter> writer =
1865 producer->CreateTraceWriter("data_source");
1866 producer->WaitForFlush(writer.get());
1867
1868 producer->WaitForDataSourceStop("data_source");
1869 consumer->WaitForTracingDisabled();
1870}
1871
Primiano Tucci03de28f2018-08-01 11:29:46 +01001872// Tests the session_id logic. Two data sources in the same tracing session
1873// should see the same session id.
1874TEST_F(TracingServiceImplTest, SessionId) {
1875 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1876 consumer->Connect(svc.get());
1877
1878 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1879 producer1->Connect(svc.get(), "mock_producer1");
1880 producer1->RegisterDataSource("ds_1A");
1881 producer1->RegisterDataSource("ds_1B");
1882
1883 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1884 producer2->Connect(svc.get(), "mock_producer2");
1885 producer2->RegisterDataSource("ds_2A");
1886
1887 testing::InSequence seq;
1888 TracingSessionID last_session_id = 0;
1889 for (int i = 0; i < 3; i++) {
1890 TraceConfig trace_config;
1891 trace_config.add_buffers()->set_size_kb(128);
1892 trace_config.add_data_sources()->mutable_config()->set_name("ds_1A");
1893 trace_config.add_data_sources()->mutable_config()->set_name("ds_1B");
1894 trace_config.add_data_sources()->mutable_config()->set_name("ds_2A");
1895 trace_config.set_duration_ms(1);
1896
1897 consumer->EnableTracing(trace_config);
1898
1899 if (i == 0)
1900 producer1->WaitForTracingSetup();
Primiano Tucci03de28f2018-08-01 11:29:46 +01001901
Primiano Tucci674076d2018-10-01 10:41:09 +01001902 producer1->WaitForDataSourceSetup("ds_1A");
1903 producer1->WaitForDataSourceSetup("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001904 if (i == 0)
1905 producer2->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001906 producer2->WaitForDataSourceSetup("ds_2A");
1907
1908 producer1->WaitForDataSourceStart("ds_1A");
1909 producer1->WaitForDataSourceStart("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001910 producer2->WaitForDataSourceStart("ds_2A");
1911
1912 auto* ds1 = producer1->GetDataSourceInstance("ds_1A");
1913 auto* ds2 = producer1->GetDataSourceInstance("ds_1B");
1914 auto* ds3 = producer2->GetDataSourceInstance("ds_2A");
1915 ASSERT_EQ(ds1->session_id, ds2->session_id);
1916 ASSERT_EQ(ds1->session_id, ds3->session_id);
1917 ASSERT_NE(ds1->session_id, last_session_id);
1918 last_session_id = ds1->session_id;
1919
1920 auto writer1 = producer1->CreateTraceWriter("ds_1A");
1921 producer1->WaitForFlush(writer1.get());
1922
1923 auto writer2 = producer2->CreateTraceWriter("ds_2A");
1924 producer2->WaitForFlush(writer2.get());
1925
1926 producer1->WaitForDataSourceStop("ds_1A");
1927 producer1->WaitForDataSourceStop("ds_1B");
1928 producer2->WaitForDataSourceStop("ds_2A");
1929 consumer->WaitForTracingDisabled();
1930 consumer->FreeBuffers();
1931 }
1932}
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001933
1934// Writes a long trace and then tests that the trace parsed in partitions
1935// derived by the synchronization markers is identical to the whole trace parsed
1936// in one go.
1937TEST_F(TracingServiceImplTest, ResynchronizeTraceStreamUsingSyncMarker) {
1938 // Setup tracing.
1939 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1940 consumer->Connect(svc.get());
1941 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1942 producer->Connect(svc.get(), "mock_producer");
1943 producer->RegisterDataSource("data_source");
1944 TraceConfig trace_config;
1945 trace_config.add_buffers()->set_size_kb(4096);
1946 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1947 ds_config->set_name("data_source");
1948 trace_config.set_write_into_file(true);
1949 trace_config.set_file_write_period_ms(1);
1950 base::TempFile tmp_file = base::TempFile::Create();
1951 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
1952 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001953 producer->WaitForDataSourceSetup("data_source");
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001954 producer->WaitForDataSourceStart("data_source");
1955
1956 // Write some variable length payload, waiting for sync markers every now
1957 // and then.
1958 const int kNumMarkers = 5;
1959 auto writer = producer->CreateTraceWriter("data_source");
1960 for (int i = 1; i <= 100; i++) {
Florian Mayereff98042018-12-10 17:44:44 +00001961 std::string payload(static_cast<size_t>(i), 'A' + (i % 25));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001962 writer->NewTracePacket()->set_for_testing()->set_str(payload.c_str());
1963 if (i % (100 / kNumMarkers) == 0) {
1964 writer->Flush();
1965 WaitForNextSyncMarker();
1966 }
1967 }
1968 writer->Flush();
1969 writer.reset();
1970 consumer->DisableTracing();
1971 producer->WaitForDataSourceStop("data_source");
1972 consumer->WaitForTracingDisabled();
1973
1974 std::string trace_raw;
1975 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
1976
1977 const auto kMarkerSize = sizeof(TracingServiceImpl::kSyncMarker);
1978 const std::string kSyncMarkerStr(
1979 reinterpret_cast<const char*>(TracingServiceImpl::kSyncMarker),
1980 kMarkerSize);
1981
1982 // Read back the trace in partitions derived from the marker.
1983 // The trace should look like this:
1984 // [uid, marker] [event] [event] [uid, marker] [event] [event]
1985 size_t num_markers = 0;
1986 size_t start = 0;
1987 size_t end = 0;
1988 protos::Trace merged_trace;
1989 for (size_t pos = 0; pos != std::string::npos; start = end) {
1990 pos = trace_raw.find(kSyncMarkerStr, pos + 1);
1991 num_markers++;
1992 end = (pos == std::string::npos) ? trace_raw.size() : pos + kMarkerSize;
1993 int size = static_cast<int>(end - start);
1994 ASSERT_GT(size, 0);
1995 protos::Trace trace_partition;
1996 ASSERT_TRUE(trace_partition.ParseFromArray(trace_raw.data() + start, size));
1997 merged_trace.MergeFrom(trace_partition);
1998 }
Lalit Maganti9bdc7ce2018-09-17 15:25:11 +01001999 EXPECT_GE(num_markers, static_cast<size_t>(kNumMarkers));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01002000
2001 protos::Trace whole_trace;
2002 ASSERT_TRUE(whole_trace.ParseFromString(trace_raw));
2003
2004 ASSERT_EQ(whole_trace.packet_size(), merged_trace.packet_size());
2005 EXPECT_EQ(whole_trace.SerializeAsString(), merged_trace.SerializeAsString());
2006}
2007
Primiano Tucci674076d2018-10-01 10:41:09 +01002008// Creates a tracing session with |deferred_start| and checks that data sources
2009// are started only after calling StartTracing().
2010TEST_F(TracingServiceImplTest, DeferredStart) {
2011 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2012 consumer->Connect(svc.get());
2013
2014 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2015 producer->Connect(svc.get(), "mock_producer");
2016
2017 // Create two data sources but enable only one of them.
2018 producer->RegisterDataSource("ds_1");
2019 producer->RegisterDataSource("ds_2");
2020
2021 TraceConfig trace_config;
2022 trace_config.add_buffers()->set_size_kb(128);
2023 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
2024 trace_config.set_deferred_start(true);
2025 trace_config.set_duration_ms(1);
2026
2027 consumer->EnableTracing(trace_config);
2028 producer->WaitForTracingSetup();
2029
2030 producer->WaitForDataSourceSetup("ds_1");
2031
2032 // Make sure we don't get unexpected DataSourceStart() notifications yet.
2033 task_runner.RunUntilIdle();
2034
2035 consumer->StartTracing();
2036
2037 producer->WaitForDataSourceStart("ds_1");
2038
Stephen Nusko1393ffd2019-03-22 13:54:58 +00002039 auto writer = producer->CreateTraceWriter("ds_1");
2040 producer->WaitForFlush(writer.get());
Primiano Tucci674076d2018-10-01 10:41:09 +01002041
2042 producer->WaitForDataSourceStop("ds_1");
2043 consumer->WaitForTracingDisabled();
2044}
2045
Eric Secklerd0ac7ca2019-02-06 09:13:45 +00002046TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
2047 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2048 consumer->Connect(svc.get());
2049
2050 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2051 producer1->Connect(svc.get(), "mock_producer1", 123u /* uid */);
2052 producer1->RegisterDataSource("data_source");
2053
2054 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2055 producer2->Connect(svc.get(), "mock_producer2", 456u /* uid */);
2056 producer2->RegisterDataSource("data_source");
2057
2058 TraceConfig trace_config;
2059 trace_config.add_buffers()->set_size_kb(128);
2060 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2061 ds_config->set_name("data_source");
2062
2063 consumer->EnableTracing(trace_config);
2064 producer1->WaitForTracingSetup();
2065 producer1->WaitForDataSourceSetup("data_source");
2066 producer2->WaitForTracingSetup();
2067 producer2->WaitForDataSourceSetup("data_source");
2068 producer1->WaitForDataSourceStart("data_source");
2069 producer2->WaitForDataSourceStart("data_source");
2070
2071 std::unique_ptr<TraceWriter> writer1a =
2072 producer1->CreateTraceWriter("data_source");
2073 std::unique_ptr<TraceWriter> writer1b =
2074 producer1->CreateTraceWriter("data_source");
2075 std::unique_ptr<TraceWriter> writer2a =
2076 producer2->CreateTraceWriter("data_source");
2077 {
2078 auto tp = writer1a->NewTracePacket();
2079 tp->set_for_testing()->set_str("payload1a1");
2080 tp = writer1b->NewTracePacket();
2081 tp->set_for_testing()->set_str("payload1b1");
2082 tp = writer1a->NewTracePacket();
2083 tp->set_for_testing()->set_str("payload1a2");
2084 tp = writer2a->NewTracePacket();
2085 tp->set_for_testing()->set_str("payload2a1");
2086 tp = writer1b->NewTracePacket();
2087 tp->set_for_testing()->set_str("payload1b2");
2088 }
2089
2090 auto flush_request = consumer->Flush();
2091 producer1->WaitForFlush({writer1a.get(), writer1b.get()});
2092 producer2->WaitForFlush(writer2a.get());
2093 ASSERT_TRUE(flush_request.WaitForReply());
2094
2095 consumer->DisableTracing();
2096 producer1->WaitForDataSourceStop("data_source");
2097 producer2->WaitForDataSourceStop("data_source");
2098 consumer->WaitForTracingDisabled();
2099 auto packets = consumer->ReadBuffers();
2100 EXPECT_THAT(
2101 packets,
2102 Contains(AllOf(
2103 Property(&protos::TracePacket::for_testing,
2104 Property(&protos::TestEvent::str, Eq("payload1a1"))),
2105 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2106 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
2107 EXPECT_THAT(
2108 packets,
2109 Contains(AllOf(
2110 Property(&protos::TracePacket::for_testing,
2111 Property(&protos::TestEvent::str, Eq("payload1a2"))),
2112 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2113 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
2114 EXPECT_THAT(
2115 packets,
2116 Contains(AllOf(
2117 Property(&protos::TracePacket::for_testing,
2118 Property(&protos::TestEvent::str, Eq("payload1b1"))),
2119 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2120 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
2121 EXPECT_THAT(
2122 packets,
2123 Contains(AllOf(
2124 Property(&protos::TracePacket::for_testing,
2125 Property(&protos::TestEvent::str, Eq("payload1b2"))),
2126 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2127 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
2128 EXPECT_THAT(
2129 packets,
2130 Contains(AllOf(
2131 Property(&protos::TracePacket::for_testing,
2132 Property(&protos::TestEvent::str, Eq("payload2a1"))),
2133 Property(&protos::TracePacket::trusted_uid, Eq(456)),
2134 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(4u)))));
2135}
2136
Eric Seckler6dc23592018-11-30 10:59:06 +00002137TEST_F(TracingServiceImplTest, AllowedBuffers) {
2138 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2139 consumer->Connect(svc.get());
2140
2141 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2142 producer1->Connect(svc.get(), "mock_producer1");
2143 ProducerID producer1_id = *last_producer_id();
2144 producer1->RegisterDataSource("data_source1");
2145 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2146 producer2->Connect(svc.get(), "mock_producer2");
2147 ProducerID producer2_id = *last_producer_id();
2148 producer2->RegisterDataSource("data_source2.1");
2149 producer2->RegisterDataSource("data_source2.2");
2150 producer2->RegisterDataSource("data_source2.3");
2151
2152 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
2153 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
2154
2155 TraceConfig trace_config;
2156 trace_config.add_buffers()->set_size_kb(128);
2157 trace_config.add_buffers()->set_size_kb(128);
2158 trace_config.add_buffers()->set_size_kb(128);
2159 auto* ds_config1 = trace_config.add_data_sources()->mutable_config();
2160 ds_config1->set_name("data_source1");
2161 ds_config1->set_target_buffer(0);
2162 auto* ds_config21 = trace_config.add_data_sources()->mutable_config();
2163 ds_config21->set_name("data_source2.1");
2164 ds_config21->set_target_buffer(1);
2165 auto* ds_config22 = trace_config.add_data_sources()->mutable_config();
2166 ds_config22->set_name("data_source2.2");
2167 ds_config22->set_target_buffer(2);
2168 auto* ds_config23 = trace_config.add_data_sources()->mutable_config();
2169 ds_config23->set_name("data_source2.3");
2170 ds_config23->set_target_buffer(2); // same buffer as data_source2.2.
2171 consumer->EnableTracing(trace_config);
2172
Primiano Tucci2abd1152018-12-03 17:00:02 +01002173 ASSERT_EQ(3u, tracing_session()->num_buffers());
Eric Seckler6dc23592018-11-30 10:59:06 +00002174 std::set<BufferID> expected_buffers_producer1 = {
2175 tracing_session()->buffers_index[0]};
2176 std::set<BufferID> expected_buffers_producer2 = {
2177 tracing_session()->buffers_index[1], tracing_session()->buffers_index[2]};
2178 EXPECT_EQ(expected_buffers_producer1, GetAllowedTargetBuffers(producer1_id));
2179 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
2180
2181 producer1->WaitForTracingSetup();
2182 producer1->WaitForDataSourceSetup("data_source1");
2183
2184 producer2->WaitForTracingSetup();
2185 producer2->WaitForDataSourceSetup("data_source2.1");
2186 producer2->WaitForDataSourceSetup("data_source2.2");
2187 producer2->WaitForDataSourceSetup("data_source2.3");
2188
2189 producer1->WaitForDataSourceStart("data_source1");
2190 producer2->WaitForDataSourceStart("data_source2.1");
2191 producer2->WaitForDataSourceStart("data_source2.2");
2192 producer2->WaitForDataSourceStart("data_source2.3");
2193
2194 producer2->UnregisterDataSource("data_source2.3");
2195 producer2->WaitForDataSourceStop("data_source2.3");
2196
2197 // Should still be allowed to write to buffers 1 (data_source2.1) and 2
2198 // (data_source2.2).
2199 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
2200
2201 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2202 // trace config didn't have the |deferred_start| flag set.
2203 consumer->StartTracing();
2204
2205 consumer->DisableTracing();
2206 producer1->WaitForDataSourceStop("data_source1");
2207 producer2->WaitForDataSourceStop("data_source2.1");
2208 producer2->WaitForDataSourceStop("data_source2.2");
2209 consumer->WaitForTracingDisabled();
2210
2211 consumer->FreeBuffers();
2212 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
2213 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
2214}
2215
Eric Seckler6aa9ece2018-12-06 16:40:12 +00002216#if !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00002217TEST_F(TracingServiceImplTest, CommitToForbiddenBufferIsDiscarded) {
2218 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2219 consumer->Connect(svc.get());
2220
2221 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2222 producer->Connect(svc.get(), "mock_producer");
2223 ProducerID producer_id = *last_producer_id();
2224 producer->RegisterDataSource("data_source");
2225
2226 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
2227
2228 TraceConfig trace_config;
2229 trace_config.add_buffers()->set_size_kb(128);
2230 trace_config.add_buffers()->set_size_kb(128);
2231 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2232 ds_config->set_name("data_source");
2233 ds_config->set_target_buffer(0);
2234 consumer->EnableTracing(trace_config);
2235
2236 ASSERT_EQ(2u, tracing_session()->num_buffers());
2237 std::set<BufferID> expected_buffers = {tracing_session()->buffers_index[0]};
2238 EXPECT_EQ(expected_buffers, GetAllowedTargetBuffers(producer_id));
2239
2240 producer->WaitForTracingSetup();
2241 producer->WaitForDataSourceSetup("data_source");
2242 producer->WaitForDataSourceStart("data_source");
2243
2244 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2245 // trace config didn't have the |deferred_start| flag set.
2246 consumer->StartTracing();
2247
2248 // Try to write to the correct buffer.
2249 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2250 tracing_session()->buffers_index[0]);
2251 {
2252 auto tp = writer->NewTracePacket();
2253 tp->set_for_testing()->set_str("good_payload");
2254 }
2255
2256 auto flush_request = consumer->Flush();
2257 producer->WaitForFlush(writer.get());
2258 ASSERT_TRUE(flush_request.WaitForReply());
2259
2260 // Try to write to the wrong buffer.
2261 writer = producer->endpoint()->CreateTraceWriter(
2262 tracing_session()->buffers_index[1]);
2263 {
2264 auto tp = writer->NewTracePacket();
2265 tp->set_for_testing()->set_str("bad_payload");
2266 }
2267
2268 flush_request = consumer->Flush();
2269 producer->WaitForFlush(writer.get());
2270 ASSERT_TRUE(flush_request.WaitForReply());
2271
2272 consumer->DisableTracing();
2273 producer->WaitForDataSourceStop("data_source");
2274 consumer->WaitForTracingDisabled();
2275
2276 auto packets = consumer->ReadBuffers();
2277 EXPECT_THAT(packets, Contains(Property(&protos::TracePacket::for_testing,
2278 Property(&protos::TestEvent::str,
2279 Eq("good_payload")))));
2280 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2281 Property(&protos::TestEvent::str,
2282 Eq("bad_payload"))))));
2283
2284 consumer->FreeBuffers();
2285 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
2286}
Eric Seckler6aa9ece2018-12-06 16:40:12 +00002287#endif // !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00002288
Eric Secklerf3f524b2018-12-13 09:09:34 +00002289TEST_F(TracingServiceImplTest, RegisterAndUnregisterTraceWriter) {
2290 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2291 consumer->Connect(svc.get());
2292
2293 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2294 producer->Connect(svc.get(), "mock_producer");
2295 ProducerID producer_id = *last_producer_id();
2296 producer->RegisterDataSource("data_source");
2297
2298 EXPECT_TRUE(GetWriters(producer_id).empty());
2299
2300 TraceConfig trace_config;
2301 trace_config.add_buffers()->set_size_kb(128);
2302 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2303 ds_config->set_name("data_source");
2304 ds_config->set_target_buffer(0);
2305 consumer->EnableTracing(trace_config);
2306
2307 producer->WaitForTracingSetup();
2308 producer->WaitForDataSourceSetup("data_source");
2309 producer->WaitForDataSourceStart("data_source");
2310
2311 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2312 // trace config didn't have the |deferred_start| flag set.
2313 consumer->StartTracing();
2314
2315 // Creating the trace writer should register it with the service.
2316 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2317 tracing_session()->buffers_index[0]);
2318
2319 WaitForTraceWritersChanged(producer_id);
2320
2321 std::map<WriterID, BufferID> expected_writers;
2322 expected_writers[writer->writer_id()] = tracing_session()->buffers_index[0];
2323 EXPECT_EQ(expected_writers, GetWriters(producer_id));
2324
2325 // Verify writing works.
2326 {
2327 auto tp = writer->NewTracePacket();
2328 tp->set_for_testing()->set_str("payload");
2329 }
2330
2331 auto flush_request = consumer->Flush();
2332 producer->WaitForFlush(writer.get());
2333 ASSERT_TRUE(flush_request.WaitForReply());
2334
2335 // Destroying the writer should unregister it.
2336 writer.reset();
2337 WaitForTraceWritersChanged(producer_id);
2338 EXPECT_TRUE(GetWriters(producer_id).empty());
2339
2340 consumer->DisableTracing();
2341 producer->WaitForDataSourceStop("data_source");
2342 consumer->WaitForTracingDisabled();
2343
2344 auto packets = consumer->ReadBuffers();
2345 EXPECT_THAT(packets, Contains(Property(
2346 &protos::TracePacket::for_testing,
2347 Property(&protos::TestEvent::str, Eq("payload")))));
2348}
2349
Eric Secklera01e28a2019-01-08 11:21:04 +00002350TEST_F(TracingServiceImplTest, ScrapeBuffersOnFlush) {
2351 svc->SetSMBScrapingEnabled(true);
2352
2353 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2354 consumer->Connect(svc.get());
2355
2356 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2357 producer->Connect(svc.get(), "mock_producer");
2358 ProducerID producer_id = *last_producer_id();
2359 producer->RegisterDataSource("data_source");
2360
2361 TraceConfig trace_config;
2362 trace_config.add_buffers()->set_size_kb(128);
2363 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2364 ds_config->set_name("data_source");
2365 ds_config->set_target_buffer(0);
2366 consumer->EnableTracing(trace_config);
2367
2368 producer->WaitForTracingSetup();
2369 producer->WaitForDataSourceSetup("data_source");
2370 producer->WaitForDataSourceStart("data_source");
2371
2372 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2373 // trace config didn't have the |deferred_start| flag set.
2374 consumer->StartTracing();
2375
2376 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2377 tracing_session()->buffers_index[0]);
2378 WaitForTraceWritersChanged(producer_id);
2379
2380 // Write a few trace packets.
2381 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2382 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2383 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2384
2385 // Flush but don't actually flush the chunk from TraceWriter.
2386 auto flush_request = consumer->Flush();
2387 producer->WaitForFlush(nullptr, /*reply=*/true);
2388 ASSERT_TRUE(flush_request.WaitForReply());
2389
2390 // Chunk with the packets should have been scraped. The service can't know
2391 // whether the last packet was completed, so shouldn't read it.
2392 auto packets = consumer->ReadBuffers();
2393 EXPECT_THAT(packets, Contains(Property(
2394 &protos::TracePacket::for_testing,
2395 Property(&protos::TestEvent::str, Eq("payload1")))));
2396 EXPECT_THAT(packets, Contains(Property(
2397 &protos::TracePacket::for_testing,
2398 Property(&protos::TestEvent::str, Eq("payload2")))));
2399 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2400 Property(&protos::TestEvent::str,
2401 Eq("payload3"))))));
2402
2403 // Write some more packets.
2404 writer->NewTracePacket()->set_for_testing()->set_str("payload4");
2405 writer->NewTracePacket()->set_for_testing()->set_str("payload5");
2406
2407 // Don't reply to flush, causing a timeout. This should scrape again.
2408 flush_request = consumer->Flush(/*timeout=*/100);
2409 producer->WaitForFlush(nullptr, /*reply=*/false);
2410 ASSERT_FALSE(flush_request.WaitForReply());
2411
2412 // Chunk with the packets should have been scraped again, overriding the
2413 // original one. Again, the last packet should be ignored and the first two
2414 // should not be read twice.
2415 packets = consumer->ReadBuffers();
2416 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2417 Property(&protos::TestEvent::str,
2418 Eq("payload1"))))));
2419 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2420 Property(&protos::TestEvent::str,
2421 Eq("payload2"))))));
2422 EXPECT_THAT(packets, Contains(Property(
2423 &protos::TracePacket::for_testing,
2424 Property(&protos::TestEvent::str, Eq("payload3")))));
2425 EXPECT_THAT(packets, Contains(Property(
2426 &protos::TracePacket::for_testing,
2427 Property(&protos::TestEvent::str, Eq("payload4")))));
2428 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2429 Property(&protos::TestEvent::str,
2430 Eq("payload5"))))));
2431
2432 consumer->DisableTracing();
2433 producer->WaitForDataSourceStop("data_source");
2434 consumer->WaitForTracingDisabled();
2435}
2436
Sami Kyostilaf5ad4642019-05-16 10:46:15 +01002437TEST_F(TracingServiceImplTest, ScrapeBuffersFromAnotherThread) {
2438 // This test verifies that there are no reported TSAN races while scraping
2439 // buffers from a producer which is actively writing more trace data
2440 // concurrently.
2441 svc->SetSMBScrapingEnabled(true);
2442
2443 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2444 consumer->Connect(svc.get());
2445
2446 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2447 producer->Connect(svc.get(), "mock_producer");
2448 ProducerID producer_id = *last_producer_id();
2449 producer->RegisterDataSource("data_source");
2450
2451 TraceConfig trace_config;
2452 trace_config.add_buffers()->set_size_kb(128);
2453 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2454 ds_config->set_name("data_source");
2455 ds_config->set_target_buffer(0);
2456 consumer->EnableTracing(trace_config);
2457
2458 producer->WaitForTracingSetup();
2459 producer->WaitForDataSourceSetup("data_source");
2460 producer->WaitForDataSourceStart("data_source");
2461 consumer->StartTracing();
2462
2463 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2464 tracing_session()->buffers_index[0]);
2465 WaitForTraceWritersChanged(producer_id);
2466
2467 constexpr int kPacketCount = 10;
2468 std::atomic<int> packets_written{};
2469 std::thread writer_thread([&] {
2470 for (int i = 0; i < kPacketCount; i++) {
2471 writer->NewTracePacket()->set_for_testing()->set_str("payload");
2472 packets_written.store(i, std::memory_order_relaxed);
2473 }
2474 });
2475
2476 // Wait until the thread has had some time to write some packets.
2477 while (packets_written.load(std::memory_order_relaxed) < kPacketCount / 2)
2478 base::SleepMicroseconds(5000);
2479
2480 // Disabling tracing will trigger scraping.
2481 consumer->DisableTracing();
2482 writer_thread.join();
2483
2484 // Because we don't synchronize with the producer thread, we can't make any
2485 // guarantees about the number of packets we will successfully read. We just
2486 // verify that no TSAN races are reported.
2487 consumer->ReadBuffers();
2488
2489 producer->WaitForDataSourceStop("data_source");
2490 consumer->WaitForTracingDisabled();
2491}
2492
Eric Secklera01e28a2019-01-08 11:21:04 +00002493// Test scraping on producer disconnect.
2494TEST_F(TracingServiceImplTest, ScrapeBuffersOnProducerDisconnect) {
2495 svc->SetSMBScrapingEnabled(true);
2496
2497 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2498 consumer->Connect(svc.get());
2499
2500 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2501 producer->Connect(svc.get(), "mock_producer");
2502 ProducerID producer_id = *last_producer_id();
2503 producer->RegisterDataSource("data_source");
2504
2505 TraceConfig trace_config;
2506 trace_config.add_buffers()->set_size_kb(128);
2507 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2508 ds_config->set_name("data_source");
2509 ds_config->set_target_buffer(0);
2510 consumer->EnableTracing(trace_config);
2511
2512 producer->WaitForTracingSetup();
2513 producer->WaitForDataSourceSetup("data_source");
2514 producer->WaitForDataSourceStart("data_source");
2515
2516 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2517 // trace config didn't have the |deferred_start| flag set.
2518 consumer->StartTracing();
2519
2520 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2521 tracing_session()->buffers_index[0]);
2522 WaitForTraceWritersChanged(producer_id);
2523
2524 // Write a few trace packets.
2525 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2526 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2527 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2528
2529 // Disconnect the producer without committing the chunk. This should cause a
2530 // scrape of the SMB. Avoid destroying the ShmemArbiter until writer is
2531 // destroyed.
2532 auto shmem_arbiter = TakeShmemArbiterForProducer(producer_id);
2533 producer.reset();
2534
2535 // Chunk with the packets should have been scraped. The service can't know
2536 // whether the last packet was completed, so shouldn't read it.
2537 auto packets = consumer->ReadBuffers();
2538 EXPECT_THAT(packets, Contains(Property(
2539 &protos::TracePacket::for_testing,
2540 Property(&protos::TestEvent::str, Eq("payload1")))));
2541 EXPECT_THAT(packets, Contains(Property(
2542 &protos::TracePacket::for_testing,
2543 Property(&protos::TestEvent::str, Eq("payload2")))));
2544 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2545 Property(&protos::TestEvent::str,
2546 Eq("payload3"))))));
2547
2548 // Cleanup writer without causing a crash because the producer already went
2549 // away.
2550 static_cast<TraceWriterImpl*>(writer.get())->ResetChunkForTesting();
2551 writer.reset();
2552 shmem_arbiter.reset();
2553
2554 consumer->DisableTracing();
2555 consumer->WaitForTracingDisabled();
2556}
2557
2558TEST_F(TracingServiceImplTest, ScrapeBuffersOnDisable) {
2559 svc->SetSMBScrapingEnabled(true);
2560
2561 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2562 consumer->Connect(svc.get());
2563
2564 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2565 producer->Connect(svc.get(), "mock_producer");
2566 ProducerID producer_id = *last_producer_id();
2567 producer->RegisterDataSource("data_source");
2568
2569 TraceConfig trace_config;
2570 trace_config.add_buffers()->set_size_kb(128);
2571 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2572 ds_config->set_name("data_source");
2573 ds_config->set_target_buffer(0);
2574 consumer->EnableTracing(trace_config);
2575
2576 producer->WaitForTracingSetup();
2577 producer->WaitForDataSourceSetup("data_source");
2578 producer->WaitForDataSourceStart("data_source");
2579
2580 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2581 // trace config didn't have the |deferred_start| flag set.
2582 consumer->StartTracing();
2583
2584 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2585 tracing_session()->buffers_index[0]);
2586 WaitForTraceWritersChanged(producer_id);
2587
2588 // Write a few trace packets.
2589 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2590 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2591 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2592
2593 consumer->DisableTracing();
2594 producer->WaitForDataSourceStop("data_source");
2595 consumer->WaitForTracingDisabled();
2596
2597 // Chunk with the packets should have been scraped. The service can't know
2598 // whether the last packet was completed, so shouldn't read it.
2599 auto packets = consumer->ReadBuffers();
2600 EXPECT_THAT(packets, Contains(Property(
2601 &protos::TracePacket::for_testing,
2602 Property(&protos::TestEvent::str, Eq("payload1")))));
2603 EXPECT_THAT(packets, Contains(Property(
2604 &protos::TracePacket::for_testing,
2605 Property(&protos::TestEvent::str, Eq("payload2")))));
2606 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2607 Property(&protos::TestEvent::str,
2608 Eq("payload3"))))));
2609}
2610
Primiano Tucciff7beab2019-01-09 21:49:20 +00002611TEST_F(TracingServiceImplTest, AbortIfTraceDurationIsTooLong) {
2612 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2613 consumer->Connect(svc.get());
2614
2615 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2616 producer->Connect(svc.get(), "mock_producer");
2617 producer->RegisterDataSource("datasource");
2618
2619 TraceConfig trace_config;
2620 trace_config.add_buffers()->set_size_kb(128);
2621 trace_config.add_data_sources()->mutable_config()->set_name("datasource");
2622 trace_config.set_duration_ms(0x7fffffff);
2623
2624 EXPECT_CALL(*producer, SetupDataSource(_, _)).Times(0);
2625 consumer->EnableTracing(trace_config);
2626
2627 // The trace is aborted immediately, 5s here is just some slack for the thread
2628 // ping-pongs for slow devices.
2629 consumer->WaitForTracingDisabled(5000);
2630}
2631
Eric Secklereaf29ed2019-01-23 09:53:55 +00002632TEST_F(TracingServiceImplTest, GetTraceStats) {
2633 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2634 consumer->Connect(svc.get());
2635
2636 consumer->GetTraceStats();
2637 consumer->WaitForTraceStats(false);
2638
2639 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2640 producer->Connect(svc.get(), "mock_producer");
2641 producer->RegisterDataSource("data_source");
2642
2643 TraceConfig trace_config;
2644 trace_config.add_buffers()->set_size_kb(128);
2645 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2646 ds_config->set_name("data_source");
2647
2648 consumer->EnableTracing(trace_config);
2649 producer->WaitForTracingSetup();
2650 producer->WaitForDataSourceSetup("data_source");
2651 producer->WaitForDataSourceStart("data_source");
2652
2653 consumer->GetTraceStats();
2654 consumer->WaitForTraceStats(true);
2655
2656 consumer->DisableTracing();
2657 producer->WaitForDataSourceStop("data_source");
2658 consumer->WaitForTracingDisabled();
2659}
2660
Eric Seckler7b0c9452019-03-18 13:14:36 +00002661TEST_F(TracingServiceImplTest, ObserveEventsDataSourceInstances) {
2662 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2663 consumer->Connect(svc.get());
2664
2665 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2666 producer->Connect(svc.get(), "mock_producer");
2667 producer->RegisterDataSource("data_source");
2668
2669 TraceConfig trace_config;
2670 trace_config.add_buffers()->set_size_kb(128);
2671 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2672 ds_config->set_name("data_source");
2673
2674 // Start tracing before the consumer is interested in events. The consumer's
2675 // OnObservableEvents() should not be called yet.
2676 consumer->EnableTracing(trace_config);
2677 producer->WaitForTracingSetup();
2678 producer->WaitForDataSourceSetup("data_source");
2679 producer->WaitForDataSourceStart("data_source");
2680
2681 // Calling ObserveEvents should cause an event for the initial instance state.
2682 consumer->ObserveEvents(TracingService::ConsumerEndpoint::
2683 ObservableEventType::kDataSourceInstances);
2684 {
2685 auto events = consumer->WaitForObservableEvents();
2686
2687 ObservableEvents::DataSourceInstanceStateChange change;
2688 change.set_producer_name("mock_producer");
2689 change.set_data_source_name("data_source");
2690 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2691 DATA_SOURCE_INSTANCE_STATE_STARTED);
2692 EXPECT_EQ(events.instance_state_changes_size(), 1);
2693 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2694 }
2695
2696 // Disabling should cause an instance state change to STOPPED.
2697 consumer->DisableTracing();
2698
2699 {
2700 auto events = consumer->WaitForObservableEvents();
2701
2702 ObservableEvents::DataSourceInstanceStateChange change;
2703 change.set_producer_name("mock_producer");
2704 change.set_data_source_name("data_source");
2705 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2706 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2707 EXPECT_EQ(events.instance_state_changes_size(), 1);
2708 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2709 }
2710
2711 producer->WaitForDataSourceStop("data_source");
2712 consumer->WaitForTracingDisabled();
2713 consumer->FreeBuffers();
2714
2715 // Enable again, this should cause a state change for a new instance to
2716 // its initial state STOPPED.
2717 trace_config.set_deferred_start(true);
2718 consumer->EnableTracing(trace_config);
2719
2720 {
2721 auto events = consumer->WaitForObservableEvents();
2722
2723 ObservableEvents::DataSourceInstanceStateChange change;
2724 change.set_producer_name("mock_producer");
2725 change.set_data_source_name("data_source");
2726 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2727 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2728 EXPECT_EQ(events.instance_state_changes_size(), 1);
2729 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2730 }
2731
2732 producer->WaitForDataSourceSetup("data_source");
2733
2734 // Should move the instance into STARTED state and thus cause an event.
2735 consumer->StartTracing();
2736
2737 {
2738 auto events = consumer->WaitForObservableEvents();
2739
2740 ObservableEvents::DataSourceInstanceStateChange change;
2741 change.set_producer_name("mock_producer");
2742 change.set_data_source_name("data_source");
2743 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2744 DATA_SOURCE_INSTANCE_STATE_STARTED);
2745 EXPECT_EQ(events.instance_state_changes_size(), 1);
2746 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2747 }
2748
2749 producer->WaitForDataSourceStart("data_source");
2750
2751 // Stop observing events.
2752 consumer->ObserveEvents(
2753 TracingService::ConsumerEndpoint::ObservableEventType::kNone);
2754
2755 // Disabling should now no longer cause events to be sent to the consumer.
2756 consumer->DisableTracing();
2757 producer->WaitForDataSourceStop("data_source");
2758 consumer->WaitForTracingDisabled();
2759}
2760
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002761TEST_F(TracingServiceImplTest, QueryServiceState) {
2762 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2763 consumer->Connect(svc.get());
2764
2765 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2766 producer1->Connect(svc.get(), "producer1");
2767
2768 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2769 producer2->Connect(svc.get(), "producer2");
2770
2771 producer1->RegisterDataSource("common_ds");
2772 producer2->RegisterDataSource("common_ds");
2773
2774 producer1->RegisterDataSource("p1_ds");
2775 producer2->RegisterDataSource("p2_ds");
2776
2777 TracingServiceState svc_state = consumer->QueryServiceState();
2778
2779 EXPECT_EQ(svc_state.producers_size(), 2u);
2780 EXPECT_EQ(svc_state.producers().at(0).id(), 1);
2781 EXPECT_EQ(svc_state.producers().at(0).name(), "producer1");
2782 EXPECT_EQ(svc_state.producers().at(1).id(), 2);
2783 EXPECT_EQ(svc_state.producers().at(1).name(), "producer2");
2784
2785 EXPECT_EQ(svc_state.data_sources_size(), 4u);
2786
2787 EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 1);
2788 EXPECT_EQ(svc_state.data_sources().at(0).descriptor().name(), "common_ds");
2789
2790 EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
2791 EXPECT_EQ(svc_state.data_sources().at(1).descriptor().name(), "common_ds");
2792
2793 EXPECT_EQ(svc_state.data_sources().at(2).producer_id(), 1);
2794 EXPECT_EQ(svc_state.data_sources().at(2).descriptor().name(), "p1_ds");
2795
2796 EXPECT_EQ(svc_state.data_sources().at(3).producer_id(), 2);
2797 EXPECT_EQ(svc_state.data_sources().at(3).descriptor().name(), "p2_ds");
2798
2799 // Test that descriptors are cleared when a producer disconnects.
2800 producer1.reset();
2801 svc_state = consumer->QueryServiceState();
2802
2803 EXPECT_EQ(svc_state.producers_size(), 1u);
2804 EXPECT_EQ(svc_state.data_sources_size(), 2u);
2805
2806 EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 2);
2807 EXPECT_EQ(svc_state.data_sources().at(0).descriptor().name(), "common_ds");
2808 EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
2809 EXPECT_EQ(svc_state.data_sources().at(1).descriptor().name(), "p2_ds");
2810}
2811
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00002812} // namespace perfetto