blob: 93348ff8c516c0746b471af1884cce9acf0acc2b [file] [log] [blame]
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Florian Mayer6a1a4d52018-06-08 16:47:07 +010017#include "src/tracing/core/tracing_service_impl.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000018
19#include <string.h>
20
Hector Dearmancdfd85b2019-05-31 16:49:14 +010021#include <gmock/gmock.h>
22#include <gtest/gtest.h>
Primiano Tucci2c5488f2019-06-01 03:27:28 +010023#include "perfetto/ext/base/file_utils.h"
24#include "perfetto/ext/base/temp_file.h"
25#include "perfetto/ext/base/utils.h"
26#include "perfetto/ext/tracing/core/consumer.h"
Primiano Tucci2c5488f2019-06-01 03:27:28 +010027#include "perfetto/ext/tracing/core/producer.h"
28#include "perfetto/ext/tracing/core/shared_memory.h"
29#include "perfetto/ext/tracing/core/trace_packet.h"
30#include "perfetto/ext/tracing/core/trace_writer.h"
Primiano Tucci0f9e0222019-06-05 09:36:41 +010031#include "perfetto/tracing/core/data_source_config.h"
32#include "perfetto/tracing/core/data_source_descriptor.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000033#include "src/base/test/test_task_runner.h"
Eric Secklera01e28a2019-01-08 11:21:04 +000034#include "src/tracing/core/shared_memory_arbiter_impl.h"
Eric Secklerf3f524b2018-12-13 09:09:34 +000035#include "src/tracing/core/trace_writer_impl.h"
Primiano Tuccidca727d2018-04-04 11:31:55 +020036#include "src/tracing/test/mock_consumer.h"
37#include "src/tracing/test/mock_producer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000038#include "src/tracing/test/test_shared_memory.h"
39
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010040#include "perfetto/trace/test_event.pbzero.h"
41#include "perfetto/trace/trace.pb.h"
Primiano Tuccidca727d2018-04-04 11:31:55 +020042#include "perfetto/trace/trace_packet.pb.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010043#include "perfetto/trace/trace_packet.pbzero.h"
44
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000045using ::testing::_;
Primiano Tuccidca727d2018-04-04 11:31:55 +020046using ::testing::Contains;
Primiano Tucci1a1951d2018-04-04 21:08:16 +020047using ::testing::ElementsAreArray;
Primiano Tuccidca727d2018-04-04 11:31:55 +020048using ::testing::Eq;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000049using ::testing::InSequence;
Primiano Tucci081d46a2018-02-28 11:09:43 +000050using ::testing::Invoke;
Primiano Tuccidca727d2018-04-04 11:31:55 +020051using ::testing::InvokeWithoutArgs;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000052using ::testing::Mock;
Eric Secklerdd0ad102018-12-06 11:32:04 +000053using ::testing::Not;
Primiano Tuccidca727d2018-04-04 11:31:55 +020054using ::testing::Property;
55using ::testing::StrictMock;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000056
Primiano Tuccidca727d2018-04-04 11:31:55 +020057namespace perfetto {
Sami Kyostila32e0b542018-02-14 08:55:43 +000058
Primiano Tucci1a1951d2018-04-04 21:08:16 +020059namespace {
Florian Mayer6a1a4d52018-06-08 16:47:07 +010060constexpr size_t kDefaultShmSizeKb = TracingServiceImpl::kDefaultShmSize / 1024;
Nicolò Mazzucato693f6aa2019-07-08 10:26:09 +010061constexpr size_t kDefaultShmPageSizeKb =
62 TracingServiceImpl::kDefaultShmPageSize / 1024;
Florian Mayer6a1a4d52018-06-08 16:47:07 +010063constexpr size_t kMaxShmSizeKb = TracingServiceImpl::kMaxShmSize / 1024;
Stephen Nusko1393ffd2019-03-22 13:54:58 +000064
65::testing::AssertionResult HasTriggerModeInternal(
66 const std::vector<protos::TracePacket>& packets,
67 protos::TraceConfig::TriggerConfig::TriggerMode mode) {
68 ::testing::StringMatchResultListener matcher_result_string;
69 bool contains = ::testing::ExplainMatchResult(
70 Contains(Property(
71 &protos::TracePacket::trace_config,
72 Property(&protos::TraceConfig::trigger_config,
73 Property(&protos::TraceConfig::TriggerConfig::trigger_mode,
74 Eq(mode))))),
75 packets, &matcher_result_string);
76 if (contains) {
77 return ::testing::AssertionSuccess();
78 }
79 return ::testing::AssertionFailure() << matcher_result_string.str();
80}
81
82MATCHER_P(HasTriggerMode, mode, "") {
83 return HasTriggerModeInternal(arg, mode);
84}
85
Primiano Tucci1a1951d2018-04-04 21:08:16 +020086} // namespace
87
Florian Mayer6a1a4d52018-06-08 16:47:07 +010088class TracingServiceImplTest : public testing::Test {
Sami Kyostila06487a22018-02-27 13:48:38 +000089 public:
Eric Seckler4ff03e52019-03-15 10:10:30 +000090 using DataSourceInstanceState =
91 TracingServiceImpl::DataSourceInstance::DataSourceInstanceState;
92
Florian Mayer6a1a4d52018-06-08 16:47:07 +010093 TracingServiceImplTest() {
Sami Kyostila06487a22018-02-27 13:48:38 +000094 auto shm_factory =
95 std::unique_ptr<SharedMemory::Factory>(new TestSharedMemory::Factory());
Florian Mayer6a1a4d52018-06-08 16:47:07 +010096 svc.reset(static_cast<TracingServiceImpl*>(
97 TracingService::CreateInstance(std::move(shm_factory), &task_runner)
Sami Kyostila06487a22018-02-27 13:48:38 +000098 .release()));
Primiano Tucci9754d0d2018-09-15 12:41:46 +010099 svc->min_write_period_ms_ = 1;
Sami Kyostila06487a22018-02-27 13:48:38 +0000100 }
101
Primiano Tuccidca727d2018-04-04 11:31:55 +0200102 std::unique_ptr<MockProducer> CreateMockProducer() {
103 return std::unique_ptr<MockProducer>(
104 new StrictMock<MockProducer>(&task_runner));
105 }
106
107 std::unique_ptr<MockConsumer> CreateMockConsumer() {
108 return std::unique_ptr<MockConsumer>(
109 new StrictMock<MockConsumer>(&task_runner));
110 }
111
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200112 ProducerID* last_producer_id() { return &svc->last_producer_id_; }
113
114 uid_t GetProducerUid(ProducerID producer_id) {
115 return svc->GetProducer(producer_id)->uid_;
116 }
117
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000118 TracingServiceImpl::TracingSession* GetTracingSession(TracingSessionID tsid) {
119 auto* session = svc->GetTracingSession(tsid);
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100120 EXPECT_NE(nullptr, session);
121 return session;
122 }
123
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000124 TracingServiceImpl::TracingSession* tracing_session() {
125 return GetTracingSession(GetTracingSessionID());
126 }
127
128 TracingSessionID GetTracingSessionID() {
129 return svc->last_tracing_session_id_;
130 }
131
Eric Seckler6dc23592018-11-30 10:59:06 +0000132 const std::set<BufferID>& GetAllowedTargetBuffers(ProducerID producer_id) {
133 return svc->GetProducer(producer_id)->allowed_target_buffers_;
134 }
135
Eric Secklerf3f524b2018-12-13 09:09:34 +0000136 const std::map<WriterID, BufferID>& GetWriters(ProducerID producer_id) {
137 return svc->GetProducer(producer_id)->writers_;
138 }
139
Eric Secklera01e28a2019-01-08 11:21:04 +0000140 std::unique_ptr<SharedMemoryArbiterImpl> TakeShmemArbiterForProducer(
141 ProducerID producer_id) {
142 return std::move(svc->GetProducer(producer_id)->inproc_shmem_arbiter_);
143 }
144
Primiano Tuccid52e6272018-04-06 19:06:53 +0200145 size_t GetNumPendingFlushes() {
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100146 return tracing_session()->pending_flushes.size();
147 }
148
149 void WaitForNextSyncMarker() {
150 tracing_session()->last_snapshot_time = base::TimeMillis(0);
151 static int attempt = 0;
152 while (tracing_session()->last_snapshot_time == base::TimeMillis(0)) {
153 auto checkpoint_name = "wait_snapshot_" + std::to_string(attempt++);
154 auto timer_expired = task_runner.CreateCheckpoint(checkpoint_name);
155 task_runner.PostDelayedTask([timer_expired] { timer_expired(); }, 1);
156 task_runner.RunUntilCheckpoint(checkpoint_name);
157 }
Primiano Tuccid52e6272018-04-06 19:06:53 +0200158 }
159
Eric Secklerf3f524b2018-12-13 09:09:34 +0000160 void WaitForTraceWritersChanged(ProducerID producer_id) {
161 static int i = 0;
162 auto checkpoint_name = "writers_changed_" + std::to_string(producer_id) +
163 "_" + std::to_string(i++);
164 auto writers_changed = task_runner.CreateCheckpoint(checkpoint_name);
165 auto writers = GetWriters(producer_id);
166 std::function<void()> task;
167 task = [&task, writers, writers_changed, producer_id, this]() {
168 if (writers != GetWriters(producer_id)) {
169 writers_changed();
170 return;
171 }
172 task_runner.PostDelayedTask(task, 1);
173 };
174 task_runner.PostDelayedTask(task, 1);
175 task_runner.RunUntilCheckpoint(checkpoint_name);
176 }
177
Eric Seckler4ff03e52019-03-15 10:10:30 +0000178 DataSourceInstanceState GetDataSourceInstanceState(const std::string& name) {
179 for (const auto& kv : tracing_session()->data_source_instances) {
180 if (kv.second.data_source_name == name)
181 return kv.second.state;
182 }
183 PERFETTO_FATAL("Can't find data source instance with name %s",
184 name.c_str());
185 }
186
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000187 base::TestTaskRunner task_runner;
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100188 std::unique_ptr<TracingServiceImpl> svc;
Sami Kyostila06487a22018-02-27 13:48:38 +0000189};
190
Hector Dearmanfb4d0732019-05-19 15:44:56 +0100191TEST_F(TracingServiceImplTest, AtMostOneConfig) {
192 std::unique_ptr<MockConsumer> consumer_a = CreateMockConsumer();
193 std::unique_ptr<MockConsumer> consumer_b = CreateMockConsumer();
194
195 consumer_a->Connect(svc.get());
196 consumer_b->Connect(svc.get());
197
198 TraceConfig trace_config_a;
199 trace_config_a.add_buffers()->set_size_kb(128);
200 trace_config_a.set_duration_ms(0);
201 trace_config_a.set_unique_session_name("foo");
202
203 TraceConfig trace_config_b;
204 trace_config_b.add_buffers()->set_size_kb(128);
205 trace_config_b.set_duration_ms(0);
206 trace_config_b.set_unique_session_name("foo");
207
208 consumer_a->EnableTracing(trace_config_a);
209 consumer_b->EnableTracing(trace_config_b);
210
211 // This will stop immediately since it has the same unique session name.
212 consumer_b->WaitForTracingDisabled();
213
214 consumer_a->DisableTracing();
215 consumer_a->WaitForTracingDisabled();
216}
217
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100218TEST_F(TracingServiceImplTest, RegisterAndUnregister) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200219 std::unique_ptr<MockProducer> mock_producer_1 = CreateMockProducer();
220 std::unique_ptr<MockProducer> mock_producer_2 = CreateMockProducer();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000221
Primiano Tuccidca727d2018-04-04 11:31:55 +0200222 mock_producer_1->Connect(svc.get(), "mock_producer_1", 123u /* uid */);
223 mock_producer_2->Connect(svc.get(), "mock_producer_2", 456u /* uid */);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000224
225 ASSERT_EQ(2u, svc->num_producers());
Primiano Tuccidca727d2018-04-04 11:31:55 +0200226 ASSERT_EQ(mock_producer_1->endpoint(), svc->GetProducer(1));
227 ASSERT_EQ(mock_producer_2->endpoint(), svc->GetProducer(2));
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200228 ASSERT_EQ(123u, GetProducerUid(1));
229 ASSERT_EQ(456u, GetProducerUid(2));
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000230
Primiano Tuccidca727d2018-04-04 11:31:55 +0200231 mock_producer_1->RegisterDataSource("foo");
232 mock_producer_2->RegisterDataSource("bar");
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000233
Primiano Tuccidca727d2018-04-04 11:31:55 +0200234 mock_producer_1->UnregisterDataSource("foo");
235 mock_producer_2->UnregisterDataSource("bar");
Primiano Tucci9daa4832018-03-28 23:28:17 +0100236
Primiano Tuccidca727d2018-04-04 11:31:55 +0200237 mock_producer_1.reset();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000238 ASSERT_EQ(1u, svc->num_producers());
239 ASSERT_EQ(nullptr, svc->GetProducer(1));
240
Primiano Tuccidca727d2018-04-04 11:31:55 +0200241 mock_producer_2.reset();
242 ASSERT_EQ(nullptr, svc->GetProducer(2));
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000243
244 ASSERT_EQ(0u, svc->num_producers());
245}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100246
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100247TEST_F(TracingServiceImplTest, EnableAndDisableTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200248 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
249 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +0000250
Primiano Tuccidca727d2018-04-04 11:31:55 +0200251 std::unique_ptr<MockProducer> producer = CreateMockProducer();
252 producer->Connect(svc.get(), "mock_producer");
253 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000254
Sami Kyostila06487a22018-02-27 13:48:38 +0000255 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200256 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +0000257 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200258 ds_config->set_name("data_source");
259 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +0000260
Primiano Tuccidca727d2018-04-04 11:31:55 +0200261 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100262 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200263 producer->WaitForDataSourceStart("data_source");
264
Primiano Tucci674076d2018-10-01 10:41:09 +0100265 // Calling StartTracing() should be a noop (% a DLOG statement) because the
266 // trace config didn't have the |deferred_start| flag set.
267 consumer->StartTracing();
268
Primiano Tuccidca727d2018-04-04 11:31:55 +0200269 consumer->DisableTracing();
270 producer->WaitForDataSourceStop("data_source");
271 consumer->WaitForTracingDisabled();
Sami Kyostila06487a22018-02-27 13:48:38 +0000272}
273
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000274// Creates a tracing session with a START_TRACING trigger and checks that data
275// sources are started only after the service receives a trigger.
276TEST_F(TracingServiceImplTest, StartTracingTriggerDeferredStart) {
277 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
278 consumer->Connect(svc.get());
279
280 std::unique_ptr<MockProducer> producer = CreateMockProducer();
281 producer->Connect(svc.get(), "mock_producer");
282
283 // Create two data sources but enable only one of them.
284 producer->RegisterDataSource("ds_1");
285 producer->RegisterDataSource("ds_2");
286
287 TraceConfig trace_config;
288 trace_config.add_buffers()->set_size_kb(128);
289 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
290 auto* trigger_config = trace_config.mutable_trigger_config();
291 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
292 auto* trigger = trigger_config->add_triggers();
293 trigger->set_name("trigger_name");
294 trigger->set_stop_delay_ms(1);
295
296 trigger_config->set_trigger_timeout_ms(8.64e+7);
297
298 // Make sure we don't get unexpected DataSourceStart() notifications yet.
299 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
300
301 consumer->EnableTracing(trace_config);
302 producer->WaitForTracingSetup();
303
304 producer->WaitForDataSourceSetup("ds_1");
305
306 // The trace won't start until we send the trigger. since we have a
307 // START_TRACING trigger defined.
308 std::vector<std::string> req;
309 req.push_back("trigger_name");
310 producer->endpoint()->ActivateTriggers(req);
311
312 producer->WaitForDataSourceStart("ds_1");
313
314 auto writer1 = producer->CreateTraceWriter("ds_1");
315 producer->WaitForFlush(writer1.get());
316
317 producer->WaitForDataSourceStop("ds_1");
318 consumer->WaitForTracingDisabled();
319
320 ASSERT_EQ(1u, tracing_session()->received_triggers.size());
321 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100322 tracing_session()->received_triggers[0].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000323
324 EXPECT_THAT(
325 consumer->ReadBuffers(),
326 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
327}
328
329// Creates a tracing session with a START_TRACING trigger and checks that the
330// session is cleaned up when no trigger is received after |trigger_timeout_ms|.
331TEST_F(TracingServiceImplTest, StartTracingTriggerTimeOut) {
332 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
333 consumer->Connect(svc.get());
334
335 std::unique_ptr<MockProducer> producer = CreateMockProducer();
336 producer->Connect(svc.get(), "mock_producer");
337
338 // Create two data sources but enable only one of them.
339 producer->RegisterDataSource("ds_1");
340 producer->RegisterDataSource("ds_2");
341
342 TraceConfig trace_config;
343 trace_config.add_buffers()->set_size_kb(128);
344 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
345 auto* trigger_config = trace_config.mutable_trigger_config();
346 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
347 auto* trigger = trigger_config->add_triggers();
348 trigger->set_name("trigger_name");
349 trigger->set_stop_delay_ms(8.64e+7);
350
351 trigger_config->set_trigger_timeout_ms(1);
352
353 // Make sure we don't get unexpected DataSourceStart() notifications yet.
354 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
355
356 consumer->EnableTracing(trace_config);
357 producer->WaitForTracingSetup();
358
359 producer->WaitForDataSourceSetup("ds_1");
360
361 // The trace won't start until we send the trigger. since we have a
362 // START_TRACING trigger defined. This is where we'd expect to have an
363 // ActivateTriggers call to the producer->endpoint().
364
365 producer->WaitForDataSourceStop("ds_1");
366 consumer->WaitForTracingDisabled();
367 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
368}
369
370// Creates a tracing session with a START_TRACING trigger and checks that
371// the session is not started when the configured trigger producer is different
372// than the producer that sent the trigger.
373TEST_F(TracingServiceImplTest, StartTracingTriggerDifferentProducer) {
374 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
375 consumer->Connect(svc.get());
376
377 std::unique_ptr<MockProducer> producer = CreateMockProducer();
378 producer->Connect(svc.get(), "mock_producer");
379
380 // Create two data sources but enable only one of them.
381 producer->RegisterDataSource("ds_1");
382 producer->RegisterDataSource("ds_2");
383
384 TraceConfig trace_config;
385 trace_config.add_buffers()->set_size_kb(128);
386 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
387 auto* trigger_config = trace_config.mutable_trigger_config();
388 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
389 auto* trigger = trigger_config->add_triggers();
390 trigger->set_name("trigger_name");
391 trigger->set_stop_delay_ms(8.64e+7);
392 trigger->set_producer_name_regex("correct_name");
393
394 trigger_config->set_trigger_timeout_ms(1);
395
396 // Make sure we don't get unexpected DataSourceStart() notifications yet.
397 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
398
399 consumer->EnableTracing(trace_config);
400 producer->WaitForTracingSetup();
401
402 producer->WaitForDataSourceSetup("ds_1");
403
404 // The trace won't start until we send the trigger called "trigger_name"
405 // coming from a producer called "correct_name", since we have a
406 // START_TRACING trigger defined. This is where we'd expect to have an
407 // ActivateTriggers call to the producer->endpoint(), but we send the trigger
408 // from a different producer so it is ignored.
409 std::vector<std::string> req;
410 req.push_back("trigger_name");
411 producer->endpoint()->ActivateTriggers(req);
412
413 producer->WaitForDataSourceStop("ds_1");
414 consumer->WaitForTracingDisabled();
415 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
416}
417
418// Creates a tracing session with a START_TRACING trigger and checks that the
419// session is started when the trigger is received from the correct producer.
420TEST_F(TracingServiceImplTest, StartTracingTriggerCorrectProducer) {
421 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
422 consumer->Connect(svc.get());
423
424 std::unique_ptr<MockProducer> producer = CreateMockProducer();
425 producer->Connect(svc.get(), "mock_producer");
426
427 // Create two data sources but enable only one of them.
428 producer->RegisterDataSource("ds_1");
429 producer->RegisterDataSource("ds_2");
430
431 TraceConfig trace_config;
432 trace_config.add_buffers()->set_size_kb(128);
433 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
434 auto* trigger_config = trace_config.mutable_trigger_config();
435 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
436 auto* trigger = trigger_config->add_triggers();
437 trigger->set_name("trigger_name");
438 trigger->set_stop_delay_ms(1);
439 trigger->set_producer_name_regex("mock_produc[e-r]+");
440
441 trigger_config->set_trigger_timeout_ms(8.64e+7);
442
443 consumer->EnableTracing(trace_config);
444 producer->WaitForTracingSetup();
445
446 producer->WaitForDataSourceSetup("ds_1");
447
448 // Start the trace at this point with ActivateTriggers.
449 std::vector<std::string> req;
450 req.push_back("trigger_name");
451 producer->endpoint()->ActivateTriggers(req);
452
453 producer->WaitForDataSourceStart("ds_1");
454
455 auto writer = producer->CreateTraceWriter("ds_1");
456 producer->WaitForFlush(writer.get());
457
458 producer->WaitForDataSourceStop("ds_1");
459 consumer->WaitForTracingDisabled();
460 EXPECT_THAT(
461 consumer->ReadBuffers(),
462 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
463}
464
465// Creates a tracing session with a START_TRACING trigger and checks that the
466// session is cleaned up even when a different trigger is received.
467TEST_F(TracingServiceImplTest, StartTracingTriggerDifferentTrigger) {
468 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
469 consumer->Connect(svc.get());
470
471 std::unique_ptr<MockProducer> producer = CreateMockProducer();
472 producer->Connect(svc.get(), "mock_producer");
473
474 // Create two data sources but enable only one of them.
475 producer->RegisterDataSource("ds_1");
476 producer->RegisterDataSource("ds_2");
477
478 TraceConfig trace_config;
479 trace_config.add_buffers()->set_size_kb(128);
480 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
481 auto* trigger_config = trace_config.mutable_trigger_config();
482 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
483 auto* trigger = trigger_config->add_triggers();
484 trigger->set_name("trigger_name");
485 trigger->set_stop_delay_ms(8.64e+7);
486
487 trigger_config->set_trigger_timeout_ms(1);
488
489 // Make sure we don't get unexpected DataSourceStart() notifications yet.
490 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
491
492 consumer->EnableTracing(trace_config);
493 producer->WaitForTracingSetup();
494
495 producer->WaitForDataSourceSetup("ds_1");
496
497 // The trace won't start until we send the trigger called "trigger_name",
498 // since we have a START_TRACING trigger defined. This is where we'd expect to
499 // have an ActivateTriggers call to the producer->endpoint(), but we send a
500 // different trigger.
501 std::vector<std::string> req;
502 req.push_back("not_correct_trigger");
503 producer->endpoint()->ActivateTriggers(req);
504
505 producer->WaitForDataSourceStop("ds_1");
506 consumer->WaitForTracingDisabled();
507 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
508}
509
510// Creates a tracing session with a START_TRACING trigger and checks that any
511// trigger can start the TracingSession.
512TEST_F(TracingServiceImplTest, StartTracingTriggerMultipleTriggers) {
513 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
514 consumer->Connect(svc.get());
515
516 std::unique_ptr<MockProducer> producer = CreateMockProducer();
517 producer->Connect(svc.get(), "mock_producer");
518
519 // Create two data sources but enable only one of them.
520 producer->RegisterDataSource("ds_1");
521 producer->RegisterDataSource("ds_2");
522
523 TraceConfig trace_config;
524 trace_config.add_buffers()->set_size_kb(128);
525 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
526 auto* trigger_config = trace_config.mutable_trigger_config();
527 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
528 auto* trigger = trigger_config->add_triggers();
529 trigger->set_name("trigger_name");
530 trigger->set_stop_delay_ms(1);
531
532 trigger_config->set_trigger_timeout_ms(8.64e+7);
533
534 consumer->EnableTracing(trace_config);
535 producer->WaitForTracingSetup();
536
537 producer->WaitForDataSourceSetup("ds_1");
538
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000539 std::vector<std::string> req;
540 req.push_back("not_correct_trigger");
541 req.push_back("trigger_name");
542 producer->endpoint()->ActivateTriggers(req);
543
544 producer->WaitForDataSourceStart("ds_1");
545
546 auto writer = producer->CreateTraceWriter("ds_1");
547 producer->WaitForFlush(writer.get());
548
549 producer->WaitForDataSourceStop("ds_1");
550 consumer->WaitForTracingDisabled();
551 EXPECT_THAT(
552 consumer->ReadBuffers(),
553 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
554}
555
556// Creates two tracing sessions with a START_TRACING trigger and checks that
557// both are able to be triggered simultaneously.
558TEST_F(TracingServiceImplTest, StartTracingTriggerMultipleTraces) {
559 std::unique_ptr<MockConsumer> consumer_1 = CreateMockConsumer();
560 consumer_1->Connect(svc.get());
561 std::unique_ptr<MockConsumer> consumer_2 = CreateMockConsumer();
562 consumer_2->Connect(svc.get());
563
564 std::unique_ptr<MockProducer> producer = CreateMockProducer();
565 producer->Connect(svc.get(), "mock_producer");
566
567 // Create two data sources but each TracingSession will only enable one of
568 // them.
569 producer->RegisterDataSource("ds_1");
570 producer->RegisterDataSource("ds_2");
571
572 TraceConfig trace_config;
573 trace_config.add_buffers()->set_size_kb(128);
574 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
575 auto* trigger_config = trace_config.mutable_trigger_config();
576 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
577 auto* trigger = trigger_config->add_triggers();
578 trigger->set_name("trigger_name");
579 trigger->set_stop_delay_ms(1);
580
581 trigger_config->set_trigger_timeout_ms(8.64e+7);
582
583 consumer_1->EnableTracing(trace_config);
584 producer->WaitForTracingSetup();
585
586 producer->WaitForDataSourceSetup("ds_1");
587
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000588 auto tracing_session_1_id = GetTracingSessionID();
589
590 (*trace_config.mutable_data_sources())[0].mutable_config()->set_name("ds_2");
591 trigger = trace_config.mutable_trigger_config()->add_triggers();
592 trigger->set_name("trigger_name_2");
593 trigger->set_stop_delay_ms(8.64e+7);
594
595 consumer_2->EnableTracing(trace_config);
596
597 producer->WaitForDataSourceSetup("ds_2");
598
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000599 auto tracing_session_2_id = GetTracingSessionID();
600 EXPECT_NE(tracing_session_1_id, tracing_session_2_id);
601
602 const DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_1");
603 const DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_2");
604
605 std::vector<std::string> req;
606 req.push_back("not_correct_trigger");
607 req.push_back("trigger_name");
608 req.push_back("trigger_name_2");
609 producer->endpoint()->ActivateTriggers(req);
610
611 // The order has to be the same as the triggers or else we're incorrectly wait
612 // on the wrong checkpoint in the |task_runner|.
613 producer->WaitForDataSourceStart("ds_1");
614 producer->WaitForDataSourceStart("ds_2");
615
616 // Now that they've started we can check the triggers they've seen.
617 auto* tracing_session_1 = GetTracingSession(tracing_session_1_id);
618 ASSERT_EQ(1u, tracing_session_1->received_triggers.size());
619 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100620 tracing_session_1->received_triggers[0].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000621
622 // This is actually dependent on the order in which the triggers were received
623 // but there isn't really a better way than iteration order so probably not to
624 // brittle of a test. And this caught a real bug in implementation.
625 auto* tracing_session_2 = GetTracingSession(tracing_session_2_id);
626 ASSERT_EQ(2u, tracing_session_2->received_triggers.size());
627
628 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100629 tracing_session_2->received_triggers[0].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000630
631 EXPECT_EQ("trigger_name_2",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100632 tracing_session_2->received_triggers[1].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000633
634 auto writer1 = producer->CreateTraceWriter("ds_1");
635 auto writer2 = producer->CreateTraceWriter("ds_2");
636
637 // We can't use the standard WaitForX in the MockProducer and MockConsumer
638 // because they assume only a single trace is going on. So we perform our own
639 // expectations and wait at the end for the two consumers to receive
640 // OnTracingDisabled.
641 bool flushed_writer_1 = false;
642 bool flushed_writer_2 = false;
643 auto flush_correct_writer = [&](FlushRequestID flush_req_id,
644 const DataSourceInstanceID* id, size_t) {
645 if (*id == id1) {
646 flushed_writer_1 = true;
647 writer1->Flush();
648 producer->endpoint()->NotifyFlushComplete(flush_req_id);
649 } else if (*id == id2) {
650 flushed_writer_2 = true;
651 writer2->Flush();
652 producer->endpoint()->NotifyFlushComplete(flush_req_id);
653 }
654 };
655 EXPECT_CALL(*producer, Flush(_, _, _))
656 .WillOnce(Invoke(flush_correct_writer))
657 .WillOnce(Invoke(flush_correct_writer));
658
659 auto checkpoint_name = "on_tracing_disabled_consumer_1_and_2";
660 auto on_tracing_disabled = task_runner.CreateCheckpoint(checkpoint_name);
661 std::atomic<size_t> counter(0);
662 EXPECT_CALL(*consumer_1, OnTracingDisabled()).WillOnce(Invoke([&]() {
663 if (++counter == 2u) {
664 on_tracing_disabled();
665 }
666 }));
667 EXPECT_CALL(*consumer_2, OnTracingDisabled()).WillOnce(Invoke([&]() {
668 if (++counter == 2u) {
669 on_tracing_disabled();
670 }
671 }));
672
673 EXPECT_CALL(*producer, StopDataSource(id1));
674 EXPECT_CALL(*producer, StopDataSource(id2));
675
676 task_runner.RunUntilCheckpoint(checkpoint_name, 1000);
677
678 EXPECT_TRUE(flushed_writer_1);
679 EXPECT_TRUE(flushed_writer_2);
680 EXPECT_THAT(
681 consumer_1->ReadBuffers(),
682 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
683 EXPECT_THAT(
684 consumer_2->ReadBuffers(),
685 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
686}
687
Stephen Nusko70ea3302019-04-01 19:44:40 +0100688// Creates a tracing session with a START_TRACING trigger and checks that the
689// received_triggers are emitted as packets.
690TEST_F(TracingServiceImplTest, EmitTriggersWithStartTracingTrigger) {
691 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
692 consumer->Connect(svc.get());
693
694 std::unique_ptr<MockProducer> producer = CreateMockProducer();
695 producer->Connect(svc.get(), "mock_producer", /* uid = */ 123u);
696
697 producer->RegisterDataSource("ds_1");
698
699 TraceConfig trace_config;
700 trace_config.add_buffers()->set_size_kb(128);
701 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
702 auto* trigger_config = trace_config.mutable_trigger_config();
703 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
704 auto* trigger = trigger_config->add_triggers();
705 trigger->set_name("trigger_name");
706 trigger->set_stop_delay_ms(1);
707 trigger->set_producer_name_regex("mock_produc[e-r]+");
708
709 trigger_config->set_trigger_timeout_ms(30000);
710
711 consumer->EnableTracing(trace_config);
712 producer->WaitForTracingSetup();
713 producer->WaitForDataSourceSetup("ds_1");
714
715 // The trace won't start until we send the trigger since we have a
716 // START_TRACING trigger defined.
717 std::vector<std::string> req;
718 req.push_back("trigger_name");
719 req.push_back("trigger_name_2");
720 req.push_back("trigger_name_3");
721 producer->endpoint()->ActivateTriggers(req);
722
723 producer->WaitForDataSourceStart("ds_1");
724 auto writer1 = producer->CreateTraceWriter("ds_1");
725 producer->WaitForFlush(writer1.get());
726 producer->WaitForDataSourceStop("ds_1");
727 consumer->WaitForTracingDisabled();
728
729 ASSERT_EQ(1u, tracing_session()->received_triggers.size());
730 EXPECT_EQ("trigger_name",
731 tracing_session()->received_triggers[0].trigger_name);
732
733 auto packets = consumer->ReadBuffers();
734 EXPECT_THAT(
735 packets,
736 Contains(Property(
737 &protos::TracePacket::trace_config,
738 Property(
739 &protos::TraceConfig::trigger_config,
740 Property(
741 &protos::TraceConfig::TriggerConfig::trigger_mode,
742 Eq(protos::TraceConfig::TriggerConfig::START_TRACING))))));
743 auto expect_received_trigger = [&](const std::string& name) {
744 return Contains(AllOf(
745 Property(
746 &protos::TracePacket::trigger,
747 AllOf(Property(&protos::Trigger::trigger_name, Eq(name)),
Eric Secklerc4024b22019-04-02 15:37:08 +0000748 Property(&protos::Trigger::trusted_producer_uid, Eq(123)),
Stephen Nusko70ea3302019-04-01 19:44:40 +0100749 Property(&protos::Trigger::producer_name,
750 Eq("mock_producer")))),
751 Property(&protos::TracePacket::trusted_packet_sequence_id,
752 Eq(kServicePacketSequenceID))));
753 };
754 EXPECT_THAT(packets, expect_received_trigger("trigger_name"));
755 EXPECT_THAT(packets,
756 ::testing::Not(expect_received_trigger("trigger_name_2")));
757 EXPECT_THAT(packets,
758 ::testing::Not(expect_received_trigger("trigger_name_3")));
759}
760
761// Creates a tracing session with a START_TRACING trigger and checks that the
762// received_triggers are emitted as packets.
763TEST_F(TracingServiceImplTest, EmitTriggersWithStopTracingTrigger) {
764 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
765 consumer->Connect(svc.get());
766
767 std::unique_ptr<MockProducer> producer = CreateMockProducer();
768 producer->Connect(svc.get(), "mock_producer", /* uid = */ 321u);
769
770 producer->RegisterDataSource("ds_1");
771
772 TraceConfig trace_config;
773 trace_config.add_buffers()->set_size_kb(128);
774 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
775 auto* trigger_config = trace_config.mutable_trigger_config();
776 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
777 auto* trigger = trigger_config->add_triggers();
778 trigger->set_name("trigger_name");
779 trigger->set_stop_delay_ms(1);
780 trigger = trigger_config->add_triggers();
781 trigger->set_name("trigger_name_3");
782 trigger->set_stop_delay_ms(30000);
783
784 trigger_config->set_trigger_timeout_ms(30000);
785
786 consumer->EnableTracing(trace_config);
787 producer->WaitForTracingSetup();
788 producer->WaitForDataSourceSetup("ds_1");
789 producer->WaitForDataSourceStart("ds_1");
790
791 // The trace won't start until we send the trigger since we have a
792 // START_TRACING trigger defined.
793 std::vector<std::string> req;
794 req.push_back("trigger_name");
795 req.push_back("trigger_name_2");
796 req.push_back("trigger_name_3");
797 producer->endpoint()->ActivateTriggers(req);
798
799 auto writer1 = producer->CreateTraceWriter("ds_1");
800 producer->WaitForFlush(writer1.get());
801 producer->WaitForDataSourceStop("ds_1");
802 consumer->WaitForTracingDisabled();
803
804 ASSERT_EQ(2u, tracing_session()->received_triggers.size());
805 EXPECT_EQ("trigger_name",
806 tracing_session()->received_triggers[0].trigger_name);
807 EXPECT_EQ("trigger_name_3",
808 tracing_session()->received_triggers[1].trigger_name);
809
810 auto packets = consumer->ReadBuffers();
811 EXPECT_THAT(
812 packets,
813 Contains(Property(
814 &protos::TracePacket::trace_config,
815 Property(
816 &protos::TraceConfig::trigger_config,
817 Property(
818 &protos::TraceConfig::TriggerConfig::trigger_mode,
819 Eq(protos::TraceConfig::TriggerConfig::STOP_TRACING))))));
820
821 auto expect_received_trigger = [&](const std::string& name) {
822 return Contains(AllOf(
823 Property(
824 &protos::TracePacket::trigger,
825 AllOf(Property(&protos::Trigger::trigger_name, Eq(name)),
Eric Secklerc4024b22019-04-02 15:37:08 +0000826 Property(&protos::Trigger::trusted_producer_uid, Eq(321)),
Stephen Nusko70ea3302019-04-01 19:44:40 +0100827 Property(&protos::Trigger::producer_name,
828 Eq("mock_producer")))),
829 Property(&protos::TracePacket::trusted_packet_sequence_id,
830 Eq(kServicePacketSequenceID))));
831 };
832 EXPECT_THAT(packets, expect_received_trigger("trigger_name"));
833 EXPECT_THAT(packets,
834 ::testing::Not(expect_received_trigger("trigger_name_2")));
835 EXPECT_THAT(packets, expect_received_trigger("trigger_name_3"));
836}
837
838// Creates a tracing session with a START_TRACING trigger and checks that the
839// received_triggers are emitted as packets even ones after the initial
840// ReadBuffers() call.
841TEST_F(TracingServiceImplTest, EmitTriggersRepeatedly) {
842 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
843 consumer->Connect(svc.get());
844
845 std::unique_ptr<MockProducer> producer = CreateMockProducer();
846 producer->Connect(svc.get(), "mock_producer");
847
848 // Create two data sources but enable only one of them.
849 producer->RegisterDataSource("ds_1");
850 producer->RegisterDataSource("ds_2");
851
852 TraceConfig trace_config;
853 trace_config.add_buffers()->set_size_kb(128);
854 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
855 auto* trigger_config = trace_config.mutable_trigger_config();
856 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
857 auto* trigger = trigger_config->add_triggers();
858 trigger->set_name("trigger_name");
859 trigger->set_stop_delay_ms(1);
860 trigger = trigger_config->add_triggers();
861 trigger->set_name("trigger_name_2");
862 trigger->set_stop_delay_ms(1);
863
864 trigger_config->set_trigger_timeout_ms(30000);
865
866 auto expect_received_trigger = [&](const std::string& name) {
867 return Contains(
868 AllOf(Property(&protos::TracePacket::trigger,
869 AllOf(Property(&protos::Trigger::trigger_name, Eq(name)),
870 Property(&protos::Trigger::producer_name,
871 Eq("mock_producer")))),
872 Property(&protos::TracePacket::trusted_packet_sequence_id,
873 Eq(kServicePacketSequenceID))));
874 };
875
876 consumer->EnableTracing(trace_config);
877 producer->WaitForTracingSetup();
878 producer->WaitForDataSourceSetup("ds_1");
879 producer->WaitForDataSourceStart("ds_1");
880
881 // The trace won't start until we send the trigger. since we have a
882 // START_TRACING trigger defined.
883 producer->endpoint()->ActivateTriggers({"trigger_name"});
884
885 auto packets = consumer->ReadBuffers();
886 EXPECT_THAT(
887 packets,
888 Contains(Property(
889 &protos::TracePacket::trace_config,
890 Property(
891 &protos::TraceConfig::trigger_config,
892 Property(
893 &protos::TraceConfig::TriggerConfig::trigger_mode,
894 Eq(protos::TraceConfig::TriggerConfig::STOP_TRACING))))));
895 EXPECT_THAT(packets, expect_received_trigger("trigger_name"));
896 EXPECT_THAT(packets,
897 ::testing::Not(expect_received_trigger("trigger_name_2")));
898
899 // Send a new trigger.
900 producer->endpoint()->ActivateTriggers({"trigger_name_2"});
901
902 auto writer1 = producer->CreateTraceWriter("ds_1");
903 producer->WaitForFlush(writer1.get());
904 producer->WaitForDataSourceStop("ds_1");
905 consumer->WaitForTracingDisabled();
906
907 ASSERT_EQ(2u, tracing_session()->received_triggers.size());
908 EXPECT_EQ("trigger_name",
909 tracing_session()->received_triggers[0].trigger_name);
910 EXPECT_EQ("trigger_name_2",
911 tracing_session()->received_triggers[1].trigger_name);
912
913 packets = consumer->ReadBuffers();
914 // We don't rewrite the old trigger.
915 EXPECT_THAT(packets, ::testing::Not(expect_received_trigger("trigger_name")));
916 EXPECT_THAT(packets, expect_received_trigger("trigger_name_2"));
917}
918
Stephen Nuskod95a7512019-03-22 13:59:39 +0000919// Creates a tracing session with a STOP_TRACING trigger and checks that the
920// session is cleaned up after |trigger_timeout_ms|.
921TEST_F(TracingServiceImplTest, StopTracingTriggerTimeout) {
922 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
923 consumer->Connect(svc.get());
924
925 std::unique_ptr<MockProducer> producer = CreateMockProducer();
926 producer->Connect(svc.get(), "mock_producer");
927
928 // Create two data sources but enable only one of them.
929 producer->RegisterDataSource("ds_1");
930 producer->RegisterDataSource("ds_2");
931
932 TraceConfig trace_config;
933 trace_config.add_buffers()->set_size_kb(128);
934 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
935 auto* trigger_config = trace_config.mutable_trigger_config();
936 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
937 auto* trigger = trigger_config->add_triggers();
938 trigger->set_name("trigger_name");
939 trigger->set_stop_delay_ms(8.64e+7);
940
941 trigger_config->set_trigger_timeout_ms(1);
942
943 // Make sure we don't get unexpected DataSourceStart() notifications yet.
944 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
945
946 consumer->EnableTracing(trace_config);
947 producer->WaitForTracingSetup();
948
949 producer->WaitForDataSourceSetup("ds_1");
950 producer->WaitForDataSourceStart("ds_1");
951
952 // The trace won't return data until unless we send a trigger at this point.
953 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
954
955 auto writer = producer->CreateTraceWriter("ds_1");
956 producer->WaitForFlush(writer.get());
957
958 ASSERT_EQ(0u, tracing_session()->received_triggers.size());
959
960 producer->WaitForDataSourceStop("ds_1");
961 consumer->WaitForTracingDisabled();
962 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
963}
964
965// Creates a tracing session with a STOP_TRACING trigger and checks that the
966// session returns data after a trigger is received, but only what is currently
967// in the buffer.
968TEST_F(TracingServiceImplTest, StopTracingTriggerRingBuffer) {
969 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
970 consumer->Connect(svc.get());
971
972 std::unique_ptr<MockProducer> producer = CreateMockProducer();
973 producer->Connect(svc.get(), "mock_producer");
974
975 // Create two data sources but enable only one of them.
976 producer->RegisterDataSource("ds_1");
977 producer->RegisterDataSource("ds_2");
978
979 TraceConfig trace_config;
980 trace_config.add_buffers()->set_size_kb(128);
981 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
982 auto* trigger_config = trace_config.mutable_trigger_config();
983 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
984 auto* trigger = trigger_config->add_triggers();
985 trigger->set_name("trigger_name");
986 trigger->set_stop_delay_ms(1);
987
988 trigger_config->set_trigger_timeout_ms(8.64e+7);
989
990 consumer->EnableTracing(trace_config);
991 producer->WaitForTracingSetup();
992
993 producer->WaitForDataSourceSetup("ds_1");
994 producer->WaitForDataSourceStart("ds_1");
995
Stephen Nuskod95a7512019-03-22 13:59:39 +0000996 // The trace won't return data until unless we send a trigger at this point.
997 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
998
999 // We write into the buffer a large packet which takes up the whole buffer. We
1000 // then add a bunch of smaller ones which causes the larger packet to be
1001 // dropped. After we activate the session we should only see a bunch of the
1002 // smaller ones.
Eric Secklera883e5f2019-04-02 22:51:29 +00001003 static const size_t kNumTestPackets = 10;
Stephen Nuskod95a7512019-03-22 13:59:39 +00001004 static const char kPayload[] = "1234567890abcdef-";
1005
1006 auto writer = producer->CreateTraceWriter("ds_1");
1007 // Buffer is 1kb so we write a packet which is slightly smaller so it fits in
1008 // the buffer.
1009 const std::string large_payload(1024 * 128 - 20, 'a');
1010 {
1011 auto tp = writer->NewTracePacket();
1012 tp->set_for_testing()->set_str(large_payload.c_str(), large_payload.size());
1013 }
1014
1015 // Now we add a bunch of data before the trigger and after.
Eric Secklera883e5f2019-04-02 22:51:29 +00001016 for (size_t i = 0; i < kNumTestPackets; i++) {
Stephen Nuskod95a7512019-03-22 13:59:39 +00001017 if (i == kNumTestPackets / 2) {
1018 std::vector<std::string> req;
1019 req.push_back("trigger_name");
1020 producer->endpoint()->ActivateTriggers(req);
1021 }
1022 auto tp = writer->NewTracePacket();
1023 std::string payload(kPayload);
1024 payload.append(std::to_string(i));
1025 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
1026 }
1027 producer->WaitForFlush(writer.get());
1028
1029 ASSERT_EQ(1u, tracing_session()->received_triggers.size());
1030 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +01001031 tracing_session()->received_triggers[0].trigger_name);
Stephen Nuskod95a7512019-03-22 13:59:39 +00001032
1033 producer->WaitForDataSourceStop("ds_1");
1034 consumer->WaitForTracingDisabled();
Stephen Nusko70ea3302019-04-01 19:44:40 +01001035
Stephen Nuskod95a7512019-03-22 13:59:39 +00001036 auto packets = consumer->ReadBuffers();
Stephen Nusko70ea3302019-04-01 19:44:40 +01001037 EXPECT_LT(kNumTestPackets, packets.size());
Stephen Nuskod95a7512019-03-22 13:59:39 +00001038 // We expect for the TraceConfig preamble packet to be there correctly and
1039 // then we expect each payload to be there, but not the |large_payload|
1040 // packet.
1041 EXPECT_THAT(packets,
1042 HasTriggerMode(protos::TraceConfig::TriggerConfig::STOP_TRACING));
Eric Secklera883e5f2019-04-02 22:51:29 +00001043 for (size_t i = 0; i < kNumTestPackets; i++) {
Stephen Nuskod95a7512019-03-22 13:59:39 +00001044 std::string payload = kPayload;
1045 payload += std::to_string(i);
1046 EXPECT_THAT(packets, Contains(Property(
1047 &protos::TracePacket::for_testing,
1048 Property(&protos::TestEvent::str, Eq(payload)))));
1049 }
1050
1051 // The large payload was overwritten before we trigger and ReadBuffers so it
1052 // should not be in the returned data.
1053 EXPECT_THAT(packets,
1054 ::testing::Not(Contains(Property(
1055 &protos::TracePacket::for_testing,
1056 Property(&protos::TestEvent::str, Eq(large_payload))))));
1057}
1058
1059// Creates a tracing session with a STOP_TRACING trigger and checks that the
1060// session only cleans up once even with multiple triggers.
1061TEST_F(TracingServiceImplTest, StopTracingTriggerMultipleTriggers) {
1062 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1063 consumer->Connect(svc.get());
1064
1065 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1066 producer->Connect(svc.get(), "mock_producer");
1067
1068 // Create two data sources but enable only one of them.
1069 producer->RegisterDataSource("ds_1");
1070 producer->RegisterDataSource("ds_2");
1071
1072 TraceConfig trace_config;
1073 trace_config.add_buffers()->set_size_kb(128);
1074 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
1075 auto* trigger_config = trace_config.mutable_trigger_config();
1076 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
1077 auto* trigger = trigger_config->add_triggers();
1078 trigger->set_name("trigger_name");
1079 trigger->set_stop_delay_ms(1);
1080 trigger = trigger_config->add_triggers();
1081 trigger->set_name("trigger_name_2");
1082 trigger->set_stop_delay_ms(8.64e+7);
1083
1084 trigger_config->set_trigger_timeout_ms(8.64e+7);
1085
1086 consumer->EnableTracing(trace_config);
1087 producer->WaitForTracingSetup();
1088
1089 producer->WaitForDataSourceSetup("ds_1");
1090 producer->WaitForDataSourceStart("ds_1");
1091
Stephen Nuskod95a7512019-03-22 13:59:39 +00001092 // The trace won't return data until unless we send a trigger at this point.
1093 EXPECT_THAT(consumer->ReadBuffers(), ::testing::IsEmpty());
1094
1095 std::vector<std::string> req;
1096 req.push_back("trigger_name");
1097 req.push_back("trigger_name_3");
1098 req.push_back("trigger_name_2");
1099 producer->endpoint()->ActivateTriggers(req);
1100
1101 auto writer = producer->CreateTraceWriter("ds_1");
1102 producer->WaitForFlush(writer.get());
1103
1104 ASSERT_EQ(2u, tracing_session()->received_triggers.size());
1105 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +01001106 tracing_session()->received_triggers[0].trigger_name);
Stephen Nuskod95a7512019-03-22 13:59:39 +00001107 EXPECT_EQ("trigger_name_2",
Stephen Nusko70ea3302019-04-01 19:44:40 +01001108 tracing_session()->received_triggers[1].trigger_name);
Stephen Nuskod95a7512019-03-22 13:59:39 +00001109
1110 producer->WaitForDataSourceStop("ds_1");
1111 consumer->WaitForTracingDisabled();
1112 EXPECT_THAT(consumer->ReadBuffers(),
1113 HasTriggerMode(protos::TraceConfig::TriggerConfig::STOP_TRACING));
1114}
1115
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001116TEST_F(TracingServiceImplTest, LockdownMode) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001117 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1118 consumer->Connect(svc.get());
1119
1120 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1121 producer->Connect(svc.get(), "mock_producer_sameuid", geteuid());
1122 producer->RegisterDataSource("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +00001123
1124 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001125 trace_config.add_buffers()->set_size_kb(128);
1126 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1127 ds_config->set_name("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +00001128 trace_config.set_lockdown_mode(
1129 TraceConfig::LockdownModeOperation::LOCKDOWN_SET);
Primiano Tuccidca727d2018-04-04 11:31:55 +02001130 consumer->EnableTracing(trace_config);
1131
1132 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001133 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001134 producer->WaitForDataSourceStart("data_source");
1135
1136 std::unique_ptr<MockProducer> producer_otheruid = CreateMockProducer();
1137 auto x = svc->ConnectProducer(producer_otheruid.get(), geteuid() + 1,
1138 "mock_producer_ouid");
1139 EXPECT_CALL(*producer_otheruid, OnConnect()).Times(0);
Florian Mayer61c55482018-03-06 14:43:54 +00001140 task_runner.RunUntilIdle();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001141 Mock::VerifyAndClearExpectations(producer_otheruid.get());
Florian Mayer61c55482018-03-06 14:43:54 +00001142
Primiano Tuccidca727d2018-04-04 11:31:55 +02001143 consumer->DisableTracing();
1144 consumer->FreeBuffers();
1145 producer->WaitForDataSourceStop("data_source");
1146 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +00001147
1148 trace_config.set_lockdown_mode(
1149 TraceConfig::LockdownModeOperation::LOCKDOWN_CLEAR);
Primiano Tuccidca727d2018-04-04 11:31:55 +02001150 consumer->EnableTracing(trace_config);
Primiano Tucci674076d2018-10-01 10:41:09 +01001151 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001152 producer->WaitForDataSourceStart("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +00001153
Primiano Tuccidca727d2018-04-04 11:31:55 +02001154 std::unique_ptr<MockProducer> producer_otheruid2 = CreateMockProducer();
1155 producer_otheruid->Connect(svc.get(), "mock_producer_ouid2", geteuid() + 1);
Florian Mayer61c55482018-03-06 14:43:54 +00001156
Primiano Tuccidca727d2018-04-04 11:31:55 +02001157 consumer->DisableTracing();
1158 producer->WaitForDataSourceStop("data_source");
1159 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +00001160}
1161
Oystein Eftevaagcb6e4c82019-03-06 15:38:26 -08001162TEST_F(TracingServiceImplTest, ProducerNameFilterChange) {
1163 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1164 consumer->Connect(svc.get());
1165
1166 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1167 producer1->Connect(svc.get(), "mock_producer_1");
1168 producer1->RegisterDataSource("data_source");
1169
1170 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1171 producer2->Connect(svc.get(), "mock_producer_2");
1172 producer2->RegisterDataSource("data_source");
1173
1174 std::unique_ptr<MockProducer> producer3 = CreateMockProducer();
1175 producer3->Connect(svc.get(), "mock_producer_3");
1176 producer3->RegisterDataSource("data_source");
1177 producer3->RegisterDataSource("unused_data_source");
1178
1179 TraceConfig trace_config;
1180 trace_config.add_buffers()->set_size_kb(128);
1181 auto* data_source = trace_config.add_data_sources();
1182 data_source->mutable_config()->set_name("data_source");
1183 *data_source->add_producer_name_filter() = "mock_producer_1";
1184
1185 // Enable tracing with only mock_producer_1 enabled;
1186 // the rest should not start up.
1187 consumer->EnableTracing(trace_config);
1188
1189 producer1->WaitForTracingSetup();
1190 producer1->WaitForDataSourceSetup("data_source");
1191 producer1->WaitForDataSourceStart("data_source");
1192
1193 EXPECT_CALL(*producer2, OnConnect()).Times(0);
1194 EXPECT_CALL(*producer3, OnConnect()).Times(0);
1195 task_runner.RunUntilIdle();
1196 Mock::VerifyAndClearExpectations(producer2.get());
1197 Mock::VerifyAndClearExpectations(producer3.get());
1198
1199 // Enable mock_producer_2, the third one should still
1200 // not get connected.
1201 *data_source->add_producer_name_filter() = "mock_producer_2";
1202 consumer->ChangeTraceConfig(trace_config);
1203
1204 producer2->WaitForTracingSetup();
1205 producer2->WaitForDataSourceSetup("data_source");
1206 producer2->WaitForDataSourceStart("data_source");
1207
1208 // Enable mock_producer_3 but also try to do an
1209 // unsupported change (adding a new data source);
1210 // mock_producer_3 should get enabled but not
1211 // for the new data source.
1212 *data_source->add_producer_name_filter() = "mock_producer_3";
1213 auto* dummy_data_source = trace_config.add_data_sources();
1214 dummy_data_source->mutable_config()->set_name("unused_data_source");
1215 *dummy_data_source->add_producer_name_filter() = "mock_producer_3";
1216
1217 consumer->ChangeTraceConfig(trace_config);
1218
1219 producer3->WaitForTracingSetup();
1220 EXPECT_CALL(*producer3, SetupDataSource(_, _)).Times(1);
1221 EXPECT_CALL(*producer3, StartDataSource(_, _)).Times(1);
1222 task_runner.RunUntilIdle();
1223 Mock::VerifyAndClearExpectations(producer3.get());
1224
1225 consumer->DisableTracing();
1226 consumer->FreeBuffers();
1227 producer1->WaitForDataSourceStop("data_source");
1228 producer2->WaitForDataSourceStop("data_source");
1229
1230 EXPECT_CALL(*producer3, StopDataSource(_)).Times(1);
1231
1232 consumer->WaitForTracingDisabled();
1233
1234 task_runner.RunUntilIdle();
1235 Mock::VerifyAndClearExpectations(producer3.get());
1236}
1237
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001238TEST_F(TracingServiceImplTest, DisconnectConsumerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001239 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1240 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +00001241
Primiano Tuccidca727d2018-04-04 11:31:55 +02001242 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1243 producer->Connect(svc.get(), "mock_producer");
1244 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001245
Primiano Tuccidca727d2018-04-04 11:31:55 +02001246 TraceConfig trace_config;
1247 trace_config.add_buffers()->set_size_kb(128);
1248 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1249 ds_config->set_name("data_source");
1250 consumer->EnableTracing(trace_config);
1251
1252 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001253 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001254 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001255
1256 // Disconnecting the consumer while tracing should trigger data source
1257 // teardown.
Primiano Tuccidca727d2018-04-04 11:31:55 +02001258 consumer.reset();
1259 producer->WaitForDataSourceStop("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001260}
1261
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001262TEST_F(TracingServiceImplTest, ReconnectProducerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001263 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1264 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +00001265
Primiano Tuccidca727d2018-04-04 11:31:55 +02001266 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1267 producer->Connect(svc.get(), "mock_producer");
1268 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001269
Sami Kyostila06487a22018-02-27 13:48:38 +00001270 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001271 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +00001272 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001273 ds_config->set_name("data_source");
1274 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +00001275
Primiano Tuccidca727d2018-04-04 11:31:55 +02001276 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001277 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001278 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001279
Primiano Tuccidca727d2018-04-04 11:31:55 +02001280 // Disconnecting and reconnecting a producer with a matching data source.
1281 // The Producer should see that data source getting enabled again.
1282 producer.reset();
1283 producer = CreateMockProducer();
1284 producer->Connect(svc.get(), "mock_producer_2");
1285 producer->RegisterDataSource("data_source");
1286 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001287 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001288 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001289}
1290
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001291TEST_F(TracingServiceImplTest, ProducerIDWrapping) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001292 std::vector<std::unique_ptr<MockProducer>> producers;
1293 producers.push_back(nullptr);
Primiano Tucci081d46a2018-02-28 11:09:43 +00001294
Primiano Tuccidca727d2018-04-04 11:31:55 +02001295 auto connect_producer_and_get_id = [&producers,
1296 this](const std::string& name) {
1297 producers.emplace_back(CreateMockProducer());
1298 producers.back()->Connect(svc.get(), "mock_producer_" + name);
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001299 return *last_producer_id();
Primiano Tucci081d46a2018-02-28 11:09:43 +00001300 };
1301
1302 // Connect producers 1-4.
1303 for (ProducerID i = 1; i <= 4; i++)
Primiano Tuccidca727d2018-04-04 11:31:55 +02001304 ASSERT_EQ(i, connect_producer_and_get_id(std::to_string(i)));
Primiano Tucci081d46a2018-02-28 11:09:43 +00001305
1306 // Disconnect producers 1,3.
Primiano Tuccidca727d2018-04-04 11:31:55 +02001307 producers[1].reset();
1308 producers[3].reset();
Primiano Tucci081d46a2018-02-28 11:09:43 +00001309
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001310 *last_producer_id() = kMaxProducerID - 1;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001311 ASSERT_EQ(kMaxProducerID, connect_producer_and_get_id("maxid"));
1312 ASSERT_EQ(1u, connect_producer_and_get_id("1_again"));
1313 ASSERT_EQ(3u, connect_producer_and_get_id("3_again"));
1314 ASSERT_EQ(5u, connect_producer_and_get_id("5"));
1315 ASSERT_EQ(6u, connect_producer_and_get_id("6"));
Primiano Tucci081d46a2018-02-28 11:09:43 +00001316}
1317
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001318// Note: file_write_period_ms is set to a large enough to have exactly one flush
1319// of the tracing buffers (and therefore at most one synchronization section),
1320// unless the test runs unrealistically slowly, or the implementation of the
1321// tracing snapshot packets changes.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001322TEST_F(TracingServiceImplTest, WriteIntoFileAndStopOnMaxSize) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001323 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1324 consumer->Connect(svc.get());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001325
Primiano Tuccidca727d2018-04-04 11:31:55 +02001326 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1327 producer->Connect(svc.get(), "mock_producer");
1328 producer->RegisterDataSource("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001329
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001330 TraceConfig trace_config;
1331 trace_config.add_buffers()->set_size_kb(4096);
1332 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001333 ds_config->set_name("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001334 ds_config->set_target_buffer(0);
1335 trace_config.set_write_into_file(true);
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001336 trace_config.set_file_write_period_ms(100000); // 100s
1337 const uint64_t kMaxFileSize = 1024;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001338 trace_config.set_max_file_size_bytes(kMaxFileSize);
1339 base::TempFile tmp_file = base::TempFile::Create();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001340 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
1341
1342 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001343 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001344 producer->WaitForDataSourceStart("data_source");
1345
Hector Dearman685f7522019-03-12 14:28:56 +00001346 // The preamble packets are:
Hector Dearmane004a572019-05-13 17:51:43 +01001347 // Trace start clocksnapshot
Hector Dearman685f7522019-03-12 14:28:56 +00001348 // Config
1349 // SystemInfo
Hector Dearmane004a572019-05-13 17:51:43 +01001350 // Trace read clocksnapshot
1351 // Trace synchronisation
Eric Seckler667e0852019-06-06 14:56:07 +01001352 static const int kNumPreamblePackets = 5;
Hector Dearmane004a572019-05-13 17:51:43 +01001353 static const int kNumTestPackets = 9;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001354 static const char kPayload[] = "1234567890abcdef-";
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001355
1356 std::unique_ptr<TraceWriter> writer =
Primiano Tuccidca727d2018-04-04 11:31:55 +02001357 producer->CreateTraceWriter("data_source");
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001358 // Tracing service will emit a preamble of packets (a synchronization section,
1359 // followed by a tracing config packet). The preamble and these test packets
1360 // should fit within kMaxFileSize.
1361 for (int i = 0; i < kNumTestPackets; i++) {
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001362 auto tp = writer->NewTracePacket();
1363 std::string payload(kPayload);
1364 payload.append(std::to_string(i));
1365 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
1366 }
1367
1368 // Finally add a packet that overflows kMaxFileSize. This should cause the
1369 // implicit stop of the trace and should *not* be written in the trace.
1370 {
1371 auto tp = writer->NewTracePacket();
1372 char big_payload[kMaxFileSize] = "BIG!";
1373 tp->set_for_testing()->set_str(big_payload, sizeof(big_payload));
1374 }
1375 writer->Flush();
1376 writer.reset();
1377
Primiano Tuccidca727d2018-04-04 11:31:55 +02001378 consumer->DisableTracing();
1379 producer->WaitForDataSourceStop("data_source");
1380 consumer->WaitForTracingDisabled();
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001381
1382 // Verify the contents of the file.
1383 std::string trace_raw;
1384 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
1385 protos::Trace trace;
1386 ASSERT_TRUE(trace.ParseFromString(trace_raw));
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001387
1388 ASSERT_EQ(trace.packet_size(), kNumPreamblePackets + kNumTestPackets);
1389 for (int i = 0; i < kNumTestPackets; i++) {
1390 const protos::TracePacket& tp = trace.packet(kNumPreamblePackets + i);
1391 ASSERT_EQ(kPayload + std::to_string(i++), tp.for_testing().str());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001392 }
Primiano Tuccidca727d2018-04-04 11:31:55 +02001393}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001394
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001395// Test the logic that allows the trace config to set the shm total size and
1396// page size from the trace config. Also check that, if the config doesn't
1397// specify a value we fall back on the hint provided by the producer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001398TEST_F(TracingServiceImplTest, ProducerShmAndPageSizeOverriddenByTraceConfig) {
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001399 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1400 consumer->Connect(svc.get());
Nicolò Mazzucato693f6aa2019-07-08 10:26:09 +01001401 const size_t kMaxPageSizeKb = SharedMemoryABI::kMaxPageSize / 1024;
1402 const size_t kConfigPageSizesKb[] = /**/ {16, 0, 3, 2, 16, 8, 0, 4096, 0};
1403 const size_t kPageHintSizesKb[] = /****/ {0, 4, 0, 0, 8, 0, 4096, 0, 0};
1404 const size_t kExpectedPageSizesKb[] = {
1405 16, // Use config value.
1406 4, // Config is 0, use hint.
1407 kDefaultShmPageSizeKb, // Config % 4 != 0, take default.
1408 kDefaultShmPageSizeKb, // Less than page size, take default.
1409 16, // Ignore the hint.
1410 8, // Use config value.
1411 kMaxPageSizeKb, // Hint too big, take max value.
1412 kMaxPageSizeKb, // Config too high, take max value.
1413 4 // Fallback to default.
1414 };
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001415
1416 const size_t kConfigSizesKb[] = /**/ {0, 16, 0, 20, 32, 7, 0, 96, 4096000};
1417 const size_t kHintSizesKb[] = /****/ {0, 0, 16, 32, 16, 0, 7, 96, 4096000};
1418 const size_t kExpectedSizesKb[] = {
1419 kDefaultShmSizeKb, // Both hint and config are 0, use default.
1420 16, // Hint is 0, use config.
1421 16, // Config is 0, use hint.
1422 20, // Hint is takes precedence over the config.
1423 32, // Ditto, even if config is higher than hint.
1424 kDefaultShmSizeKb, // Config is invalid and hint is 0, use default.
1425 kDefaultShmSizeKb, // Config is 0 and hint is invalid, use default.
1426 kDefaultShmSizeKb, // 96 KB isn't a multiple of the page size (64 KB).
1427 kMaxShmSizeKb // Too big, cap at kMaxShmSize.
1428 };
1429
1430 const size_t kNumProducers = base::ArraySize(kHintSizesKb);
1431 std::unique_ptr<MockProducer> producer[kNumProducers];
1432 for (size_t i = 0; i < kNumProducers; i++) {
1433 auto name = "mock_producer_" + std::to_string(i);
1434 producer[i] = CreateMockProducer();
Nicolò Mazzucato693f6aa2019-07-08 10:26:09 +01001435 producer[i]->Connect(svc.get(), name, geteuid(), kHintSizesKb[i] * 1024,
1436 kPageHintSizesKb[i] * 1024);
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001437 producer[i]->RegisterDataSource("data_source");
1438 }
1439
1440 TraceConfig trace_config;
1441 trace_config.add_buffers()->set_size_kb(128);
1442 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1443 ds_config->set_name("data_source");
1444 for (size_t i = 0; i < kNumProducers; i++) {
1445 auto* producer_config = trace_config.add_producers();
1446 producer_config->set_producer_name("mock_producer_" + std::to_string(i));
Primiano Tucci3cbb10a2018-04-10 17:52:40 +01001447 producer_config->set_shm_size_kb(static_cast<uint32_t>(kConfigSizesKb[i]));
1448 producer_config->set_page_size_kb(
1449 static_cast<uint32_t>(kConfigPageSizesKb[i]));
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001450 }
1451
1452 consumer->EnableTracing(trace_config);
1453 size_t actual_shm_sizes_kb[kNumProducers]{};
1454 size_t actual_page_sizes_kb[kNumProducers]{};
1455 for (size_t i = 0; i < kNumProducers; i++) {
1456 producer[i]->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001457 producer[i]->WaitForDataSourceSetup("data_source");
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001458 actual_shm_sizes_kb[i] =
1459 producer[i]->endpoint()->shared_memory()->size() / 1024;
1460 actual_page_sizes_kb[i] =
1461 producer[i]->endpoint()->shared_buffer_page_size_kb();
1462 }
Primiano Tucci674076d2018-10-01 10:41:09 +01001463 for (size_t i = 0; i < kNumProducers; i++) {
1464 producer[i]->WaitForDataSourceStart("data_source");
1465 }
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001466 ASSERT_THAT(actual_page_sizes_kb, ElementsAreArray(kExpectedPageSizesKb));
1467 ASSERT_THAT(actual_shm_sizes_kb, ElementsAreArray(kExpectedSizesKb));
1468}
1469
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001470TEST_F(TracingServiceImplTest, ExplicitFlush) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001471 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1472 consumer->Connect(svc.get());
1473
1474 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1475 producer->Connect(svc.get(), "mock_producer");
1476 producer->RegisterDataSource("data_source");
1477
1478 TraceConfig trace_config;
1479 trace_config.add_buffers()->set_size_kb(128);
1480 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1481 ds_config->set_name("data_source");
1482
1483 consumer->EnableTracing(trace_config);
1484 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001485 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001486 producer->WaitForDataSourceStart("data_source");
1487
1488 std::unique_ptr<TraceWriter> writer =
1489 producer->CreateTraceWriter("data_source");
1490 {
1491 auto tp = writer->NewTracePacket();
1492 tp->set_for_testing()->set_str("payload");
1493 }
1494
1495 auto flush_request = consumer->Flush();
1496 producer->WaitForFlush(writer.get());
1497 ASSERT_TRUE(flush_request.WaitForReply());
1498
1499 consumer->DisableTracing();
1500 producer->WaitForDataSourceStop("data_source");
1501 consumer->WaitForTracingDisabled();
1502 EXPECT_THAT(
1503 consumer->ReadBuffers(),
1504 Contains(Property(&protos::TracePacket::for_testing,
1505 Property(&protos::TestEvent::str, Eq("payload")))));
1506}
1507
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001508TEST_F(TracingServiceImplTest, ImplicitFlushOnTimedTraces) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001509 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1510 consumer->Connect(svc.get());
1511
1512 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1513 producer->Connect(svc.get(), "mock_producer");
1514 producer->RegisterDataSource("data_source");
1515
1516 TraceConfig trace_config;
1517 trace_config.add_buffers()->set_size_kb(128);
1518 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1519 ds_config->set_name("data_source");
1520 trace_config.set_duration_ms(1);
1521
1522 consumer->EnableTracing(trace_config);
1523 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001524 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001525 producer->WaitForDataSourceStart("data_source");
1526
1527 std::unique_ptr<TraceWriter> writer =
1528 producer->CreateTraceWriter("data_source");
1529 {
1530 auto tp = writer->NewTracePacket();
1531 tp->set_for_testing()->set_str("payload");
1532 }
1533
1534 producer->WaitForFlush(writer.get());
1535
1536 producer->WaitForDataSourceStop("data_source");
1537 consumer->WaitForTracingDisabled();
1538
1539 EXPECT_THAT(
1540 consumer->ReadBuffers(),
1541 Contains(Property(&protos::TracePacket::for_testing,
1542 Property(&protos::TestEvent::str, Eq("payload")))));
1543}
1544
1545// Tests the monotonic semantic of flush request IDs, i.e., once a producer
1546// acks flush request N, all flush requests <= N are considered successful and
1547// acked to the consumer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001548TEST_F(TracingServiceImplTest, BatchFlushes) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001549 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1550 consumer->Connect(svc.get());
1551
1552 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1553 producer->Connect(svc.get(), "mock_producer");
1554 producer->RegisterDataSource("data_source");
1555
1556 TraceConfig trace_config;
1557 trace_config.add_buffers()->set_size_kb(128);
1558 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1559 ds_config->set_name("data_source");
1560
1561 consumer->EnableTracing(trace_config);
1562 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001563 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001564 producer->WaitForDataSourceStart("data_source");
1565
1566 std::unique_ptr<TraceWriter> writer =
1567 producer->CreateTraceWriter("data_source");
1568 {
1569 auto tp = writer->NewTracePacket();
1570 tp->set_for_testing()->set_str("payload");
1571 }
1572
1573 auto flush_req_1 = consumer->Flush();
1574 auto flush_req_2 = consumer->Flush();
1575 auto flush_req_3 = consumer->Flush();
1576
1577 // We'll deliberately let the 4th flush request timeout. Use a lower timeout
1578 // to keep test time short.
1579 auto flush_req_4 = consumer->Flush(/*timeout_ms=*/10);
1580 ASSERT_EQ(4u, GetNumPendingFlushes());
1581
1582 // Make the producer reply only to the 3rd flush request.
1583 testing::InSequence seq;
Eric Secklera01e28a2019-01-08 11:21:04 +00001584 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 1.
1585 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 2.
1586 producer->WaitForFlush(writer.get()); // Reply only to flush 3.
1587 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 4.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001588
1589 // Even if the producer explicily replied only to flush ID == 3, all the
1590 // previous flushed < 3 should be implicitly acked.
1591 ASSERT_TRUE(flush_req_1.WaitForReply());
1592 ASSERT_TRUE(flush_req_2.WaitForReply());
1593 ASSERT_TRUE(flush_req_3.WaitForReply());
1594
1595 // At this point flush id == 4 should still be pending and should fail because
1596 // of reaching its timeout.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001597 ASSERT_FALSE(flush_req_4.WaitForReply());
1598
1599 consumer->DisableTracing();
1600 producer->WaitForDataSourceStop("data_source");
1601 consumer->WaitForTracingDisabled();
1602 EXPECT_THAT(
1603 consumer->ReadBuffers(),
1604 Contains(Property(&protos::TracePacket::for_testing,
1605 Property(&protos::TestEvent::str, Eq("payload")))));
1606}
1607
Primiano Tuccicaa57802018-11-25 11:07:07 +00001608TEST_F(TracingServiceImplTest, PeriodicFlush) {
1609 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1610 consumer->Connect(svc.get());
1611
1612 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1613 producer->Connect(svc.get(), "mock_producer");
1614 producer->RegisterDataSource("data_source");
1615
1616 TraceConfig trace_config;
1617 trace_config.add_buffers()->set_size_kb(128);
1618 trace_config.set_flush_period_ms(1);
1619 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1620 ds_config->set_name("data_source");
1621
1622 consumer->EnableTracing(trace_config);
1623 producer->WaitForTracingSetup();
1624 producer->WaitForDataSourceSetup("data_source");
1625 producer->WaitForDataSourceStart("data_source");
1626
1627 std::unique_ptr<TraceWriter> writer =
1628 producer->CreateTraceWriter("data_source");
1629
1630 const int kNumFlushes = 3;
1631 auto checkpoint = task_runner.CreateCheckpoint("all_flushes_done");
1632 int flushes_seen = 0;
1633 EXPECT_CALL(*producer, Flush(_, _, _))
1634 .WillRepeatedly(Invoke([&producer, &writer, &flushes_seen, checkpoint](
1635 FlushRequestID flush_req_id,
1636 const DataSourceInstanceID*, size_t) {
1637 {
1638 auto tp = writer->NewTracePacket();
1639 char payload[32];
1640 sprintf(payload, "f_%d", flushes_seen);
1641 tp->set_for_testing()->set_str(payload);
1642 }
1643 writer->Flush();
1644 producer->endpoint()->NotifyFlushComplete(flush_req_id);
1645 if (++flushes_seen == kNumFlushes)
1646 checkpoint();
1647 }));
1648 task_runner.RunUntilCheckpoint("all_flushes_done");
1649
1650 consumer->DisableTracing();
1651 producer->WaitForDataSourceStop("data_source");
1652 consumer->WaitForTracingDisabled();
1653 auto trace_packets = consumer->ReadBuffers();
1654 for (int i = 0; i < kNumFlushes; i++) {
1655 EXPECT_THAT(trace_packets,
1656 Contains(Property(&protos::TracePacket::for_testing,
1657 Property(&protos::TestEvent::str,
1658 Eq("f_" + std::to_string(i))))));
1659 }
1660}
1661
Ryan Savitski33868d52019-05-13 10:56:14 +01001662TEST_F(TracingServiceImplTest, PeriodicClearIncrementalState) {
1663 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1664 consumer->Connect(svc.get());
1665 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1666 producer->Connect(svc.get(), "mock_producer");
1667
1668 // Incremental data source that expects to receive the clear.
1669 producer->RegisterDataSource("ds_incremental1", false, false,
1670 /*handles_incremental_state_clear=*/true);
1671
1672 // Incremental data source that expects to receive the clear.
1673 producer->RegisterDataSource("ds_incremental2", false, false,
1674 /*handles_incremental_state_clear=*/true);
1675
Ryan Savitski0b4008a2019-05-13 17:55:53 +01001676 // Data source that does *not* advertise itself as supporting incremental
1677 // state clears.
Ryan Savitski33868d52019-05-13 10:56:14 +01001678 producer->RegisterDataSource("ds_selfcontained", false, false,
1679 /*handles_incremental_state_clear=*/false);
1680
1681 // Incremental data source that is registered, but won't be active within the
1682 // test's tracing session.
1683 producer->RegisterDataSource("ds_inactive", false, false,
1684 /*handles_incremental_state_clear=*/true);
1685
1686 TraceConfig trace_config;
1687 trace_config.add_buffers()->set_size_kb(128);
1688 trace_config.mutable_incremental_state_config()->set_clear_period_ms(1);
1689 trace_config.add_data_sources()->mutable_config()->set_name(
1690 "ds_selfcontained");
1691 trace_config.add_data_sources()->mutable_config()->set_name(
1692 "ds_incremental1");
1693 trace_config.add_data_sources()->mutable_config()->set_name(
1694 "ds_incremental2");
1695
1696 // note: the mocking is very brittle, and has to assume a specific order of
1697 // the data sources' setup/start.
1698 consumer->EnableTracing(trace_config);
1699 producer->WaitForTracingSetup();
1700 producer->WaitForDataSourceSetup("ds_selfcontained");
1701 producer->WaitForDataSourceSetup("ds_incremental1");
1702 producer->WaitForDataSourceSetup("ds_incremental2");
1703 producer->WaitForDataSourceStart("ds_selfcontained");
1704 producer->WaitForDataSourceStart("ds_incremental1");
1705 producer->WaitForDataSourceStart("ds_incremental2");
1706
1707 DataSourceInstanceID ds_incremental1 =
1708 producer->GetDataSourceInstanceId("ds_incremental1");
1709 DataSourceInstanceID ds_incremental2 =
1710 producer->GetDataSourceInstanceId("ds_incremental2");
1711
Ryan Savitskiba8a5f52019-05-14 11:58:21 +01001712 const size_t kNumClears = 3;
Ryan Savitski33868d52019-05-13 10:56:14 +01001713 std::function<void()> checkpoint =
1714 task_runner.CreateCheckpoint("clears_received");
1715 std::vector<std::vector<DataSourceInstanceID>> clears_seen;
1716 EXPECT_CALL(*producer, ClearIncrementalState(_, _))
1717 .WillRepeatedly(Invoke([&clears_seen, &checkpoint](
1718 const DataSourceInstanceID* data_source_ids,
1719 size_t num_data_sources) {
1720 std::vector<DataSourceInstanceID> ds_ids;
1721 for (size_t i = 0; i < num_data_sources; i++) {
1722 ds_ids.push_back(*data_source_ids++);
1723 }
1724 clears_seen.push_back(ds_ids);
1725 if (clears_seen.size() >= kNumClears)
1726 checkpoint();
1727 }));
1728 task_runner.RunUntilCheckpoint("clears_received");
1729
1730 consumer->DisableTracing();
1731
1732 // Assert that the clears were only for the active incremental data sources.
1733 ASSERT_EQ(clears_seen.size(), kNumClears);
1734 for (const std::vector<DataSourceInstanceID>& ds_ids : clears_seen) {
1735 ASSERT_THAT(ds_ids, ElementsAreArray({ds_incremental1, ds_incremental2}));
1736 }
1737}
1738
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001739// Creates a tracing session where some of the data sources set the
1740// |will_notify_on_stop| flag and checks that the OnTracingDisabled notification
1741// to the consumer is delayed until the acks are received.
1742TEST_F(TracingServiceImplTest, OnTracingDisabledWaitsForDataSourceStopAcks) {
1743 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1744 consumer->Connect(svc.get());
1745
1746 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1747 producer->Connect(svc.get(), "mock_producer");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001748 producer->RegisterDataSource("ds_will_ack_1", /*ack_stop=*/true,
1749 /*ack_start=*/true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001750 producer->RegisterDataSource("ds_wont_ack");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001751 producer->RegisterDataSource("ds_will_ack_2", /*ack_stop=*/true,
1752 /*ack_start=*/false);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001753
1754 TraceConfig trace_config;
1755 trace_config.add_buffers()->set_size_kb(128);
1756 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_1");
1757 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1758 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_2");
1759 trace_config.set_duration_ms(1);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001760 trace_config.set_deferred_start(true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001761
1762 consumer->EnableTracing(trace_config);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001763
1764 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1765 DataSourceInstanceState::CONFIGURED);
1766 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1767 DataSourceInstanceState::CONFIGURED);
1768 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1769 DataSourceInstanceState::CONFIGURED);
1770
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001771 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001772
1773 producer->WaitForDataSourceSetup("ds_will_ack_1");
1774 producer->WaitForDataSourceSetup("ds_wont_ack");
1775 producer->WaitForDataSourceSetup("ds_will_ack_2");
1776
Eric Seckler4ff03e52019-03-15 10:10:30 +00001777 DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_will_ack_1");
1778 DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_will_ack_2");
1779
1780 consumer->StartTracing();
1781
1782 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1783 DataSourceInstanceState::STARTING);
1784 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1785 DataSourceInstanceState::STARTED);
1786 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1787 DataSourceInstanceState::STARTED);
1788
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001789 producer->WaitForDataSourceStart("ds_will_ack_1");
1790 producer->WaitForDataSourceStart("ds_wont_ack");
1791 producer->WaitForDataSourceStart("ds_will_ack_2");
1792
Eric Seckler4ff03e52019-03-15 10:10:30 +00001793 producer->endpoint()->NotifyDataSourceStarted(id1);
1794
1795 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1796 DataSourceInstanceState::STARTED);
1797
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001798 std::unique_ptr<TraceWriter> writer =
1799 producer->CreateTraceWriter("ds_wont_ack");
1800 producer->WaitForFlush(writer.get());
1801
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001802 producer->WaitForDataSourceStop("ds_will_ack_1");
1803 producer->WaitForDataSourceStop("ds_wont_ack");
1804 producer->WaitForDataSourceStop("ds_will_ack_2");
1805
Eric Seckler4ff03e52019-03-15 10:10:30 +00001806 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1807 DataSourceInstanceState::STOPPING);
1808 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1809 DataSourceInstanceState::STOPPED);
1810 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1811 DataSourceInstanceState::STOPPING);
1812
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001813 producer->endpoint()->NotifyDataSourceStopped(id1);
1814 producer->endpoint()->NotifyDataSourceStopped(id2);
1815
Eric Seckler4ff03e52019-03-15 10:10:30 +00001816 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1817 DataSourceInstanceState::STOPPED);
1818 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1819 DataSourceInstanceState::STOPPED);
1820
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001821 // Wait for at most half of the service timeout, so that this test fails if
1822 // the service falls back on calling the OnTracingDisabled() because some of
1823 // the expected acks weren't received.
1824 consumer->WaitForTracingDisabled(
1825 TracingServiceImpl::kDataSourceStopTimeoutMs / 2);
1826}
1827
Oystein Eftevaagf250e1c2018-08-23 16:10:52 -07001828// Creates a tracing session where a second data source
1829// is added while the service is waiting for DisableTracing
1830// acks; the service should not enable the new datasource
1831// and should not hit any asserts when the consumer is
1832// subsequently destroyed.
1833TEST_F(TracingServiceImplTest, OnDataSourceAddedWhilePendingDisableAcks) {
1834 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1835 consumer->Connect(svc.get());
1836
1837 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1838 producer->Connect(svc.get(), "mock_producer");
1839 producer->RegisterDataSource("ds_will_ack", /*ack_stop=*/true);
1840
1841 TraceConfig trace_config;
1842 trace_config.add_buffers()->set_size_kb(128);
1843 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack");
1844 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1845
1846 consumer->EnableTracing(trace_config);
1847 producer->WaitForTracingSetup();
1848
1849 consumer->DisableTracing();
1850
1851 producer->RegisterDataSource("ds_wont_ack");
1852
1853 consumer.reset();
1854}
1855
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001856// Similar to OnTracingDisabledWaitsForDataSourceStopAcks, but deliberately
1857// skips the ack and checks that the service invokes the OnTracingDisabled()
1858// after the timeout.
1859TEST_F(TracingServiceImplTest, OnTracingDisabledCalledAnywaysInCaseOfTimeout) {
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001860 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1861 consumer->Connect(svc.get());
1862
1863 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1864 producer->Connect(svc.get(), "mock_producer");
1865 producer->RegisterDataSource("data_source", /*ack_stop=*/true);
1866
1867 TraceConfig trace_config;
1868 trace_config.add_buffers()->set_size_kb(128);
1869 trace_config.add_data_sources()->mutable_config()->set_name("data_source");
1870 trace_config.set_duration_ms(1);
Florian Mayer990e6d72019-06-03 11:34:52 +01001871 trace_config.set_data_source_stop_timeout_ms(1);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001872
1873 consumer->EnableTracing(trace_config);
1874 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001875 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001876 producer->WaitForDataSourceStart("data_source");
1877
1878 std::unique_ptr<TraceWriter> writer =
1879 producer->CreateTraceWriter("data_source");
1880 producer->WaitForFlush(writer.get());
1881
1882 producer->WaitForDataSourceStop("data_source");
1883 consumer->WaitForTracingDisabled();
1884}
1885
Primiano Tucci03de28f2018-08-01 11:29:46 +01001886// Tests the session_id logic. Two data sources in the same tracing session
1887// should see the same session id.
1888TEST_F(TracingServiceImplTest, SessionId) {
1889 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1890 consumer->Connect(svc.get());
1891
1892 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1893 producer1->Connect(svc.get(), "mock_producer1");
1894 producer1->RegisterDataSource("ds_1A");
1895 producer1->RegisterDataSource("ds_1B");
1896
1897 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1898 producer2->Connect(svc.get(), "mock_producer2");
1899 producer2->RegisterDataSource("ds_2A");
1900
1901 testing::InSequence seq;
1902 TracingSessionID last_session_id = 0;
1903 for (int i = 0; i < 3; i++) {
1904 TraceConfig trace_config;
1905 trace_config.add_buffers()->set_size_kb(128);
1906 trace_config.add_data_sources()->mutable_config()->set_name("ds_1A");
1907 trace_config.add_data_sources()->mutable_config()->set_name("ds_1B");
1908 trace_config.add_data_sources()->mutable_config()->set_name("ds_2A");
1909 trace_config.set_duration_ms(1);
1910
1911 consumer->EnableTracing(trace_config);
1912
1913 if (i == 0)
1914 producer1->WaitForTracingSetup();
Primiano Tucci03de28f2018-08-01 11:29:46 +01001915
Primiano Tucci674076d2018-10-01 10:41:09 +01001916 producer1->WaitForDataSourceSetup("ds_1A");
1917 producer1->WaitForDataSourceSetup("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001918 if (i == 0)
1919 producer2->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001920 producer2->WaitForDataSourceSetup("ds_2A");
1921
1922 producer1->WaitForDataSourceStart("ds_1A");
1923 producer1->WaitForDataSourceStart("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001924 producer2->WaitForDataSourceStart("ds_2A");
1925
1926 auto* ds1 = producer1->GetDataSourceInstance("ds_1A");
1927 auto* ds2 = producer1->GetDataSourceInstance("ds_1B");
1928 auto* ds3 = producer2->GetDataSourceInstance("ds_2A");
1929 ASSERT_EQ(ds1->session_id, ds2->session_id);
1930 ASSERT_EQ(ds1->session_id, ds3->session_id);
1931 ASSERT_NE(ds1->session_id, last_session_id);
1932 last_session_id = ds1->session_id;
1933
1934 auto writer1 = producer1->CreateTraceWriter("ds_1A");
1935 producer1->WaitForFlush(writer1.get());
1936
1937 auto writer2 = producer2->CreateTraceWriter("ds_2A");
1938 producer2->WaitForFlush(writer2.get());
1939
1940 producer1->WaitForDataSourceStop("ds_1A");
1941 producer1->WaitForDataSourceStop("ds_1B");
1942 producer2->WaitForDataSourceStop("ds_2A");
1943 consumer->WaitForTracingDisabled();
1944 consumer->FreeBuffers();
1945 }
1946}
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001947
1948// Writes a long trace and then tests that the trace parsed in partitions
1949// derived by the synchronization markers is identical to the whole trace parsed
1950// in one go.
1951TEST_F(TracingServiceImplTest, ResynchronizeTraceStreamUsingSyncMarker) {
1952 // Setup tracing.
1953 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1954 consumer->Connect(svc.get());
1955 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1956 producer->Connect(svc.get(), "mock_producer");
1957 producer->RegisterDataSource("data_source");
1958 TraceConfig trace_config;
1959 trace_config.add_buffers()->set_size_kb(4096);
1960 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1961 ds_config->set_name("data_source");
1962 trace_config.set_write_into_file(true);
1963 trace_config.set_file_write_period_ms(1);
1964 base::TempFile tmp_file = base::TempFile::Create();
1965 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
1966 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001967 producer->WaitForDataSourceSetup("data_source");
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001968 producer->WaitForDataSourceStart("data_source");
1969
1970 // Write some variable length payload, waiting for sync markers every now
1971 // and then.
1972 const int kNumMarkers = 5;
1973 auto writer = producer->CreateTraceWriter("data_source");
1974 for (int i = 1; i <= 100; i++) {
Florian Mayereff98042018-12-10 17:44:44 +00001975 std::string payload(static_cast<size_t>(i), 'A' + (i % 25));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001976 writer->NewTracePacket()->set_for_testing()->set_str(payload.c_str());
1977 if (i % (100 / kNumMarkers) == 0) {
1978 writer->Flush();
1979 WaitForNextSyncMarker();
1980 }
1981 }
1982 writer->Flush();
1983 writer.reset();
1984 consumer->DisableTracing();
1985 producer->WaitForDataSourceStop("data_source");
1986 consumer->WaitForTracingDisabled();
1987
1988 std::string trace_raw;
1989 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
1990
1991 const auto kMarkerSize = sizeof(TracingServiceImpl::kSyncMarker);
1992 const std::string kSyncMarkerStr(
1993 reinterpret_cast<const char*>(TracingServiceImpl::kSyncMarker),
1994 kMarkerSize);
1995
1996 // Read back the trace in partitions derived from the marker.
1997 // The trace should look like this:
1998 // [uid, marker] [event] [event] [uid, marker] [event] [event]
1999 size_t num_markers = 0;
2000 size_t start = 0;
2001 size_t end = 0;
2002 protos::Trace merged_trace;
2003 for (size_t pos = 0; pos != std::string::npos; start = end) {
2004 pos = trace_raw.find(kSyncMarkerStr, pos + 1);
2005 num_markers++;
2006 end = (pos == std::string::npos) ? trace_raw.size() : pos + kMarkerSize;
2007 int size = static_cast<int>(end - start);
2008 ASSERT_GT(size, 0);
2009 protos::Trace trace_partition;
2010 ASSERT_TRUE(trace_partition.ParseFromArray(trace_raw.data() + start, size));
2011 merged_trace.MergeFrom(trace_partition);
2012 }
Lalit Maganti9bdc7ce2018-09-17 15:25:11 +01002013 EXPECT_GE(num_markers, static_cast<size_t>(kNumMarkers));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01002014
2015 protos::Trace whole_trace;
2016 ASSERT_TRUE(whole_trace.ParseFromString(trace_raw));
2017
2018 ASSERT_EQ(whole_trace.packet_size(), merged_trace.packet_size());
2019 EXPECT_EQ(whole_trace.SerializeAsString(), merged_trace.SerializeAsString());
2020}
2021
Primiano Tucci674076d2018-10-01 10:41:09 +01002022// Creates a tracing session with |deferred_start| and checks that data sources
2023// are started only after calling StartTracing().
2024TEST_F(TracingServiceImplTest, DeferredStart) {
2025 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2026 consumer->Connect(svc.get());
2027
2028 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2029 producer->Connect(svc.get(), "mock_producer");
2030
2031 // Create two data sources but enable only one of them.
2032 producer->RegisterDataSource("ds_1");
2033 producer->RegisterDataSource("ds_2");
2034
2035 TraceConfig trace_config;
2036 trace_config.add_buffers()->set_size_kb(128);
2037 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
2038 trace_config.set_deferred_start(true);
2039 trace_config.set_duration_ms(1);
2040
2041 consumer->EnableTracing(trace_config);
2042 producer->WaitForTracingSetup();
2043
2044 producer->WaitForDataSourceSetup("ds_1");
2045
2046 // Make sure we don't get unexpected DataSourceStart() notifications yet.
2047 task_runner.RunUntilIdle();
2048
2049 consumer->StartTracing();
2050
2051 producer->WaitForDataSourceStart("ds_1");
2052
Stephen Nusko1393ffd2019-03-22 13:54:58 +00002053 auto writer = producer->CreateTraceWriter("ds_1");
2054 producer->WaitForFlush(writer.get());
Primiano Tucci674076d2018-10-01 10:41:09 +01002055
2056 producer->WaitForDataSourceStop("ds_1");
2057 consumer->WaitForTracingDisabled();
2058}
2059
Eric Secklerd0ac7ca2019-02-06 09:13:45 +00002060TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
2061 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2062 consumer->Connect(svc.get());
2063
2064 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2065 producer1->Connect(svc.get(), "mock_producer1", 123u /* uid */);
2066 producer1->RegisterDataSource("data_source");
2067
2068 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2069 producer2->Connect(svc.get(), "mock_producer2", 456u /* uid */);
2070 producer2->RegisterDataSource("data_source");
2071
2072 TraceConfig trace_config;
2073 trace_config.add_buffers()->set_size_kb(128);
2074 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2075 ds_config->set_name("data_source");
2076
2077 consumer->EnableTracing(trace_config);
2078 producer1->WaitForTracingSetup();
2079 producer1->WaitForDataSourceSetup("data_source");
2080 producer2->WaitForTracingSetup();
2081 producer2->WaitForDataSourceSetup("data_source");
2082 producer1->WaitForDataSourceStart("data_source");
2083 producer2->WaitForDataSourceStart("data_source");
2084
2085 std::unique_ptr<TraceWriter> writer1a =
2086 producer1->CreateTraceWriter("data_source");
2087 std::unique_ptr<TraceWriter> writer1b =
2088 producer1->CreateTraceWriter("data_source");
2089 std::unique_ptr<TraceWriter> writer2a =
2090 producer2->CreateTraceWriter("data_source");
2091 {
2092 auto tp = writer1a->NewTracePacket();
2093 tp->set_for_testing()->set_str("payload1a1");
2094 tp = writer1b->NewTracePacket();
2095 tp->set_for_testing()->set_str("payload1b1");
2096 tp = writer1a->NewTracePacket();
2097 tp->set_for_testing()->set_str("payload1a2");
2098 tp = writer2a->NewTracePacket();
2099 tp->set_for_testing()->set_str("payload2a1");
2100 tp = writer1b->NewTracePacket();
2101 tp->set_for_testing()->set_str("payload1b2");
2102 }
2103
2104 auto flush_request = consumer->Flush();
2105 producer1->WaitForFlush({writer1a.get(), writer1b.get()});
2106 producer2->WaitForFlush(writer2a.get());
2107 ASSERT_TRUE(flush_request.WaitForReply());
2108
2109 consumer->DisableTracing();
2110 producer1->WaitForDataSourceStop("data_source");
2111 producer2->WaitForDataSourceStop("data_source");
2112 consumer->WaitForTracingDisabled();
2113 auto packets = consumer->ReadBuffers();
2114 EXPECT_THAT(
2115 packets,
2116 Contains(AllOf(
2117 Property(&protos::TracePacket::for_testing,
2118 Property(&protos::TestEvent::str, Eq("payload1a1"))),
2119 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2120 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
2121 EXPECT_THAT(
2122 packets,
2123 Contains(AllOf(
2124 Property(&protos::TracePacket::for_testing,
2125 Property(&protos::TestEvent::str, Eq("payload1a2"))),
2126 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2127 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
2128 EXPECT_THAT(
2129 packets,
2130 Contains(AllOf(
2131 Property(&protos::TracePacket::for_testing,
2132 Property(&protos::TestEvent::str, Eq("payload1b1"))),
2133 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2134 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
2135 EXPECT_THAT(
2136 packets,
2137 Contains(AllOf(
2138 Property(&protos::TracePacket::for_testing,
2139 Property(&protos::TestEvent::str, Eq("payload1b2"))),
2140 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2141 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
2142 EXPECT_THAT(
2143 packets,
2144 Contains(AllOf(
2145 Property(&protos::TracePacket::for_testing,
2146 Property(&protos::TestEvent::str, Eq("payload2a1"))),
2147 Property(&protos::TracePacket::trusted_uid, Eq(456)),
2148 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(4u)))));
2149}
2150
Eric Seckler6dc23592018-11-30 10:59:06 +00002151TEST_F(TracingServiceImplTest, AllowedBuffers) {
2152 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2153 consumer->Connect(svc.get());
2154
2155 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2156 producer1->Connect(svc.get(), "mock_producer1");
2157 ProducerID producer1_id = *last_producer_id();
2158 producer1->RegisterDataSource("data_source1");
2159 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2160 producer2->Connect(svc.get(), "mock_producer2");
2161 ProducerID producer2_id = *last_producer_id();
2162 producer2->RegisterDataSource("data_source2.1");
2163 producer2->RegisterDataSource("data_source2.2");
2164 producer2->RegisterDataSource("data_source2.3");
2165
2166 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
2167 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
2168
2169 TraceConfig trace_config;
2170 trace_config.add_buffers()->set_size_kb(128);
2171 trace_config.add_buffers()->set_size_kb(128);
2172 trace_config.add_buffers()->set_size_kb(128);
2173 auto* ds_config1 = trace_config.add_data_sources()->mutable_config();
2174 ds_config1->set_name("data_source1");
2175 ds_config1->set_target_buffer(0);
2176 auto* ds_config21 = trace_config.add_data_sources()->mutable_config();
2177 ds_config21->set_name("data_source2.1");
2178 ds_config21->set_target_buffer(1);
2179 auto* ds_config22 = trace_config.add_data_sources()->mutable_config();
2180 ds_config22->set_name("data_source2.2");
2181 ds_config22->set_target_buffer(2);
2182 auto* ds_config23 = trace_config.add_data_sources()->mutable_config();
2183 ds_config23->set_name("data_source2.3");
2184 ds_config23->set_target_buffer(2); // same buffer as data_source2.2.
2185 consumer->EnableTracing(trace_config);
2186
Primiano Tucci2abd1152018-12-03 17:00:02 +01002187 ASSERT_EQ(3u, tracing_session()->num_buffers());
Eric Seckler6dc23592018-11-30 10:59:06 +00002188 std::set<BufferID> expected_buffers_producer1 = {
2189 tracing_session()->buffers_index[0]};
2190 std::set<BufferID> expected_buffers_producer2 = {
2191 tracing_session()->buffers_index[1], tracing_session()->buffers_index[2]};
2192 EXPECT_EQ(expected_buffers_producer1, GetAllowedTargetBuffers(producer1_id));
2193 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
2194
2195 producer1->WaitForTracingSetup();
2196 producer1->WaitForDataSourceSetup("data_source1");
2197
2198 producer2->WaitForTracingSetup();
2199 producer2->WaitForDataSourceSetup("data_source2.1");
2200 producer2->WaitForDataSourceSetup("data_source2.2");
2201 producer2->WaitForDataSourceSetup("data_source2.3");
2202
2203 producer1->WaitForDataSourceStart("data_source1");
2204 producer2->WaitForDataSourceStart("data_source2.1");
2205 producer2->WaitForDataSourceStart("data_source2.2");
2206 producer2->WaitForDataSourceStart("data_source2.3");
2207
2208 producer2->UnregisterDataSource("data_source2.3");
2209 producer2->WaitForDataSourceStop("data_source2.3");
2210
2211 // Should still be allowed to write to buffers 1 (data_source2.1) and 2
2212 // (data_source2.2).
2213 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
2214
2215 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2216 // trace config didn't have the |deferred_start| flag set.
2217 consumer->StartTracing();
2218
2219 consumer->DisableTracing();
2220 producer1->WaitForDataSourceStop("data_source1");
2221 producer2->WaitForDataSourceStop("data_source2.1");
2222 producer2->WaitForDataSourceStop("data_source2.2");
2223 consumer->WaitForTracingDisabled();
2224
2225 consumer->FreeBuffers();
2226 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
2227 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
2228}
2229
Eric Seckler6aa9ece2018-12-06 16:40:12 +00002230#if !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00002231TEST_F(TracingServiceImplTest, CommitToForbiddenBufferIsDiscarded) {
2232 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2233 consumer->Connect(svc.get());
2234
2235 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2236 producer->Connect(svc.get(), "mock_producer");
2237 ProducerID producer_id = *last_producer_id();
2238 producer->RegisterDataSource("data_source");
2239
2240 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
2241
2242 TraceConfig trace_config;
2243 trace_config.add_buffers()->set_size_kb(128);
2244 trace_config.add_buffers()->set_size_kb(128);
2245 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2246 ds_config->set_name("data_source");
2247 ds_config->set_target_buffer(0);
2248 consumer->EnableTracing(trace_config);
2249
2250 ASSERT_EQ(2u, tracing_session()->num_buffers());
2251 std::set<BufferID> expected_buffers = {tracing_session()->buffers_index[0]};
2252 EXPECT_EQ(expected_buffers, GetAllowedTargetBuffers(producer_id));
2253
2254 producer->WaitForTracingSetup();
2255 producer->WaitForDataSourceSetup("data_source");
2256 producer->WaitForDataSourceStart("data_source");
2257
2258 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2259 // trace config didn't have the |deferred_start| flag set.
2260 consumer->StartTracing();
2261
2262 // Try to write to the correct buffer.
2263 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2264 tracing_session()->buffers_index[0]);
2265 {
2266 auto tp = writer->NewTracePacket();
2267 tp->set_for_testing()->set_str("good_payload");
2268 }
2269
2270 auto flush_request = consumer->Flush();
2271 producer->WaitForFlush(writer.get());
2272 ASSERT_TRUE(flush_request.WaitForReply());
2273
2274 // Try to write to the wrong buffer.
2275 writer = producer->endpoint()->CreateTraceWriter(
2276 tracing_session()->buffers_index[1]);
2277 {
2278 auto tp = writer->NewTracePacket();
2279 tp->set_for_testing()->set_str("bad_payload");
2280 }
2281
2282 flush_request = consumer->Flush();
2283 producer->WaitForFlush(writer.get());
2284 ASSERT_TRUE(flush_request.WaitForReply());
2285
2286 consumer->DisableTracing();
2287 producer->WaitForDataSourceStop("data_source");
2288 consumer->WaitForTracingDisabled();
2289
2290 auto packets = consumer->ReadBuffers();
2291 EXPECT_THAT(packets, Contains(Property(&protos::TracePacket::for_testing,
2292 Property(&protos::TestEvent::str,
2293 Eq("good_payload")))));
2294 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2295 Property(&protos::TestEvent::str,
2296 Eq("bad_payload"))))));
2297
2298 consumer->FreeBuffers();
2299 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
2300}
Eric Seckler6aa9ece2018-12-06 16:40:12 +00002301#endif // !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00002302
Eric Secklerf3f524b2018-12-13 09:09:34 +00002303TEST_F(TracingServiceImplTest, RegisterAndUnregisterTraceWriter) {
2304 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2305 consumer->Connect(svc.get());
2306
2307 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2308 producer->Connect(svc.get(), "mock_producer");
2309 ProducerID producer_id = *last_producer_id();
2310 producer->RegisterDataSource("data_source");
2311
2312 EXPECT_TRUE(GetWriters(producer_id).empty());
2313
2314 TraceConfig trace_config;
2315 trace_config.add_buffers()->set_size_kb(128);
2316 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2317 ds_config->set_name("data_source");
2318 ds_config->set_target_buffer(0);
2319 consumer->EnableTracing(trace_config);
2320
2321 producer->WaitForTracingSetup();
2322 producer->WaitForDataSourceSetup("data_source");
2323 producer->WaitForDataSourceStart("data_source");
2324
2325 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2326 // trace config didn't have the |deferred_start| flag set.
2327 consumer->StartTracing();
2328
2329 // Creating the trace writer should register it with the service.
2330 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2331 tracing_session()->buffers_index[0]);
2332
2333 WaitForTraceWritersChanged(producer_id);
2334
2335 std::map<WriterID, BufferID> expected_writers;
2336 expected_writers[writer->writer_id()] = tracing_session()->buffers_index[0];
2337 EXPECT_EQ(expected_writers, GetWriters(producer_id));
2338
2339 // Verify writing works.
2340 {
2341 auto tp = writer->NewTracePacket();
2342 tp->set_for_testing()->set_str("payload");
2343 }
2344
2345 auto flush_request = consumer->Flush();
2346 producer->WaitForFlush(writer.get());
2347 ASSERT_TRUE(flush_request.WaitForReply());
2348
2349 // Destroying the writer should unregister it.
2350 writer.reset();
2351 WaitForTraceWritersChanged(producer_id);
2352 EXPECT_TRUE(GetWriters(producer_id).empty());
2353
2354 consumer->DisableTracing();
2355 producer->WaitForDataSourceStop("data_source");
2356 consumer->WaitForTracingDisabled();
2357
2358 auto packets = consumer->ReadBuffers();
2359 EXPECT_THAT(packets, Contains(Property(
2360 &protos::TracePacket::for_testing,
2361 Property(&protos::TestEvent::str, Eq("payload")))));
2362}
2363
Eric Secklera01e28a2019-01-08 11:21:04 +00002364TEST_F(TracingServiceImplTest, ScrapeBuffersOnFlush) {
2365 svc->SetSMBScrapingEnabled(true);
2366
2367 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2368 consumer->Connect(svc.get());
2369
2370 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2371 producer->Connect(svc.get(), "mock_producer");
2372 ProducerID producer_id = *last_producer_id();
2373 producer->RegisterDataSource("data_source");
2374
2375 TraceConfig trace_config;
2376 trace_config.add_buffers()->set_size_kb(128);
2377 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2378 ds_config->set_name("data_source");
2379 ds_config->set_target_buffer(0);
2380 consumer->EnableTracing(trace_config);
2381
2382 producer->WaitForTracingSetup();
2383 producer->WaitForDataSourceSetup("data_source");
2384 producer->WaitForDataSourceStart("data_source");
2385
2386 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2387 // trace config didn't have the |deferred_start| flag set.
2388 consumer->StartTracing();
2389
2390 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2391 tracing_session()->buffers_index[0]);
2392 WaitForTraceWritersChanged(producer_id);
2393
2394 // Write a few trace packets.
2395 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2396 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2397 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2398
2399 // Flush but don't actually flush the chunk from TraceWriter.
2400 auto flush_request = consumer->Flush();
2401 producer->WaitForFlush(nullptr, /*reply=*/true);
2402 ASSERT_TRUE(flush_request.WaitForReply());
2403
2404 // Chunk with the packets should have been scraped. The service can't know
2405 // whether the last packet was completed, so shouldn't read it.
2406 auto packets = consumer->ReadBuffers();
2407 EXPECT_THAT(packets, Contains(Property(
2408 &protos::TracePacket::for_testing,
2409 Property(&protos::TestEvent::str, Eq("payload1")))));
2410 EXPECT_THAT(packets, Contains(Property(
2411 &protos::TracePacket::for_testing,
2412 Property(&protos::TestEvent::str, Eq("payload2")))));
2413 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2414 Property(&protos::TestEvent::str,
2415 Eq("payload3"))))));
2416
2417 // Write some more packets.
2418 writer->NewTracePacket()->set_for_testing()->set_str("payload4");
2419 writer->NewTracePacket()->set_for_testing()->set_str("payload5");
2420
2421 // Don't reply to flush, causing a timeout. This should scrape again.
2422 flush_request = consumer->Flush(/*timeout=*/100);
2423 producer->WaitForFlush(nullptr, /*reply=*/false);
2424 ASSERT_FALSE(flush_request.WaitForReply());
2425
2426 // Chunk with the packets should have been scraped again, overriding the
2427 // original one. Again, the last packet should be ignored and the first two
2428 // should not be read twice.
2429 packets = consumer->ReadBuffers();
2430 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2431 Property(&protos::TestEvent::str,
2432 Eq("payload1"))))));
2433 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2434 Property(&protos::TestEvent::str,
2435 Eq("payload2"))))));
2436 EXPECT_THAT(packets, Contains(Property(
2437 &protos::TracePacket::for_testing,
2438 Property(&protos::TestEvent::str, Eq("payload3")))));
2439 EXPECT_THAT(packets, Contains(Property(
2440 &protos::TracePacket::for_testing,
2441 Property(&protos::TestEvent::str, Eq("payload4")))));
2442 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2443 Property(&protos::TestEvent::str,
2444 Eq("payload5"))))));
2445
2446 consumer->DisableTracing();
2447 producer->WaitForDataSourceStop("data_source");
2448 consumer->WaitForTracingDisabled();
2449}
2450
Sami Kyostilaf5ad4642019-05-16 10:46:15 +01002451TEST_F(TracingServiceImplTest, ScrapeBuffersFromAnotherThread) {
2452 // This test verifies that there are no reported TSAN races while scraping
2453 // buffers from a producer which is actively writing more trace data
2454 // concurrently.
2455 svc->SetSMBScrapingEnabled(true);
2456
2457 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2458 consumer->Connect(svc.get());
2459
2460 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2461 producer->Connect(svc.get(), "mock_producer");
2462 ProducerID producer_id = *last_producer_id();
2463 producer->RegisterDataSource("data_source");
2464
2465 TraceConfig trace_config;
2466 trace_config.add_buffers()->set_size_kb(128);
2467 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2468 ds_config->set_name("data_source");
2469 ds_config->set_target_buffer(0);
2470 consumer->EnableTracing(trace_config);
2471
2472 producer->WaitForTracingSetup();
2473 producer->WaitForDataSourceSetup("data_source");
2474 producer->WaitForDataSourceStart("data_source");
2475 consumer->StartTracing();
2476
2477 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2478 tracing_session()->buffers_index[0]);
2479 WaitForTraceWritersChanged(producer_id);
2480
2481 constexpr int kPacketCount = 10;
2482 std::atomic<int> packets_written{};
2483 std::thread writer_thread([&] {
2484 for (int i = 0; i < kPacketCount; i++) {
2485 writer->NewTracePacket()->set_for_testing()->set_str("payload");
2486 packets_written.store(i, std::memory_order_relaxed);
2487 }
2488 });
2489
2490 // Wait until the thread has had some time to write some packets.
2491 while (packets_written.load(std::memory_order_relaxed) < kPacketCount / 2)
2492 base::SleepMicroseconds(5000);
2493
2494 // Disabling tracing will trigger scraping.
2495 consumer->DisableTracing();
2496 writer_thread.join();
2497
2498 // Because we don't synchronize with the producer thread, we can't make any
2499 // guarantees about the number of packets we will successfully read. We just
2500 // verify that no TSAN races are reported.
2501 consumer->ReadBuffers();
2502
2503 producer->WaitForDataSourceStop("data_source");
2504 consumer->WaitForTracingDisabled();
2505}
2506
Eric Secklera01e28a2019-01-08 11:21:04 +00002507// Test scraping on producer disconnect.
2508TEST_F(TracingServiceImplTest, ScrapeBuffersOnProducerDisconnect) {
2509 svc->SetSMBScrapingEnabled(true);
2510
2511 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2512 consumer->Connect(svc.get());
2513
2514 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2515 producer->Connect(svc.get(), "mock_producer");
2516 ProducerID producer_id = *last_producer_id();
2517 producer->RegisterDataSource("data_source");
2518
2519 TraceConfig trace_config;
2520 trace_config.add_buffers()->set_size_kb(128);
2521 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2522 ds_config->set_name("data_source");
2523 ds_config->set_target_buffer(0);
2524 consumer->EnableTracing(trace_config);
2525
2526 producer->WaitForTracingSetup();
2527 producer->WaitForDataSourceSetup("data_source");
2528 producer->WaitForDataSourceStart("data_source");
2529
2530 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2531 // trace config didn't have the |deferred_start| flag set.
2532 consumer->StartTracing();
2533
2534 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2535 tracing_session()->buffers_index[0]);
2536 WaitForTraceWritersChanged(producer_id);
2537
2538 // Write a few trace packets.
2539 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2540 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2541 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2542
2543 // Disconnect the producer without committing the chunk. This should cause a
2544 // scrape of the SMB. Avoid destroying the ShmemArbiter until writer is
2545 // destroyed.
2546 auto shmem_arbiter = TakeShmemArbiterForProducer(producer_id);
2547 producer.reset();
2548
2549 // Chunk with the packets should have been scraped. The service can't know
2550 // whether the last packet was completed, so shouldn't read it.
2551 auto packets = consumer->ReadBuffers();
2552 EXPECT_THAT(packets, Contains(Property(
2553 &protos::TracePacket::for_testing,
2554 Property(&protos::TestEvent::str, Eq("payload1")))));
2555 EXPECT_THAT(packets, Contains(Property(
2556 &protos::TracePacket::for_testing,
2557 Property(&protos::TestEvent::str, Eq("payload2")))));
2558 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2559 Property(&protos::TestEvent::str,
2560 Eq("payload3"))))));
2561
2562 // Cleanup writer without causing a crash because the producer already went
2563 // away.
2564 static_cast<TraceWriterImpl*>(writer.get())->ResetChunkForTesting();
2565 writer.reset();
2566 shmem_arbiter.reset();
2567
2568 consumer->DisableTracing();
2569 consumer->WaitForTracingDisabled();
2570}
2571
2572TEST_F(TracingServiceImplTest, ScrapeBuffersOnDisable) {
2573 svc->SetSMBScrapingEnabled(true);
2574
2575 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2576 consumer->Connect(svc.get());
2577
2578 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2579 producer->Connect(svc.get(), "mock_producer");
2580 ProducerID producer_id = *last_producer_id();
2581 producer->RegisterDataSource("data_source");
2582
2583 TraceConfig trace_config;
2584 trace_config.add_buffers()->set_size_kb(128);
2585 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2586 ds_config->set_name("data_source");
2587 ds_config->set_target_buffer(0);
2588 consumer->EnableTracing(trace_config);
2589
2590 producer->WaitForTracingSetup();
2591 producer->WaitForDataSourceSetup("data_source");
2592 producer->WaitForDataSourceStart("data_source");
2593
2594 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2595 // trace config didn't have the |deferred_start| flag set.
2596 consumer->StartTracing();
2597
2598 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2599 tracing_session()->buffers_index[0]);
2600 WaitForTraceWritersChanged(producer_id);
2601
2602 // Write a few trace packets.
2603 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2604 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2605 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2606
2607 consumer->DisableTracing();
2608 producer->WaitForDataSourceStop("data_source");
2609 consumer->WaitForTracingDisabled();
2610
2611 // Chunk with the packets should have been scraped. The service can't know
2612 // whether the last packet was completed, so shouldn't read it.
2613 auto packets = consumer->ReadBuffers();
2614 EXPECT_THAT(packets, Contains(Property(
2615 &protos::TracePacket::for_testing,
2616 Property(&protos::TestEvent::str, Eq("payload1")))));
2617 EXPECT_THAT(packets, Contains(Property(
2618 &protos::TracePacket::for_testing,
2619 Property(&protos::TestEvent::str, Eq("payload2")))));
2620 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2621 Property(&protos::TestEvent::str,
2622 Eq("payload3"))))));
2623}
2624
Primiano Tucciff7beab2019-01-09 21:49:20 +00002625TEST_F(TracingServiceImplTest, AbortIfTraceDurationIsTooLong) {
2626 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2627 consumer->Connect(svc.get());
2628
2629 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2630 producer->Connect(svc.get(), "mock_producer");
2631 producer->RegisterDataSource("datasource");
2632
2633 TraceConfig trace_config;
2634 trace_config.add_buffers()->set_size_kb(128);
2635 trace_config.add_data_sources()->mutable_config()->set_name("datasource");
2636 trace_config.set_duration_ms(0x7fffffff);
2637
2638 EXPECT_CALL(*producer, SetupDataSource(_, _)).Times(0);
2639 consumer->EnableTracing(trace_config);
2640
2641 // The trace is aborted immediately, 5s here is just some slack for the thread
2642 // ping-pongs for slow devices.
2643 consumer->WaitForTracingDisabled(5000);
2644}
2645
Eric Secklereaf29ed2019-01-23 09:53:55 +00002646TEST_F(TracingServiceImplTest, GetTraceStats) {
2647 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2648 consumer->Connect(svc.get());
2649
2650 consumer->GetTraceStats();
2651 consumer->WaitForTraceStats(false);
2652
2653 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2654 producer->Connect(svc.get(), "mock_producer");
2655 producer->RegisterDataSource("data_source");
2656
2657 TraceConfig trace_config;
2658 trace_config.add_buffers()->set_size_kb(128);
2659 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2660 ds_config->set_name("data_source");
2661
2662 consumer->EnableTracing(trace_config);
2663 producer->WaitForTracingSetup();
2664 producer->WaitForDataSourceSetup("data_source");
2665 producer->WaitForDataSourceStart("data_source");
2666
2667 consumer->GetTraceStats();
2668 consumer->WaitForTraceStats(true);
2669
2670 consumer->DisableTracing();
2671 producer->WaitForDataSourceStop("data_source");
2672 consumer->WaitForTracingDisabled();
2673}
2674
Eric Seckler7b0c9452019-03-18 13:14:36 +00002675TEST_F(TracingServiceImplTest, ObserveEventsDataSourceInstances) {
2676 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2677 consumer->Connect(svc.get());
2678
2679 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2680 producer->Connect(svc.get(), "mock_producer");
2681 producer->RegisterDataSource("data_source");
2682
2683 TraceConfig trace_config;
2684 trace_config.add_buffers()->set_size_kb(128);
2685 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2686 ds_config->set_name("data_source");
2687
2688 // Start tracing before the consumer is interested in events. The consumer's
2689 // OnObservableEvents() should not be called yet.
2690 consumer->EnableTracing(trace_config);
2691 producer->WaitForTracingSetup();
2692 producer->WaitForDataSourceSetup("data_source");
2693 producer->WaitForDataSourceStart("data_source");
2694
2695 // Calling ObserveEvents should cause an event for the initial instance state.
2696 consumer->ObserveEvents(TracingService::ConsumerEndpoint::
2697 ObservableEventType::kDataSourceInstances);
2698 {
2699 auto events = consumer->WaitForObservableEvents();
2700
2701 ObservableEvents::DataSourceInstanceStateChange change;
2702 change.set_producer_name("mock_producer");
2703 change.set_data_source_name("data_source");
2704 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2705 DATA_SOURCE_INSTANCE_STATE_STARTED);
2706 EXPECT_EQ(events.instance_state_changes_size(), 1);
2707 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2708 }
2709
2710 // Disabling should cause an instance state change to STOPPED.
2711 consumer->DisableTracing();
2712
2713 {
2714 auto events = consumer->WaitForObservableEvents();
2715
2716 ObservableEvents::DataSourceInstanceStateChange change;
2717 change.set_producer_name("mock_producer");
2718 change.set_data_source_name("data_source");
2719 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2720 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2721 EXPECT_EQ(events.instance_state_changes_size(), 1);
2722 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2723 }
2724
2725 producer->WaitForDataSourceStop("data_source");
2726 consumer->WaitForTracingDisabled();
2727 consumer->FreeBuffers();
2728
2729 // Enable again, this should cause a state change for a new instance to
2730 // its initial state STOPPED.
2731 trace_config.set_deferred_start(true);
2732 consumer->EnableTracing(trace_config);
2733
2734 {
2735 auto events = consumer->WaitForObservableEvents();
2736
2737 ObservableEvents::DataSourceInstanceStateChange change;
2738 change.set_producer_name("mock_producer");
2739 change.set_data_source_name("data_source");
2740 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2741 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2742 EXPECT_EQ(events.instance_state_changes_size(), 1);
2743 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2744 }
2745
2746 producer->WaitForDataSourceSetup("data_source");
2747
2748 // Should move the instance into STARTED state and thus cause an event.
2749 consumer->StartTracing();
2750
2751 {
2752 auto events = consumer->WaitForObservableEvents();
2753
2754 ObservableEvents::DataSourceInstanceStateChange change;
2755 change.set_producer_name("mock_producer");
2756 change.set_data_source_name("data_source");
2757 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2758 DATA_SOURCE_INSTANCE_STATE_STARTED);
2759 EXPECT_EQ(events.instance_state_changes_size(), 1);
2760 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2761 }
2762
2763 producer->WaitForDataSourceStart("data_source");
2764
2765 // Stop observing events.
2766 consumer->ObserveEvents(
2767 TracingService::ConsumerEndpoint::ObservableEventType::kNone);
2768
2769 // Disabling should now no longer cause events to be sent to the consumer.
2770 consumer->DisableTracing();
2771 producer->WaitForDataSourceStop("data_source");
2772 consumer->WaitForTracingDisabled();
2773}
2774
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002775TEST_F(TracingServiceImplTest, QueryServiceState) {
2776 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2777 consumer->Connect(svc.get());
2778
2779 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2780 producer1->Connect(svc.get(), "producer1");
2781
2782 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2783 producer2->Connect(svc.get(), "producer2");
2784
2785 producer1->RegisterDataSource("common_ds");
2786 producer2->RegisterDataSource("common_ds");
2787
2788 producer1->RegisterDataSource("p1_ds");
2789 producer2->RegisterDataSource("p2_ds");
2790
2791 TracingServiceState svc_state = consumer->QueryServiceState();
2792
Eric Seckler4ffe6c22019-06-05 09:07:16 +01002793 EXPECT_EQ(svc_state.producers_size(), 2);
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002794 EXPECT_EQ(svc_state.producers().at(0).id(), 1);
2795 EXPECT_EQ(svc_state.producers().at(0).name(), "producer1");
2796 EXPECT_EQ(svc_state.producers().at(1).id(), 2);
2797 EXPECT_EQ(svc_state.producers().at(1).name(), "producer2");
2798
Eric Seckler4ffe6c22019-06-05 09:07:16 +01002799 EXPECT_EQ(svc_state.data_sources_size(), 4);
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002800
2801 EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 1);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002802 EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().name(), "common_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002803
2804 EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002805 EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().name(), "common_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002806
2807 EXPECT_EQ(svc_state.data_sources().at(2).producer_id(), 1);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002808 EXPECT_EQ(svc_state.data_sources().at(2).ds_descriptor().name(), "p1_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002809
2810 EXPECT_EQ(svc_state.data_sources().at(3).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002811 EXPECT_EQ(svc_state.data_sources().at(3).ds_descriptor().name(), "p2_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002812
2813 // Test that descriptors are cleared when a producer disconnects.
2814 producer1.reset();
2815 svc_state = consumer->QueryServiceState();
2816
Eric Seckler4ffe6c22019-06-05 09:07:16 +01002817 EXPECT_EQ(svc_state.producers_size(), 1);
2818 EXPECT_EQ(svc_state.data_sources_size(), 2);
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002819
2820 EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002821 EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().name(), "common_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002822 EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002823 EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().name(), "p2_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002824}
2825
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00002826} // namespace perfetto