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