blob: cb52f791dc9757669cfbf5473e5d3bc04cc78199 [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
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100671TEST_F(TracingServiceImplTest, LockdownMode) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200672 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
673 consumer->Connect(svc.get());
674
675 std::unique_ptr<MockProducer> producer = CreateMockProducer();
676 producer->Connect(svc.get(), "mock_producer_sameuid", geteuid());
677 producer->RegisterDataSource("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +0000678
679 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200680 trace_config.add_buffers()->set_size_kb(128);
681 auto* ds_config = trace_config.add_data_sources()->mutable_config();
682 ds_config->set_name("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +0000683 trace_config.set_lockdown_mode(
684 TraceConfig::LockdownModeOperation::LOCKDOWN_SET);
Primiano Tuccidca727d2018-04-04 11:31:55 +0200685 consumer->EnableTracing(trace_config);
686
687 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100688 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200689 producer->WaitForDataSourceStart("data_source");
690
691 std::unique_ptr<MockProducer> producer_otheruid = CreateMockProducer();
692 auto x = svc->ConnectProducer(producer_otheruid.get(), geteuid() + 1,
693 "mock_producer_ouid");
694 EXPECT_CALL(*producer_otheruid, OnConnect()).Times(0);
Florian Mayer61c55482018-03-06 14:43:54 +0000695 task_runner.RunUntilIdle();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200696 Mock::VerifyAndClearExpectations(producer_otheruid.get());
Florian Mayer61c55482018-03-06 14:43:54 +0000697
Primiano Tuccidca727d2018-04-04 11:31:55 +0200698 consumer->DisableTracing();
699 consumer->FreeBuffers();
700 producer->WaitForDataSourceStop("data_source");
701 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +0000702
703 trace_config.set_lockdown_mode(
704 TraceConfig::LockdownModeOperation::LOCKDOWN_CLEAR);
Primiano Tuccidca727d2018-04-04 11:31:55 +0200705 consumer->EnableTracing(trace_config);
Primiano Tucci674076d2018-10-01 10:41:09 +0100706 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200707 producer->WaitForDataSourceStart("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +0000708
Primiano Tuccidca727d2018-04-04 11:31:55 +0200709 std::unique_ptr<MockProducer> producer_otheruid2 = CreateMockProducer();
710 producer_otheruid->Connect(svc.get(), "mock_producer_ouid2", geteuid() + 1);
Florian Mayer61c55482018-03-06 14:43:54 +0000711
Primiano Tuccidca727d2018-04-04 11:31:55 +0200712 consumer->DisableTracing();
713 producer->WaitForDataSourceStop("data_source");
714 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +0000715}
716
Oystein Eftevaagcb6e4c82019-03-06 15:38:26 -0800717TEST_F(TracingServiceImplTest, ProducerNameFilterChange) {
718 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
719 consumer->Connect(svc.get());
720
721 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
722 producer1->Connect(svc.get(), "mock_producer_1");
723 producer1->RegisterDataSource("data_source");
724
725 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
726 producer2->Connect(svc.get(), "mock_producer_2");
727 producer2->RegisterDataSource("data_source");
728
729 std::unique_ptr<MockProducer> producer3 = CreateMockProducer();
730 producer3->Connect(svc.get(), "mock_producer_3");
731 producer3->RegisterDataSource("data_source");
732 producer3->RegisterDataSource("unused_data_source");
733
734 TraceConfig trace_config;
735 trace_config.add_buffers()->set_size_kb(128);
736 auto* data_source = trace_config.add_data_sources();
737 data_source->mutable_config()->set_name("data_source");
738 *data_source->add_producer_name_filter() = "mock_producer_1";
739
740 // Enable tracing with only mock_producer_1 enabled;
741 // the rest should not start up.
742 consumer->EnableTracing(trace_config);
743
744 producer1->WaitForTracingSetup();
745 producer1->WaitForDataSourceSetup("data_source");
746 producer1->WaitForDataSourceStart("data_source");
747
748 EXPECT_CALL(*producer2, OnConnect()).Times(0);
749 EXPECT_CALL(*producer3, OnConnect()).Times(0);
750 task_runner.RunUntilIdle();
751 Mock::VerifyAndClearExpectations(producer2.get());
752 Mock::VerifyAndClearExpectations(producer3.get());
753
754 // Enable mock_producer_2, the third one should still
755 // not get connected.
756 *data_source->add_producer_name_filter() = "mock_producer_2";
757 consumer->ChangeTraceConfig(trace_config);
758
759 producer2->WaitForTracingSetup();
760 producer2->WaitForDataSourceSetup("data_source");
761 producer2->WaitForDataSourceStart("data_source");
762
763 // Enable mock_producer_3 but also try to do an
764 // unsupported change (adding a new data source);
765 // mock_producer_3 should get enabled but not
766 // for the new data source.
767 *data_source->add_producer_name_filter() = "mock_producer_3";
768 auto* dummy_data_source = trace_config.add_data_sources();
769 dummy_data_source->mutable_config()->set_name("unused_data_source");
770 *dummy_data_source->add_producer_name_filter() = "mock_producer_3";
771
772 consumer->ChangeTraceConfig(trace_config);
773
774 producer3->WaitForTracingSetup();
775 EXPECT_CALL(*producer3, SetupDataSource(_, _)).Times(1);
776 EXPECT_CALL(*producer3, StartDataSource(_, _)).Times(1);
777 task_runner.RunUntilIdle();
778 Mock::VerifyAndClearExpectations(producer3.get());
779
780 consumer->DisableTracing();
781 consumer->FreeBuffers();
782 producer1->WaitForDataSourceStop("data_source");
783 producer2->WaitForDataSourceStop("data_source");
784
785 EXPECT_CALL(*producer3, StopDataSource(_)).Times(1);
786
787 consumer->WaitForTracingDisabled();
788
789 task_runner.RunUntilIdle();
790 Mock::VerifyAndClearExpectations(producer3.get());
791}
792
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100793TEST_F(TracingServiceImplTest, DisconnectConsumerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200794 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
795 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +0000796
Primiano Tuccidca727d2018-04-04 11:31:55 +0200797 std::unique_ptr<MockProducer> producer = CreateMockProducer();
798 producer->Connect(svc.get(), "mock_producer");
799 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000800
Primiano Tuccidca727d2018-04-04 11:31:55 +0200801 TraceConfig trace_config;
802 trace_config.add_buffers()->set_size_kb(128);
803 auto* ds_config = trace_config.add_data_sources()->mutable_config();
804 ds_config->set_name("data_source");
805 consumer->EnableTracing(trace_config);
806
807 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100808 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200809 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000810
811 // Disconnecting the consumer while tracing should trigger data source
812 // teardown.
Primiano Tuccidca727d2018-04-04 11:31:55 +0200813 consumer.reset();
814 producer->WaitForDataSourceStop("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000815}
816
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100817TEST_F(TracingServiceImplTest, ReconnectProducerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200818 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
819 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +0000820
Primiano Tuccidca727d2018-04-04 11:31:55 +0200821 std::unique_ptr<MockProducer> producer = CreateMockProducer();
822 producer->Connect(svc.get(), "mock_producer");
823 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000824
Sami Kyostila06487a22018-02-27 13:48:38 +0000825 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200826 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +0000827 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200828 ds_config->set_name("data_source");
829 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +0000830
Primiano Tuccidca727d2018-04-04 11:31:55 +0200831 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100832 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200833 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000834
Primiano Tuccidca727d2018-04-04 11:31:55 +0200835 // Disconnecting and reconnecting a producer with a matching data source.
836 // The Producer should see that data source getting enabled again.
837 producer.reset();
838 producer = CreateMockProducer();
839 producer->Connect(svc.get(), "mock_producer_2");
840 producer->RegisterDataSource("data_source");
841 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100842 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200843 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000844}
845
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100846TEST_F(TracingServiceImplTest, ProducerIDWrapping) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200847 std::vector<std::unique_ptr<MockProducer>> producers;
848 producers.push_back(nullptr);
Primiano Tucci081d46a2018-02-28 11:09:43 +0000849
Primiano Tuccidca727d2018-04-04 11:31:55 +0200850 auto connect_producer_and_get_id = [&producers,
851 this](const std::string& name) {
852 producers.emplace_back(CreateMockProducer());
853 producers.back()->Connect(svc.get(), "mock_producer_" + name);
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200854 return *last_producer_id();
Primiano Tucci081d46a2018-02-28 11:09:43 +0000855 };
856
857 // Connect producers 1-4.
858 for (ProducerID i = 1; i <= 4; i++)
Primiano Tuccidca727d2018-04-04 11:31:55 +0200859 ASSERT_EQ(i, connect_producer_and_get_id(std::to_string(i)));
Primiano Tucci081d46a2018-02-28 11:09:43 +0000860
861 // Disconnect producers 1,3.
Primiano Tuccidca727d2018-04-04 11:31:55 +0200862 producers[1].reset();
863 producers[3].reset();
Primiano Tucci081d46a2018-02-28 11:09:43 +0000864
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200865 *last_producer_id() = kMaxProducerID - 1;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200866 ASSERT_EQ(kMaxProducerID, connect_producer_and_get_id("maxid"));
867 ASSERT_EQ(1u, connect_producer_and_get_id("1_again"));
868 ASSERT_EQ(3u, connect_producer_and_get_id("3_again"));
869 ASSERT_EQ(5u, connect_producer_and_get_id("5"));
870 ASSERT_EQ(6u, connect_producer_and_get_id("6"));
Primiano Tucci081d46a2018-02-28 11:09:43 +0000871}
872
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000873// Note: file_write_period_ms is set to a large enough to have exactly one flush
874// of the tracing buffers (and therefore at most one synchronization section),
875// unless the test runs unrealistically slowly, or the implementation of the
876// tracing snapshot packets changes.
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100877TEST_F(TracingServiceImplTest, WriteIntoFileAndStopOnMaxSize) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200878 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
879 consumer->Connect(svc.get());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100880
Primiano Tuccidca727d2018-04-04 11:31:55 +0200881 std::unique_ptr<MockProducer> producer = CreateMockProducer();
882 producer->Connect(svc.get(), "mock_producer");
883 producer->RegisterDataSource("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100884
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100885 TraceConfig trace_config;
886 trace_config.add_buffers()->set_size_kb(4096);
887 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200888 ds_config->set_name("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100889 ds_config->set_target_buffer(0);
890 trace_config.set_write_into_file(true);
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000891 trace_config.set_file_write_period_ms(100000); // 100s
892 const uint64_t kMaxFileSize = 1024;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100893 trace_config.set_max_file_size_bytes(kMaxFileSize);
894 base::TempFile tmp_file = base::TempFile::Create();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200895 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
896
897 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100898 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200899 producer->WaitForDataSourceStart("data_source");
900
Hector Dearman685f7522019-03-12 14:28:56 +0000901 // The preamble packets are:
902 // Config
903 // SystemInfo
904 // 3x unknown
905 static const int kNumPreamblePackets = 5;
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000906 static const int kNumTestPackets = 10;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200907 static const char kPayload[] = "1234567890abcdef-";
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100908
909 std::unique_ptr<TraceWriter> writer =
Primiano Tuccidca727d2018-04-04 11:31:55 +0200910 producer->CreateTraceWriter("data_source");
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000911 // Tracing service will emit a preamble of packets (a synchronization section,
912 // followed by a tracing config packet). The preamble and these test packets
913 // should fit within kMaxFileSize.
914 for (int i = 0; i < kNumTestPackets; i++) {
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100915 auto tp = writer->NewTracePacket();
916 std::string payload(kPayload);
917 payload.append(std::to_string(i));
918 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
919 }
920
921 // Finally add a packet that overflows kMaxFileSize. This should cause the
922 // implicit stop of the trace and should *not* be written in the trace.
923 {
924 auto tp = writer->NewTracePacket();
925 char big_payload[kMaxFileSize] = "BIG!";
926 tp->set_for_testing()->set_str(big_payload, sizeof(big_payload));
927 }
928 writer->Flush();
929 writer.reset();
930
Primiano Tuccidca727d2018-04-04 11:31:55 +0200931 consumer->DisableTracing();
932 producer->WaitForDataSourceStop("data_source");
933 consumer->WaitForTracingDisabled();
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100934
935 // Verify the contents of the file.
936 std::string trace_raw;
937 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
938 protos::Trace trace;
939 ASSERT_TRUE(trace.ParseFromString(trace_raw));
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000940
941 ASSERT_EQ(trace.packet_size(), kNumPreamblePackets + kNumTestPackets);
942 for (int i = 0; i < kNumTestPackets; i++) {
943 const protos::TracePacket& tp = trace.packet(kNumPreamblePackets + i);
944 ASSERT_EQ(kPayload + std::to_string(i++), tp.for_testing().str());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100945 }
Primiano Tuccidca727d2018-04-04 11:31:55 +0200946}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100947
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200948// Test the logic that allows the trace config to set the shm total size and
949// page size from the trace config. Also check that, if the config doesn't
950// specify a value we fall back on the hint provided by the producer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100951TEST_F(TracingServiceImplTest, ProducerShmAndPageSizeOverriddenByTraceConfig) {
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200952 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
953 consumer->Connect(svc.get());
954 const size_t kConfigPageSizesKb[] = /****/ {16, 16, 4, 0, 16, 8, 3, 4096, 4};
955 const size_t kExpectedPageSizesKb[] = /**/ {16, 16, 4, 4, 16, 8, 4, 64, 4};
956
957 const size_t kConfigSizesKb[] = /**/ {0, 16, 0, 20, 32, 7, 0, 96, 4096000};
958 const size_t kHintSizesKb[] = /****/ {0, 0, 16, 32, 16, 0, 7, 96, 4096000};
959 const size_t kExpectedSizesKb[] = {
960 kDefaultShmSizeKb, // Both hint and config are 0, use default.
961 16, // Hint is 0, use config.
962 16, // Config is 0, use hint.
963 20, // Hint is takes precedence over the config.
964 32, // Ditto, even if config is higher than hint.
965 kDefaultShmSizeKb, // Config is invalid and hint is 0, use default.
966 kDefaultShmSizeKb, // Config is 0 and hint is invalid, use default.
967 kDefaultShmSizeKb, // 96 KB isn't a multiple of the page size (64 KB).
968 kMaxShmSizeKb // Too big, cap at kMaxShmSize.
969 };
970
971 const size_t kNumProducers = base::ArraySize(kHintSizesKb);
972 std::unique_ptr<MockProducer> producer[kNumProducers];
973 for (size_t i = 0; i < kNumProducers; i++) {
974 auto name = "mock_producer_" + std::to_string(i);
975 producer[i] = CreateMockProducer();
976 producer[i]->Connect(svc.get(), name, geteuid(), kHintSizesKb[i] * 1024);
977 producer[i]->RegisterDataSource("data_source");
978 }
979
980 TraceConfig trace_config;
981 trace_config.add_buffers()->set_size_kb(128);
982 auto* ds_config = trace_config.add_data_sources()->mutable_config();
983 ds_config->set_name("data_source");
984 for (size_t i = 0; i < kNumProducers; i++) {
985 auto* producer_config = trace_config.add_producers();
986 producer_config->set_producer_name("mock_producer_" + std::to_string(i));
Primiano Tucci3cbb10a2018-04-10 17:52:40 +0100987 producer_config->set_shm_size_kb(static_cast<uint32_t>(kConfigSizesKb[i]));
988 producer_config->set_page_size_kb(
989 static_cast<uint32_t>(kConfigPageSizesKb[i]));
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200990 }
991
992 consumer->EnableTracing(trace_config);
993 size_t actual_shm_sizes_kb[kNumProducers]{};
994 size_t actual_page_sizes_kb[kNumProducers]{};
995 for (size_t i = 0; i < kNumProducers; i++) {
996 producer[i]->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100997 producer[i]->WaitForDataSourceSetup("data_source");
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200998 actual_shm_sizes_kb[i] =
999 producer[i]->endpoint()->shared_memory()->size() / 1024;
1000 actual_page_sizes_kb[i] =
1001 producer[i]->endpoint()->shared_buffer_page_size_kb();
1002 }
Primiano Tucci674076d2018-10-01 10:41:09 +01001003 for (size_t i = 0; i < kNumProducers; i++) {
1004 producer[i]->WaitForDataSourceStart("data_source");
1005 }
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001006 ASSERT_THAT(actual_page_sizes_kb, ElementsAreArray(kExpectedPageSizesKb));
1007 ASSERT_THAT(actual_shm_sizes_kb, ElementsAreArray(kExpectedSizesKb));
1008}
1009
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001010TEST_F(TracingServiceImplTest, ExplicitFlush) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001011 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1012 consumer->Connect(svc.get());
1013
1014 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1015 producer->Connect(svc.get(), "mock_producer");
1016 producer->RegisterDataSource("data_source");
1017
1018 TraceConfig trace_config;
1019 trace_config.add_buffers()->set_size_kb(128);
1020 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1021 ds_config->set_name("data_source");
1022
1023 consumer->EnableTracing(trace_config);
1024 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001025 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001026 producer->WaitForDataSourceStart("data_source");
1027
1028 std::unique_ptr<TraceWriter> writer =
1029 producer->CreateTraceWriter("data_source");
1030 {
1031 auto tp = writer->NewTracePacket();
1032 tp->set_for_testing()->set_str("payload");
1033 }
1034
1035 auto flush_request = consumer->Flush();
1036 producer->WaitForFlush(writer.get());
1037 ASSERT_TRUE(flush_request.WaitForReply());
1038
1039 consumer->DisableTracing();
1040 producer->WaitForDataSourceStop("data_source");
1041 consumer->WaitForTracingDisabled();
1042 EXPECT_THAT(
1043 consumer->ReadBuffers(),
1044 Contains(Property(&protos::TracePacket::for_testing,
1045 Property(&protos::TestEvent::str, Eq("payload")))));
1046}
1047
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001048TEST_F(TracingServiceImplTest, ImplicitFlushOnTimedTraces) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001049 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1050 consumer->Connect(svc.get());
1051
1052 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1053 producer->Connect(svc.get(), "mock_producer");
1054 producer->RegisterDataSource("data_source");
1055
1056 TraceConfig trace_config;
1057 trace_config.add_buffers()->set_size_kb(128);
1058 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1059 ds_config->set_name("data_source");
1060 trace_config.set_duration_ms(1);
1061
1062 consumer->EnableTracing(trace_config);
1063 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001064 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001065 producer->WaitForDataSourceStart("data_source");
1066
1067 std::unique_ptr<TraceWriter> writer =
1068 producer->CreateTraceWriter("data_source");
1069 {
1070 auto tp = writer->NewTracePacket();
1071 tp->set_for_testing()->set_str("payload");
1072 }
1073
1074 producer->WaitForFlush(writer.get());
1075
1076 producer->WaitForDataSourceStop("data_source");
1077 consumer->WaitForTracingDisabled();
1078
1079 EXPECT_THAT(
1080 consumer->ReadBuffers(),
1081 Contains(Property(&protos::TracePacket::for_testing,
1082 Property(&protos::TestEvent::str, Eq("payload")))));
1083}
1084
1085// Tests the monotonic semantic of flush request IDs, i.e., once a producer
1086// acks flush request N, all flush requests <= N are considered successful and
1087// acked to the consumer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001088TEST_F(TracingServiceImplTest, BatchFlushes) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001089 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1090 consumer->Connect(svc.get());
1091
1092 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1093 producer->Connect(svc.get(), "mock_producer");
1094 producer->RegisterDataSource("data_source");
1095
1096 TraceConfig trace_config;
1097 trace_config.add_buffers()->set_size_kb(128);
1098 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1099 ds_config->set_name("data_source");
1100
1101 consumer->EnableTracing(trace_config);
1102 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001103 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001104 producer->WaitForDataSourceStart("data_source");
1105
1106 std::unique_ptr<TraceWriter> writer =
1107 producer->CreateTraceWriter("data_source");
1108 {
1109 auto tp = writer->NewTracePacket();
1110 tp->set_for_testing()->set_str("payload");
1111 }
1112
1113 auto flush_req_1 = consumer->Flush();
1114 auto flush_req_2 = consumer->Flush();
1115 auto flush_req_3 = consumer->Flush();
1116
1117 // We'll deliberately let the 4th flush request timeout. Use a lower timeout
1118 // to keep test time short.
1119 auto flush_req_4 = consumer->Flush(/*timeout_ms=*/10);
1120 ASSERT_EQ(4u, GetNumPendingFlushes());
1121
1122 // Make the producer reply only to the 3rd flush request.
1123 testing::InSequence seq;
Eric Secklera01e28a2019-01-08 11:21:04 +00001124 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 1.
1125 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 2.
1126 producer->WaitForFlush(writer.get()); // Reply only to flush 3.
1127 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 4.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001128
1129 // Even if the producer explicily replied only to flush ID == 3, all the
1130 // previous flushed < 3 should be implicitly acked.
1131 ASSERT_TRUE(flush_req_1.WaitForReply());
1132 ASSERT_TRUE(flush_req_2.WaitForReply());
1133 ASSERT_TRUE(flush_req_3.WaitForReply());
1134
1135 // At this point flush id == 4 should still be pending and should fail because
1136 // of reaching its timeout.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001137 ASSERT_FALSE(flush_req_4.WaitForReply());
1138
1139 consumer->DisableTracing();
1140 producer->WaitForDataSourceStop("data_source");
1141 consumer->WaitForTracingDisabled();
1142 EXPECT_THAT(
1143 consumer->ReadBuffers(),
1144 Contains(Property(&protos::TracePacket::for_testing,
1145 Property(&protos::TestEvent::str, Eq("payload")))));
1146}
1147
Primiano Tuccicaa57802018-11-25 11:07:07 +00001148TEST_F(TracingServiceImplTest, PeriodicFlush) {
1149 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1150 consumer->Connect(svc.get());
1151
1152 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1153 producer->Connect(svc.get(), "mock_producer");
1154 producer->RegisterDataSource("data_source");
1155
1156 TraceConfig trace_config;
1157 trace_config.add_buffers()->set_size_kb(128);
1158 trace_config.set_flush_period_ms(1);
1159 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1160 ds_config->set_name("data_source");
1161
1162 consumer->EnableTracing(trace_config);
1163 producer->WaitForTracingSetup();
1164 producer->WaitForDataSourceSetup("data_source");
1165 producer->WaitForDataSourceStart("data_source");
1166
1167 std::unique_ptr<TraceWriter> writer =
1168 producer->CreateTraceWriter("data_source");
1169
1170 const int kNumFlushes = 3;
1171 auto checkpoint = task_runner.CreateCheckpoint("all_flushes_done");
1172 int flushes_seen = 0;
1173 EXPECT_CALL(*producer, Flush(_, _, _))
1174 .WillRepeatedly(Invoke([&producer, &writer, &flushes_seen, checkpoint](
1175 FlushRequestID flush_req_id,
1176 const DataSourceInstanceID*, size_t) {
1177 {
1178 auto tp = writer->NewTracePacket();
1179 char payload[32];
1180 sprintf(payload, "f_%d", flushes_seen);
1181 tp->set_for_testing()->set_str(payload);
1182 }
1183 writer->Flush();
1184 producer->endpoint()->NotifyFlushComplete(flush_req_id);
1185 if (++flushes_seen == kNumFlushes)
1186 checkpoint();
1187 }));
1188 task_runner.RunUntilCheckpoint("all_flushes_done");
1189
1190 consumer->DisableTracing();
1191 producer->WaitForDataSourceStop("data_source");
1192 consumer->WaitForTracingDisabled();
1193 auto trace_packets = consumer->ReadBuffers();
1194 for (int i = 0; i < kNumFlushes; i++) {
1195 EXPECT_THAT(trace_packets,
1196 Contains(Property(&protos::TracePacket::for_testing,
1197 Property(&protos::TestEvent::str,
1198 Eq("f_" + std::to_string(i))))));
1199 }
1200}
1201
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001202// Creates a tracing session where some of the data sources set the
1203// |will_notify_on_stop| flag and checks that the OnTracingDisabled notification
1204// to the consumer is delayed until the acks are received.
1205TEST_F(TracingServiceImplTest, OnTracingDisabledWaitsForDataSourceStopAcks) {
1206 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1207 consumer->Connect(svc.get());
1208
1209 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1210 producer->Connect(svc.get(), "mock_producer");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001211 producer->RegisterDataSource("ds_will_ack_1", /*ack_stop=*/true,
1212 /*ack_start=*/true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001213 producer->RegisterDataSource("ds_wont_ack");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001214 producer->RegisterDataSource("ds_will_ack_2", /*ack_stop=*/true,
1215 /*ack_start=*/false);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001216
1217 TraceConfig trace_config;
1218 trace_config.add_buffers()->set_size_kb(128);
1219 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_1");
1220 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1221 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_2");
1222 trace_config.set_duration_ms(1);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001223 trace_config.set_deferred_start(true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001224
1225 consumer->EnableTracing(trace_config);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001226
1227 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1228 DataSourceInstanceState::CONFIGURED);
1229 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1230 DataSourceInstanceState::CONFIGURED);
1231 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1232 DataSourceInstanceState::CONFIGURED);
1233
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001234 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001235
1236 producer->WaitForDataSourceSetup("ds_will_ack_1");
1237 producer->WaitForDataSourceSetup("ds_wont_ack");
1238 producer->WaitForDataSourceSetup("ds_will_ack_2");
1239
Eric Seckler4ff03e52019-03-15 10:10:30 +00001240 DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_will_ack_1");
1241 DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_will_ack_2");
1242
1243 consumer->StartTracing();
1244
1245 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1246 DataSourceInstanceState::STARTING);
1247 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1248 DataSourceInstanceState::STARTED);
1249 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1250 DataSourceInstanceState::STARTED);
1251
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001252 producer->WaitForDataSourceStart("ds_will_ack_1");
1253 producer->WaitForDataSourceStart("ds_wont_ack");
1254 producer->WaitForDataSourceStart("ds_will_ack_2");
1255
Eric Seckler4ff03e52019-03-15 10:10:30 +00001256 producer->endpoint()->NotifyDataSourceStarted(id1);
1257
1258 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1259 DataSourceInstanceState::STARTED);
1260
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001261 std::unique_ptr<TraceWriter> writer =
1262 producer->CreateTraceWriter("ds_wont_ack");
1263 producer->WaitForFlush(writer.get());
1264
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001265 producer->WaitForDataSourceStop("ds_will_ack_1");
1266 producer->WaitForDataSourceStop("ds_wont_ack");
1267 producer->WaitForDataSourceStop("ds_will_ack_2");
1268
Eric Seckler4ff03e52019-03-15 10:10:30 +00001269 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1270 DataSourceInstanceState::STOPPING);
1271 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1272 DataSourceInstanceState::STOPPED);
1273 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1274 DataSourceInstanceState::STOPPING);
1275
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001276 producer->endpoint()->NotifyDataSourceStopped(id1);
1277 producer->endpoint()->NotifyDataSourceStopped(id2);
1278
Eric Seckler4ff03e52019-03-15 10:10:30 +00001279 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1280 DataSourceInstanceState::STOPPED);
1281 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1282 DataSourceInstanceState::STOPPED);
1283
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001284 // Wait for at most half of the service timeout, so that this test fails if
1285 // the service falls back on calling the OnTracingDisabled() because some of
1286 // the expected acks weren't received.
1287 consumer->WaitForTracingDisabled(
1288 TracingServiceImpl::kDataSourceStopTimeoutMs / 2);
1289}
1290
Oystein Eftevaagf250e1c2018-08-23 16:10:52 -07001291// Creates a tracing session where a second data source
1292// is added while the service is waiting for DisableTracing
1293// acks; the service should not enable the new datasource
1294// and should not hit any asserts when the consumer is
1295// subsequently destroyed.
1296TEST_F(TracingServiceImplTest, OnDataSourceAddedWhilePendingDisableAcks) {
1297 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1298 consumer->Connect(svc.get());
1299
1300 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1301 producer->Connect(svc.get(), "mock_producer");
1302 producer->RegisterDataSource("ds_will_ack", /*ack_stop=*/true);
1303
1304 TraceConfig trace_config;
1305 trace_config.add_buffers()->set_size_kb(128);
1306 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack");
1307 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1308
1309 consumer->EnableTracing(trace_config);
1310 producer->WaitForTracingSetup();
1311
1312 consumer->DisableTracing();
1313
1314 producer->RegisterDataSource("ds_wont_ack");
1315
1316 consumer.reset();
1317}
1318
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001319// Similar to OnTracingDisabledWaitsForDataSourceStopAcks, but deliberately
1320// skips the ack and checks that the service invokes the OnTracingDisabled()
1321// after the timeout.
1322TEST_F(TracingServiceImplTest, OnTracingDisabledCalledAnywaysInCaseOfTimeout) {
1323 svc->override_data_source_test_timeout_ms_for_testing = 1;
1324 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1325 consumer->Connect(svc.get());
1326
1327 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1328 producer->Connect(svc.get(), "mock_producer");
1329 producer->RegisterDataSource("data_source", /*ack_stop=*/true);
1330
1331 TraceConfig trace_config;
1332 trace_config.add_buffers()->set_size_kb(128);
1333 trace_config.add_data_sources()->mutable_config()->set_name("data_source");
1334 trace_config.set_duration_ms(1);
1335
1336 consumer->EnableTracing(trace_config);
1337 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001338 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001339 producer->WaitForDataSourceStart("data_source");
1340
1341 std::unique_ptr<TraceWriter> writer =
1342 producer->CreateTraceWriter("data_source");
1343 producer->WaitForFlush(writer.get());
1344
1345 producer->WaitForDataSourceStop("data_source");
1346 consumer->WaitForTracingDisabled();
1347}
1348
Primiano Tucci03de28f2018-08-01 11:29:46 +01001349// Tests the session_id logic. Two data sources in the same tracing session
1350// should see the same session id.
1351TEST_F(TracingServiceImplTest, SessionId) {
1352 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1353 consumer->Connect(svc.get());
1354
1355 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1356 producer1->Connect(svc.get(), "mock_producer1");
1357 producer1->RegisterDataSource("ds_1A");
1358 producer1->RegisterDataSource("ds_1B");
1359
1360 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1361 producer2->Connect(svc.get(), "mock_producer2");
1362 producer2->RegisterDataSource("ds_2A");
1363
1364 testing::InSequence seq;
1365 TracingSessionID last_session_id = 0;
1366 for (int i = 0; i < 3; i++) {
1367 TraceConfig trace_config;
1368 trace_config.add_buffers()->set_size_kb(128);
1369 trace_config.add_data_sources()->mutable_config()->set_name("ds_1A");
1370 trace_config.add_data_sources()->mutable_config()->set_name("ds_1B");
1371 trace_config.add_data_sources()->mutable_config()->set_name("ds_2A");
1372 trace_config.set_duration_ms(1);
1373
1374 consumer->EnableTracing(trace_config);
1375
1376 if (i == 0)
1377 producer1->WaitForTracingSetup();
Primiano Tucci03de28f2018-08-01 11:29:46 +01001378
Primiano Tucci674076d2018-10-01 10:41:09 +01001379 producer1->WaitForDataSourceSetup("ds_1A");
1380 producer1->WaitForDataSourceSetup("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001381 if (i == 0)
1382 producer2->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001383 producer2->WaitForDataSourceSetup("ds_2A");
1384
1385 producer1->WaitForDataSourceStart("ds_1A");
1386 producer1->WaitForDataSourceStart("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001387 producer2->WaitForDataSourceStart("ds_2A");
1388
1389 auto* ds1 = producer1->GetDataSourceInstance("ds_1A");
1390 auto* ds2 = producer1->GetDataSourceInstance("ds_1B");
1391 auto* ds3 = producer2->GetDataSourceInstance("ds_2A");
1392 ASSERT_EQ(ds1->session_id, ds2->session_id);
1393 ASSERT_EQ(ds1->session_id, ds3->session_id);
1394 ASSERT_NE(ds1->session_id, last_session_id);
1395 last_session_id = ds1->session_id;
1396
1397 auto writer1 = producer1->CreateTraceWriter("ds_1A");
1398 producer1->WaitForFlush(writer1.get());
1399
1400 auto writer2 = producer2->CreateTraceWriter("ds_2A");
1401 producer2->WaitForFlush(writer2.get());
1402
1403 producer1->WaitForDataSourceStop("ds_1A");
1404 producer1->WaitForDataSourceStop("ds_1B");
1405 producer2->WaitForDataSourceStop("ds_2A");
1406 consumer->WaitForTracingDisabled();
1407 consumer->FreeBuffers();
1408 }
1409}
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001410
1411// Writes a long trace and then tests that the trace parsed in partitions
1412// derived by the synchronization markers is identical to the whole trace parsed
1413// in one go.
1414TEST_F(TracingServiceImplTest, ResynchronizeTraceStreamUsingSyncMarker) {
1415 // Setup tracing.
1416 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1417 consumer->Connect(svc.get());
1418 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1419 producer->Connect(svc.get(), "mock_producer");
1420 producer->RegisterDataSource("data_source");
1421 TraceConfig trace_config;
1422 trace_config.add_buffers()->set_size_kb(4096);
1423 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1424 ds_config->set_name("data_source");
1425 trace_config.set_write_into_file(true);
1426 trace_config.set_file_write_period_ms(1);
1427 base::TempFile tmp_file = base::TempFile::Create();
1428 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
1429 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001430 producer->WaitForDataSourceSetup("data_source");
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001431 producer->WaitForDataSourceStart("data_source");
1432
1433 // Write some variable length payload, waiting for sync markers every now
1434 // and then.
1435 const int kNumMarkers = 5;
1436 auto writer = producer->CreateTraceWriter("data_source");
1437 for (int i = 1; i <= 100; i++) {
Florian Mayereff98042018-12-10 17:44:44 +00001438 std::string payload(static_cast<size_t>(i), 'A' + (i % 25));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001439 writer->NewTracePacket()->set_for_testing()->set_str(payload.c_str());
1440 if (i % (100 / kNumMarkers) == 0) {
1441 writer->Flush();
1442 WaitForNextSyncMarker();
1443 }
1444 }
1445 writer->Flush();
1446 writer.reset();
1447 consumer->DisableTracing();
1448 producer->WaitForDataSourceStop("data_source");
1449 consumer->WaitForTracingDisabled();
1450
1451 std::string trace_raw;
1452 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
1453
1454 const auto kMarkerSize = sizeof(TracingServiceImpl::kSyncMarker);
1455 const std::string kSyncMarkerStr(
1456 reinterpret_cast<const char*>(TracingServiceImpl::kSyncMarker),
1457 kMarkerSize);
1458
1459 // Read back the trace in partitions derived from the marker.
1460 // The trace should look like this:
1461 // [uid, marker] [event] [event] [uid, marker] [event] [event]
1462 size_t num_markers = 0;
1463 size_t start = 0;
1464 size_t end = 0;
1465 protos::Trace merged_trace;
1466 for (size_t pos = 0; pos != std::string::npos; start = end) {
1467 pos = trace_raw.find(kSyncMarkerStr, pos + 1);
1468 num_markers++;
1469 end = (pos == std::string::npos) ? trace_raw.size() : pos + kMarkerSize;
1470 int size = static_cast<int>(end - start);
1471 ASSERT_GT(size, 0);
1472 protos::Trace trace_partition;
1473 ASSERT_TRUE(trace_partition.ParseFromArray(trace_raw.data() + start, size));
1474 merged_trace.MergeFrom(trace_partition);
1475 }
Lalit Maganti9bdc7ce2018-09-17 15:25:11 +01001476 EXPECT_GE(num_markers, static_cast<size_t>(kNumMarkers));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001477
1478 protos::Trace whole_trace;
1479 ASSERT_TRUE(whole_trace.ParseFromString(trace_raw));
1480
1481 ASSERT_EQ(whole_trace.packet_size(), merged_trace.packet_size());
1482 EXPECT_EQ(whole_trace.SerializeAsString(), merged_trace.SerializeAsString());
1483}
1484
Primiano Tucci674076d2018-10-01 10:41:09 +01001485// Creates a tracing session with |deferred_start| and checks that data sources
1486// are started only after calling StartTracing().
1487TEST_F(TracingServiceImplTest, DeferredStart) {
1488 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1489 consumer->Connect(svc.get());
1490
1491 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1492 producer->Connect(svc.get(), "mock_producer");
1493
1494 // Create two data sources but enable only one of them.
1495 producer->RegisterDataSource("ds_1");
1496 producer->RegisterDataSource("ds_2");
1497
1498 TraceConfig trace_config;
1499 trace_config.add_buffers()->set_size_kb(128);
1500 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
1501 trace_config.set_deferred_start(true);
1502 trace_config.set_duration_ms(1);
1503
1504 consumer->EnableTracing(trace_config);
1505 producer->WaitForTracingSetup();
1506
1507 producer->WaitForDataSourceSetup("ds_1");
1508
1509 // Make sure we don't get unexpected DataSourceStart() notifications yet.
1510 task_runner.RunUntilIdle();
1511
1512 consumer->StartTracing();
1513
1514 producer->WaitForDataSourceStart("ds_1");
1515
Stephen Nusko1393ffd2019-03-22 13:54:58 +00001516 auto writer = producer->CreateTraceWriter("ds_1");
1517 producer->WaitForFlush(writer.get());
Primiano Tucci674076d2018-10-01 10:41:09 +01001518
1519 producer->WaitForDataSourceStop("ds_1");
1520 consumer->WaitForTracingDisabled();
1521}
1522
Eric Secklerd0ac7ca2019-02-06 09:13:45 +00001523TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
1524 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1525 consumer->Connect(svc.get());
1526
1527 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1528 producer1->Connect(svc.get(), "mock_producer1", 123u /* uid */);
1529 producer1->RegisterDataSource("data_source");
1530
1531 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1532 producer2->Connect(svc.get(), "mock_producer2", 456u /* uid */);
1533 producer2->RegisterDataSource("data_source");
1534
1535 TraceConfig trace_config;
1536 trace_config.add_buffers()->set_size_kb(128);
1537 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1538 ds_config->set_name("data_source");
1539
1540 consumer->EnableTracing(trace_config);
1541 producer1->WaitForTracingSetup();
1542 producer1->WaitForDataSourceSetup("data_source");
1543 producer2->WaitForTracingSetup();
1544 producer2->WaitForDataSourceSetup("data_source");
1545 producer1->WaitForDataSourceStart("data_source");
1546 producer2->WaitForDataSourceStart("data_source");
1547
1548 std::unique_ptr<TraceWriter> writer1a =
1549 producer1->CreateTraceWriter("data_source");
1550 std::unique_ptr<TraceWriter> writer1b =
1551 producer1->CreateTraceWriter("data_source");
1552 std::unique_ptr<TraceWriter> writer2a =
1553 producer2->CreateTraceWriter("data_source");
1554 {
1555 auto tp = writer1a->NewTracePacket();
1556 tp->set_for_testing()->set_str("payload1a1");
1557 tp = writer1b->NewTracePacket();
1558 tp->set_for_testing()->set_str("payload1b1");
1559 tp = writer1a->NewTracePacket();
1560 tp->set_for_testing()->set_str("payload1a2");
1561 tp = writer2a->NewTracePacket();
1562 tp->set_for_testing()->set_str("payload2a1");
1563 tp = writer1b->NewTracePacket();
1564 tp->set_for_testing()->set_str("payload1b2");
1565 }
1566
1567 auto flush_request = consumer->Flush();
1568 producer1->WaitForFlush({writer1a.get(), writer1b.get()});
1569 producer2->WaitForFlush(writer2a.get());
1570 ASSERT_TRUE(flush_request.WaitForReply());
1571
1572 consumer->DisableTracing();
1573 producer1->WaitForDataSourceStop("data_source");
1574 producer2->WaitForDataSourceStop("data_source");
1575 consumer->WaitForTracingDisabled();
1576 auto packets = consumer->ReadBuffers();
1577 EXPECT_THAT(
1578 packets,
1579 Contains(AllOf(
1580 Property(&protos::TracePacket::for_testing,
1581 Property(&protos::TestEvent::str, Eq("payload1a1"))),
1582 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1583 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
1584 EXPECT_THAT(
1585 packets,
1586 Contains(AllOf(
1587 Property(&protos::TracePacket::for_testing,
1588 Property(&protos::TestEvent::str, Eq("payload1a2"))),
1589 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1590 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
1591 EXPECT_THAT(
1592 packets,
1593 Contains(AllOf(
1594 Property(&protos::TracePacket::for_testing,
1595 Property(&protos::TestEvent::str, Eq("payload1b1"))),
1596 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1597 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
1598 EXPECT_THAT(
1599 packets,
1600 Contains(AllOf(
1601 Property(&protos::TracePacket::for_testing,
1602 Property(&protos::TestEvent::str, Eq("payload1b2"))),
1603 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1604 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
1605 EXPECT_THAT(
1606 packets,
1607 Contains(AllOf(
1608 Property(&protos::TracePacket::for_testing,
1609 Property(&protos::TestEvent::str, Eq("payload2a1"))),
1610 Property(&protos::TracePacket::trusted_uid, Eq(456)),
1611 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(4u)))));
1612}
1613
Eric Seckler6dc23592018-11-30 10:59:06 +00001614TEST_F(TracingServiceImplTest, AllowedBuffers) {
1615 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1616 consumer->Connect(svc.get());
1617
1618 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1619 producer1->Connect(svc.get(), "mock_producer1");
1620 ProducerID producer1_id = *last_producer_id();
1621 producer1->RegisterDataSource("data_source1");
1622 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1623 producer2->Connect(svc.get(), "mock_producer2");
1624 ProducerID producer2_id = *last_producer_id();
1625 producer2->RegisterDataSource("data_source2.1");
1626 producer2->RegisterDataSource("data_source2.2");
1627 producer2->RegisterDataSource("data_source2.3");
1628
1629 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
1630 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
1631
1632 TraceConfig trace_config;
1633 trace_config.add_buffers()->set_size_kb(128);
1634 trace_config.add_buffers()->set_size_kb(128);
1635 trace_config.add_buffers()->set_size_kb(128);
1636 auto* ds_config1 = trace_config.add_data_sources()->mutable_config();
1637 ds_config1->set_name("data_source1");
1638 ds_config1->set_target_buffer(0);
1639 auto* ds_config21 = trace_config.add_data_sources()->mutable_config();
1640 ds_config21->set_name("data_source2.1");
1641 ds_config21->set_target_buffer(1);
1642 auto* ds_config22 = trace_config.add_data_sources()->mutable_config();
1643 ds_config22->set_name("data_source2.2");
1644 ds_config22->set_target_buffer(2);
1645 auto* ds_config23 = trace_config.add_data_sources()->mutable_config();
1646 ds_config23->set_name("data_source2.3");
1647 ds_config23->set_target_buffer(2); // same buffer as data_source2.2.
1648 consumer->EnableTracing(trace_config);
1649
Primiano Tucci2abd1152018-12-03 17:00:02 +01001650 ASSERT_EQ(3u, tracing_session()->num_buffers());
Eric Seckler6dc23592018-11-30 10:59:06 +00001651 std::set<BufferID> expected_buffers_producer1 = {
1652 tracing_session()->buffers_index[0]};
1653 std::set<BufferID> expected_buffers_producer2 = {
1654 tracing_session()->buffers_index[1], tracing_session()->buffers_index[2]};
1655 EXPECT_EQ(expected_buffers_producer1, GetAllowedTargetBuffers(producer1_id));
1656 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
1657
1658 producer1->WaitForTracingSetup();
1659 producer1->WaitForDataSourceSetup("data_source1");
1660
1661 producer2->WaitForTracingSetup();
1662 producer2->WaitForDataSourceSetup("data_source2.1");
1663 producer2->WaitForDataSourceSetup("data_source2.2");
1664 producer2->WaitForDataSourceSetup("data_source2.3");
1665
1666 producer1->WaitForDataSourceStart("data_source1");
1667 producer2->WaitForDataSourceStart("data_source2.1");
1668 producer2->WaitForDataSourceStart("data_source2.2");
1669 producer2->WaitForDataSourceStart("data_source2.3");
1670
1671 producer2->UnregisterDataSource("data_source2.3");
1672 producer2->WaitForDataSourceStop("data_source2.3");
1673
1674 // Should still be allowed to write to buffers 1 (data_source2.1) and 2
1675 // (data_source2.2).
1676 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
1677
1678 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1679 // trace config didn't have the |deferred_start| flag set.
1680 consumer->StartTracing();
1681
1682 consumer->DisableTracing();
1683 producer1->WaitForDataSourceStop("data_source1");
1684 producer2->WaitForDataSourceStop("data_source2.1");
1685 producer2->WaitForDataSourceStop("data_source2.2");
1686 consumer->WaitForTracingDisabled();
1687
1688 consumer->FreeBuffers();
1689 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
1690 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
1691}
1692
Eric Seckler6aa9ece2018-12-06 16:40:12 +00001693#if !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00001694TEST_F(TracingServiceImplTest, CommitToForbiddenBufferIsDiscarded) {
1695 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1696 consumer->Connect(svc.get());
1697
1698 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1699 producer->Connect(svc.get(), "mock_producer");
1700 ProducerID producer_id = *last_producer_id();
1701 producer->RegisterDataSource("data_source");
1702
1703 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
1704
1705 TraceConfig trace_config;
1706 trace_config.add_buffers()->set_size_kb(128);
1707 trace_config.add_buffers()->set_size_kb(128);
1708 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1709 ds_config->set_name("data_source");
1710 ds_config->set_target_buffer(0);
1711 consumer->EnableTracing(trace_config);
1712
1713 ASSERT_EQ(2u, tracing_session()->num_buffers());
1714 std::set<BufferID> expected_buffers = {tracing_session()->buffers_index[0]};
1715 EXPECT_EQ(expected_buffers, GetAllowedTargetBuffers(producer_id));
1716
1717 producer->WaitForTracingSetup();
1718 producer->WaitForDataSourceSetup("data_source");
1719 producer->WaitForDataSourceStart("data_source");
1720
1721 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1722 // trace config didn't have the |deferred_start| flag set.
1723 consumer->StartTracing();
1724
1725 // Try to write to the correct buffer.
1726 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1727 tracing_session()->buffers_index[0]);
1728 {
1729 auto tp = writer->NewTracePacket();
1730 tp->set_for_testing()->set_str("good_payload");
1731 }
1732
1733 auto flush_request = consumer->Flush();
1734 producer->WaitForFlush(writer.get());
1735 ASSERT_TRUE(flush_request.WaitForReply());
1736
1737 // Try to write to the wrong buffer.
1738 writer = producer->endpoint()->CreateTraceWriter(
1739 tracing_session()->buffers_index[1]);
1740 {
1741 auto tp = writer->NewTracePacket();
1742 tp->set_for_testing()->set_str("bad_payload");
1743 }
1744
1745 flush_request = consumer->Flush();
1746 producer->WaitForFlush(writer.get());
1747 ASSERT_TRUE(flush_request.WaitForReply());
1748
1749 consumer->DisableTracing();
1750 producer->WaitForDataSourceStop("data_source");
1751 consumer->WaitForTracingDisabled();
1752
1753 auto packets = consumer->ReadBuffers();
1754 EXPECT_THAT(packets, Contains(Property(&protos::TracePacket::for_testing,
1755 Property(&protos::TestEvent::str,
1756 Eq("good_payload")))));
1757 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1758 Property(&protos::TestEvent::str,
1759 Eq("bad_payload"))))));
1760
1761 consumer->FreeBuffers();
1762 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
1763}
Eric Seckler6aa9ece2018-12-06 16:40:12 +00001764#endif // !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00001765
Eric Secklerf3f524b2018-12-13 09:09:34 +00001766TEST_F(TracingServiceImplTest, RegisterAndUnregisterTraceWriter) {
1767 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1768 consumer->Connect(svc.get());
1769
1770 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1771 producer->Connect(svc.get(), "mock_producer");
1772 ProducerID producer_id = *last_producer_id();
1773 producer->RegisterDataSource("data_source");
1774
1775 EXPECT_TRUE(GetWriters(producer_id).empty());
1776
1777 TraceConfig trace_config;
1778 trace_config.add_buffers()->set_size_kb(128);
1779 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1780 ds_config->set_name("data_source");
1781 ds_config->set_target_buffer(0);
1782 consumer->EnableTracing(trace_config);
1783
1784 producer->WaitForTracingSetup();
1785 producer->WaitForDataSourceSetup("data_source");
1786 producer->WaitForDataSourceStart("data_source");
1787
1788 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1789 // trace config didn't have the |deferred_start| flag set.
1790 consumer->StartTracing();
1791
1792 // Creating the trace writer should register it with the service.
1793 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1794 tracing_session()->buffers_index[0]);
1795
1796 WaitForTraceWritersChanged(producer_id);
1797
1798 std::map<WriterID, BufferID> expected_writers;
1799 expected_writers[writer->writer_id()] = tracing_session()->buffers_index[0];
1800 EXPECT_EQ(expected_writers, GetWriters(producer_id));
1801
1802 // Verify writing works.
1803 {
1804 auto tp = writer->NewTracePacket();
1805 tp->set_for_testing()->set_str("payload");
1806 }
1807
1808 auto flush_request = consumer->Flush();
1809 producer->WaitForFlush(writer.get());
1810 ASSERT_TRUE(flush_request.WaitForReply());
1811
1812 // Destroying the writer should unregister it.
1813 writer.reset();
1814 WaitForTraceWritersChanged(producer_id);
1815 EXPECT_TRUE(GetWriters(producer_id).empty());
1816
1817 consumer->DisableTracing();
1818 producer->WaitForDataSourceStop("data_source");
1819 consumer->WaitForTracingDisabled();
1820
1821 auto packets = consumer->ReadBuffers();
1822 EXPECT_THAT(packets, Contains(Property(
1823 &protos::TracePacket::for_testing,
1824 Property(&protos::TestEvent::str, Eq("payload")))));
1825}
1826
Eric Secklera01e28a2019-01-08 11:21:04 +00001827TEST_F(TracingServiceImplTest, ScrapeBuffersOnFlush) {
1828 svc->SetSMBScrapingEnabled(true);
1829
1830 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1831 consumer->Connect(svc.get());
1832
1833 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1834 producer->Connect(svc.get(), "mock_producer");
1835 ProducerID producer_id = *last_producer_id();
1836 producer->RegisterDataSource("data_source");
1837
1838 TraceConfig trace_config;
1839 trace_config.add_buffers()->set_size_kb(128);
1840 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1841 ds_config->set_name("data_source");
1842 ds_config->set_target_buffer(0);
1843 consumer->EnableTracing(trace_config);
1844
1845 producer->WaitForTracingSetup();
1846 producer->WaitForDataSourceSetup("data_source");
1847 producer->WaitForDataSourceStart("data_source");
1848
1849 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1850 // trace config didn't have the |deferred_start| flag set.
1851 consumer->StartTracing();
1852
1853 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1854 tracing_session()->buffers_index[0]);
1855 WaitForTraceWritersChanged(producer_id);
1856
1857 // Write a few trace packets.
1858 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
1859 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
1860 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
1861
1862 // Flush but don't actually flush the chunk from TraceWriter.
1863 auto flush_request = consumer->Flush();
1864 producer->WaitForFlush(nullptr, /*reply=*/true);
1865 ASSERT_TRUE(flush_request.WaitForReply());
1866
1867 // Chunk with the packets should have been scraped. The service can't know
1868 // whether the last packet was completed, so shouldn't read it.
1869 auto packets = consumer->ReadBuffers();
1870 EXPECT_THAT(packets, Contains(Property(
1871 &protos::TracePacket::for_testing,
1872 Property(&protos::TestEvent::str, Eq("payload1")))));
1873 EXPECT_THAT(packets, Contains(Property(
1874 &protos::TracePacket::for_testing,
1875 Property(&protos::TestEvent::str, Eq("payload2")))));
1876 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1877 Property(&protos::TestEvent::str,
1878 Eq("payload3"))))));
1879
1880 // Write some more packets.
1881 writer->NewTracePacket()->set_for_testing()->set_str("payload4");
1882 writer->NewTracePacket()->set_for_testing()->set_str("payload5");
1883
1884 // Don't reply to flush, causing a timeout. This should scrape again.
1885 flush_request = consumer->Flush(/*timeout=*/100);
1886 producer->WaitForFlush(nullptr, /*reply=*/false);
1887 ASSERT_FALSE(flush_request.WaitForReply());
1888
1889 // Chunk with the packets should have been scraped again, overriding the
1890 // original one. Again, the last packet should be ignored and the first two
1891 // should not be read twice.
1892 packets = consumer->ReadBuffers();
1893 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1894 Property(&protos::TestEvent::str,
1895 Eq("payload1"))))));
1896 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1897 Property(&protos::TestEvent::str,
1898 Eq("payload2"))))));
1899 EXPECT_THAT(packets, Contains(Property(
1900 &protos::TracePacket::for_testing,
1901 Property(&protos::TestEvent::str, Eq("payload3")))));
1902 EXPECT_THAT(packets, Contains(Property(
1903 &protos::TracePacket::for_testing,
1904 Property(&protos::TestEvent::str, Eq("payload4")))));
1905 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1906 Property(&protos::TestEvent::str,
1907 Eq("payload5"))))));
1908
1909 consumer->DisableTracing();
1910 producer->WaitForDataSourceStop("data_source");
1911 consumer->WaitForTracingDisabled();
1912}
1913
1914// Test scraping on producer disconnect.
1915TEST_F(TracingServiceImplTest, ScrapeBuffersOnProducerDisconnect) {
1916 svc->SetSMBScrapingEnabled(true);
1917
1918 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1919 consumer->Connect(svc.get());
1920
1921 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1922 producer->Connect(svc.get(), "mock_producer");
1923 ProducerID producer_id = *last_producer_id();
1924 producer->RegisterDataSource("data_source");
1925
1926 TraceConfig trace_config;
1927 trace_config.add_buffers()->set_size_kb(128);
1928 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1929 ds_config->set_name("data_source");
1930 ds_config->set_target_buffer(0);
1931 consumer->EnableTracing(trace_config);
1932
1933 producer->WaitForTracingSetup();
1934 producer->WaitForDataSourceSetup("data_source");
1935 producer->WaitForDataSourceStart("data_source");
1936
1937 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1938 // trace config didn't have the |deferred_start| flag set.
1939 consumer->StartTracing();
1940
1941 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1942 tracing_session()->buffers_index[0]);
1943 WaitForTraceWritersChanged(producer_id);
1944
1945 // Write a few trace packets.
1946 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
1947 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
1948 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
1949
1950 // Disconnect the producer without committing the chunk. This should cause a
1951 // scrape of the SMB. Avoid destroying the ShmemArbiter until writer is
1952 // destroyed.
1953 auto shmem_arbiter = TakeShmemArbiterForProducer(producer_id);
1954 producer.reset();
1955
1956 // Chunk with the packets should have been scraped. The service can't know
1957 // whether the last packet was completed, so shouldn't read it.
1958 auto packets = consumer->ReadBuffers();
1959 EXPECT_THAT(packets, Contains(Property(
1960 &protos::TracePacket::for_testing,
1961 Property(&protos::TestEvent::str, Eq("payload1")))));
1962 EXPECT_THAT(packets, Contains(Property(
1963 &protos::TracePacket::for_testing,
1964 Property(&protos::TestEvent::str, Eq("payload2")))));
1965 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1966 Property(&protos::TestEvent::str,
1967 Eq("payload3"))))));
1968
1969 // Cleanup writer without causing a crash because the producer already went
1970 // away.
1971 static_cast<TraceWriterImpl*>(writer.get())->ResetChunkForTesting();
1972 writer.reset();
1973 shmem_arbiter.reset();
1974
1975 consumer->DisableTracing();
1976 consumer->WaitForTracingDisabled();
1977}
1978
1979TEST_F(TracingServiceImplTest, ScrapeBuffersOnDisable) {
1980 svc->SetSMBScrapingEnabled(true);
1981
1982 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1983 consumer->Connect(svc.get());
1984
1985 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1986 producer->Connect(svc.get(), "mock_producer");
1987 ProducerID producer_id = *last_producer_id();
1988 producer->RegisterDataSource("data_source");
1989
1990 TraceConfig trace_config;
1991 trace_config.add_buffers()->set_size_kb(128);
1992 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1993 ds_config->set_name("data_source");
1994 ds_config->set_target_buffer(0);
1995 consumer->EnableTracing(trace_config);
1996
1997 producer->WaitForTracingSetup();
1998 producer->WaitForDataSourceSetup("data_source");
1999 producer->WaitForDataSourceStart("data_source");
2000
2001 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2002 // trace config didn't have the |deferred_start| flag set.
2003 consumer->StartTracing();
2004
2005 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2006 tracing_session()->buffers_index[0]);
2007 WaitForTraceWritersChanged(producer_id);
2008
2009 // Write a few trace packets.
2010 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2011 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2012 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2013
2014 consumer->DisableTracing();
2015 producer->WaitForDataSourceStop("data_source");
2016 consumer->WaitForTracingDisabled();
2017
2018 // Chunk with the packets should have been scraped. The service can't know
2019 // whether the last packet was completed, so shouldn't read it.
2020 auto packets = consumer->ReadBuffers();
2021 EXPECT_THAT(packets, Contains(Property(
2022 &protos::TracePacket::for_testing,
2023 Property(&protos::TestEvent::str, Eq("payload1")))));
2024 EXPECT_THAT(packets, Contains(Property(
2025 &protos::TracePacket::for_testing,
2026 Property(&protos::TestEvent::str, Eq("payload2")))));
2027 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2028 Property(&protos::TestEvent::str,
2029 Eq("payload3"))))));
2030}
2031
Primiano Tucciff7beab2019-01-09 21:49:20 +00002032TEST_F(TracingServiceImplTest, AbortIfTraceDurationIsTooLong) {
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 producer->RegisterDataSource("datasource");
2039
2040 TraceConfig trace_config;
2041 trace_config.add_buffers()->set_size_kb(128);
2042 trace_config.add_data_sources()->mutable_config()->set_name("datasource");
2043 trace_config.set_duration_ms(0x7fffffff);
2044
2045 EXPECT_CALL(*producer, SetupDataSource(_, _)).Times(0);
2046 consumer->EnableTracing(trace_config);
2047
2048 // The trace is aborted immediately, 5s here is just some slack for the thread
2049 // ping-pongs for slow devices.
2050 consumer->WaitForTracingDisabled(5000);
2051}
2052
Eric Secklereaf29ed2019-01-23 09:53:55 +00002053TEST_F(TracingServiceImplTest, GetTraceStats) {
2054 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2055 consumer->Connect(svc.get());
2056
2057 consumer->GetTraceStats();
2058 consumer->WaitForTraceStats(false);
2059
2060 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2061 producer->Connect(svc.get(), "mock_producer");
2062 producer->RegisterDataSource("data_source");
2063
2064 TraceConfig trace_config;
2065 trace_config.add_buffers()->set_size_kb(128);
2066 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2067 ds_config->set_name("data_source");
2068
2069 consumer->EnableTracing(trace_config);
2070 producer->WaitForTracingSetup();
2071 producer->WaitForDataSourceSetup("data_source");
2072 producer->WaitForDataSourceStart("data_source");
2073
2074 consumer->GetTraceStats();
2075 consumer->WaitForTraceStats(true);
2076
2077 consumer->DisableTracing();
2078 producer->WaitForDataSourceStop("data_source");
2079 consumer->WaitForTracingDisabled();
2080}
2081
Eric Seckler7b0c9452019-03-18 13:14:36 +00002082TEST_F(TracingServiceImplTest, ObserveEventsDataSourceInstances) {
2083 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2084 consumer->Connect(svc.get());
2085
2086 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2087 producer->Connect(svc.get(), "mock_producer");
2088 producer->RegisterDataSource("data_source");
2089
2090 TraceConfig trace_config;
2091 trace_config.add_buffers()->set_size_kb(128);
2092 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2093 ds_config->set_name("data_source");
2094
2095 // Start tracing before the consumer is interested in events. The consumer's
2096 // OnObservableEvents() should not be called yet.
2097 consumer->EnableTracing(trace_config);
2098 producer->WaitForTracingSetup();
2099 producer->WaitForDataSourceSetup("data_source");
2100 producer->WaitForDataSourceStart("data_source");
2101
2102 // Calling ObserveEvents should cause an event for the initial instance state.
2103 consumer->ObserveEvents(TracingService::ConsumerEndpoint::
2104 ObservableEventType::kDataSourceInstances);
2105 {
2106 auto events = consumer->WaitForObservableEvents();
2107
2108 ObservableEvents::DataSourceInstanceStateChange change;
2109 change.set_producer_name("mock_producer");
2110 change.set_data_source_name("data_source");
2111 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2112 DATA_SOURCE_INSTANCE_STATE_STARTED);
2113 EXPECT_EQ(events.instance_state_changes_size(), 1);
2114 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2115 }
2116
2117 // Disabling should cause an instance state change to STOPPED.
2118 consumer->DisableTracing();
2119
2120 {
2121 auto events = consumer->WaitForObservableEvents();
2122
2123 ObservableEvents::DataSourceInstanceStateChange change;
2124 change.set_producer_name("mock_producer");
2125 change.set_data_source_name("data_source");
2126 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2127 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2128 EXPECT_EQ(events.instance_state_changes_size(), 1);
2129 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2130 }
2131
2132 producer->WaitForDataSourceStop("data_source");
2133 consumer->WaitForTracingDisabled();
2134 consumer->FreeBuffers();
2135
2136 // Enable again, this should cause a state change for a new instance to
2137 // its initial state STOPPED.
2138 trace_config.set_deferred_start(true);
2139 consumer->EnableTracing(trace_config);
2140
2141 {
2142 auto events = consumer->WaitForObservableEvents();
2143
2144 ObservableEvents::DataSourceInstanceStateChange change;
2145 change.set_producer_name("mock_producer");
2146 change.set_data_source_name("data_source");
2147 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2148 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2149 EXPECT_EQ(events.instance_state_changes_size(), 1);
2150 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2151 }
2152
2153 producer->WaitForDataSourceSetup("data_source");
2154
2155 // Should move the instance into STARTED state and thus cause an event.
2156 consumer->StartTracing();
2157
2158 {
2159 auto events = consumer->WaitForObservableEvents();
2160
2161 ObservableEvents::DataSourceInstanceStateChange change;
2162 change.set_producer_name("mock_producer");
2163 change.set_data_source_name("data_source");
2164 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2165 DATA_SOURCE_INSTANCE_STATE_STARTED);
2166 EXPECT_EQ(events.instance_state_changes_size(), 1);
2167 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2168 }
2169
2170 producer->WaitForDataSourceStart("data_source");
2171
2172 // Stop observing events.
2173 consumer->ObserveEvents(
2174 TracingService::ConsumerEndpoint::ObservableEventType::kNone);
2175
2176 // Disabling should now no longer cause events to be sent to the consumer.
2177 consumer->DisableTracing();
2178 producer->WaitForDataSourceStop("data_source");
2179 consumer->WaitForTracingDisabled();
2180}
2181
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00002182} // namespace perfetto