blob: 53afd92d59ce733d76b97c23ba2c785cdbbfef8b [file] [log] [blame]
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "src/tracing/core/service_impl.h"
18
19#include <string.h>
20
21#include "gmock/gmock.h"
22#include "gtest/gtest.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010023#include "perfetto/base/file_utils.h"
24#include "perfetto/base/temp_file.h"
Sami Kyostila06487a22018-02-27 13:48:38 +000025#include "perfetto/tracing/core/consumer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000026#include "perfetto/tracing/core/data_source_config.h"
27#include "perfetto/tracing/core/data_source_descriptor.h"
28#include "perfetto/tracing/core/producer.h"
29#include "perfetto/tracing/core/shared_memory.h"
Sami Kyostila06487a22018-02-27 13:48:38 +000030#include "perfetto/tracing/core/trace_packet.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010031#include "perfetto/tracing/core/trace_writer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000032#include "src/base/test/test_task_runner.h"
33#include "src/tracing/test/test_shared_memory.h"
34
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010035#include "perfetto/trace/test_event.pbzero.h"
36#include "perfetto/trace/trace.pb.h"
37#include "perfetto/trace/trace_packet.pbzero.h"
38
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000039namespace perfetto {
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000040using ::testing::_;
41using ::testing::InSequence;
Primiano Tucci081d46a2018-02-28 11:09:43 +000042using ::testing::Invoke;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000043using ::testing::Mock;
44
Sami Kyostila32e0b542018-02-14 08:55:43 +000045namespace {
46
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000047class MockProducer : public Producer {
48 public:
49 ~MockProducer() override {}
50
51 // Producer implementation.
52 MOCK_METHOD0(OnConnect, void());
53 MOCK_METHOD0(OnDisconnect, void());
54 MOCK_METHOD2(CreateDataSourceInstance,
55 void(DataSourceInstanceID, const DataSourceConfig&));
56 MOCK_METHOD1(TearDownDataSourceInstance, void(DataSourceInstanceID));
Isabelle Taylor69faa902018-03-21 15:42:03 +000057 MOCK_METHOD0(OnTracingStart, void());
58 MOCK_METHOD0(OnTracingStop, void());
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000059};
60
Sami Kyostila06487a22018-02-27 13:48:38 +000061class MockConsumer : public Consumer {
62 public:
63 ~MockConsumer() override {}
64
65 // Consumer implementation.
66 MOCK_METHOD0(OnConnect, void());
67 MOCK_METHOD0(OnDisconnect, void());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010068 MOCK_METHOD0(OnTracingStop, void());
Sami Kyostila06487a22018-02-27 13:48:38 +000069
70 void OnTraceData(std::vector<TracePacket> packets, bool has_more) override {}
71};
72
Sami Kyostila32e0b542018-02-14 08:55:43 +000073} // namespace
74
Sami Kyostila06487a22018-02-27 13:48:38 +000075class ServiceImplTest : public testing::Test {
76 public:
77 ServiceImplTest() {
78 auto shm_factory =
79 std::unique_ptr<SharedMemory::Factory>(new TestSharedMemory::Factory());
80 svc.reset(static_cast<ServiceImpl*>(
81 Service::CreateInstance(std::move(shm_factory), &task_runner)
82 .release()));
83 }
84
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000085 base::TestTaskRunner task_runner;
Sami Kyostila06487a22018-02-27 13:48:38 +000086 std::unique_ptr<ServiceImpl> svc;
87};
88
89TEST_F(ServiceImplTest, RegisterAndUnregister) {
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000090 MockProducer mock_producer_1;
91 MockProducer mock_producer_2;
92 std::unique_ptr<Service::ProducerEndpoint> producer_endpoint_1 =
Sami Kyostila32e0b542018-02-14 08:55:43 +000093 svc->ConnectProducer(&mock_producer_1, 123u /* uid */);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000094 std::unique_ptr<Service::ProducerEndpoint> producer_endpoint_2 =
Sami Kyostila32e0b542018-02-14 08:55:43 +000095 svc->ConnectProducer(&mock_producer_2, 456u /* uid */);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000096
97 ASSERT_TRUE(producer_endpoint_1);
98 ASSERT_TRUE(producer_endpoint_2);
99
100 InSequence seq;
101 EXPECT_CALL(mock_producer_1, OnConnect());
102 EXPECT_CALL(mock_producer_2, OnConnect());
103 task_runner.RunUntilIdle();
104
105 ASSERT_EQ(2u, svc->num_producers());
106 ASSERT_EQ(producer_endpoint_1.get(), svc->GetProducer(1));
107 ASSERT_EQ(producer_endpoint_2.get(), svc->GetProducer(2));
Sami Kyostila32e0b542018-02-14 08:55:43 +0000108 ASSERT_EQ(123u, svc->GetProducer(1)->uid_);
109 ASSERT_EQ(456u, svc->GetProducer(2)->uid_);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000110
Primiano Tucci114b6492017-12-11 23:09:45 +0000111 DataSourceDescriptor ds_desc1;
112 ds_desc1.set_name("foo");
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000113 producer_endpoint_1->RegisterDataSource(
Sami Kyostila06487a22018-02-27 13:48:38 +0000114 ds_desc1, [this, &producer_endpoint_1](DataSourceID id) {
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000115 EXPECT_EQ(1u, id);
116 task_runner.PostTask(
117 std::bind(&Service::ProducerEndpoint::UnregisterDataSource,
118 producer_endpoint_1.get(), id));
119 });
120
Primiano Tucci114b6492017-12-11 23:09:45 +0000121 DataSourceDescriptor ds_desc2;
122 ds_desc2.set_name("bar");
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000123 producer_endpoint_2->RegisterDataSource(
Sami Kyostila06487a22018-02-27 13:48:38 +0000124 ds_desc2, [this, &producer_endpoint_2](DataSourceID id) {
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000125 EXPECT_EQ(1u, id);
126 task_runner.PostTask(
127 std::bind(&Service::ProducerEndpoint::UnregisterDataSource,
128 producer_endpoint_2.get(), id));
129 });
130
131 task_runner.RunUntilIdle();
132
133 EXPECT_CALL(mock_producer_1, OnDisconnect());
134 producer_endpoint_1.reset();
135 task_runner.RunUntilIdle();
136 Mock::VerifyAndClearExpectations(&mock_producer_1);
137
138 ASSERT_EQ(1u, svc->num_producers());
139 ASSERT_EQ(nullptr, svc->GetProducer(1));
140
141 EXPECT_CALL(mock_producer_2, OnDisconnect());
142 producer_endpoint_2.reset();
143 task_runner.RunUntilIdle();
144 Mock::VerifyAndClearExpectations(&mock_producer_2);
145
146 ASSERT_EQ(0u, svc->num_producers());
147}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100148
Sami Kyostila06487a22018-02-27 13:48:38 +0000149TEST_F(ServiceImplTest, EnableAndDisableTracing) {
150 MockProducer mock_producer;
151 std::unique_ptr<Service::ProducerEndpoint> producer_endpoint =
152 svc->ConnectProducer(&mock_producer, 123u /* uid */);
153 MockConsumer mock_consumer;
154 std::unique_ptr<Service::ConsumerEndpoint> consumer_endpoint =
155 svc->ConnectConsumer(&mock_consumer);
156
157 InSequence seq;
158 EXPECT_CALL(mock_producer, OnConnect());
159 EXPECT_CALL(mock_consumer, OnConnect());
160 task_runner.RunUntilIdle();
161
162 DataSourceDescriptor ds_desc;
163 ds_desc.set_name("foo");
164 producer_endpoint->RegisterDataSource(ds_desc, [](DataSourceID) {});
165
166 task_runner.RunUntilIdle();
167
168 EXPECT_CALL(mock_producer, CreateDataSourceInstance(_, _));
169 EXPECT_CALL(mock_producer, TearDownDataSourceInstance(_));
170 TraceConfig trace_config;
171 trace_config.add_buffers()->set_size_kb(4096 * 10);
172 auto* ds_config = trace_config.add_data_sources()->mutable_config();
173 ds_config->set_name("foo");
174 ds_config->set_target_buffer(0);
175 consumer_endpoint->EnableTracing(trace_config);
176 task_runner.RunUntilIdle();
177
178 EXPECT_CALL(mock_producer, OnDisconnect());
179 EXPECT_CALL(mock_consumer, OnDisconnect());
180 consumer_endpoint->DisableTracing();
181 producer_endpoint.reset();
182 consumer_endpoint.reset();
183 task_runner.RunUntilIdle();
184 Mock::VerifyAndClearExpectations(&mock_producer);
185 Mock::VerifyAndClearExpectations(&mock_consumer);
186}
187
Florian Mayer61c55482018-03-06 14:43:54 +0000188TEST_F(ServiceImplTest, LockdownMode) {
189 MockConsumer mock_consumer;
190 EXPECT_CALL(mock_consumer, OnConnect());
191 std::unique_ptr<Service::ConsumerEndpoint> consumer_endpoint =
192 svc->ConnectConsumer(&mock_consumer);
193
194 TraceConfig trace_config;
195 trace_config.set_lockdown_mode(
196 TraceConfig::LockdownModeOperation::LOCKDOWN_SET);
197 consumer_endpoint->EnableTracing(trace_config);
198 task_runner.RunUntilIdle();
199
200 InSequence seq;
201
202 MockProducer mock_producer;
203 std::unique_ptr<Service::ProducerEndpoint> producer_endpoint =
204 svc->ConnectProducer(&mock_producer, geteuid() + 1 /* uid */);
205
206 MockProducer mock_producer_sameuid;
207 std::unique_ptr<Service::ProducerEndpoint> producer_endpoint_sameuid =
208 svc->ConnectProducer(&mock_producer_sameuid, geteuid() /* uid */);
209
210 EXPECT_CALL(mock_producer, OnConnect()).Times(0);
211 EXPECT_CALL(mock_producer_sameuid, OnConnect());
212 task_runner.RunUntilIdle();
213
214 Mock::VerifyAndClearExpectations(&mock_producer);
215
216 consumer_endpoint->DisableTracing();
217 task_runner.RunUntilIdle();
218
219 trace_config.set_lockdown_mode(
220 TraceConfig::LockdownModeOperation::LOCKDOWN_CLEAR);
221 consumer_endpoint->EnableTracing(trace_config);
222 task_runner.RunUntilIdle();
223
Hector Dearman5afe5012018-03-22 12:09:01 +0000224 EXPECT_CALL(mock_producer_sameuid, OnDisconnect());
Florian Mayer61c55482018-03-06 14:43:54 +0000225 EXPECT_CALL(mock_producer, OnConnect());
226 producer_endpoint_sameuid =
227 svc->ConnectProducer(&mock_producer, geteuid() + 1);
228
Hector Dearman5afe5012018-03-22 12:09:01 +0000229 EXPECT_CALL(mock_producer, OnDisconnect());
Florian Mayer61c55482018-03-06 14:43:54 +0000230 task_runner.RunUntilIdle();
231}
232
Sami Kyostila06487a22018-02-27 13:48:38 +0000233TEST_F(ServiceImplTest, DisconnectConsumerWhileTracing) {
234 MockProducer mock_producer;
235 std::unique_ptr<Service::ProducerEndpoint> producer_endpoint =
236 svc->ConnectProducer(&mock_producer, 123u /* uid */);
237 MockConsumer mock_consumer;
238 std::unique_ptr<Service::ConsumerEndpoint> consumer_endpoint =
239 svc->ConnectConsumer(&mock_consumer);
240
241 InSequence seq;
242 EXPECT_CALL(mock_producer, OnConnect());
243 EXPECT_CALL(mock_consumer, OnConnect());
244 task_runner.RunUntilIdle();
245
246 DataSourceDescriptor ds_desc;
247 ds_desc.set_name("foo");
248 producer_endpoint->RegisterDataSource(ds_desc, [](DataSourceID) {});
249 task_runner.RunUntilIdle();
250
251 // Disconnecting the consumer while tracing should trigger data source
252 // teardown.
253 EXPECT_CALL(mock_producer, CreateDataSourceInstance(_, _));
254 EXPECT_CALL(mock_producer, TearDownDataSourceInstance(_));
255 TraceConfig trace_config;
256 trace_config.add_buffers()->set_size_kb(4096 * 10);
257 auto* ds_config = trace_config.add_data_sources()->mutable_config();
258 ds_config->set_name("foo");
259 ds_config->set_target_buffer(0);
260 consumer_endpoint->EnableTracing(trace_config);
261 task_runner.RunUntilIdle();
262
263 EXPECT_CALL(mock_consumer, OnDisconnect());
264 consumer_endpoint.reset();
265 task_runner.RunUntilIdle();
266
267 EXPECT_CALL(mock_producer, OnDisconnect());
268 producer_endpoint.reset();
269 Mock::VerifyAndClearExpectations(&mock_producer);
270 Mock::VerifyAndClearExpectations(&mock_consumer);
271}
272
273TEST_F(ServiceImplTest, ReconnectProducerWhileTracing) {
274 MockProducer mock_producer;
275 std::unique_ptr<Service::ProducerEndpoint> producer_endpoint =
276 svc->ConnectProducer(&mock_producer, 123u /* uid */);
277 MockConsumer mock_consumer;
278 std::unique_ptr<Service::ConsumerEndpoint> consumer_endpoint =
279 svc->ConnectConsumer(&mock_consumer);
280
281 InSequence seq;
282 EXPECT_CALL(mock_producer, OnConnect());
283 EXPECT_CALL(mock_consumer, OnConnect());
284 task_runner.RunUntilIdle();
285
286 DataSourceDescriptor ds_desc;
287 ds_desc.set_name("foo");
288 producer_endpoint->RegisterDataSource(ds_desc, [](DataSourceID) {});
289 task_runner.RunUntilIdle();
290
291 // Disconnecting the producer while tracing should trigger data source
292 // teardown.
293 EXPECT_CALL(mock_producer, CreateDataSourceInstance(_, _));
294 EXPECT_CALL(mock_producer, TearDownDataSourceInstance(_));
295 EXPECT_CALL(mock_producer, OnDisconnect());
296 TraceConfig trace_config;
297 trace_config.add_buffers()->set_size_kb(4096 * 10);
298 auto* ds_config = trace_config.add_data_sources()->mutable_config();
299 ds_config->set_name("foo");
300 ds_config->set_target_buffer(0);
301 consumer_endpoint->EnableTracing(trace_config);
302 producer_endpoint.reset();
303 task_runner.RunUntilIdle();
304
305 // Reconnecting a producer with a matching data source should see that data
306 // source getting enabled.
307 EXPECT_CALL(mock_producer, OnConnect());
308 producer_endpoint = svc->ConnectProducer(&mock_producer, 123u /* uid */);
309 task_runner.RunUntilIdle();
310 EXPECT_CALL(mock_producer, CreateDataSourceInstance(_, _));
311 EXPECT_CALL(mock_producer, TearDownDataSourceInstance(_));
312 producer_endpoint->RegisterDataSource(ds_desc, [](DataSourceID) {});
313 task_runner.RunUntilIdle();
314
315 EXPECT_CALL(mock_consumer, OnDisconnect());
316 consumer_endpoint->DisableTracing();
317 consumer_endpoint.reset();
318 task_runner.RunUntilIdle();
319
320 EXPECT_CALL(mock_producer, OnDisconnect());
321 producer_endpoint.reset();
322 Mock::VerifyAndClearExpectations(&mock_producer);
323 Mock::VerifyAndClearExpectations(&mock_consumer);
324}
325
Primiano Tucci081d46a2018-02-28 11:09:43 +0000326TEST_F(ServiceImplTest, ProducerIDWrapping) {
327 base::TestTaskRunner task_runner;
328 auto shm_factory =
329 std::unique_ptr<SharedMemory::Factory>(new TestSharedMemory::Factory());
330 std::unique_ptr<ServiceImpl> svc(static_cast<ServiceImpl*>(
331 Service::CreateInstance(std::move(shm_factory), &task_runner).release()));
332
333 std::map<ProducerID, std::pair<std::unique_ptr<MockProducer>,
334 std::unique_ptr<Service::ProducerEndpoint>>>
335 producers;
336
337 auto ConnectProducerAndWait = [&task_runner, &svc, &producers]() {
338 char checkpoint_name[32];
339 static int checkpoint_num = 0;
340 sprintf(checkpoint_name, "on_connect_%d", checkpoint_num++);
341 auto on_connect = task_runner.CreateCheckpoint(checkpoint_name);
342 std::unique_ptr<MockProducer> producer(new MockProducer());
343 std::unique_ptr<Service::ProducerEndpoint> producer_endpoint =
344 svc->ConnectProducer(producer.get(), 123u /* uid */);
345 EXPECT_CALL(*producer, OnConnect()).WillOnce(Invoke(on_connect));
346 task_runner.RunUntilCheckpoint(checkpoint_name);
347 EXPECT_EQ(&*producer_endpoint, svc->GetProducer(svc->last_producer_id_));
348 const ProducerID pr_id = svc->last_producer_id_;
349 producers.emplace(pr_id, std::make_pair(std::move(producer),
350 std::move(producer_endpoint)));
351 return pr_id;
352 };
353
354 auto DisconnectProducerAndWait = [&task_runner,
355 &producers](ProducerID pr_id) {
356 char checkpoint_name[32];
357 static int checkpoint_num = 0;
358 sprintf(checkpoint_name, "on_disconnect_%d", checkpoint_num++);
359 auto on_disconnect = task_runner.CreateCheckpoint(checkpoint_name);
360 auto it = producers.find(pr_id);
361 PERFETTO_CHECK(it != producers.end());
362 EXPECT_CALL(*it->second.first, OnDisconnect())
363 .WillOnce(Invoke(on_disconnect));
364 producers.erase(pr_id);
365 task_runner.RunUntilCheckpoint(checkpoint_name);
366 };
367
368 // Connect producers 1-4.
369 for (ProducerID i = 1; i <= 4; i++)
370 ASSERT_EQ(i, ConnectProducerAndWait());
371
372 // Disconnect producers 1,3.
373 DisconnectProducerAndWait(1);
374 DisconnectProducerAndWait(3);
375
376 svc->last_producer_id_ = kMaxProducerID - 1;
377 ASSERT_EQ(kMaxProducerID, ConnectProducerAndWait());
378 ASSERT_EQ(1u, ConnectProducerAndWait());
379 ASSERT_EQ(3u, ConnectProducerAndWait());
380 ASSERT_EQ(5u, ConnectProducerAndWait());
381 ASSERT_EQ(6u, ConnectProducerAndWait());
382
383 // Disconnect all producers to mute spurious callbacks.
384 DisconnectProducerAndWait(kMaxProducerID);
385 for (ProducerID i = 1; i <= 6; i++)
386 DisconnectProducerAndWait(i);
387}
388
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100389TEST_F(ServiceImplTest, WriteIntoFileAndStopOnMaxSize) {
390 MockProducer mock_producer;
391 std::unique_ptr<Service::ProducerEndpoint> producer_endpoint =
392 svc->ConnectProducer(&mock_producer, 123u /* uid */);
393 MockConsumer mock_consumer;
394 std::unique_ptr<Service::ConsumerEndpoint> consumer_endpoint =
395 svc->ConnectConsumer(&mock_consumer);
396
397 EXPECT_CALL(mock_producer, OnConnect());
398 EXPECT_CALL(mock_consumer, OnConnect());
399 task_runner.RunUntilIdle();
400
401 DataSourceDescriptor ds_desc;
402 ds_desc.set_name("datasource");
403 producer_endpoint->RegisterDataSource(ds_desc, [](DataSourceID) {});
404 task_runner.RunUntilIdle();
405
406 static const char kPayload[] = "1234567890abcdef-";
407 static const int kNumPackets = 10;
408 TraceConfig trace_config;
409 trace_config.add_buffers()->set_size_kb(4096);
410 auto* ds_config = trace_config.add_data_sources()->mutable_config();
411 ds_config->set_name("datasource");
412 ds_config->set_target_buffer(0);
413 trace_config.set_write_into_file(true);
414 trace_config.set_file_write_period_ms(1);
415 const uint64_t kMaxFileSize = 512;
416 trace_config.set_max_file_size_bytes(kMaxFileSize);
417 base::TempFile tmp_file = base::TempFile::Create();
418 auto on_tracing_start = task_runner.CreateCheckpoint("on_tracing_start");
419 BufferID buf_id = 0;
420 EXPECT_CALL(mock_producer, OnTracingStart());
421 EXPECT_CALL(mock_producer, CreateDataSourceInstance(_, _))
422 .WillOnce(Invoke([on_tracing_start, &buf_id](
423 DataSourceInstanceID, const DataSourceConfig& cfg) {
424 buf_id = static_cast<BufferID>(cfg.target_buffer());
425 on_tracing_start();
426 }));
427 consumer_endpoint->EnableTracing(trace_config,
428 base::ScopedFile(dup(tmp_file.fd())));
429 task_runner.RunUntilCheckpoint("on_tracing_start");
430
431 std::unique_ptr<TraceWriter> writer =
432 producer_endpoint->CreateTraceWriter(buf_id);
433 // All these packets should fit within kMaxFileSize.
434 for (int i = 0; i < kNumPackets; i++) {
435 auto tp = writer->NewTracePacket();
436 std::string payload(kPayload);
437 payload.append(std::to_string(i));
438 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
439 }
440
441 // Finally add a packet that overflows kMaxFileSize. This should cause the
442 // implicit stop of the trace and should *not* be written in the trace.
443 {
444 auto tp = writer->NewTracePacket();
445 char big_payload[kMaxFileSize] = "BIG!";
446 tp->set_for_testing()->set_str(big_payload, sizeof(big_payload));
447 }
448 writer->Flush();
449 writer.reset();
450
451 auto on_tracing_stop = task_runner.CreateCheckpoint("on_tracing_stop");
452 EXPECT_CALL(mock_producer, TearDownDataSourceInstance(_));
453 EXPECT_CALL(mock_consumer, OnTracingStop()).WillOnce(Invoke(on_tracing_stop));
454 task_runner.RunUntilCheckpoint("on_tracing_stop");
455
456 EXPECT_CALL(mock_consumer, OnDisconnect());
457 EXPECT_CALL(mock_producer, OnDisconnect());
458 consumer_endpoint->DisableTracing();
459 consumer_endpoint.reset();
460 producer_endpoint.reset();
461 task_runner.RunUntilIdle();
462
463 // Verify the contents of the file.
464 std::string trace_raw;
465 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
466 protos::Trace trace;
467 ASSERT_TRUE(trace.ParseFromString(trace_raw));
468 ASSERT_GE(trace.packet_size(), kNumPackets);
469 int num_testing_packet = 0;
470 for (int i = 0; i < trace.packet_size(); i++) {
471 const protos::TracePacket& tp = trace.packet(i);
472 if (!tp.has_for_testing())
473 continue;
474 ASSERT_EQ(kPayload + std::to_string(num_testing_packet++),
475 tp.for_testing().str());
476 }
477} // namespace perfetto
478
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000479} // namespace perfetto