1 /*
2 * Copyright (C) 2022 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 <string>
18
19 #include "perfetto/base/build_config.h"
20 #include "perfetto/base/logging.h"
21 #include "perfetto/ext/base/file_utils.h"
22 #include "perfetto/ext/base/pipe.h"
23 #include "perfetto/ext/base/scoped_file.h"
24 #include "perfetto/ext/base/string_utils.h"
25 #include "perfetto/ext/base/temp_file.h"
26 #include "perfetto/ext/base/unix_socket.h"
27 #include "perfetto/ext/base/utils.h"
28 #include "perfetto/ext/tracing/core/commit_data_request.h"
29 #include "perfetto/ext/tracing/core/null_consumer_endpoint_for_testing.h"
30 #include "perfetto/ext/tracing/core/trace_packet.h"
31 #include "perfetto/ext/tracing/core/tracing_service.h"
32 #include "perfetto/protozero/scattered_heap_buffer.h"
33 #include "perfetto/tracing/core/tracing_service_state.h"
34 #include "src/base/test/test_task_runner.h"
35 #include "src/base/test/utils.h"
36 #include "src/protozero/filtering/filter_bytecode_generator.h"
37 #include "test/gtest_and_gmock.h"
38 #include "test/test_helper.h"
39
40 #include "protos/perfetto/config/test_config.gen.h"
41 #include "protos/perfetto/config/trace_config.gen.h"
42 #include "protos/perfetto/trace/perfetto/tracing_service_event.gen.h"
43 #include "protos/perfetto/trace/test_event.gen.h"
44 #include "protos/perfetto/trace/trace.gen.h"
45 #include "protos/perfetto/trace/trace_packet.gen.h"
46 #include "protos/perfetto/trace/trace_packet.pbzero.h"
47
48 namespace perfetto {
49
50 namespace {
51
52 using ::testing::ContainsRegex;
53 using ::testing::Each;
54 using ::testing::ElementsAreArray;
55 using ::testing::HasSubstr;
56 using ::testing::Property;
57 using ::testing::SizeIs;
58
59 } // namespace
60
TEST(PerfettoTracedIntegrationTest,NullConsumerEndpointBuilds)61 TEST(PerfettoTracedIntegrationTest, NullConsumerEndpointBuilds) {
62 NullConsumerEndpointForTesting npe;
63 npe.StartTracing();
64 }
65
TEST(PerfettoTracedIntegrationTest,TestFakeProducer)66 TEST(PerfettoTracedIntegrationTest, TestFakeProducer) {
67 base::TestTaskRunner task_runner;
68
69 TestHelper helper(&task_runner);
70 helper.StartServiceIfRequired();
71 helper.ConnectFakeProducer();
72 helper.ConnectConsumer();
73 helper.WaitForConsumerConnect();
74
75 TraceConfig trace_config;
76 trace_config.add_buffers()->set_size_kb(1024);
77 trace_config.set_duration_ms(200);
78
79 auto* ds_config = trace_config.add_data_sources()->mutable_config();
80 ds_config->set_name("android.perfetto.FakeProducer");
81 ds_config->set_target_buffer(0);
82
83 static constexpr size_t kNumPackets = 12;
84 static constexpr uint32_t kRandomSeed = 42;
85 static constexpr uint32_t kMsgSize = 1024;
86 ds_config->mutable_for_testing()->set_seed(kRandomSeed);
87 ds_config->mutable_for_testing()->set_message_count(kNumPackets);
88 ds_config->mutable_for_testing()->set_message_size(kMsgSize);
89 ds_config->mutable_for_testing()->set_send_batch_on_register(true);
90
91 helper.StartTracing(trace_config);
92 helper.WaitForTracingDisabled();
93
94 helper.ReadData();
95 helper.WaitForReadData();
96
97 const auto& packets = helper.trace();
98 ASSERT_EQ(packets.size(), kNumPackets);
99
100 std::minstd_rand0 rnd_engine(kRandomSeed);
101 for (const auto& packet : packets) {
102 ASSERT_TRUE(packet.has_for_testing());
103 ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
104 }
105 }
106
TEST(PerfettoTracedIntegrationTest,VeryLargePackets)107 TEST(PerfettoTracedIntegrationTest, VeryLargePackets) {
108 base::TestTaskRunner task_runner;
109
110 TestHelper helper(&task_runner);
111 helper.StartServiceIfRequired();
112 helper.ConnectFakeProducer();
113 helper.ConnectConsumer();
114 helper.WaitForConsumerConnect();
115
116 TraceConfig trace_config;
117 trace_config.add_buffers()->set_size_kb(4096 * 10);
118 trace_config.set_duration_ms(500);
119
120 auto* ds_config = trace_config.add_data_sources()->mutable_config();
121 ds_config->set_name("android.perfetto.FakeProducer");
122 ds_config->set_target_buffer(0);
123
124 static constexpr size_t kNumPackets = 7;
125 static constexpr uint32_t kRandomSeed = 42;
126 static constexpr uint32_t kMsgSize = 1024 * 1024 - 42;
127 ds_config->mutable_for_testing()->set_seed(kRandomSeed);
128 ds_config->mutable_for_testing()->set_message_count(kNumPackets);
129 ds_config->mutable_for_testing()->set_message_size(kMsgSize);
130 ds_config->mutable_for_testing()->set_send_batch_on_register(true);
131
132 helper.StartTracing(trace_config);
133 helper.WaitForTracingDisabled();
134
135 helper.ReadData();
136 helper.WaitForReadData(/* read_count */ 0, /* timeout_ms */ 10000);
137
138 const auto& packets = helper.trace();
139 ASSERT_EQ(packets.size(), kNumPackets);
140
141 std::minstd_rand0 rnd_engine(kRandomSeed);
142 for (const auto& packet : packets) {
143 ASSERT_TRUE(packet.has_for_testing());
144 ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
145 size_t msg_size = packet.for_testing().str().size();
146 ASSERT_EQ(kMsgSize, msg_size);
147 for (size_t i = 0; i < msg_size; i++)
148 ASSERT_EQ(i < msg_size - 1 ? '.' : 0, packet.for_testing().str()[i]);
149 }
150 }
151
152 // This is a regression test see b/169051440 for context.
153 //
154 // In this test we ensure that traced will not crash if a Producer stops
155 // responding or draining the socket (i.e. after we fill up the IPC buffer
156 // traced doesn't block on trying to write to the IPC buffer and watchdog
157 // doesn't kill it).
TEST(PerfettoTracedIntegrationTest,UnresponsiveProducer)158 TEST(PerfettoTracedIntegrationTest, UnresponsiveProducer) {
159 base::TestTaskRunner task_runner;
160
161 TestHelper helper(&task_runner);
162 helper.StartServiceIfRequired();
163 auto* producer = helper.ConnectFakeProducer();
164 helper.ConnectConsumer();
165 helper.WaitForConsumerConnect();
166
167 TraceConfig trace_config;
168 trace_config.add_buffers()->set_size_kb(4096 * 10);
169 trace_config.set_duration_ms(100);
170 trace_config.set_flush_timeout_ms(1);
171 trace_config.set_data_source_stop_timeout_ms(1);
172
173 auto* ds_config = trace_config.add_data_sources()->mutable_config();
174 ds_config->set_name("android.perfetto.FakeProducer");
175
176 static constexpr size_t kNumPackets = 1;
177 static constexpr uint32_t kRandomSeed = 42;
178 static constexpr uint32_t kMsgSize = 1024 * 1024 - 42;
179 ds_config->mutable_for_testing()->set_seed(kRandomSeed);
180 ds_config->mutable_for_testing()->set_message_count(kNumPackets);
181 ds_config->mutable_for_testing()->set_message_size(kMsgSize);
182 ds_config->mutable_for_testing()->set_send_batch_on_register(true);
183
184 // This string is just used to make the StartDataSource IPC larger.
185 ds_config->set_legacy_config(std::string(8192, '.'));
186 ds_config->set_target_buffer(0);
187
188 // Run one legit trace, this ensures that the producer above is
189 // valid and correct and mirrors real life producers.
190 helper.StartTracing(trace_config);
191 helper.WaitForProducerEnabled();
192 helper.WaitForTracingDisabled();
193
194 helper.ReadData();
195 helper.WaitForReadData(/* read_count */ 0, /* timeout_ms */ 10000);
196
197 const auto& packets = helper.trace();
198 ASSERT_EQ(packets.size(), 1u);
199 ASSERT_TRUE(packets[0].has_for_testing());
200 ASSERT_FALSE(packets[0].for_testing().str().empty());
201 helper.FreeBuffers();
202
203 // Switch the producer to ignoring the IPC socket. On a pixel 4 it took 13
204 // traces to fill up the IPC buffer and cause traced to block (and eventually
205 // watchdog to kill it).
206 helper.producer_thread()->get()->RemoveFileDescriptorWatch(
207 producer->unix_socket_fd());
208
209 trace_config.set_duration_ms(1);
210 for (uint32_t i = 0u; i < 15u; i++) {
211 helper.StartTracing(trace_config, base::ScopedFile());
212 helper.WaitForTracingDisabled(/* timeout_ms = */ 20000);
213 helper.FreeBuffers();
214 }
215 // We need to readd the FileDescriptor (otherwise when the UnixSocket attempts
216 // to remove it a the FakeProducer is destroyed will hit a CHECK failure.
217 helper.producer_thread()->get()->AddFileDescriptorWatch(
218 producer->unix_socket_fd(), []() {});
219 }
220
TEST(PerfettoTracedIntegrationTest,DetachAndReattach)221 TEST(PerfettoTracedIntegrationTest, DetachAndReattach) {
222 base::TestTaskRunner task_runner;
223
224 TraceConfig trace_config;
225 trace_config.add_buffers()->set_size_kb(1024);
226 trace_config.set_duration_ms(10000); // Max timeout, session is ended before.
227 auto* ds_config = trace_config.add_data_sources()->mutable_config();
228 ds_config->set_name("android.perfetto.FakeProducer");
229 static constexpr size_t kNumPackets = 11;
230 ds_config->mutable_for_testing()->set_message_count(kNumPackets);
231 ds_config->mutable_for_testing()->set_message_size(32);
232
233 // Enable tracing and detach as soon as it gets started.
234 TestHelper helper(&task_runner);
235 helper.StartServiceIfRequired();
236 auto* fake_producer = helper.ConnectFakeProducer();
237 helper.ConnectConsumer();
238 helper.WaitForConsumerConnect();
239 helper.StartTracing(trace_config);
240
241 // Detach.
242 helper.DetachConsumer("key");
243
244 // Write data while detached.
245 helper.WaitForProducerEnabled();
246 auto on_data_written = task_runner.CreateCheckpoint("data_written");
247 fake_producer->ProduceEventBatch(helper.WrapTask(on_data_written));
248 task_runner.RunUntilCheckpoint("data_written");
249
250 // Then reattach the consumer.
251 helper.ConnectConsumer();
252 helper.WaitForConsumerConnect();
253 helper.AttachConsumer("key");
254
255 helper.DisableTracing();
256 helper.WaitForTracingDisabled();
257
258 helper.ReadData();
259 helper.WaitForReadData();
260 const auto& packets = helper.trace();
261 ASSERT_EQ(packets.size(), kNumPackets);
262 }
263
264 // Tests that a detached trace session is automatically cleaned up if the
265 // consumer doesn't re-attach before its expiration time.
TEST(PerfettoTracedIntegrationTest,ReattachFailsAfterTimeout)266 TEST(PerfettoTracedIntegrationTest, ReattachFailsAfterTimeout) {
267 base::TestTaskRunner task_runner;
268
269 TraceConfig trace_config;
270 trace_config.add_buffers()->set_size_kb(1024);
271 trace_config.set_duration_ms(250);
272 trace_config.set_write_into_file(true);
273 trace_config.set_file_write_period_ms(100000);
274 auto* ds_config = trace_config.add_data_sources()->mutable_config();
275 ds_config->set_name("android.perfetto.FakeProducer");
276 ds_config->mutable_for_testing()->set_message_count(1);
277 ds_config->mutable_for_testing()->set_message_size(32);
278 ds_config->mutable_for_testing()->set_send_batch_on_register(true);
279
280 // Enable tracing and detach as soon as it gets started.
281 TestHelper helper(&task_runner);
282 helper.StartServiceIfRequired();
283 helper.ConnectFakeProducer();
284 helper.ConnectConsumer();
285 helper.WaitForConsumerConnect();
286
287 auto pipe_pair = base::Pipe::Create();
288 helper.StartTracing(trace_config, std::move(pipe_pair.wr));
289
290 // Detach.
291 helper.DetachConsumer("key");
292
293 // Use the file EOF (write end closed) as a way to detect when the trace
294 // session is ended.
295 char buf[1024];
296 while (PERFETTO_EINTR(read(*pipe_pair.rd, buf, sizeof(buf))) > 0) {
297 }
298
299 // Give some margin for the tracing service to destroy the session.
300 usleep(250000);
301
302 // Reconnect and find out that it's too late and the session is gone.
303 helper.ConnectConsumer();
304 helper.WaitForConsumerConnect();
305 EXPECT_FALSE(helper.AttachConsumer("key"));
306 }
307
TEST(PerfettoTracedIntegrationTest,TestProducerProvidedSMB)308 TEST(PerfettoTracedIntegrationTest, TestProducerProvidedSMB) {
309 base::TestTaskRunner task_runner;
310
311 TestHelper helper(&task_runner);
312 helper.CreateProducerProvidedSmb();
313
314 protos::gen::TestConfig test_config;
315 test_config.set_seed(42);
316 test_config.set_message_count(1);
317 test_config.set_message_size(1024);
318 test_config.set_send_batch_on_register(true);
319
320 // Write a first batch before connection.
321 helper.ProduceStartupEventBatch(test_config);
322
323 helper.StartServiceIfRequired();
324 helper.ConnectFakeProducer();
325 helper.ConnectConsumer();
326 helper.WaitForConsumerConnect();
327
328 TraceConfig trace_config;
329 trace_config.add_buffers()->set_size_kb(1024);
330 trace_config.set_duration_ms(200);
331
332 auto* ds_config = trace_config.add_data_sources()->mutable_config();
333 ds_config->set_name("android.perfetto.FakeProducer");
334 ds_config->set_target_buffer(0);
335 *ds_config->mutable_for_testing() = test_config;
336
337 // The data source is configured to emit another batch when it is started via
338 // send_batch_on_register in the TestConfig.
339 helper.StartTracing(trace_config);
340 helper.WaitForTracingDisabled();
341
342 EXPECT_TRUE(helper.IsShmemProvidedByProducer());
343
344 helper.ReadData();
345 helper.WaitForReadData();
346
347 const auto& packets = helper.trace();
348 // We should have produced two batches, one before the producer connected and
349 // another one when the data source was started.
350 ASSERT_EQ(packets.size(), 2u);
351 ASSERT_TRUE(packets[0].has_for_testing());
352 ASSERT_TRUE(packets[1].has_for_testing());
353 }
354
355 // Regression test for b/153142114.
TEST(PerfettoTracedIntegrationTest,QueryServiceStateLargeResponse)356 TEST(PerfettoTracedIntegrationTest, QueryServiceStateLargeResponse) {
357 base::TestTaskRunner task_runner;
358
359 TestHelper helper(&task_runner);
360 helper.StartServiceIfRequired();
361 helper.ConnectConsumer();
362 helper.WaitForConsumerConnect();
363
364 FakeProducer* producer = helper.ConnectFakeProducer();
365
366 // Register 5 data sources with very large descriptors. Each descriptor will
367 // max out the IPC message size, so that the service has no other choice
368 // than chunking them.
369 std::map<std::string, std::string> ds_expected;
370 for (int i = 0; i < 5; i++) {
371 DataSourceDescriptor dsd;
372 std::string name = "big_ds_" + std::to_string(i);
373 dsd.set_name(name);
374 std::string descriptor(ipc::kIPCBufferSize - 64,
375 static_cast<char>((' ' + i) % 64));
376 dsd.set_track_event_descriptor_raw(descriptor);
377 ds_expected[name] = std::move(descriptor);
378 producer->RegisterDataSource(dsd);
379 }
380
381 // Linearize the producer with the service. We need to make sure that all the
382 // RegisterDataSource() calls above have been seen by the service before
383 // continuing.
384 helper.SyncAndWaitProducer();
385
386 // Now invoke QueryServiceState() and wait for the reply. The service will
387 // send 6 (1 + 5) IPCs which will be merged together in
388 // producer_ipc_client_impl.cc.
389 auto svc_state = helper.QueryServiceStateAndWait();
390
391 ASSERT_GE(svc_state.producers().size(), 1u);
392
393 std::map<std::string, std::string> ds_found;
394 for (const auto& ds : svc_state.data_sources()) {
395 if (!base::StartsWith(ds.ds_descriptor().name(), "big_ds_"))
396 continue;
397 ds_found[ds.ds_descriptor().name()] =
398 ds.ds_descriptor().track_event_descriptor_raw();
399 }
400 EXPECT_THAT(ds_found, ElementsAreArray(ds_expected));
401 }
402
403 // Regression test for b/195065199. Check that trace filtering works when a
404 // packet size exceeds the IPC limit. This tests that the tracing service, when
405 // reassembling packets after filtering, doesn't "overglue" them. They still
406 // need to be slice-able to fit into the ReadBuffers ipc.
TEST(PerfettoTracedIntegrationTest,TraceFilterLargePackets)407 TEST(PerfettoTracedIntegrationTest, TraceFilterLargePackets) {
408 base::TestTaskRunner task_runner;
409 TestHelper helper(&task_runner);
410
411 helper.StartServiceIfRequired();
412 helper.ConnectFakeProducer();
413 helper.ConnectConsumer();
414 helper.WaitForConsumerConnect();
415
416 TraceConfig trace_config;
417 trace_config.add_buffers()->set_size_kb(1024 * 16);
418 trace_config.set_duration_ms(500);
419 auto* prod_config = trace_config.add_producers();
420 prod_config->set_producer_name("android.perfetto.FakeProducer");
421 prod_config->set_shm_size_kb(1024 * 16);
422 prod_config->set_page_size_kb(32);
423
424 static constexpr size_t kNumPackets = 3;
425 static constexpr uint32_t kRandomSeed = 42;
426 static constexpr uint32_t kMsgSize = 8 * ipc::kIPCBufferSize;
427 auto* ds_config = trace_config.add_data_sources()->mutable_config();
428 ds_config->set_name("android.perfetto.FakeProducer");
429 auto* test_config = ds_config->mutable_for_testing();
430 test_config->set_seed(kRandomSeed);
431 test_config->set_message_count(kNumPackets);
432 test_config->set_message_size(kMsgSize);
433 test_config->set_send_batch_on_register(true);
434
435 protozero::FilterBytecodeGenerator filt;
436 // Message 0: root Trace proto.
437 filt.AddNestedField(1 /* root trace.packet*/, 1);
438 filt.EndMessage();
439
440 // Message 1: TracePacket proto. Allow all fields.
441 filt.AddSimpleFieldRange(1, 1000);
442 filt.EndMessage();
443
444 trace_config.mutable_trace_filter()->set_bytecode(filt.Serialize());
445
446 // The data source is configured to emit another batch when it is started via
447 // send_batch_on_register in the TestConfig.
448 helper.StartTracing(trace_config);
449 helper.WaitForTracingDisabled();
450
451 helper.ReadData();
452 helper.WaitForReadData(/* read_count */ 0, /* timeout_ms */ 10000);
453
454 const std::vector<protos::gen::TracePacket>& packets = helper.trace();
455 EXPECT_EQ(packets.size(), kNumPackets);
456 EXPECT_THAT(packets,
457 Each(Property(&protos::gen::TracePacket::has_for_testing, true)));
458 EXPECT_THAT(
459 packets,
460 Each(Property(&protos::gen::TracePacket::for_testing,
461 Property(&protos::gen::TestEvent::str, SizeIs(kMsgSize)))));
462 }
463
464 #if (PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS) && \
465 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)) || \
466 PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)
TEST(PerfettoTracedIntegrationTest,TestMultipleProducerSockets)467 TEST(PerfettoTracedIntegrationTest, TestMultipleProducerSockets) {
468 base::TestTaskRunner task_runner;
469 auto temp_dir = base::TempDir::Create();
470
471 std::vector<std::string> producer_socket_names{
472 temp_dir.path() + "/producer1.sock",
473 temp_dir.path() + "/producer2.sock",
474 };
475 auto producer_sock_name = base::Join(producer_socket_names, ",");
476 // We need to start the service thread for multiple producer sockets.
477 TestHelper helper(&task_runner, TestHelper::Mode::kStartDaemons,
478 producer_sock_name.c_str());
479 ASSERT_EQ(helper.num_producers(), 2u);
480 helper.StartServiceIfRequired();
481 // Setup the 1st producer (default).
482 helper.ConnectFakeProducer();
483 // Setup the 2ns producer.
484 helper.ConnectFakeProducer(1);
485 helper.ConnectConsumer();
486 helper.WaitForConsumerConnect();
487
488 TraceConfig trace_config;
489 trace_config.add_buffers()->set_size_kb(1024);
490 trace_config.set_duration_ms(200);
491
492 static constexpr uint32_t kMsgSize = 1024;
493 // Enable the 1st producer.
494 auto* ds_config = trace_config.add_data_sources()->mutable_config();
495 ds_config->set_name("android.perfetto.FakeProducer");
496 ds_config->set_target_buffer(0);
497 ds_config->mutable_for_testing()->set_message_count(12);
498 ds_config->mutable_for_testing()->set_message_size(kMsgSize);
499 ds_config->mutable_for_testing()->set_send_batch_on_register(true);
500 // Enable the 2nd producer.
501 ds_config = trace_config.add_data_sources()->mutable_config();
502 ds_config->set_name("android.perfetto.FakeProducer.1");
503 ds_config->set_target_buffer(0);
504 ds_config->mutable_for_testing()->set_message_count(24);
505 ds_config->mutable_for_testing()->set_message_size(kMsgSize);
506 ds_config->mutable_for_testing()->set_send_batch_on_register(true);
507
508 helper.StartTracing(trace_config);
509 helper.WaitForTracingDisabled();
510
511 helper.ReadData();
512 helper.WaitForReadData();
513
514 const auto& packets = helper.trace();
515 ASSERT_EQ(packets.size(), 36u);
516
517 for (const auto& packet : packets) {
518 ASSERT_TRUE(packet.has_for_testing());
519 }
520
521 for (const auto& sock_name : producer_socket_names)
522 remove(sock_name.c_str());
523 }
524
TEST(PerfettoTracedIntegrationTest,TestShmemEmulation)525 TEST(PerfettoTracedIntegrationTest, TestShmemEmulation) {
526 base::TestTaskRunner task_runner;
527 auto temp_dir = base::TempDir::Create();
528
529 std::string sock_name;
530 {
531 // Set up a server UnixSocket to find an unused TCP port.
532 base::UnixSocket::EventListener event_listener;
533 auto srv = base::UnixSocket::Listen("127.0.0.1:0", &event_listener,
534 &task_runner, base::SockFamily::kInet,
535 base::SockType::kStream);
536 ASSERT_TRUE(srv->is_listening());
537 sock_name = srv->GetSockAddr();
538 // Shut down |srv| here to free the port. It's unlikely that the port will
539 // be taken by another process so quickly before we reach the code below.
540 }
541
542 TestHelper helper(&task_runner, TestHelper::Mode::kStartDaemons,
543 sock_name.c_str());
544 ASSERT_EQ(helper.num_producers(), 1u);
545 helper.StartServiceIfRequired();
546 // Setup the 1st producer (default).
547 helper.ConnectFakeProducer();
548 helper.ConnectConsumer();
549 helper.WaitForConsumerConnect();
550
551 TraceConfig trace_config;
552 trace_config.add_buffers()->set_size_kb(1024);
553 trace_config.set_duration_ms(200);
554
555 static constexpr uint32_t kMsgSize = 1024;
556 static constexpr uint32_t kRandomSeed = 42;
557 // Enable the producer.
558 auto* ds_config = trace_config.add_data_sources()->mutable_config();
559 ds_config->set_name("android.perfetto.FakeProducer");
560 ds_config->set_target_buffer(0);
561 ds_config->mutable_for_testing()->set_seed(kRandomSeed);
562 ds_config->mutable_for_testing()->set_message_count(12);
563 ds_config->mutable_for_testing()->set_message_size(kMsgSize);
564 ds_config->mutable_for_testing()->set_send_batch_on_register(true);
565
566 helper.StartTracing(trace_config);
567 helper.WaitForTracingDisabled();
568
569 helper.ReadData();
570 helper.WaitForReadData();
571
572 const auto& packets = helper.trace();
573 ASSERT_EQ(packets.size(), 12u);
574
575 std::minstd_rand0 rnd_engine(kRandomSeed);
576 for (const auto& packet : packets) {
577 ASSERT_TRUE(packet.has_for_testing());
578 ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
579 }
580 }
581 #endif
582
583 } // namespace perfetto
584