blob: 6a80565df0d276de639c067a511fc14d5dbfe8eb [file] [log] [blame]
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Florian Mayer6a1a4d52018-06-08 16:47:07 +010017#include "src/tracing/core/tracing_service_impl.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000018
19#include <string.h>
20
21#include "gmock/gmock.h"
22#include "gtest/gtest.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010023#include "perfetto/base/file_utils.h"
24#include "perfetto/base/temp_file.h"
Primiano Tucci1a1951d2018-04-04 21:08:16 +020025#include "perfetto/base/utils.h"
Sami Kyostila06487a22018-02-27 13:48:38 +000026#include "perfetto/tracing/core/consumer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000027#include "perfetto/tracing/core/data_source_config.h"
28#include "perfetto/tracing/core/data_source_descriptor.h"
29#include "perfetto/tracing/core/producer.h"
30#include "perfetto/tracing/core/shared_memory.h"
Sami Kyostila06487a22018-02-27 13:48:38 +000031#include "perfetto/tracing/core/trace_packet.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010032#include "perfetto/tracing/core/trace_writer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000033#include "src/base/test/test_task_runner.h"
Eric Secklera01e28a2019-01-08 11:21:04 +000034#include "src/tracing/core/shared_memory_arbiter_impl.h"
Eric Secklerf3f524b2018-12-13 09:09:34 +000035#include "src/tracing/core/trace_writer_impl.h"
Primiano Tuccidca727d2018-04-04 11:31:55 +020036#include "src/tracing/test/mock_consumer.h"
37#include "src/tracing/test/mock_producer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000038#include "src/tracing/test/test_shared_memory.h"
39
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010040#include "perfetto/trace/test_event.pbzero.h"
41#include "perfetto/trace/trace.pb.h"
Primiano Tuccidca727d2018-04-04 11:31:55 +020042#include "perfetto/trace/trace_packet.pb.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010043#include "perfetto/trace/trace_packet.pbzero.h"
44
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000045using ::testing::_;
Primiano Tuccidca727d2018-04-04 11:31:55 +020046using ::testing::Contains;
Primiano Tucci1a1951d2018-04-04 21:08:16 +020047using ::testing::ElementsAreArray;
Primiano Tuccidca727d2018-04-04 11:31:55 +020048using ::testing::Eq;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000049using ::testing::InSequence;
Primiano Tucci081d46a2018-02-28 11:09:43 +000050using ::testing::Invoke;
Primiano Tuccidca727d2018-04-04 11:31:55 +020051using ::testing::InvokeWithoutArgs;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000052using ::testing::Mock;
Eric Secklerdd0ad102018-12-06 11:32:04 +000053using ::testing::Not;
Primiano Tuccidca727d2018-04-04 11:31:55 +020054using ::testing::Property;
55using ::testing::StrictMock;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000056
Primiano Tuccidca727d2018-04-04 11:31:55 +020057namespace perfetto {
Sami Kyostila32e0b542018-02-14 08:55:43 +000058
Primiano Tucci1a1951d2018-04-04 21:08:16 +020059namespace {
Florian Mayer6a1a4d52018-06-08 16:47:07 +010060constexpr size_t kDefaultShmSizeKb = TracingServiceImpl::kDefaultShmSize / 1024;
61constexpr size_t kMaxShmSizeKb = TracingServiceImpl::kMaxShmSize / 1024;
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
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100189TEST_F(TracingServiceImplTest, RegisterAndUnregister) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200190 std::unique_ptr<MockProducer> mock_producer_1 = CreateMockProducer();
191 std::unique_ptr<MockProducer> mock_producer_2 = CreateMockProducer();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000192
Primiano Tuccidca727d2018-04-04 11:31:55 +0200193 mock_producer_1->Connect(svc.get(), "mock_producer_1", 123u /* uid */);
194 mock_producer_2->Connect(svc.get(), "mock_producer_2", 456u /* uid */);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000195
196 ASSERT_EQ(2u, svc->num_producers());
Primiano Tuccidca727d2018-04-04 11:31:55 +0200197 ASSERT_EQ(mock_producer_1->endpoint(), svc->GetProducer(1));
198 ASSERT_EQ(mock_producer_2->endpoint(), svc->GetProducer(2));
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200199 ASSERT_EQ(123u, GetProducerUid(1));
200 ASSERT_EQ(456u, GetProducerUid(2));
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000201
Primiano Tuccidca727d2018-04-04 11:31:55 +0200202 mock_producer_1->RegisterDataSource("foo");
203 mock_producer_2->RegisterDataSource("bar");
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000204
Primiano Tuccidca727d2018-04-04 11:31:55 +0200205 mock_producer_1->UnregisterDataSource("foo");
206 mock_producer_2->UnregisterDataSource("bar");
Primiano Tucci9daa4832018-03-28 23:28:17 +0100207
Primiano Tuccidca727d2018-04-04 11:31:55 +0200208 mock_producer_1.reset();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000209 ASSERT_EQ(1u, svc->num_producers());
210 ASSERT_EQ(nullptr, svc->GetProducer(1));
211
Primiano Tuccidca727d2018-04-04 11:31:55 +0200212 mock_producer_2.reset();
213 ASSERT_EQ(nullptr, svc->GetProducer(2));
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000214
215 ASSERT_EQ(0u, svc->num_producers());
216}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100217
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100218TEST_F(TracingServiceImplTest, EnableAndDisableTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200219 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
220 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +0000221
Primiano Tuccidca727d2018-04-04 11:31:55 +0200222 std::unique_ptr<MockProducer> producer = CreateMockProducer();
223 producer->Connect(svc.get(), "mock_producer");
224 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000225
Sami Kyostila06487a22018-02-27 13:48:38 +0000226 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200227 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +0000228 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200229 ds_config->set_name("data_source");
230 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +0000231
Primiano Tuccidca727d2018-04-04 11:31:55 +0200232 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100233 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200234 producer->WaitForDataSourceStart("data_source");
235
Primiano Tucci674076d2018-10-01 10:41:09 +0100236 // Calling StartTracing() should be a noop (% a DLOG statement) because the
237 // trace config didn't have the |deferred_start| flag set.
238 consumer->StartTracing();
239
Primiano Tuccidca727d2018-04-04 11:31:55 +0200240 consumer->DisableTracing();
241 producer->WaitForDataSourceStop("data_source");
242 consumer->WaitForTracingDisabled();
Sami Kyostila06487a22018-02-27 13:48:38 +0000243}
244
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000245// Creates a tracing session with a START_TRACING trigger and checks that data
246// sources are started only after the service receives a trigger.
247TEST_F(TracingServiceImplTest, StartTracingTriggerDeferredStart) {
248 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
249 consumer->Connect(svc.get());
250
251 std::unique_ptr<MockProducer> producer = CreateMockProducer();
252 producer->Connect(svc.get(), "mock_producer");
253
254 // Create two data sources but enable only one of them.
255 producer->RegisterDataSource("ds_1");
256 producer->RegisterDataSource("ds_2");
257
258 TraceConfig trace_config;
259 trace_config.add_buffers()->set_size_kb(128);
260 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
261 auto* trigger_config = trace_config.mutable_trigger_config();
262 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
263 auto* trigger = trigger_config->add_triggers();
264 trigger->set_name("trigger_name");
265 trigger->set_stop_delay_ms(1);
266
267 trigger_config->set_trigger_timeout_ms(8.64e+7);
268
269 // Make sure we don't get unexpected DataSourceStart() notifications yet.
270 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
271
272 consumer->EnableTracing(trace_config);
273 producer->WaitForTracingSetup();
274
275 producer->WaitForDataSourceSetup("ds_1");
276
277 // The trace won't start until we send the trigger. since we have a
278 // START_TRACING trigger defined.
279 std::vector<std::string> req;
280 req.push_back("trigger_name");
281 producer->endpoint()->ActivateTriggers(req);
282
283 producer->WaitForDataSourceStart("ds_1");
284
285 auto writer1 = producer->CreateTraceWriter("ds_1");
286 producer->WaitForFlush(writer1.get());
287
288 producer->WaitForDataSourceStop("ds_1");
289 consumer->WaitForTracingDisabled();
290
291 ASSERT_EQ(1u, tracing_session()->received_triggers.size());
292 EXPECT_EQ("trigger_name",
293 tracing_session()->received_triggers[0].second.name());
294
295 EXPECT_THAT(
296 consumer->ReadBuffers(),
297 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
298}
299
300// Creates a tracing session with a START_TRACING trigger and checks that the
301// session is cleaned up when no trigger is received after |trigger_timeout_ms|.
302TEST_F(TracingServiceImplTest, StartTracingTriggerTimeOut) {
303 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
304 consumer->Connect(svc.get());
305
306 std::unique_ptr<MockProducer> producer = CreateMockProducer();
307 producer->Connect(svc.get(), "mock_producer");
308
309 // Create two data sources but enable only one of them.
310 producer->RegisterDataSource("ds_1");
311 producer->RegisterDataSource("ds_2");
312
313 TraceConfig trace_config;
314 trace_config.add_buffers()->set_size_kb(128);
315 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
316 auto* trigger_config = trace_config.mutable_trigger_config();
317 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
318 auto* trigger = trigger_config->add_triggers();
319 trigger->set_name("trigger_name");
320 trigger->set_stop_delay_ms(8.64e+7);
321
322 trigger_config->set_trigger_timeout_ms(1);
323
324 // Make sure we don't get unexpected DataSourceStart() notifications yet.
325 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
326
327 consumer->EnableTracing(trace_config);
328 producer->WaitForTracingSetup();
329
330 producer->WaitForDataSourceSetup("ds_1");
331
332 // The trace won't start until we send the trigger. since we have a
333 // START_TRACING trigger defined. This is where we'd expect to have an
334 // ActivateTriggers call to the producer->endpoint().
335
336 producer->WaitForDataSourceStop("ds_1");
337 consumer->WaitForTracingDisabled();
338 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
339}
340
341// Creates a tracing session with a START_TRACING trigger and checks that
342// the session is not started when the configured trigger producer is different
343// than the producer that sent the trigger.
344TEST_F(TracingServiceImplTest, StartTracingTriggerDifferentProducer) {
345 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
346 consumer->Connect(svc.get());
347
348 std::unique_ptr<MockProducer> producer = CreateMockProducer();
349 producer->Connect(svc.get(), "mock_producer");
350
351 // Create two data sources but enable only one of them.
352 producer->RegisterDataSource("ds_1");
353 producer->RegisterDataSource("ds_2");
354
355 TraceConfig trace_config;
356 trace_config.add_buffers()->set_size_kb(128);
357 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
358 auto* trigger_config = trace_config.mutable_trigger_config();
359 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
360 auto* trigger = trigger_config->add_triggers();
361 trigger->set_name("trigger_name");
362 trigger->set_stop_delay_ms(8.64e+7);
363 trigger->set_producer_name_regex("correct_name");
364
365 trigger_config->set_trigger_timeout_ms(1);
366
367 // Make sure we don't get unexpected DataSourceStart() notifications yet.
368 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
369
370 consumer->EnableTracing(trace_config);
371 producer->WaitForTracingSetup();
372
373 producer->WaitForDataSourceSetup("ds_1");
374
375 // The trace won't start until we send the trigger called "trigger_name"
376 // coming from a producer called "correct_name", since we have a
377 // START_TRACING trigger defined. This is where we'd expect to have an
378 // ActivateTriggers call to the producer->endpoint(), but we send the trigger
379 // from a different producer so it is ignored.
380 std::vector<std::string> req;
381 req.push_back("trigger_name");
382 producer->endpoint()->ActivateTriggers(req);
383
384 producer->WaitForDataSourceStop("ds_1");
385 consumer->WaitForTracingDisabled();
386 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
387}
388
389// Creates a tracing session with a START_TRACING trigger and checks that the
390// session is started when the trigger is received from the correct producer.
391TEST_F(TracingServiceImplTest, StartTracingTriggerCorrectProducer) {
392 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
393 consumer->Connect(svc.get());
394
395 std::unique_ptr<MockProducer> producer = CreateMockProducer();
396 producer->Connect(svc.get(), "mock_producer");
397
398 // Create two data sources but enable only one of them.
399 producer->RegisterDataSource("ds_1");
400 producer->RegisterDataSource("ds_2");
401
402 TraceConfig trace_config;
403 trace_config.add_buffers()->set_size_kb(128);
404 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
405 auto* trigger_config = trace_config.mutable_trigger_config();
406 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
407 auto* trigger = trigger_config->add_triggers();
408 trigger->set_name("trigger_name");
409 trigger->set_stop_delay_ms(1);
410 trigger->set_producer_name_regex("mock_produc[e-r]+");
411
412 trigger_config->set_trigger_timeout_ms(8.64e+7);
413
414 consumer->EnableTracing(trace_config);
415 producer->WaitForTracingSetup();
416
417 producer->WaitForDataSourceSetup("ds_1");
418
419 // Start the trace at this point with ActivateTriggers.
420 std::vector<std::string> req;
421 req.push_back("trigger_name");
422 producer->endpoint()->ActivateTriggers(req);
423
424 producer->WaitForDataSourceStart("ds_1");
425
426 auto writer = producer->CreateTraceWriter("ds_1");
427 producer->WaitForFlush(writer.get());
428
429 producer->WaitForDataSourceStop("ds_1");
430 consumer->WaitForTracingDisabled();
431 EXPECT_THAT(
432 consumer->ReadBuffers(),
433 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
434}
435
436// Creates a tracing session with a START_TRACING trigger and checks that the
437// session is cleaned up even when a different trigger is received.
438TEST_F(TracingServiceImplTest, StartTracingTriggerDifferentTrigger) {
439 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
440 consumer->Connect(svc.get());
441
442 std::unique_ptr<MockProducer> producer = CreateMockProducer();
443 producer->Connect(svc.get(), "mock_producer");
444
445 // Create two data sources but enable only one of them.
446 producer->RegisterDataSource("ds_1");
447 producer->RegisterDataSource("ds_2");
448
449 TraceConfig trace_config;
450 trace_config.add_buffers()->set_size_kb(128);
451 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
452 auto* trigger_config = trace_config.mutable_trigger_config();
453 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
454 auto* trigger = trigger_config->add_triggers();
455 trigger->set_name("trigger_name");
456 trigger->set_stop_delay_ms(8.64e+7);
457
458 trigger_config->set_trigger_timeout_ms(1);
459
460 // Make sure we don't get unexpected DataSourceStart() notifications yet.
461 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
462
463 consumer->EnableTracing(trace_config);
464 producer->WaitForTracingSetup();
465
466 producer->WaitForDataSourceSetup("ds_1");
467
468 // The trace won't start until we send the trigger called "trigger_name",
469 // since we have a START_TRACING trigger defined. This is where we'd expect to
470 // have an ActivateTriggers call to the producer->endpoint(), but we send a
471 // different trigger.
472 std::vector<std::string> req;
473 req.push_back("not_correct_trigger");
474 producer->endpoint()->ActivateTriggers(req);
475
476 producer->WaitForDataSourceStop("ds_1");
477 consumer->WaitForTracingDisabled();
478 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
479}
480
481// Creates a tracing session with a START_TRACING trigger and checks that any
482// trigger can start the TracingSession.
483TEST_F(TracingServiceImplTest, StartTracingTriggerMultipleTriggers) {
484 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
485 consumer->Connect(svc.get());
486
487 std::unique_ptr<MockProducer> producer = CreateMockProducer();
488 producer->Connect(svc.get(), "mock_producer");
489
490 // Create two data sources but enable only one of them.
491 producer->RegisterDataSource("ds_1");
492 producer->RegisterDataSource("ds_2");
493
494 TraceConfig trace_config;
495 trace_config.add_buffers()->set_size_kb(128);
496 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
497 auto* trigger_config = trace_config.mutable_trigger_config();
498 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
499 auto* trigger = trigger_config->add_triggers();
500 trigger->set_name("trigger_name");
501 trigger->set_stop_delay_ms(1);
502
503 trigger_config->set_trigger_timeout_ms(8.64e+7);
504
505 consumer->EnableTracing(trace_config);
506 producer->WaitForTracingSetup();
507
508 producer->WaitForDataSourceSetup("ds_1");
509
510 // Make sure we don't get unexpected DataSourceStart() notifications yet.
511 task_runner.RunUntilIdle();
512
513 std::vector<std::string> req;
514 req.push_back("not_correct_trigger");
515 req.push_back("trigger_name");
516 producer->endpoint()->ActivateTriggers(req);
517
518 producer->WaitForDataSourceStart("ds_1");
519
520 auto writer = producer->CreateTraceWriter("ds_1");
521 producer->WaitForFlush(writer.get());
522
523 producer->WaitForDataSourceStop("ds_1");
524 consumer->WaitForTracingDisabled();
525 EXPECT_THAT(
526 consumer->ReadBuffers(),
527 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
528}
529
530// Creates two tracing sessions with a START_TRACING trigger and checks that
531// both are able to be triggered simultaneously.
532TEST_F(TracingServiceImplTest, StartTracingTriggerMultipleTraces) {
533 std::unique_ptr<MockConsumer> consumer_1 = CreateMockConsumer();
534 consumer_1->Connect(svc.get());
535 std::unique_ptr<MockConsumer> consumer_2 = CreateMockConsumer();
536 consumer_2->Connect(svc.get());
537
538 std::unique_ptr<MockProducer> producer = CreateMockProducer();
539 producer->Connect(svc.get(), "mock_producer");
540
541 // Create two data sources but each TracingSession will only enable one of
542 // them.
543 producer->RegisterDataSource("ds_1");
544 producer->RegisterDataSource("ds_2");
545
546 TraceConfig trace_config;
547 trace_config.add_buffers()->set_size_kb(128);
548 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
549 auto* trigger_config = trace_config.mutable_trigger_config();
550 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
551 auto* trigger = trigger_config->add_triggers();
552 trigger->set_name("trigger_name");
553 trigger->set_stop_delay_ms(1);
554
555 trigger_config->set_trigger_timeout_ms(8.64e+7);
556
557 consumer_1->EnableTracing(trace_config);
558 producer->WaitForTracingSetup();
559
560 producer->WaitForDataSourceSetup("ds_1");
561
562 // Make sure we don't get unexpected DataSourceStart() notifications yet from
563 // consumer_1.
564 task_runner.RunUntilIdle();
565 auto tracing_session_1_id = GetTracingSessionID();
566
567 (*trace_config.mutable_data_sources())[0].mutable_config()->set_name("ds_2");
568 trigger = trace_config.mutable_trigger_config()->add_triggers();
569 trigger->set_name("trigger_name_2");
570 trigger->set_stop_delay_ms(8.64e+7);
571
572 consumer_2->EnableTracing(trace_config);
573
574 producer->WaitForDataSourceSetup("ds_2");
575
576 // Make sure we don't get unexpected DataSourceStart() notifications yet from
577 // consumer_2.
578 task_runner.RunUntilIdle();
579 auto tracing_session_2_id = GetTracingSessionID();
580 EXPECT_NE(tracing_session_1_id, tracing_session_2_id);
581
582 const DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_1");
583 const DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_2");
584
585 std::vector<std::string> req;
586 req.push_back("not_correct_trigger");
587 req.push_back("trigger_name");
588 req.push_back("trigger_name_2");
589 producer->endpoint()->ActivateTriggers(req);
590
591 // The order has to be the same as the triggers or else we're incorrectly wait
592 // on the wrong checkpoint in the |task_runner|.
593 producer->WaitForDataSourceStart("ds_1");
594 producer->WaitForDataSourceStart("ds_2");
595
596 // Now that they've started we can check the triggers they've seen.
597 auto* tracing_session_1 = GetTracingSession(tracing_session_1_id);
598 ASSERT_EQ(1u, tracing_session_1->received_triggers.size());
599 EXPECT_EQ("trigger_name",
600 tracing_session_1->received_triggers[0].second.name());
601
602 // This is actually dependent on the order in which the triggers were received
603 // but there isn't really a better way than iteration order so probably not to
604 // brittle of a test. And this caught a real bug in implementation.
605 auto* tracing_session_2 = GetTracingSession(tracing_session_2_id);
606 ASSERT_EQ(2u, tracing_session_2->received_triggers.size());
607
608 EXPECT_EQ("trigger_name",
609 tracing_session_2->received_triggers[0].second.name());
610 EXPECT_EQ(1, tracing_session_2->received_triggers[0].second.stop_delay_ms());
611
612 EXPECT_EQ("trigger_name_2",
613 tracing_session_2->received_triggers[1].second.name());
614 EXPECT_EQ(8.64e+7,
615 tracing_session_2->received_triggers[1].second.stop_delay_ms());
616
617 auto writer1 = producer->CreateTraceWriter("ds_1");
618 auto writer2 = producer->CreateTraceWriter("ds_2");
619
620 // We can't use the standard WaitForX in the MockProducer and MockConsumer
621 // because they assume only a single trace is going on. So we perform our own
622 // expectations and wait at the end for the two consumers to receive
623 // OnTracingDisabled.
624 bool flushed_writer_1 = false;
625 bool flushed_writer_2 = false;
626 auto flush_correct_writer = [&](FlushRequestID flush_req_id,
627 const DataSourceInstanceID* id, size_t) {
628 if (*id == id1) {
629 flushed_writer_1 = true;
630 writer1->Flush();
631 producer->endpoint()->NotifyFlushComplete(flush_req_id);
632 } else if (*id == id2) {
633 flushed_writer_2 = true;
634 writer2->Flush();
635 producer->endpoint()->NotifyFlushComplete(flush_req_id);
636 }
637 };
638 EXPECT_CALL(*producer, Flush(_, _, _))
639 .WillOnce(Invoke(flush_correct_writer))
640 .WillOnce(Invoke(flush_correct_writer));
641
642 auto checkpoint_name = "on_tracing_disabled_consumer_1_and_2";
643 auto on_tracing_disabled = task_runner.CreateCheckpoint(checkpoint_name);
644 std::atomic<size_t> counter(0);
645 EXPECT_CALL(*consumer_1, OnTracingDisabled()).WillOnce(Invoke([&]() {
646 if (++counter == 2u) {
647 on_tracing_disabled();
648 }
649 }));
650 EXPECT_CALL(*consumer_2, OnTracingDisabled()).WillOnce(Invoke([&]() {
651 if (++counter == 2u) {
652 on_tracing_disabled();
653 }
654 }));
655
656 EXPECT_CALL(*producer, StopDataSource(id1));
657 EXPECT_CALL(*producer, StopDataSource(id2));
658
659 task_runner.RunUntilCheckpoint(checkpoint_name, 1000);
660
661 EXPECT_TRUE(flushed_writer_1);
662 EXPECT_TRUE(flushed_writer_2);
663 EXPECT_THAT(
664 consumer_1->ReadBuffers(),
665 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
666 EXPECT_THAT(
667 consumer_2->ReadBuffers(),
668 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
669}
670
Stephen Nuskod95a7512019-03-22 13:59:39 +0000671// Creates a tracing session with a STOP_TRACING trigger and checks that the
672// session is cleaned up after |trigger_timeout_ms|.
673TEST_F(TracingServiceImplTest, StopTracingTriggerTimeout) {
674 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
675 consumer->Connect(svc.get());
676
677 std::unique_ptr<MockProducer> producer = CreateMockProducer();
678 producer->Connect(svc.get(), "mock_producer");
679
680 // Create two data sources but enable only one of them.
681 producer->RegisterDataSource("ds_1");
682 producer->RegisterDataSource("ds_2");
683
684 TraceConfig trace_config;
685 trace_config.add_buffers()->set_size_kb(128);
686 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
687 auto* trigger_config = trace_config.mutable_trigger_config();
688 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
689 auto* trigger = trigger_config->add_triggers();
690 trigger->set_name("trigger_name");
691 trigger->set_stop_delay_ms(8.64e+7);
692
693 trigger_config->set_trigger_timeout_ms(1);
694
695 // Make sure we don't get unexpected DataSourceStart() notifications yet.
696 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
697
698 consumer->EnableTracing(trace_config);
699 producer->WaitForTracingSetup();
700
701 producer->WaitForDataSourceSetup("ds_1");
702 producer->WaitForDataSourceStart("ds_1");
703
704 // The trace won't return data until unless we send a trigger at this point.
705 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
706
707 auto writer = producer->CreateTraceWriter("ds_1");
708 producer->WaitForFlush(writer.get());
709
710 ASSERT_EQ(0u, tracing_session()->received_triggers.size());
711
712 producer->WaitForDataSourceStop("ds_1");
713 consumer->WaitForTracingDisabled();
714 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
715}
716
717// Creates a tracing session with a STOP_TRACING trigger and checks that the
718// session returns data after a trigger is received, but only what is currently
719// in the buffer.
720TEST_F(TracingServiceImplTest, StopTracingTriggerRingBuffer) {
721 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
722 consumer->Connect(svc.get());
723
724 std::unique_ptr<MockProducer> producer = CreateMockProducer();
725 producer->Connect(svc.get(), "mock_producer");
726
727 // Create two data sources but enable only one of them.
728 producer->RegisterDataSource("ds_1");
729 producer->RegisterDataSource("ds_2");
730
731 TraceConfig trace_config;
732 trace_config.add_buffers()->set_size_kb(128);
733 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
734 auto* trigger_config = trace_config.mutable_trigger_config();
735 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
736 auto* trigger = trigger_config->add_triggers();
737 trigger->set_name("trigger_name");
738 trigger->set_stop_delay_ms(1);
739
740 trigger_config->set_trigger_timeout_ms(8.64e+7);
741
742 consumer->EnableTracing(trace_config);
743 producer->WaitForTracingSetup();
744
745 producer->WaitForDataSourceSetup("ds_1");
746 producer->WaitForDataSourceStart("ds_1");
747
748 task_runner.RunUntilIdle();
749
750 // The trace won't return data until unless we send a trigger at this point.
751 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
752
753 // We write into the buffer a large packet which takes up the whole buffer. We
754 // then add a bunch of smaller ones which causes the larger packet to be
755 // dropped. After we activate the session we should only see a bunch of the
756 // smaller ones.
757 static const int kNumTestPackets = 10;
758 static const char kPayload[] = "1234567890abcdef-";
759
760 auto writer = producer->CreateTraceWriter("ds_1");
761 // Buffer is 1kb so we write a packet which is slightly smaller so it fits in
762 // the buffer.
763 const std::string large_payload(1024 * 128 - 20, 'a');
764 {
765 auto tp = writer->NewTracePacket();
766 tp->set_for_testing()->set_str(large_payload.c_str(), large_payload.size());
767 }
768
769 // Now we add a bunch of data before the trigger and after.
770 for (int i = 0; i < kNumTestPackets; i++) {
771 if (i == kNumTestPackets / 2) {
772 std::vector<std::string> req;
773 req.push_back("trigger_name");
774 producer->endpoint()->ActivateTriggers(req);
775 }
776 auto tp = writer->NewTracePacket();
777 std::string payload(kPayload);
778 payload.append(std::to_string(i));
779 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
780 }
781 producer->WaitForFlush(writer.get());
782
783 ASSERT_EQ(1u, tracing_session()->received_triggers.size());
784 EXPECT_EQ("trigger_name",
785 tracing_session()->received_triggers[0].second.name());
786
787 producer->WaitForDataSourceStop("ds_1");
788 consumer->WaitForTracingDisabled();
789 // There are 5 preample packets plus the kNumTestPackets we wrote out. The
790 // large_payload one should be overwritten.
791 static const int kNumPreamblePackets = 5;
792 auto packets = consumer->ReadBuffers();
793 EXPECT_EQ(kNumTestPackets + kNumPreamblePackets, packets.size());
794 // We expect for the TraceConfig preamble packet to be there correctly and
795 // then we expect each payload to be there, but not the |large_payload|
796 // packet.
797 EXPECT_THAT(packets,
798 HasTriggerMode(protos::TraceConfig::TriggerConfig::STOP_TRACING));
799 for (int i = 0; i < kNumTestPackets; i++) {
800 std::string payload = kPayload;
801 payload += std::to_string(i);
802 EXPECT_THAT(packets, Contains(Property(
803 &protos::TracePacket::for_testing,
804 Property(&protos::TestEvent::str, Eq(payload)))));
805 }
806
807 // The large payload was overwritten before we trigger and ReadBuffers so it
808 // should not be in the returned data.
809 EXPECT_THAT(packets,
810 ::testing::Not(Contains(Property(
811 &protos::TracePacket::for_testing,
812 Property(&protos::TestEvent::str, Eq(large_payload))))));
813}
814
815// Creates a tracing session with a STOP_TRACING trigger and checks that the
816// session only cleans up once even with multiple triggers.
817TEST_F(TracingServiceImplTest, StopTracingTriggerMultipleTriggers) {
818 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
819 consumer->Connect(svc.get());
820
821 std::unique_ptr<MockProducer> producer = CreateMockProducer();
822 producer->Connect(svc.get(), "mock_producer");
823
824 // Create two data sources but enable only one of them.
825 producer->RegisterDataSource("ds_1");
826 producer->RegisterDataSource("ds_2");
827
828 TraceConfig trace_config;
829 trace_config.add_buffers()->set_size_kb(128);
830 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
831 auto* trigger_config = trace_config.mutable_trigger_config();
832 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
833 auto* trigger = trigger_config->add_triggers();
834 trigger->set_name("trigger_name");
835 trigger->set_stop_delay_ms(1);
836 trigger = trigger_config->add_triggers();
837 trigger->set_name("trigger_name_2");
838 trigger->set_stop_delay_ms(8.64e+7);
839
840 trigger_config->set_trigger_timeout_ms(8.64e+7);
841
842 consumer->EnableTracing(trace_config);
843 producer->WaitForTracingSetup();
844
845 producer->WaitForDataSourceSetup("ds_1");
846 producer->WaitForDataSourceStart("ds_1");
847
848 task_runner.RunUntilIdle();
849
850 // The trace won't return data until unless we send a trigger at this point.
851 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
852
853 std::vector<std::string> req;
854 req.push_back("trigger_name");
855 req.push_back("trigger_name_3");
856 req.push_back("trigger_name_2");
857 producer->endpoint()->ActivateTriggers(req);
858
859 auto writer = producer->CreateTraceWriter("ds_1");
860 producer->WaitForFlush(writer.get());
861
862 ASSERT_EQ(2u, tracing_session()->received_triggers.size());
863 EXPECT_EQ("trigger_name",
864 tracing_session()->received_triggers[0].second.name());
865 EXPECT_EQ("trigger_name_2",
866 tracing_session()->received_triggers[1].second.name());
867
868 producer->WaitForDataSourceStop("ds_1");
869 consumer->WaitForTracingDisabled();
870 EXPECT_THAT(consumer->ReadBuffers(),
871 HasTriggerMode(protos::TraceConfig::TriggerConfig::STOP_TRACING));
872}
873
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100874TEST_F(TracingServiceImplTest, LockdownMode) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200875 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
876 consumer->Connect(svc.get());
877
878 std::unique_ptr<MockProducer> producer = CreateMockProducer();
879 producer->Connect(svc.get(), "mock_producer_sameuid", geteuid());
880 producer->RegisterDataSource("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +0000881
882 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200883 trace_config.add_buffers()->set_size_kb(128);
884 auto* ds_config = trace_config.add_data_sources()->mutable_config();
885 ds_config->set_name("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +0000886 trace_config.set_lockdown_mode(
887 TraceConfig::LockdownModeOperation::LOCKDOWN_SET);
Primiano Tuccidca727d2018-04-04 11:31:55 +0200888 consumer->EnableTracing(trace_config);
889
890 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100891 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200892 producer->WaitForDataSourceStart("data_source");
893
894 std::unique_ptr<MockProducer> producer_otheruid = CreateMockProducer();
895 auto x = svc->ConnectProducer(producer_otheruid.get(), geteuid() + 1,
896 "mock_producer_ouid");
897 EXPECT_CALL(*producer_otheruid, OnConnect()).Times(0);
Florian Mayer61c55482018-03-06 14:43:54 +0000898 task_runner.RunUntilIdle();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200899 Mock::VerifyAndClearExpectations(producer_otheruid.get());
Florian Mayer61c55482018-03-06 14:43:54 +0000900
Primiano Tuccidca727d2018-04-04 11:31:55 +0200901 consumer->DisableTracing();
902 consumer->FreeBuffers();
903 producer->WaitForDataSourceStop("data_source");
904 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +0000905
906 trace_config.set_lockdown_mode(
907 TraceConfig::LockdownModeOperation::LOCKDOWN_CLEAR);
Primiano Tuccidca727d2018-04-04 11:31:55 +0200908 consumer->EnableTracing(trace_config);
Primiano Tucci674076d2018-10-01 10:41:09 +0100909 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200910 producer->WaitForDataSourceStart("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +0000911
Primiano Tuccidca727d2018-04-04 11:31:55 +0200912 std::unique_ptr<MockProducer> producer_otheruid2 = CreateMockProducer();
913 producer_otheruid->Connect(svc.get(), "mock_producer_ouid2", geteuid() + 1);
Florian Mayer61c55482018-03-06 14:43:54 +0000914
Primiano Tuccidca727d2018-04-04 11:31:55 +0200915 consumer->DisableTracing();
916 producer->WaitForDataSourceStop("data_source");
917 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +0000918}
919
Oystein Eftevaagcb6e4c82019-03-06 15:38:26 -0800920TEST_F(TracingServiceImplTest, ProducerNameFilterChange) {
921 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
922 consumer->Connect(svc.get());
923
924 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
925 producer1->Connect(svc.get(), "mock_producer_1");
926 producer1->RegisterDataSource("data_source");
927
928 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
929 producer2->Connect(svc.get(), "mock_producer_2");
930 producer2->RegisterDataSource("data_source");
931
932 std::unique_ptr<MockProducer> producer3 = CreateMockProducer();
933 producer3->Connect(svc.get(), "mock_producer_3");
934 producer3->RegisterDataSource("data_source");
935 producer3->RegisterDataSource("unused_data_source");
936
937 TraceConfig trace_config;
938 trace_config.add_buffers()->set_size_kb(128);
939 auto* data_source = trace_config.add_data_sources();
940 data_source->mutable_config()->set_name("data_source");
941 *data_source->add_producer_name_filter() = "mock_producer_1";
942
943 // Enable tracing with only mock_producer_1 enabled;
944 // the rest should not start up.
945 consumer->EnableTracing(trace_config);
946
947 producer1->WaitForTracingSetup();
948 producer1->WaitForDataSourceSetup("data_source");
949 producer1->WaitForDataSourceStart("data_source");
950
951 EXPECT_CALL(*producer2, OnConnect()).Times(0);
952 EXPECT_CALL(*producer3, OnConnect()).Times(0);
953 task_runner.RunUntilIdle();
954 Mock::VerifyAndClearExpectations(producer2.get());
955 Mock::VerifyAndClearExpectations(producer3.get());
956
957 // Enable mock_producer_2, the third one should still
958 // not get connected.
959 *data_source->add_producer_name_filter() = "mock_producer_2";
960 consumer->ChangeTraceConfig(trace_config);
961
962 producer2->WaitForTracingSetup();
963 producer2->WaitForDataSourceSetup("data_source");
964 producer2->WaitForDataSourceStart("data_source");
965
966 // Enable mock_producer_3 but also try to do an
967 // unsupported change (adding a new data source);
968 // mock_producer_3 should get enabled but not
969 // for the new data source.
970 *data_source->add_producer_name_filter() = "mock_producer_3";
971 auto* dummy_data_source = trace_config.add_data_sources();
972 dummy_data_source->mutable_config()->set_name("unused_data_source");
973 *dummy_data_source->add_producer_name_filter() = "mock_producer_3";
974
975 consumer->ChangeTraceConfig(trace_config);
976
977 producer3->WaitForTracingSetup();
978 EXPECT_CALL(*producer3, SetupDataSource(_, _)).Times(1);
979 EXPECT_CALL(*producer3, StartDataSource(_, _)).Times(1);
980 task_runner.RunUntilIdle();
981 Mock::VerifyAndClearExpectations(producer3.get());
982
983 consumer->DisableTracing();
984 consumer->FreeBuffers();
985 producer1->WaitForDataSourceStop("data_source");
986 producer2->WaitForDataSourceStop("data_source");
987
988 EXPECT_CALL(*producer3, StopDataSource(_)).Times(1);
989
990 consumer->WaitForTracingDisabled();
991
992 task_runner.RunUntilIdle();
993 Mock::VerifyAndClearExpectations(producer3.get());
994}
995
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100996TEST_F(TracingServiceImplTest, DisconnectConsumerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200997 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
998 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +0000999
Primiano Tuccidca727d2018-04-04 11:31:55 +02001000 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1001 producer->Connect(svc.get(), "mock_producer");
1002 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001003
Primiano Tuccidca727d2018-04-04 11:31:55 +02001004 TraceConfig trace_config;
1005 trace_config.add_buffers()->set_size_kb(128);
1006 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1007 ds_config->set_name("data_source");
1008 consumer->EnableTracing(trace_config);
1009
1010 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001011 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001012 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001013
1014 // Disconnecting the consumer while tracing should trigger data source
1015 // teardown.
Primiano Tuccidca727d2018-04-04 11:31:55 +02001016 consumer.reset();
1017 producer->WaitForDataSourceStop("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001018}
1019
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001020TEST_F(TracingServiceImplTest, ReconnectProducerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001021 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1022 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +00001023
Primiano Tuccidca727d2018-04-04 11:31:55 +02001024 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1025 producer->Connect(svc.get(), "mock_producer");
1026 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001027
Sami Kyostila06487a22018-02-27 13:48:38 +00001028 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001029 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +00001030 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001031 ds_config->set_name("data_source");
1032 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +00001033
Primiano Tuccidca727d2018-04-04 11:31:55 +02001034 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001035 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001036 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001037
Primiano Tuccidca727d2018-04-04 11:31:55 +02001038 // Disconnecting and reconnecting a producer with a matching data source.
1039 // The Producer should see that data source getting enabled again.
1040 producer.reset();
1041 producer = CreateMockProducer();
1042 producer->Connect(svc.get(), "mock_producer_2");
1043 producer->RegisterDataSource("data_source");
1044 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001045 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001046 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001047}
1048
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001049TEST_F(TracingServiceImplTest, ProducerIDWrapping) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001050 std::vector<std::unique_ptr<MockProducer>> producers;
1051 producers.push_back(nullptr);
Primiano Tucci081d46a2018-02-28 11:09:43 +00001052
Primiano Tuccidca727d2018-04-04 11:31:55 +02001053 auto connect_producer_and_get_id = [&producers,
1054 this](const std::string& name) {
1055 producers.emplace_back(CreateMockProducer());
1056 producers.back()->Connect(svc.get(), "mock_producer_" + name);
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001057 return *last_producer_id();
Primiano Tucci081d46a2018-02-28 11:09:43 +00001058 };
1059
1060 // Connect producers 1-4.
1061 for (ProducerID i = 1; i <= 4; i++)
Primiano Tuccidca727d2018-04-04 11:31:55 +02001062 ASSERT_EQ(i, connect_producer_and_get_id(std::to_string(i)));
Primiano Tucci081d46a2018-02-28 11:09:43 +00001063
1064 // Disconnect producers 1,3.
Primiano Tuccidca727d2018-04-04 11:31:55 +02001065 producers[1].reset();
1066 producers[3].reset();
Primiano Tucci081d46a2018-02-28 11:09:43 +00001067
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001068 *last_producer_id() = kMaxProducerID - 1;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001069 ASSERT_EQ(kMaxProducerID, connect_producer_and_get_id("maxid"));
1070 ASSERT_EQ(1u, connect_producer_and_get_id("1_again"));
1071 ASSERT_EQ(3u, connect_producer_and_get_id("3_again"));
1072 ASSERT_EQ(5u, connect_producer_and_get_id("5"));
1073 ASSERT_EQ(6u, connect_producer_and_get_id("6"));
Primiano Tucci081d46a2018-02-28 11:09:43 +00001074}
1075
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001076// Note: file_write_period_ms is set to a large enough to have exactly one flush
1077// of the tracing buffers (and therefore at most one synchronization section),
1078// unless the test runs unrealistically slowly, or the implementation of the
1079// tracing snapshot packets changes.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001080TEST_F(TracingServiceImplTest, WriteIntoFileAndStopOnMaxSize) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001081 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1082 consumer->Connect(svc.get());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001083
Primiano Tuccidca727d2018-04-04 11:31:55 +02001084 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1085 producer->Connect(svc.get(), "mock_producer");
1086 producer->RegisterDataSource("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001087
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001088 TraceConfig trace_config;
1089 trace_config.add_buffers()->set_size_kb(4096);
1090 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001091 ds_config->set_name("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001092 ds_config->set_target_buffer(0);
1093 trace_config.set_write_into_file(true);
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001094 trace_config.set_file_write_period_ms(100000); // 100s
1095 const uint64_t kMaxFileSize = 1024;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001096 trace_config.set_max_file_size_bytes(kMaxFileSize);
1097 base::TempFile tmp_file = base::TempFile::Create();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001098 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
1099
1100 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001101 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001102 producer->WaitForDataSourceStart("data_source");
1103
Hector Dearman685f7522019-03-12 14:28:56 +00001104 // The preamble packets are:
1105 // Config
1106 // SystemInfo
1107 // 3x unknown
1108 static const int kNumPreamblePackets = 5;
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001109 static const int kNumTestPackets = 10;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001110 static const char kPayload[] = "1234567890abcdef-";
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001111
1112 std::unique_ptr<TraceWriter> writer =
Primiano Tuccidca727d2018-04-04 11:31:55 +02001113 producer->CreateTraceWriter("data_source");
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001114 // Tracing service will emit a preamble of packets (a synchronization section,
1115 // followed by a tracing config packet). The preamble and these test packets
1116 // should fit within kMaxFileSize.
1117 for (int i = 0; i < kNumTestPackets; i++) {
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001118 auto tp = writer->NewTracePacket();
1119 std::string payload(kPayload);
1120 payload.append(std::to_string(i));
1121 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
1122 }
1123
1124 // Finally add a packet that overflows kMaxFileSize. This should cause the
1125 // implicit stop of the trace and should *not* be written in the trace.
1126 {
1127 auto tp = writer->NewTracePacket();
1128 char big_payload[kMaxFileSize] = "BIG!";
1129 tp->set_for_testing()->set_str(big_payload, sizeof(big_payload));
1130 }
1131 writer->Flush();
1132 writer.reset();
1133
Primiano Tuccidca727d2018-04-04 11:31:55 +02001134 consumer->DisableTracing();
1135 producer->WaitForDataSourceStop("data_source");
1136 consumer->WaitForTracingDisabled();
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001137
1138 // Verify the contents of the file.
1139 std::string trace_raw;
1140 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
1141 protos::Trace trace;
1142 ASSERT_TRUE(trace.ParseFromString(trace_raw));
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001143
1144 ASSERT_EQ(trace.packet_size(), kNumPreamblePackets + kNumTestPackets);
1145 for (int i = 0; i < kNumTestPackets; i++) {
1146 const protos::TracePacket& tp = trace.packet(kNumPreamblePackets + i);
1147 ASSERT_EQ(kPayload + std::to_string(i++), tp.for_testing().str());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001148 }
Primiano Tuccidca727d2018-04-04 11:31:55 +02001149}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001150
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001151// Test the logic that allows the trace config to set the shm total size and
1152// page size from the trace config. Also check that, if the config doesn't
1153// specify a value we fall back on the hint provided by the producer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001154TEST_F(TracingServiceImplTest, ProducerShmAndPageSizeOverriddenByTraceConfig) {
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001155 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1156 consumer->Connect(svc.get());
1157 const size_t kConfigPageSizesKb[] = /****/ {16, 16, 4, 0, 16, 8, 3, 4096, 4};
1158 const size_t kExpectedPageSizesKb[] = /**/ {16, 16, 4, 4, 16, 8, 4, 64, 4};
1159
1160 const size_t kConfigSizesKb[] = /**/ {0, 16, 0, 20, 32, 7, 0, 96, 4096000};
1161 const size_t kHintSizesKb[] = /****/ {0, 0, 16, 32, 16, 0, 7, 96, 4096000};
1162 const size_t kExpectedSizesKb[] = {
1163 kDefaultShmSizeKb, // Both hint and config are 0, use default.
1164 16, // Hint is 0, use config.
1165 16, // Config is 0, use hint.
1166 20, // Hint is takes precedence over the config.
1167 32, // Ditto, even if config is higher than hint.
1168 kDefaultShmSizeKb, // Config is invalid and hint is 0, use default.
1169 kDefaultShmSizeKb, // Config is 0 and hint is invalid, use default.
1170 kDefaultShmSizeKb, // 96 KB isn't a multiple of the page size (64 KB).
1171 kMaxShmSizeKb // Too big, cap at kMaxShmSize.
1172 };
1173
1174 const size_t kNumProducers = base::ArraySize(kHintSizesKb);
1175 std::unique_ptr<MockProducer> producer[kNumProducers];
1176 for (size_t i = 0; i < kNumProducers; i++) {
1177 auto name = "mock_producer_" + std::to_string(i);
1178 producer[i] = CreateMockProducer();
1179 producer[i]->Connect(svc.get(), name, geteuid(), kHintSizesKb[i] * 1024);
1180 producer[i]->RegisterDataSource("data_source");
1181 }
1182
1183 TraceConfig trace_config;
1184 trace_config.add_buffers()->set_size_kb(128);
1185 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1186 ds_config->set_name("data_source");
1187 for (size_t i = 0; i < kNumProducers; i++) {
1188 auto* producer_config = trace_config.add_producers();
1189 producer_config->set_producer_name("mock_producer_" + std::to_string(i));
Primiano Tucci3cbb10a2018-04-10 17:52:40 +01001190 producer_config->set_shm_size_kb(static_cast<uint32_t>(kConfigSizesKb[i]));
1191 producer_config->set_page_size_kb(
1192 static_cast<uint32_t>(kConfigPageSizesKb[i]));
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001193 }
1194
1195 consumer->EnableTracing(trace_config);
1196 size_t actual_shm_sizes_kb[kNumProducers]{};
1197 size_t actual_page_sizes_kb[kNumProducers]{};
1198 for (size_t i = 0; i < kNumProducers; i++) {
1199 producer[i]->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001200 producer[i]->WaitForDataSourceSetup("data_source");
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001201 actual_shm_sizes_kb[i] =
1202 producer[i]->endpoint()->shared_memory()->size() / 1024;
1203 actual_page_sizes_kb[i] =
1204 producer[i]->endpoint()->shared_buffer_page_size_kb();
1205 }
Primiano Tucci674076d2018-10-01 10:41:09 +01001206 for (size_t i = 0; i < kNumProducers; i++) {
1207 producer[i]->WaitForDataSourceStart("data_source");
1208 }
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001209 ASSERT_THAT(actual_page_sizes_kb, ElementsAreArray(kExpectedPageSizesKb));
1210 ASSERT_THAT(actual_shm_sizes_kb, ElementsAreArray(kExpectedSizesKb));
1211}
1212
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001213TEST_F(TracingServiceImplTest, ExplicitFlush) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001214 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1215 consumer->Connect(svc.get());
1216
1217 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1218 producer->Connect(svc.get(), "mock_producer");
1219 producer->RegisterDataSource("data_source");
1220
1221 TraceConfig trace_config;
1222 trace_config.add_buffers()->set_size_kb(128);
1223 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1224 ds_config->set_name("data_source");
1225
1226 consumer->EnableTracing(trace_config);
1227 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001228 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001229 producer->WaitForDataSourceStart("data_source");
1230
1231 std::unique_ptr<TraceWriter> writer =
1232 producer->CreateTraceWriter("data_source");
1233 {
1234 auto tp = writer->NewTracePacket();
1235 tp->set_for_testing()->set_str("payload");
1236 }
1237
1238 auto flush_request = consumer->Flush();
1239 producer->WaitForFlush(writer.get());
1240 ASSERT_TRUE(flush_request.WaitForReply());
1241
1242 consumer->DisableTracing();
1243 producer->WaitForDataSourceStop("data_source");
1244 consumer->WaitForTracingDisabled();
1245 EXPECT_THAT(
1246 consumer->ReadBuffers(),
1247 Contains(Property(&protos::TracePacket::for_testing,
1248 Property(&protos::TestEvent::str, Eq("payload")))));
1249}
1250
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001251TEST_F(TracingServiceImplTest, ImplicitFlushOnTimedTraces) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001252 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1253 consumer->Connect(svc.get());
1254
1255 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1256 producer->Connect(svc.get(), "mock_producer");
1257 producer->RegisterDataSource("data_source");
1258
1259 TraceConfig trace_config;
1260 trace_config.add_buffers()->set_size_kb(128);
1261 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1262 ds_config->set_name("data_source");
1263 trace_config.set_duration_ms(1);
1264
1265 consumer->EnableTracing(trace_config);
1266 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001267 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001268 producer->WaitForDataSourceStart("data_source");
1269
1270 std::unique_ptr<TraceWriter> writer =
1271 producer->CreateTraceWriter("data_source");
1272 {
1273 auto tp = writer->NewTracePacket();
1274 tp->set_for_testing()->set_str("payload");
1275 }
1276
1277 producer->WaitForFlush(writer.get());
1278
1279 producer->WaitForDataSourceStop("data_source");
1280 consumer->WaitForTracingDisabled();
1281
1282 EXPECT_THAT(
1283 consumer->ReadBuffers(),
1284 Contains(Property(&protos::TracePacket::for_testing,
1285 Property(&protos::TestEvent::str, Eq("payload")))));
1286}
1287
1288// Tests the monotonic semantic of flush request IDs, i.e., once a producer
1289// acks flush request N, all flush requests <= N are considered successful and
1290// acked to the consumer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001291TEST_F(TracingServiceImplTest, BatchFlushes) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001292 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1293 consumer->Connect(svc.get());
1294
1295 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1296 producer->Connect(svc.get(), "mock_producer");
1297 producer->RegisterDataSource("data_source");
1298
1299 TraceConfig trace_config;
1300 trace_config.add_buffers()->set_size_kb(128);
1301 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1302 ds_config->set_name("data_source");
1303
1304 consumer->EnableTracing(trace_config);
1305 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001306 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001307 producer->WaitForDataSourceStart("data_source");
1308
1309 std::unique_ptr<TraceWriter> writer =
1310 producer->CreateTraceWriter("data_source");
1311 {
1312 auto tp = writer->NewTracePacket();
1313 tp->set_for_testing()->set_str("payload");
1314 }
1315
1316 auto flush_req_1 = consumer->Flush();
1317 auto flush_req_2 = consumer->Flush();
1318 auto flush_req_3 = consumer->Flush();
1319
1320 // We'll deliberately let the 4th flush request timeout. Use a lower timeout
1321 // to keep test time short.
1322 auto flush_req_4 = consumer->Flush(/*timeout_ms=*/10);
1323 ASSERT_EQ(4u, GetNumPendingFlushes());
1324
1325 // Make the producer reply only to the 3rd flush request.
1326 testing::InSequence seq;
Eric Secklera01e28a2019-01-08 11:21:04 +00001327 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 1.
1328 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 2.
1329 producer->WaitForFlush(writer.get()); // Reply only to flush 3.
1330 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 4.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001331
1332 // Even if the producer explicily replied only to flush ID == 3, all the
1333 // previous flushed < 3 should be implicitly acked.
1334 ASSERT_TRUE(flush_req_1.WaitForReply());
1335 ASSERT_TRUE(flush_req_2.WaitForReply());
1336 ASSERT_TRUE(flush_req_3.WaitForReply());
1337
1338 // At this point flush id == 4 should still be pending and should fail because
1339 // of reaching its timeout.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001340 ASSERT_FALSE(flush_req_4.WaitForReply());
1341
1342 consumer->DisableTracing();
1343 producer->WaitForDataSourceStop("data_source");
1344 consumer->WaitForTracingDisabled();
1345 EXPECT_THAT(
1346 consumer->ReadBuffers(),
1347 Contains(Property(&protos::TracePacket::for_testing,
1348 Property(&protos::TestEvent::str, Eq("payload")))));
1349}
1350
Primiano Tuccicaa57802018-11-25 11:07:07 +00001351TEST_F(TracingServiceImplTest, PeriodicFlush) {
1352 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1353 consumer->Connect(svc.get());
1354
1355 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1356 producer->Connect(svc.get(), "mock_producer");
1357 producer->RegisterDataSource("data_source");
1358
1359 TraceConfig trace_config;
1360 trace_config.add_buffers()->set_size_kb(128);
1361 trace_config.set_flush_period_ms(1);
1362 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1363 ds_config->set_name("data_source");
1364
1365 consumer->EnableTracing(trace_config);
1366 producer->WaitForTracingSetup();
1367 producer->WaitForDataSourceSetup("data_source");
1368 producer->WaitForDataSourceStart("data_source");
1369
1370 std::unique_ptr<TraceWriter> writer =
1371 producer->CreateTraceWriter("data_source");
1372
1373 const int kNumFlushes = 3;
1374 auto checkpoint = task_runner.CreateCheckpoint("all_flushes_done");
1375 int flushes_seen = 0;
1376 EXPECT_CALL(*producer, Flush(_, _, _))
1377 .WillRepeatedly(Invoke([&producer, &writer, &flushes_seen, checkpoint](
1378 FlushRequestID flush_req_id,
1379 const DataSourceInstanceID*, size_t) {
1380 {
1381 auto tp = writer->NewTracePacket();
1382 char payload[32];
1383 sprintf(payload, "f_%d", flushes_seen);
1384 tp->set_for_testing()->set_str(payload);
1385 }
1386 writer->Flush();
1387 producer->endpoint()->NotifyFlushComplete(flush_req_id);
1388 if (++flushes_seen == kNumFlushes)
1389 checkpoint();
1390 }));
1391 task_runner.RunUntilCheckpoint("all_flushes_done");
1392
1393 consumer->DisableTracing();
1394 producer->WaitForDataSourceStop("data_source");
1395 consumer->WaitForTracingDisabled();
1396 auto trace_packets = consumer->ReadBuffers();
1397 for (int i = 0; i < kNumFlushes; i++) {
1398 EXPECT_THAT(trace_packets,
1399 Contains(Property(&protos::TracePacket::for_testing,
1400 Property(&protos::TestEvent::str,
1401 Eq("f_" + std::to_string(i))))));
1402 }
1403}
1404
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001405// Creates a tracing session where some of the data sources set the
1406// |will_notify_on_stop| flag and checks that the OnTracingDisabled notification
1407// to the consumer is delayed until the acks are received.
1408TEST_F(TracingServiceImplTest, OnTracingDisabledWaitsForDataSourceStopAcks) {
1409 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1410 consumer->Connect(svc.get());
1411
1412 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1413 producer->Connect(svc.get(), "mock_producer");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001414 producer->RegisterDataSource("ds_will_ack_1", /*ack_stop=*/true,
1415 /*ack_start=*/true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001416 producer->RegisterDataSource("ds_wont_ack");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001417 producer->RegisterDataSource("ds_will_ack_2", /*ack_stop=*/true,
1418 /*ack_start=*/false);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001419
1420 TraceConfig trace_config;
1421 trace_config.add_buffers()->set_size_kb(128);
1422 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_1");
1423 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1424 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_2");
1425 trace_config.set_duration_ms(1);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001426 trace_config.set_deferred_start(true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001427
1428 consumer->EnableTracing(trace_config);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001429
1430 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1431 DataSourceInstanceState::CONFIGURED);
1432 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1433 DataSourceInstanceState::CONFIGURED);
1434 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1435 DataSourceInstanceState::CONFIGURED);
1436
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001437 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001438
1439 producer->WaitForDataSourceSetup("ds_will_ack_1");
1440 producer->WaitForDataSourceSetup("ds_wont_ack");
1441 producer->WaitForDataSourceSetup("ds_will_ack_2");
1442
Eric Seckler4ff03e52019-03-15 10:10:30 +00001443 DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_will_ack_1");
1444 DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_will_ack_2");
1445
1446 consumer->StartTracing();
1447
1448 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1449 DataSourceInstanceState::STARTING);
1450 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1451 DataSourceInstanceState::STARTED);
1452 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1453 DataSourceInstanceState::STARTED);
1454
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001455 producer->WaitForDataSourceStart("ds_will_ack_1");
1456 producer->WaitForDataSourceStart("ds_wont_ack");
1457 producer->WaitForDataSourceStart("ds_will_ack_2");
1458
Eric Seckler4ff03e52019-03-15 10:10:30 +00001459 producer->endpoint()->NotifyDataSourceStarted(id1);
1460
1461 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1462 DataSourceInstanceState::STARTED);
1463
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001464 std::unique_ptr<TraceWriter> writer =
1465 producer->CreateTraceWriter("ds_wont_ack");
1466 producer->WaitForFlush(writer.get());
1467
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001468 producer->WaitForDataSourceStop("ds_will_ack_1");
1469 producer->WaitForDataSourceStop("ds_wont_ack");
1470 producer->WaitForDataSourceStop("ds_will_ack_2");
1471
Eric Seckler4ff03e52019-03-15 10:10:30 +00001472 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1473 DataSourceInstanceState::STOPPING);
1474 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1475 DataSourceInstanceState::STOPPED);
1476 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1477 DataSourceInstanceState::STOPPING);
1478
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001479 producer->endpoint()->NotifyDataSourceStopped(id1);
1480 producer->endpoint()->NotifyDataSourceStopped(id2);
1481
Eric Seckler4ff03e52019-03-15 10:10:30 +00001482 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1483 DataSourceInstanceState::STOPPED);
1484 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1485 DataSourceInstanceState::STOPPED);
1486
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001487 // Wait for at most half of the service timeout, so that this test fails if
1488 // the service falls back on calling the OnTracingDisabled() because some of
1489 // the expected acks weren't received.
1490 consumer->WaitForTracingDisabled(
1491 TracingServiceImpl::kDataSourceStopTimeoutMs / 2);
1492}
1493
Oystein Eftevaagf250e1c2018-08-23 16:10:52 -07001494// Creates a tracing session where a second data source
1495// is added while the service is waiting for DisableTracing
1496// acks; the service should not enable the new datasource
1497// and should not hit any asserts when the consumer is
1498// subsequently destroyed.
1499TEST_F(TracingServiceImplTest, OnDataSourceAddedWhilePendingDisableAcks) {
1500 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1501 consumer->Connect(svc.get());
1502
1503 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1504 producer->Connect(svc.get(), "mock_producer");
1505 producer->RegisterDataSource("ds_will_ack", /*ack_stop=*/true);
1506
1507 TraceConfig trace_config;
1508 trace_config.add_buffers()->set_size_kb(128);
1509 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack");
1510 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1511
1512 consumer->EnableTracing(trace_config);
1513 producer->WaitForTracingSetup();
1514
1515 consumer->DisableTracing();
1516
1517 producer->RegisterDataSource("ds_wont_ack");
1518
1519 consumer.reset();
1520}
1521
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001522// Similar to OnTracingDisabledWaitsForDataSourceStopAcks, but deliberately
1523// skips the ack and checks that the service invokes the OnTracingDisabled()
1524// after the timeout.
1525TEST_F(TracingServiceImplTest, OnTracingDisabledCalledAnywaysInCaseOfTimeout) {
1526 svc->override_data_source_test_timeout_ms_for_testing = 1;
1527 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1528 consumer->Connect(svc.get());
1529
1530 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1531 producer->Connect(svc.get(), "mock_producer");
1532 producer->RegisterDataSource("data_source", /*ack_stop=*/true);
1533
1534 TraceConfig trace_config;
1535 trace_config.add_buffers()->set_size_kb(128);
1536 trace_config.add_data_sources()->mutable_config()->set_name("data_source");
1537 trace_config.set_duration_ms(1);
1538
1539 consumer->EnableTracing(trace_config);
1540 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001541 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001542 producer->WaitForDataSourceStart("data_source");
1543
1544 std::unique_ptr<TraceWriter> writer =
1545 producer->CreateTraceWriter("data_source");
1546 producer->WaitForFlush(writer.get());
1547
1548 producer->WaitForDataSourceStop("data_source");
1549 consumer->WaitForTracingDisabled();
1550}
1551
Primiano Tucci03de28f2018-08-01 11:29:46 +01001552// Tests the session_id logic. Two data sources in the same tracing session
1553// should see the same session id.
1554TEST_F(TracingServiceImplTest, SessionId) {
1555 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1556 consumer->Connect(svc.get());
1557
1558 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1559 producer1->Connect(svc.get(), "mock_producer1");
1560 producer1->RegisterDataSource("ds_1A");
1561 producer1->RegisterDataSource("ds_1B");
1562
1563 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1564 producer2->Connect(svc.get(), "mock_producer2");
1565 producer2->RegisterDataSource("ds_2A");
1566
1567 testing::InSequence seq;
1568 TracingSessionID last_session_id = 0;
1569 for (int i = 0; i < 3; i++) {
1570 TraceConfig trace_config;
1571 trace_config.add_buffers()->set_size_kb(128);
1572 trace_config.add_data_sources()->mutable_config()->set_name("ds_1A");
1573 trace_config.add_data_sources()->mutable_config()->set_name("ds_1B");
1574 trace_config.add_data_sources()->mutable_config()->set_name("ds_2A");
1575 trace_config.set_duration_ms(1);
1576
1577 consumer->EnableTracing(trace_config);
1578
1579 if (i == 0)
1580 producer1->WaitForTracingSetup();
Primiano Tucci03de28f2018-08-01 11:29:46 +01001581
Primiano Tucci674076d2018-10-01 10:41:09 +01001582 producer1->WaitForDataSourceSetup("ds_1A");
1583 producer1->WaitForDataSourceSetup("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001584 if (i == 0)
1585 producer2->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001586 producer2->WaitForDataSourceSetup("ds_2A");
1587
1588 producer1->WaitForDataSourceStart("ds_1A");
1589 producer1->WaitForDataSourceStart("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001590 producer2->WaitForDataSourceStart("ds_2A");
1591
1592 auto* ds1 = producer1->GetDataSourceInstance("ds_1A");
1593 auto* ds2 = producer1->GetDataSourceInstance("ds_1B");
1594 auto* ds3 = producer2->GetDataSourceInstance("ds_2A");
1595 ASSERT_EQ(ds1->session_id, ds2->session_id);
1596 ASSERT_EQ(ds1->session_id, ds3->session_id);
1597 ASSERT_NE(ds1->session_id, last_session_id);
1598 last_session_id = ds1->session_id;
1599
1600 auto writer1 = producer1->CreateTraceWriter("ds_1A");
1601 producer1->WaitForFlush(writer1.get());
1602
1603 auto writer2 = producer2->CreateTraceWriter("ds_2A");
1604 producer2->WaitForFlush(writer2.get());
1605
1606 producer1->WaitForDataSourceStop("ds_1A");
1607 producer1->WaitForDataSourceStop("ds_1B");
1608 producer2->WaitForDataSourceStop("ds_2A");
1609 consumer->WaitForTracingDisabled();
1610 consumer->FreeBuffers();
1611 }
1612}
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001613
1614// Writes a long trace and then tests that the trace parsed in partitions
1615// derived by the synchronization markers is identical to the whole trace parsed
1616// in one go.
1617TEST_F(TracingServiceImplTest, ResynchronizeTraceStreamUsingSyncMarker) {
1618 // Setup tracing.
1619 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1620 consumer->Connect(svc.get());
1621 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1622 producer->Connect(svc.get(), "mock_producer");
1623 producer->RegisterDataSource("data_source");
1624 TraceConfig trace_config;
1625 trace_config.add_buffers()->set_size_kb(4096);
1626 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1627 ds_config->set_name("data_source");
1628 trace_config.set_write_into_file(true);
1629 trace_config.set_file_write_period_ms(1);
1630 base::TempFile tmp_file = base::TempFile::Create();
1631 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
1632 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001633 producer->WaitForDataSourceSetup("data_source");
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001634 producer->WaitForDataSourceStart("data_source");
1635
1636 // Write some variable length payload, waiting for sync markers every now
1637 // and then.
1638 const int kNumMarkers = 5;
1639 auto writer = producer->CreateTraceWriter("data_source");
1640 for (int i = 1; i <= 100; i++) {
Florian Mayereff98042018-12-10 17:44:44 +00001641 std::string payload(static_cast<size_t>(i), 'A' + (i % 25));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001642 writer->NewTracePacket()->set_for_testing()->set_str(payload.c_str());
1643 if (i % (100 / kNumMarkers) == 0) {
1644 writer->Flush();
1645 WaitForNextSyncMarker();
1646 }
1647 }
1648 writer->Flush();
1649 writer.reset();
1650 consumer->DisableTracing();
1651 producer->WaitForDataSourceStop("data_source");
1652 consumer->WaitForTracingDisabled();
1653
1654 std::string trace_raw;
1655 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
1656
1657 const auto kMarkerSize = sizeof(TracingServiceImpl::kSyncMarker);
1658 const std::string kSyncMarkerStr(
1659 reinterpret_cast<const char*>(TracingServiceImpl::kSyncMarker),
1660 kMarkerSize);
1661
1662 // Read back the trace in partitions derived from the marker.
1663 // The trace should look like this:
1664 // [uid, marker] [event] [event] [uid, marker] [event] [event]
1665 size_t num_markers = 0;
1666 size_t start = 0;
1667 size_t end = 0;
1668 protos::Trace merged_trace;
1669 for (size_t pos = 0; pos != std::string::npos; start = end) {
1670 pos = trace_raw.find(kSyncMarkerStr, pos + 1);
1671 num_markers++;
1672 end = (pos == std::string::npos) ? trace_raw.size() : pos + kMarkerSize;
1673 int size = static_cast<int>(end - start);
1674 ASSERT_GT(size, 0);
1675 protos::Trace trace_partition;
1676 ASSERT_TRUE(trace_partition.ParseFromArray(trace_raw.data() + start, size));
1677 merged_trace.MergeFrom(trace_partition);
1678 }
Lalit Maganti9bdc7ce2018-09-17 15:25:11 +01001679 EXPECT_GE(num_markers, static_cast<size_t>(kNumMarkers));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001680
1681 protos::Trace whole_trace;
1682 ASSERT_TRUE(whole_trace.ParseFromString(trace_raw));
1683
1684 ASSERT_EQ(whole_trace.packet_size(), merged_trace.packet_size());
1685 EXPECT_EQ(whole_trace.SerializeAsString(), merged_trace.SerializeAsString());
1686}
1687
Primiano Tucci674076d2018-10-01 10:41:09 +01001688// Creates a tracing session with |deferred_start| and checks that data sources
1689// are started only after calling StartTracing().
1690TEST_F(TracingServiceImplTest, DeferredStart) {
1691 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1692 consumer->Connect(svc.get());
1693
1694 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1695 producer->Connect(svc.get(), "mock_producer");
1696
1697 // Create two data sources but enable only one of them.
1698 producer->RegisterDataSource("ds_1");
1699 producer->RegisterDataSource("ds_2");
1700
1701 TraceConfig trace_config;
1702 trace_config.add_buffers()->set_size_kb(128);
1703 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
1704 trace_config.set_deferred_start(true);
1705 trace_config.set_duration_ms(1);
1706
1707 consumer->EnableTracing(trace_config);
1708 producer->WaitForTracingSetup();
1709
1710 producer->WaitForDataSourceSetup("ds_1");
1711
1712 // Make sure we don't get unexpected DataSourceStart() notifications yet.
1713 task_runner.RunUntilIdle();
1714
1715 consumer->StartTracing();
1716
1717 producer->WaitForDataSourceStart("ds_1");
1718
Stephen Nusko1393ffd2019-03-22 13:54:58 +00001719 auto writer = producer->CreateTraceWriter("ds_1");
1720 producer->WaitForFlush(writer.get());
Primiano Tucci674076d2018-10-01 10:41:09 +01001721
1722 producer->WaitForDataSourceStop("ds_1");
1723 consumer->WaitForTracingDisabled();
1724}
1725
Eric Secklerd0ac7ca2019-02-06 09:13:45 +00001726TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
1727 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1728 consumer->Connect(svc.get());
1729
1730 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1731 producer1->Connect(svc.get(), "mock_producer1", 123u /* uid */);
1732 producer1->RegisterDataSource("data_source");
1733
1734 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1735 producer2->Connect(svc.get(), "mock_producer2", 456u /* uid */);
1736 producer2->RegisterDataSource("data_source");
1737
1738 TraceConfig trace_config;
1739 trace_config.add_buffers()->set_size_kb(128);
1740 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1741 ds_config->set_name("data_source");
1742
1743 consumer->EnableTracing(trace_config);
1744 producer1->WaitForTracingSetup();
1745 producer1->WaitForDataSourceSetup("data_source");
1746 producer2->WaitForTracingSetup();
1747 producer2->WaitForDataSourceSetup("data_source");
1748 producer1->WaitForDataSourceStart("data_source");
1749 producer2->WaitForDataSourceStart("data_source");
1750
1751 std::unique_ptr<TraceWriter> writer1a =
1752 producer1->CreateTraceWriter("data_source");
1753 std::unique_ptr<TraceWriter> writer1b =
1754 producer1->CreateTraceWriter("data_source");
1755 std::unique_ptr<TraceWriter> writer2a =
1756 producer2->CreateTraceWriter("data_source");
1757 {
1758 auto tp = writer1a->NewTracePacket();
1759 tp->set_for_testing()->set_str("payload1a1");
1760 tp = writer1b->NewTracePacket();
1761 tp->set_for_testing()->set_str("payload1b1");
1762 tp = writer1a->NewTracePacket();
1763 tp->set_for_testing()->set_str("payload1a2");
1764 tp = writer2a->NewTracePacket();
1765 tp->set_for_testing()->set_str("payload2a1");
1766 tp = writer1b->NewTracePacket();
1767 tp->set_for_testing()->set_str("payload1b2");
1768 }
1769
1770 auto flush_request = consumer->Flush();
1771 producer1->WaitForFlush({writer1a.get(), writer1b.get()});
1772 producer2->WaitForFlush(writer2a.get());
1773 ASSERT_TRUE(flush_request.WaitForReply());
1774
1775 consumer->DisableTracing();
1776 producer1->WaitForDataSourceStop("data_source");
1777 producer2->WaitForDataSourceStop("data_source");
1778 consumer->WaitForTracingDisabled();
1779 auto packets = consumer->ReadBuffers();
1780 EXPECT_THAT(
1781 packets,
1782 Contains(AllOf(
1783 Property(&protos::TracePacket::for_testing,
1784 Property(&protos::TestEvent::str, Eq("payload1a1"))),
1785 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1786 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
1787 EXPECT_THAT(
1788 packets,
1789 Contains(AllOf(
1790 Property(&protos::TracePacket::for_testing,
1791 Property(&protos::TestEvent::str, Eq("payload1a2"))),
1792 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1793 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
1794 EXPECT_THAT(
1795 packets,
1796 Contains(AllOf(
1797 Property(&protos::TracePacket::for_testing,
1798 Property(&protos::TestEvent::str, Eq("payload1b1"))),
1799 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1800 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
1801 EXPECT_THAT(
1802 packets,
1803 Contains(AllOf(
1804 Property(&protos::TracePacket::for_testing,
1805 Property(&protos::TestEvent::str, Eq("payload1b2"))),
1806 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1807 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
1808 EXPECT_THAT(
1809 packets,
1810 Contains(AllOf(
1811 Property(&protos::TracePacket::for_testing,
1812 Property(&protos::TestEvent::str, Eq("payload2a1"))),
1813 Property(&protos::TracePacket::trusted_uid, Eq(456)),
1814 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(4u)))));
1815}
1816
Eric Seckler6dc23592018-11-30 10:59:06 +00001817TEST_F(TracingServiceImplTest, AllowedBuffers) {
1818 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1819 consumer->Connect(svc.get());
1820
1821 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1822 producer1->Connect(svc.get(), "mock_producer1");
1823 ProducerID producer1_id = *last_producer_id();
1824 producer1->RegisterDataSource("data_source1");
1825 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1826 producer2->Connect(svc.get(), "mock_producer2");
1827 ProducerID producer2_id = *last_producer_id();
1828 producer2->RegisterDataSource("data_source2.1");
1829 producer2->RegisterDataSource("data_source2.2");
1830 producer2->RegisterDataSource("data_source2.3");
1831
1832 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
1833 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
1834
1835 TraceConfig trace_config;
1836 trace_config.add_buffers()->set_size_kb(128);
1837 trace_config.add_buffers()->set_size_kb(128);
1838 trace_config.add_buffers()->set_size_kb(128);
1839 auto* ds_config1 = trace_config.add_data_sources()->mutable_config();
1840 ds_config1->set_name("data_source1");
1841 ds_config1->set_target_buffer(0);
1842 auto* ds_config21 = trace_config.add_data_sources()->mutable_config();
1843 ds_config21->set_name("data_source2.1");
1844 ds_config21->set_target_buffer(1);
1845 auto* ds_config22 = trace_config.add_data_sources()->mutable_config();
1846 ds_config22->set_name("data_source2.2");
1847 ds_config22->set_target_buffer(2);
1848 auto* ds_config23 = trace_config.add_data_sources()->mutable_config();
1849 ds_config23->set_name("data_source2.3");
1850 ds_config23->set_target_buffer(2); // same buffer as data_source2.2.
1851 consumer->EnableTracing(trace_config);
1852
Primiano Tucci2abd1152018-12-03 17:00:02 +01001853 ASSERT_EQ(3u, tracing_session()->num_buffers());
Eric Seckler6dc23592018-11-30 10:59:06 +00001854 std::set<BufferID> expected_buffers_producer1 = {
1855 tracing_session()->buffers_index[0]};
1856 std::set<BufferID> expected_buffers_producer2 = {
1857 tracing_session()->buffers_index[1], tracing_session()->buffers_index[2]};
1858 EXPECT_EQ(expected_buffers_producer1, GetAllowedTargetBuffers(producer1_id));
1859 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
1860
1861 producer1->WaitForTracingSetup();
1862 producer1->WaitForDataSourceSetup("data_source1");
1863
1864 producer2->WaitForTracingSetup();
1865 producer2->WaitForDataSourceSetup("data_source2.1");
1866 producer2->WaitForDataSourceSetup("data_source2.2");
1867 producer2->WaitForDataSourceSetup("data_source2.3");
1868
1869 producer1->WaitForDataSourceStart("data_source1");
1870 producer2->WaitForDataSourceStart("data_source2.1");
1871 producer2->WaitForDataSourceStart("data_source2.2");
1872 producer2->WaitForDataSourceStart("data_source2.3");
1873
1874 producer2->UnregisterDataSource("data_source2.3");
1875 producer2->WaitForDataSourceStop("data_source2.3");
1876
1877 // Should still be allowed to write to buffers 1 (data_source2.1) and 2
1878 // (data_source2.2).
1879 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
1880
1881 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1882 // trace config didn't have the |deferred_start| flag set.
1883 consumer->StartTracing();
1884
1885 consumer->DisableTracing();
1886 producer1->WaitForDataSourceStop("data_source1");
1887 producer2->WaitForDataSourceStop("data_source2.1");
1888 producer2->WaitForDataSourceStop("data_source2.2");
1889 consumer->WaitForTracingDisabled();
1890
1891 consumer->FreeBuffers();
1892 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
1893 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
1894}
1895
Eric Seckler6aa9ece2018-12-06 16:40:12 +00001896#if !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00001897TEST_F(TracingServiceImplTest, CommitToForbiddenBufferIsDiscarded) {
1898 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1899 consumer->Connect(svc.get());
1900
1901 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1902 producer->Connect(svc.get(), "mock_producer");
1903 ProducerID producer_id = *last_producer_id();
1904 producer->RegisterDataSource("data_source");
1905
1906 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
1907
1908 TraceConfig trace_config;
1909 trace_config.add_buffers()->set_size_kb(128);
1910 trace_config.add_buffers()->set_size_kb(128);
1911 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1912 ds_config->set_name("data_source");
1913 ds_config->set_target_buffer(0);
1914 consumer->EnableTracing(trace_config);
1915
1916 ASSERT_EQ(2u, tracing_session()->num_buffers());
1917 std::set<BufferID> expected_buffers = {tracing_session()->buffers_index[0]};
1918 EXPECT_EQ(expected_buffers, GetAllowedTargetBuffers(producer_id));
1919
1920 producer->WaitForTracingSetup();
1921 producer->WaitForDataSourceSetup("data_source");
1922 producer->WaitForDataSourceStart("data_source");
1923
1924 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1925 // trace config didn't have the |deferred_start| flag set.
1926 consumer->StartTracing();
1927
1928 // Try to write to the correct buffer.
1929 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1930 tracing_session()->buffers_index[0]);
1931 {
1932 auto tp = writer->NewTracePacket();
1933 tp->set_for_testing()->set_str("good_payload");
1934 }
1935
1936 auto flush_request = consumer->Flush();
1937 producer->WaitForFlush(writer.get());
1938 ASSERT_TRUE(flush_request.WaitForReply());
1939
1940 // Try to write to the wrong buffer.
1941 writer = producer->endpoint()->CreateTraceWriter(
1942 tracing_session()->buffers_index[1]);
1943 {
1944 auto tp = writer->NewTracePacket();
1945 tp->set_for_testing()->set_str("bad_payload");
1946 }
1947
1948 flush_request = consumer->Flush();
1949 producer->WaitForFlush(writer.get());
1950 ASSERT_TRUE(flush_request.WaitForReply());
1951
1952 consumer->DisableTracing();
1953 producer->WaitForDataSourceStop("data_source");
1954 consumer->WaitForTracingDisabled();
1955
1956 auto packets = consumer->ReadBuffers();
1957 EXPECT_THAT(packets, Contains(Property(&protos::TracePacket::for_testing,
1958 Property(&protos::TestEvent::str,
1959 Eq("good_payload")))));
1960 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1961 Property(&protos::TestEvent::str,
1962 Eq("bad_payload"))))));
1963
1964 consumer->FreeBuffers();
1965 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
1966}
Eric Seckler6aa9ece2018-12-06 16:40:12 +00001967#endif // !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00001968
Eric Secklerf3f524b2018-12-13 09:09:34 +00001969TEST_F(TracingServiceImplTest, RegisterAndUnregisterTraceWriter) {
1970 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1971 consumer->Connect(svc.get());
1972
1973 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1974 producer->Connect(svc.get(), "mock_producer");
1975 ProducerID producer_id = *last_producer_id();
1976 producer->RegisterDataSource("data_source");
1977
1978 EXPECT_TRUE(GetWriters(producer_id).empty());
1979
1980 TraceConfig trace_config;
1981 trace_config.add_buffers()->set_size_kb(128);
1982 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1983 ds_config->set_name("data_source");
1984 ds_config->set_target_buffer(0);
1985 consumer->EnableTracing(trace_config);
1986
1987 producer->WaitForTracingSetup();
1988 producer->WaitForDataSourceSetup("data_source");
1989 producer->WaitForDataSourceStart("data_source");
1990
1991 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1992 // trace config didn't have the |deferred_start| flag set.
1993 consumer->StartTracing();
1994
1995 // Creating the trace writer should register it with the service.
1996 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1997 tracing_session()->buffers_index[0]);
1998
1999 WaitForTraceWritersChanged(producer_id);
2000
2001 std::map<WriterID, BufferID> expected_writers;
2002 expected_writers[writer->writer_id()] = tracing_session()->buffers_index[0];
2003 EXPECT_EQ(expected_writers, GetWriters(producer_id));
2004
2005 // Verify writing works.
2006 {
2007 auto tp = writer->NewTracePacket();
2008 tp->set_for_testing()->set_str("payload");
2009 }
2010
2011 auto flush_request = consumer->Flush();
2012 producer->WaitForFlush(writer.get());
2013 ASSERT_TRUE(flush_request.WaitForReply());
2014
2015 // Destroying the writer should unregister it.
2016 writer.reset();
2017 WaitForTraceWritersChanged(producer_id);
2018 EXPECT_TRUE(GetWriters(producer_id).empty());
2019
2020 consumer->DisableTracing();
2021 producer->WaitForDataSourceStop("data_source");
2022 consumer->WaitForTracingDisabled();
2023
2024 auto packets = consumer->ReadBuffers();
2025 EXPECT_THAT(packets, Contains(Property(
2026 &protos::TracePacket::for_testing,
2027 Property(&protos::TestEvent::str, Eq("payload")))));
2028}
2029
Eric Secklera01e28a2019-01-08 11:21:04 +00002030TEST_F(TracingServiceImplTest, ScrapeBuffersOnFlush) {
2031 svc->SetSMBScrapingEnabled(true);
2032
2033 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2034 consumer->Connect(svc.get());
2035
2036 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2037 producer->Connect(svc.get(), "mock_producer");
2038 ProducerID producer_id = *last_producer_id();
2039 producer->RegisterDataSource("data_source");
2040
2041 TraceConfig trace_config;
2042 trace_config.add_buffers()->set_size_kb(128);
2043 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2044 ds_config->set_name("data_source");
2045 ds_config->set_target_buffer(0);
2046 consumer->EnableTracing(trace_config);
2047
2048 producer->WaitForTracingSetup();
2049 producer->WaitForDataSourceSetup("data_source");
2050 producer->WaitForDataSourceStart("data_source");
2051
2052 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2053 // trace config didn't have the |deferred_start| flag set.
2054 consumer->StartTracing();
2055
2056 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2057 tracing_session()->buffers_index[0]);
2058 WaitForTraceWritersChanged(producer_id);
2059
2060 // Write a few trace packets.
2061 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2062 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2063 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2064
2065 // Flush but don't actually flush the chunk from TraceWriter.
2066 auto flush_request = consumer->Flush();
2067 producer->WaitForFlush(nullptr, /*reply=*/true);
2068 ASSERT_TRUE(flush_request.WaitForReply());
2069
2070 // Chunk with the packets should have been scraped. The service can't know
2071 // whether the last packet was completed, so shouldn't read it.
2072 auto packets = consumer->ReadBuffers();
2073 EXPECT_THAT(packets, Contains(Property(
2074 &protos::TracePacket::for_testing,
2075 Property(&protos::TestEvent::str, Eq("payload1")))));
2076 EXPECT_THAT(packets, Contains(Property(
2077 &protos::TracePacket::for_testing,
2078 Property(&protos::TestEvent::str, Eq("payload2")))));
2079 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2080 Property(&protos::TestEvent::str,
2081 Eq("payload3"))))));
2082
2083 // Write some more packets.
2084 writer->NewTracePacket()->set_for_testing()->set_str("payload4");
2085 writer->NewTracePacket()->set_for_testing()->set_str("payload5");
2086
2087 // Don't reply to flush, causing a timeout. This should scrape again.
2088 flush_request = consumer->Flush(/*timeout=*/100);
2089 producer->WaitForFlush(nullptr, /*reply=*/false);
2090 ASSERT_FALSE(flush_request.WaitForReply());
2091
2092 // Chunk with the packets should have been scraped again, overriding the
2093 // original one. Again, the last packet should be ignored and the first two
2094 // should not be read twice.
2095 packets = consumer->ReadBuffers();
2096 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2097 Property(&protos::TestEvent::str,
2098 Eq("payload1"))))));
2099 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2100 Property(&protos::TestEvent::str,
2101 Eq("payload2"))))));
2102 EXPECT_THAT(packets, Contains(Property(
2103 &protos::TracePacket::for_testing,
2104 Property(&protos::TestEvent::str, Eq("payload3")))));
2105 EXPECT_THAT(packets, Contains(Property(
2106 &protos::TracePacket::for_testing,
2107 Property(&protos::TestEvent::str, Eq("payload4")))));
2108 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2109 Property(&protos::TestEvent::str,
2110 Eq("payload5"))))));
2111
2112 consumer->DisableTracing();
2113 producer->WaitForDataSourceStop("data_source");
2114 consumer->WaitForTracingDisabled();
2115}
2116
2117// Test scraping on producer disconnect.
2118TEST_F(TracingServiceImplTest, ScrapeBuffersOnProducerDisconnect) {
2119 svc->SetSMBScrapingEnabled(true);
2120
2121 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2122 consumer->Connect(svc.get());
2123
2124 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2125 producer->Connect(svc.get(), "mock_producer");
2126 ProducerID producer_id = *last_producer_id();
2127 producer->RegisterDataSource("data_source");
2128
2129 TraceConfig trace_config;
2130 trace_config.add_buffers()->set_size_kb(128);
2131 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2132 ds_config->set_name("data_source");
2133 ds_config->set_target_buffer(0);
2134 consumer->EnableTracing(trace_config);
2135
2136 producer->WaitForTracingSetup();
2137 producer->WaitForDataSourceSetup("data_source");
2138 producer->WaitForDataSourceStart("data_source");
2139
2140 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2141 // trace config didn't have the |deferred_start| flag set.
2142 consumer->StartTracing();
2143
2144 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2145 tracing_session()->buffers_index[0]);
2146 WaitForTraceWritersChanged(producer_id);
2147
2148 // Write a few trace packets.
2149 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2150 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2151 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2152
2153 // Disconnect the producer without committing the chunk. This should cause a
2154 // scrape of the SMB. Avoid destroying the ShmemArbiter until writer is
2155 // destroyed.
2156 auto shmem_arbiter = TakeShmemArbiterForProducer(producer_id);
2157 producer.reset();
2158
2159 // Chunk with the packets should have been scraped. The service can't know
2160 // whether the last packet was completed, so shouldn't read it.
2161 auto packets = consumer->ReadBuffers();
2162 EXPECT_THAT(packets, Contains(Property(
2163 &protos::TracePacket::for_testing,
2164 Property(&protos::TestEvent::str, Eq("payload1")))));
2165 EXPECT_THAT(packets, Contains(Property(
2166 &protos::TracePacket::for_testing,
2167 Property(&protos::TestEvent::str, Eq("payload2")))));
2168 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2169 Property(&protos::TestEvent::str,
2170 Eq("payload3"))))));
2171
2172 // Cleanup writer without causing a crash because the producer already went
2173 // away.
2174 static_cast<TraceWriterImpl*>(writer.get())->ResetChunkForTesting();
2175 writer.reset();
2176 shmem_arbiter.reset();
2177
2178 consumer->DisableTracing();
2179 consumer->WaitForTracingDisabled();
2180}
2181
2182TEST_F(TracingServiceImplTest, ScrapeBuffersOnDisable) {
2183 svc->SetSMBScrapingEnabled(true);
2184
2185 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2186 consumer->Connect(svc.get());
2187
2188 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2189 producer->Connect(svc.get(), "mock_producer");
2190 ProducerID producer_id = *last_producer_id();
2191 producer->RegisterDataSource("data_source");
2192
2193 TraceConfig trace_config;
2194 trace_config.add_buffers()->set_size_kb(128);
2195 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2196 ds_config->set_name("data_source");
2197 ds_config->set_target_buffer(0);
2198 consumer->EnableTracing(trace_config);
2199
2200 producer->WaitForTracingSetup();
2201 producer->WaitForDataSourceSetup("data_source");
2202 producer->WaitForDataSourceStart("data_source");
2203
2204 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2205 // trace config didn't have the |deferred_start| flag set.
2206 consumer->StartTracing();
2207
2208 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2209 tracing_session()->buffers_index[0]);
2210 WaitForTraceWritersChanged(producer_id);
2211
2212 // Write a few trace packets.
2213 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2214 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2215 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2216
2217 consumer->DisableTracing();
2218 producer->WaitForDataSourceStop("data_source");
2219 consumer->WaitForTracingDisabled();
2220
2221 // Chunk with the packets should have been scraped. The service can't know
2222 // whether the last packet was completed, so shouldn't read it.
2223 auto packets = consumer->ReadBuffers();
2224 EXPECT_THAT(packets, Contains(Property(
2225 &protos::TracePacket::for_testing,
2226 Property(&protos::TestEvent::str, Eq("payload1")))));
2227 EXPECT_THAT(packets, Contains(Property(
2228 &protos::TracePacket::for_testing,
2229 Property(&protos::TestEvent::str, Eq("payload2")))));
2230 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2231 Property(&protos::TestEvent::str,
2232 Eq("payload3"))))));
2233}
2234
Primiano Tucciff7beab2019-01-09 21:49:20 +00002235TEST_F(TracingServiceImplTest, AbortIfTraceDurationIsTooLong) {
2236 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2237 consumer->Connect(svc.get());
2238
2239 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2240 producer->Connect(svc.get(), "mock_producer");
2241 producer->RegisterDataSource("datasource");
2242
2243 TraceConfig trace_config;
2244 trace_config.add_buffers()->set_size_kb(128);
2245 trace_config.add_data_sources()->mutable_config()->set_name("datasource");
2246 trace_config.set_duration_ms(0x7fffffff);
2247
2248 EXPECT_CALL(*producer, SetupDataSource(_, _)).Times(0);
2249 consumer->EnableTracing(trace_config);
2250
2251 // The trace is aborted immediately, 5s here is just some slack for the thread
2252 // ping-pongs for slow devices.
2253 consumer->WaitForTracingDisabled(5000);
2254}
2255
Eric Secklereaf29ed2019-01-23 09:53:55 +00002256TEST_F(TracingServiceImplTest, GetTraceStats) {
2257 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2258 consumer->Connect(svc.get());
2259
2260 consumer->GetTraceStats();
2261 consumer->WaitForTraceStats(false);
2262
2263 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2264 producer->Connect(svc.get(), "mock_producer");
2265 producer->RegisterDataSource("data_source");
2266
2267 TraceConfig trace_config;
2268 trace_config.add_buffers()->set_size_kb(128);
2269 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2270 ds_config->set_name("data_source");
2271
2272 consumer->EnableTracing(trace_config);
2273 producer->WaitForTracingSetup();
2274 producer->WaitForDataSourceSetup("data_source");
2275 producer->WaitForDataSourceStart("data_source");
2276
2277 consumer->GetTraceStats();
2278 consumer->WaitForTraceStats(true);
2279
2280 consumer->DisableTracing();
2281 producer->WaitForDataSourceStop("data_source");
2282 consumer->WaitForTracingDisabled();
2283}
2284
Eric Seckler7b0c9452019-03-18 13:14:36 +00002285TEST_F(TracingServiceImplTest, ObserveEventsDataSourceInstances) {
2286 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2287 consumer->Connect(svc.get());
2288
2289 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2290 producer->Connect(svc.get(), "mock_producer");
2291 producer->RegisterDataSource("data_source");
2292
2293 TraceConfig trace_config;
2294 trace_config.add_buffers()->set_size_kb(128);
2295 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2296 ds_config->set_name("data_source");
2297
2298 // Start tracing before the consumer is interested in events. The consumer's
2299 // OnObservableEvents() should not be called yet.
2300 consumer->EnableTracing(trace_config);
2301 producer->WaitForTracingSetup();
2302 producer->WaitForDataSourceSetup("data_source");
2303 producer->WaitForDataSourceStart("data_source");
2304
2305 // Calling ObserveEvents should cause an event for the initial instance state.
2306 consumer->ObserveEvents(TracingService::ConsumerEndpoint::
2307 ObservableEventType::kDataSourceInstances);
2308 {
2309 auto events = consumer->WaitForObservableEvents();
2310
2311 ObservableEvents::DataSourceInstanceStateChange change;
2312 change.set_producer_name("mock_producer");
2313 change.set_data_source_name("data_source");
2314 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2315 DATA_SOURCE_INSTANCE_STATE_STARTED);
2316 EXPECT_EQ(events.instance_state_changes_size(), 1);
2317 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2318 }
2319
2320 // Disabling should cause an instance state change to STOPPED.
2321 consumer->DisableTracing();
2322
2323 {
2324 auto events = consumer->WaitForObservableEvents();
2325
2326 ObservableEvents::DataSourceInstanceStateChange change;
2327 change.set_producer_name("mock_producer");
2328 change.set_data_source_name("data_source");
2329 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2330 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2331 EXPECT_EQ(events.instance_state_changes_size(), 1);
2332 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2333 }
2334
2335 producer->WaitForDataSourceStop("data_source");
2336 consumer->WaitForTracingDisabled();
2337 consumer->FreeBuffers();
2338
2339 // Enable again, this should cause a state change for a new instance to
2340 // its initial state STOPPED.
2341 trace_config.set_deferred_start(true);
2342 consumer->EnableTracing(trace_config);
2343
2344 {
2345 auto events = consumer->WaitForObservableEvents();
2346
2347 ObservableEvents::DataSourceInstanceStateChange change;
2348 change.set_producer_name("mock_producer");
2349 change.set_data_source_name("data_source");
2350 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2351 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2352 EXPECT_EQ(events.instance_state_changes_size(), 1);
2353 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2354 }
2355
2356 producer->WaitForDataSourceSetup("data_source");
2357
2358 // Should move the instance into STARTED state and thus cause an event.
2359 consumer->StartTracing();
2360
2361 {
2362 auto events = consumer->WaitForObservableEvents();
2363
2364 ObservableEvents::DataSourceInstanceStateChange change;
2365 change.set_producer_name("mock_producer");
2366 change.set_data_source_name("data_source");
2367 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2368 DATA_SOURCE_INSTANCE_STATE_STARTED);
2369 EXPECT_EQ(events.instance_state_changes_size(), 1);
2370 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2371 }
2372
2373 producer->WaitForDataSourceStart("data_source");
2374
2375 // Stop observing events.
2376 consumer->ObserveEvents(
2377 TracingService::ConsumerEndpoint::ObservableEventType::kNone);
2378
2379 // Disabling should now no longer cause events to be sent to the consumer.
2380 consumer->DisableTracing();
2381 producer->WaitForDataSourceStop("data_source");
2382 consumer->WaitForTracingDisabled();
2383}
2384
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00002385} // namespace perfetto