blob: 81f46345fb837bcd10a4b43232946b1933dfdbf2 [file] [log] [blame]
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Florian Mayer6a1a4d52018-06-08 16:47:07 +010017#include "src/tracing/core/tracing_service_impl.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000018
19#include <string.h>
20
21#include "gmock/gmock.h"
22#include "gtest/gtest.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010023#include "perfetto/base/file_utils.h"
24#include "perfetto/base/temp_file.h"
Primiano Tucci1a1951d2018-04-04 21:08:16 +020025#include "perfetto/base/utils.h"
Sami Kyostila06487a22018-02-27 13:48:38 +000026#include "perfetto/tracing/core/consumer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000027#include "perfetto/tracing/core/data_source_config.h"
28#include "perfetto/tracing/core/data_source_descriptor.h"
29#include "perfetto/tracing/core/producer.h"
30#include "perfetto/tracing/core/shared_memory.h"
Sami Kyostila06487a22018-02-27 13:48:38 +000031#include "perfetto/tracing/core/trace_packet.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010032#include "perfetto/tracing/core/trace_writer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000033#include "src/base/test/test_task_runner.h"
Eric Secklera01e28a2019-01-08 11:21:04 +000034#include "src/tracing/core/shared_memory_arbiter_impl.h"
Eric Secklerf3f524b2018-12-13 09:09:34 +000035#include "src/tracing/core/trace_writer_impl.h"
Primiano Tuccidca727d2018-04-04 11:31:55 +020036#include "src/tracing/test/mock_consumer.h"
37#include "src/tracing/test/mock_producer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000038#include "src/tracing/test/test_shared_memory.h"
39
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010040#include "perfetto/trace/test_event.pbzero.h"
41#include "perfetto/trace/trace.pb.h"
Primiano Tuccidca727d2018-04-04 11:31:55 +020042#include "perfetto/trace/trace_packet.pb.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010043#include "perfetto/trace/trace_packet.pbzero.h"
44
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000045using ::testing::_;
Primiano Tuccidca727d2018-04-04 11:31:55 +020046using ::testing::Contains;
Primiano Tucci1a1951d2018-04-04 21:08:16 +020047using ::testing::ElementsAreArray;
Primiano Tuccidca727d2018-04-04 11:31:55 +020048using ::testing::Eq;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000049using ::testing::InSequence;
Primiano Tucci081d46a2018-02-28 11:09:43 +000050using ::testing::Invoke;
Primiano Tuccidca727d2018-04-04 11:31:55 +020051using ::testing::InvokeWithoutArgs;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000052using ::testing::Mock;
Eric Secklerdd0ad102018-12-06 11:32:04 +000053using ::testing::Not;
Primiano Tuccidca727d2018-04-04 11:31:55 +020054using ::testing::Property;
55using ::testing::StrictMock;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000056
Primiano Tuccidca727d2018-04-04 11:31:55 +020057namespace perfetto {
Sami Kyostila32e0b542018-02-14 08:55:43 +000058
Primiano Tucci1a1951d2018-04-04 21:08:16 +020059namespace {
Florian Mayer6a1a4d52018-06-08 16:47:07 +010060constexpr size_t kDefaultShmSizeKb = TracingServiceImpl::kDefaultShmSize / 1024;
61constexpr size_t kMaxShmSizeKb = TracingServiceImpl::kMaxShmSize / 1024;
Primiano Tucci1a1951d2018-04-04 21:08:16 +020062} // namespace
63
Florian Mayer6a1a4d52018-06-08 16:47:07 +010064class TracingServiceImplTest : public testing::Test {
Sami Kyostila06487a22018-02-27 13:48:38 +000065 public:
Florian Mayer6a1a4d52018-06-08 16:47:07 +010066 TracingServiceImplTest() {
Sami Kyostila06487a22018-02-27 13:48:38 +000067 auto shm_factory =
68 std::unique_ptr<SharedMemory::Factory>(new TestSharedMemory::Factory());
Florian Mayer6a1a4d52018-06-08 16:47:07 +010069 svc.reset(static_cast<TracingServiceImpl*>(
70 TracingService::CreateInstance(std::move(shm_factory), &task_runner)
Sami Kyostila06487a22018-02-27 13:48:38 +000071 .release()));
Primiano Tucci9754d0d2018-09-15 12:41:46 +010072 svc->min_write_period_ms_ = 1;
Sami Kyostila06487a22018-02-27 13:48:38 +000073 }
74
Primiano Tuccidca727d2018-04-04 11:31:55 +020075 std::unique_ptr<MockProducer> CreateMockProducer() {
76 return std::unique_ptr<MockProducer>(
77 new StrictMock<MockProducer>(&task_runner));
78 }
79
80 std::unique_ptr<MockConsumer> CreateMockConsumer() {
81 return std::unique_ptr<MockConsumer>(
82 new StrictMock<MockConsumer>(&task_runner));
83 }
84
Primiano Tucci1a1951d2018-04-04 21:08:16 +020085 ProducerID* last_producer_id() { return &svc->last_producer_id_; }
86
87 uid_t GetProducerUid(ProducerID producer_id) {
88 return svc->GetProducer(producer_id)->uid_;
89 }
90
Primiano Tucci9754d0d2018-09-15 12:41:46 +010091 TracingServiceImpl::TracingSession* tracing_session() {
92 auto* session = svc->GetTracingSession(svc->last_tracing_session_id_);
93 EXPECT_NE(nullptr, session);
94 return session;
95 }
96
Eric Seckler6dc23592018-11-30 10:59:06 +000097 const std::set<BufferID>& GetAllowedTargetBuffers(ProducerID producer_id) {
98 return svc->GetProducer(producer_id)->allowed_target_buffers_;
99 }
100
Eric Secklerf3f524b2018-12-13 09:09:34 +0000101 const std::map<WriterID, BufferID>& GetWriters(ProducerID producer_id) {
102 return svc->GetProducer(producer_id)->writers_;
103 }
104
Eric Secklera01e28a2019-01-08 11:21:04 +0000105 std::unique_ptr<SharedMemoryArbiterImpl> TakeShmemArbiterForProducer(
106 ProducerID producer_id) {
107 return std::move(svc->GetProducer(producer_id)->inproc_shmem_arbiter_);
108 }
109
Primiano Tuccid52e6272018-04-06 19:06:53 +0200110 size_t GetNumPendingFlushes() {
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100111 return tracing_session()->pending_flushes.size();
112 }
113
114 void WaitForNextSyncMarker() {
115 tracing_session()->last_snapshot_time = base::TimeMillis(0);
116 static int attempt = 0;
117 while (tracing_session()->last_snapshot_time == base::TimeMillis(0)) {
118 auto checkpoint_name = "wait_snapshot_" + std::to_string(attempt++);
119 auto timer_expired = task_runner.CreateCheckpoint(checkpoint_name);
120 task_runner.PostDelayedTask([timer_expired] { timer_expired(); }, 1);
121 task_runner.RunUntilCheckpoint(checkpoint_name);
122 }
Primiano Tuccid52e6272018-04-06 19:06:53 +0200123 }
124
Eric Secklerf3f524b2018-12-13 09:09:34 +0000125 void WaitForTraceWritersChanged(ProducerID producer_id) {
126 static int i = 0;
127 auto checkpoint_name = "writers_changed_" + std::to_string(producer_id) +
128 "_" + std::to_string(i++);
129 auto writers_changed = task_runner.CreateCheckpoint(checkpoint_name);
130 auto writers = GetWriters(producer_id);
131 std::function<void()> task;
132 task = [&task, writers, writers_changed, producer_id, this]() {
133 if (writers != GetWriters(producer_id)) {
134 writers_changed();
135 return;
136 }
137 task_runner.PostDelayedTask(task, 1);
138 };
139 task_runner.PostDelayedTask(task, 1);
140 task_runner.RunUntilCheckpoint(checkpoint_name);
141 }
142
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000143 base::TestTaskRunner task_runner;
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100144 std::unique_ptr<TracingServiceImpl> svc;
Sami Kyostila06487a22018-02-27 13:48:38 +0000145};
146
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100147TEST_F(TracingServiceImplTest, RegisterAndUnregister) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200148 std::unique_ptr<MockProducer> mock_producer_1 = CreateMockProducer();
149 std::unique_ptr<MockProducer> mock_producer_2 = CreateMockProducer();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000150
Primiano Tuccidca727d2018-04-04 11:31:55 +0200151 mock_producer_1->Connect(svc.get(), "mock_producer_1", 123u /* uid */);
152 mock_producer_2->Connect(svc.get(), "mock_producer_2", 456u /* uid */);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000153
154 ASSERT_EQ(2u, svc->num_producers());
Primiano Tuccidca727d2018-04-04 11:31:55 +0200155 ASSERT_EQ(mock_producer_1->endpoint(), svc->GetProducer(1));
156 ASSERT_EQ(mock_producer_2->endpoint(), svc->GetProducer(2));
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200157 ASSERT_EQ(123u, GetProducerUid(1));
158 ASSERT_EQ(456u, GetProducerUid(2));
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000159
Primiano Tuccidca727d2018-04-04 11:31:55 +0200160 mock_producer_1->RegisterDataSource("foo");
161 mock_producer_2->RegisterDataSource("bar");
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000162
Primiano Tuccidca727d2018-04-04 11:31:55 +0200163 mock_producer_1->UnregisterDataSource("foo");
164 mock_producer_2->UnregisterDataSource("bar");
Primiano Tucci9daa4832018-03-28 23:28:17 +0100165
Primiano Tuccidca727d2018-04-04 11:31:55 +0200166 mock_producer_1.reset();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000167 ASSERT_EQ(1u, svc->num_producers());
168 ASSERT_EQ(nullptr, svc->GetProducer(1));
169
Primiano Tuccidca727d2018-04-04 11:31:55 +0200170 mock_producer_2.reset();
171 ASSERT_EQ(nullptr, svc->GetProducer(2));
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000172
173 ASSERT_EQ(0u, svc->num_producers());
174}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100175
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100176TEST_F(TracingServiceImplTest, EnableAndDisableTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200177 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
178 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +0000179
Primiano Tuccidca727d2018-04-04 11:31:55 +0200180 std::unique_ptr<MockProducer> producer = CreateMockProducer();
181 producer->Connect(svc.get(), "mock_producer");
182 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000183
Sami Kyostila06487a22018-02-27 13:48:38 +0000184 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200185 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +0000186 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200187 ds_config->set_name("data_source");
188 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +0000189
Primiano Tuccidca727d2018-04-04 11:31:55 +0200190 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100191 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200192 producer->WaitForDataSourceStart("data_source");
193
Primiano Tucci674076d2018-10-01 10:41:09 +0100194 // Calling StartTracing() should be a noop (% a DLOG statement) because the
195 // trace config didn't have the |deferred_start| flag set.
196 consumer->StartTracing();
197
Primiano Tuccidca727d2018-04-04 11:31:55 +0200198 consumer->DisableTracing();
199 producer->WaitForDataSourceStop("data_source");
200 consumer->WaitForTracingDisabled();
Sami Kyostila06487a22018-02-27 13:48:38 +0000201}
202
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100203TEST_F(TracingServiceImplTest, LockdownMode) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200204 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
205 consumer->Connect(svc.get());
206
207 std::unique_ptr<MockProducer> producer = CreateMockProducer();
208 producer->Connect(svc.get(), "mock_producer_sameuid", geteuid());
209 producer->RegisterDataSource("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +0000210
211 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200212 trace_config.add_buffers()->set_size_kb(128);
213 auto* ds_config = trace_config.add_data_sources()->mutable_config();
214 ds_config->set_name("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +0000215 trace_config.set_lockdown_mode(
216 TraceConfig::LockdownModeOperation::LOCKDOWN_SET);
Primiano Tuccidca727d2018-04-04 11:31:55 +0200217 consumer->EnableTracing(trace_config);
218
219 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100220 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200221 producer->WaitForDataSourceStart("data_source");
222
223 std::unique_ptr<MockProducer> producer_otheruid = CreateMockProducer();
224 auto x = svc->ConnectProducer(producer_otheruid.get(), geteuid() + 1,
225 "mock_producer_ouid");
226 EXPECT_CALL(*producer_otheruid, OnConnect()).Times(0);
Florian Mayer61c55482018-03-06 14:43:54 +0000227 task_runner.RunUntilIdle();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200228 Mock::VerifyAndClearExpectations(producer_otheruid.get());
Florian Mayer61c55482018-03-06 14:43:54 +0000229
Primiano Tuccidca727d2018-04-04 11:31:55 +0200230 consumer->DisableTracing();
231 consumer->FreeBuffers();
232 producer->WaitForDataSourceStop("data_source");
233 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +0000234
235 trace_config.set_lockdown_mode(
236 TraceConfig::LockdownModeOperation::LOCKDOWN_CLEAR);
Primiano Tuccidca727d2018-04-04 11:31:55 +0200237 consumer->EnableTracing(trace_config);
Primiano Tucci674076d2018-10-01 10:41:09 +0100238 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200239 producer->WaitForDataSourceStart("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +0000240
Primiano Tuccidca727d2018-04-04 11:31:55 +0200241 std::unique_ptr<MockProducer> producer_otheruid2 = CreateMockProducer();
242 producer_otheruid->Connect(svc.get(), "mock_producer_ouid2", geteuid() + 1);
Florian Mayer61c55482018-03-06 14:43:54 +0000243
Primiano Tuccidca727d2018-04-04 11:31:55 +0200244 consumer->DisableTracing();
245 producer->WaitForDataSourceStop("data_source");
246 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +0000247}
248
Oystein Eftevaagcb6e4c82019-03-06 15:38:26 -0800249TEST_F(TracingServiceImplTest, ProducerNameFilterChange) {
250 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
251 consumer->Connect(svc.get());
252
253 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
254 producer1->Connect(svc.get(), "mock_producer_1");
255 producer1->RegisterDataSource("data_source");
256
257 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
258 producer2->Connect(svc.get(), "mock_producer_2");
259 producer2->RegisterDataSource("data_source");
260
261 std::unique_ptr<MockProducer> producer3 = CreateMockProducer();
262 producer3->Connect(svc.get(), "mock_producer_3");
263 producer3->RegisterDataSource("data_source");
264 producer3->RegisterDataSource("unused_data_source");
265
266 TraceConfig trace_config;
267 trace_config.add_buffers()->set_size_kb(128);
268 auto* data_source = trace_config.add_data_sources();
269 data_source->mutable_config()->set_name("data_source");
270 *data_source->add_producer_name_filter() = "mock_producer_1";
271
272 // Enable tracing with only mock_producer_1 enabled;
273 // the rest should not start up.
274 consumer->EnableTracing(trace_config);
275
276 producer1->WaitForTracingSetup();
277 producer1->WaitForDataSourceSetup("data_source");
278 producer1->WaitForDataSourceStart("data_source");
279
280 EXPECT_CALL(*producer2, OnConnect()).Times(0);
281 EXPECT_CALL(*producer3, OnConnect()).Times(0);
282 task_runner.RunUntilIdle();
283 Mock::VerifyAndClearExpectations(producer2.get());
284 Mock::VerifyAndClearExpectations(producer3.get());
285
286 // Enable mock_producer_2, the third one should still
287 // not get connected.
288 *data_source->add_producer_name_filter() = "mock_producer_2";
289 consumer->ChangeTraceConfig(trace_config);
290
291 producer2->WaitForTracingSetup();
292 producer2->WaitForDataSourceSetup("data_source");
293 producer2->WaitForDataSourceStart("data_source");
294
295 // Enable mock_producer_3 but also try to do an
296 // unsupported change (adding a new data source);
297 // mock_producer_3 should get enabled but not
298 // for the new data source.
299 *data_source->add_producer_name_filter() = "mock_producer_3";
300 auto* dummy_data_source = trace_config.add_data_sources();
301 dummy_data_source->mutable_config()->set_name("unused_data_source");
302 *dummy_data_source->add_producer_name_filter() = "mock_producer_3";
303
304 consumer->ChangeTraceConfig(trace_config);
305
306 producer3->WaitForTracingSetup();
307 EXPECT_CALL(*producer3, SetupDataSource(_, _)).Times(1);
308 EXPECT_CALL(*producer3, StartDataSource(_, _)).Times(1);
309 task_runner.RunUntilIdle();
310 Mock::VerifyAndClearExpectations(producer3.get());
311
312 consumer->DisableTracing();
313 consumer->FreeBuffers();
314 producer1->WaitForDataSourceStop("data_source");
315 producer2->WaitForDataSourceStop("data_source");
316
317 EXPECT_CALL(*producer3, StopDataSource(_)).Times(1);
318
319 consumer->WaitForTracingDisabled();
320
321 task_runner.RunUntilIdle();
322 Mock::VerifyAndClearExpectations(producer3.get());
323}
324
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100325TEST_F(TracingServiceImplTest, DisconnectConsumerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200326 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
327 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +0000328
Primiano Tuccidca727d2018-04-04 11:31:55 +0200329 std::unique_ptr<MockProducer> producer = CreateMockProducer();
330 producer->Connect(svc.get(), "mock_producer");
331 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000332
Primiano Tuccidca727d2018-04-04 11:31:55 +0200333 TraceConfig trace_config;
334 trace_config.add_buffers()->set_size_kb(128);
335 auto* ds_config = trace_config.add_data_sources()->mutable_config();
336 ds_config->set_name("data_source");
337 consumer->EnableTracing(trace_config);
338
339 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100340 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200341 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000342
343 // Disconnecting the consumer while tracing should trigger data source
344 // teardown.
Primiano Tuccidca727d2018-04-04 11:31:55 +0200345 consumer.reset();
346 producer->WaitForDataSourceStop("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000347}
348
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100349TEST_F(TracingServiceImplTest, ReconnectProducerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200350 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
351 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +0000352
Primiano Tuccidca727d2018-04-04 11:31:55 +0200353 std::unique_ptr<MockProducer> producer = CreateMockProducer();
354 producer->Connect(svc.get(), "mock_producer");
355 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000356
Sami Kyostila06487a22018-02-27 13:48:38 +0000357 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200358 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +0000359 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200360 ds_config->set_name("data_source");
361 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +0000362
Primiano Tuccidca727d2018-04-04 11:31:55 +0200363 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100364 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200365 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000366
Primiano Tuccidca727d2018-04-04 11:31:55 +0200367 // Disconnecting and reconnecting a producer with a matching data source.
368 // The Producer should see that data source getting enabled again.
369 producer.reset();
370 producer = CreateMockProducer();
371 producer->Connect(svc.get(), "mock_producer_2");
372 producer->RegisterDataSource("data_source");
373 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100374 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200375 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000376}
377
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100378TEST_F(TracingServiceImplTest, ProducerIDWrapping) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200379 std::vector<std::unique_ptr<MockProducer>> producers;
380 producers.push_back(nullptr);
Primiano Tucci081d46a2018-02-28 11:09:43 +0000381
Primiano Tuccidca727d2018-04-04 11:31:55 +0200382 auto connect_producer_and_get_id = [&producers,
383 this](const std::string& name) {
384 producers.emplace_back(CreateMockProducer());
385 producers.back()->Connect(svc.get(), "mock_producer_" + name);
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200386 return *last_producer_id();
Primiano Tucci081d46a2018-02-28 11:09:43 +0000387 };
388
389 // Connect producers 1-4.
390 for (ProducerID i = 1; i <= 4; i++)
Primiano Tuccidca727d2018-04-04 11:31:55 +0200391 ASSERT_EQ(i, connect_producer_and_get_id(std::to_string(i)));
Primiano Tucci081d46a2018-02-28 11:09:43 +0000392
393 // Disconnect producers 1,3.
Primiano Tuccidca727d2018-04-04 11:31:55 +0200394 producers[1].reset();
395 producers[3].reset();
Primiano Tucci081d46a2018-02-28 11:09:43 +0000396
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200397 *last_producer_id() = kMaxProducerID - 1;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200398 ASSERT_EQ(kMaxProducerID, connect_producer_and_get_id("maxid"));
399 ASSERT_EQ(1u, connect_producer_and_get_id("1_again"));
400 ASSERT_EQ(3u, connect_producer_and_get_id("3_again"));
401 ASSERT_EQ(5u, connect_producer_and_get_id("5"));
402 ASSERT_EQ(6u, connect_producer_and_get_id("6"));
Primiano Tucci081d46a2018-02-28 11:09:43 +0000403}
404
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000405// Note: file_write_period_ms is set to a large enough to have exactly one flush
406// of the tracing buffers (and therefore at most one synchronization section),
407// unless the test runs unrealistically slowly, or the implementation of the
408// tracing snapshot packets changes.
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100409TEST_F(TracingServiceImplTest, WriteIntoFileAndStopOnMaxSize) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200410 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
411 consumer->Connect(svc.get());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100412
Primiano Tuccidca727d2018-04-04 11:31:55 +0200413 std::unique_ptr<MockProducer> producer = CreateMockProducer();
414 producer->Connect(svc.get(), "mock_producer");
415 producer->RegisterDataSource("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100416
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100417 TraceConfig trace_config;
418 trace_config.add_buffers()->set_size_kb(4096);
419 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200420 ds_config->set_name("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100421 ds_config->set_target_buffer(0);
422 trace_config.set_write_into_file(true);
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000423 trace_config.set_file_write_period_ms(100000); // 100s
424 const uint64_t kMaxFileSize = 1024;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100425 trace_config.set_max_file_size_bytes(kMaxFileSize);
426 base::TempFile tmp_file = base::TempFile::Create();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200427 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
428
429 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100430 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200431 producer->WaitForDataSourceStart("data_source");
432
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000433 static const int kNumPreamblePackets = 4;
434 static const int kNumTestPackets = 10;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200435 static const char kPayload[] = "1234567890abcdef-";
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100436
437 std::unique_ptr<TraceWriter> writer =
Primiano Tuccidca727d2018-04-04 11:31:55 +0200438 producer->CreateTraceWriter("data_source");
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000439 // Tracing service will emit a preamble of packets (a synchronization section,
440 // followed by a tracing config packet). The preamble and these test packets
441 // should fit within kMaxFileSize.
442 for (int i = 0; i < kNumTestPackets; i++) {
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100443 auto tp = writer->NewTracePacket();
444 std::string payload(kPayload);
445 payload.append(std::to_string(i));
446 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
447 }
448
449 // Finally add a packet that overflows kMaxFileSize. This should cause the
450 // implicit stop of the trace and should *not* be written in the trace.
451 {
452 auto tp = writer->NewTracePacket();
453 char big_payload[kMaxFileSize] = "BIG!";
454 tp->set_for_testing()->set_str(big_payload, sizeof(big_payload));
455 }
456 writer->Flush();
457 writer.reset();
458
Primiano Tuccidca727d2018-04-04 11:31:55 +0200459 consumer->DisableTracing();
460 producer->WaitForDataSourceStop("data_source");
461 consumer->WaitForTracingDisabled();
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100462
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));
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000468
469 ASSERT_EQ(trace.packet_size(), kNumPreamblePackets + kNumTestPackets);
470 for (int i = 0; i < kNumTestPackets; i++) {
471 const protos::TracePacket& tp = trace.packet(kNumPreamblePackets + i);
472 ASSERT_EQ(kPayload + std::to_string(i++), tp.for_testing().str());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100473 }
Primiano Tuccidca727d2018-04-04 11:31:55 +0200474}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100475
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200476// Test the logic that allows the trace config to set the shm total size and
477// page size from the trace config. Also check that, if the config doesn't
478// specify a value we fall back on the hint provided by the producer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100479TEST_F(TracingServiceImplTest, ProducerShmAndPageSizeOverriddenByTraceConfig) {
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200480 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
481 consumer->Connect(svc.get());
482 const size_t kConfigPageSizesKb[] = /****/ {16, 16, 4, 0, 16, 8, 3, 4096, 4};
483 const size_t kExpectedPageSizesKb[] = /**/ {16, 16, 4, 4, 16, 8, 4, 64, 4};
484
485 const size_t kConfigSizesKb[] = /**/ {0, 16, 0, 20, 32, 7, 0, 96, 4096000};
486 const size_t kHintSizesKb[] = /****/ {0, 0, 16, 32, 16, 0, 7, 96, 4096000};
487 const size_t kExpectedSizesKb[] = {
488 kDefaultShmSizeKb, // Both hint and config are 0, use default.
489 16, // Hint is 0, use config.
490 16, // Config is 0, use hint.
491 20, // Hint is takes precedence over the config.
492 32, // Ditto, even if config is higher than hint.
493 kDefaultShmSizeKb, // Config is invalid and hint is 0, use default.
494 kDefaultShmSizeKb, // Config is 0 and hint is invalid, use default.
495 kDefaultShmSizeKb, // 96 KB isn't a multiple of the page size (64 KB).
496 kMaxShmSizeKb // Too big, cap at kMaxShmSize.
497 };
498
499 const size_t kNumProducers = base::ArraySize(kHintSizesKb);
500 std::unique_ptr<MockProducer> producer[kNumProducers];
501 for (size_t i = 0; i < kNumProducers; i++) {
502 auto name = "mock_producer_" + std::to_string(i);
503 producer[i] = CreateMockProducer();
504 producer[i]->Connect(svc.get(), name, geteuid(), kHintSizesKb[i] * 1024);
505 producer[i]->RegisterDataSource("data_source");
506 }
507
508 TraceConfig trace_config;
509 trace_config.add_buffers()->set_size_kb(128);
510 auto* ds_config = trace_config.add_data_sources()->mutable_config();
511 ds_config->set_name("data_source");
512 for (size_t i = 0; i < kNumProducers; i++) {
513 auto* producer_config = trace_config.add_producers();
514 producer_config->set_producer_name("mock_producer_" + std::to_string(i));
Primiano Tucci3cbb10a2018-04-10 17:52:40 +0100515 producer_config->set_shm_size_kb(static_cast<uint32_t>(kConfigSizesKb[i]));
516 producer_config->set_page_size_kb(
517 static_cast<uint32_t>(kConfigPageSizesKb[i]));
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200518 }
519
520 consumer->EnableTracing(trace_config);
521 size_t actual_shm_sizes_kb[kNumProducers]{};
522 size_t actual_page_sizes_kb[kNumProducers]{};
523 for (size_t i = 0; i < kNumProducers; i++) {
524 producer[i]->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100525 producer[i]->WaitForDataSourceSetup("data_source");
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200526 actual_shm_sizes_kb[i] =
527 producer[i]->endpoint()->shared_memory()->size() / 1024;
528 actual_page_sizes_kb[i] =
529 producer[i]->endpoint()->shared_buffer_page_size_kb();
530 }
Primiano Tucci674076d2018-10-01 10:41:09 +0100531 for (size_t i = 0; i < kNumProducers; i++) {
532 producer[i]->WaitForDataSourceStart("data_source");
533 }
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200534 ASSERT_THAT(actual_page_sizes_kb, ElementsAreArray(kExpectedPageSizesKb));
535 ASSERT_THAT(actual_shm_sizes_kb, ElementsAreArray(kExpectedSizesKb));
536}
537
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100538TEST_F(TracingServiceImplTest, ExplicitFlush) {
Primiano Tuccid52e6272018-04-06 19:06:53 +0200539 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
540 consumer->Connect(svc.get());
541
542 std::unique_ptr<MockProducer> producer = CreateMockProducer();
543 producer->Connect(svc.get(), "mock_producer");
544 producer->RegisterDataSource("data_source");
545
546 TraceConfig trace_config;
547 trace_config.add_buffers()->set_size_kb(128);
548 auto* ds_config = trace_config.add_data_sources()->mutable_config();
549 ds_config->set_name("data_source");
550
551 consumer->EnableTracing(trace_config);
552 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100553 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +0200554 producer->WaitForDataSourceStart("data_source");
555
556 std::unique_ptr<TraceWriter> writer =
557 producer->CreateTraceWriter("data_source");
558 {
559 auto tp = writer->NewTracePacket();
560 tp->set_for_testing()->set_str("payload");
561 }
562
563 auto flush_request = consumer->Flush();
564 producer->WaitForFlush(writer.get());
565 ASSERT_TRUE(flush_request.WaitForReply());
566
567 consumer->DisableTracing();
568 producer->WaitForDataSourceStop("data_source");
569 consumer->WaitForTracingDisabled();
570 EXPECT_THAT(
571 consumer->ReadBuffers(),
572 Contains(Property(&protos::TracePacket::for_testing,
573 Property(&protos::TestEvent::str, Eq("payload")))));
574}
575
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100576TEST_F(TracingServiceImplTest, ImplicitFlushOnTimedTraces) {
Primiano Tuccid52e6272018-04-06 19:06:53 +0200577 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
578 consumer->Connect(svc.get());
579
580 std::unique_ptr<MockProducer> producer = CreateMockProducer();
581 producer->Connect(svc.get(), "mock_producer");
582 producer->RegisterDataSource("data_source");
583
584 TraceConfig trace_config;
585 trace_config.add_buffers()->set_size_kb(128);
586 auto* ds_config = trace_config.add_data_sources()->mutable_config();
587 ds_config->set_name("data_source");
588 trace_config.set_duration_ms(1);
589
590 consumer->EnableTracing(trace_config);
591 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100592 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +0200593 producer->WaitForDataSourceStart("data_source");
594
595 std::unique_ptr<TraceWriter> writer =
596 producer->CreateTraceWriter("data_source");
597 {
598 auto tp = writer->NewTracePacket();
599 tp->set_for_testing()->set_str("payload");
600 }
601
602 producer->WaitForFlush(writer.get());
603
604 producer->WaitForDataSourceStop("data_source");
605 consumer->WaitForTracingDisabled();
606
607 EXPECT_THAT(
608 consumer->ReadBuffers(),
609 Contains(Property(&protos::TracePacket::for_testing,
610 Property(&protos::TestEvent::str, Eq("payload")))));
611}
612
613// Tests the monotonic semantic of flush request IDs, i.e., once a producer
614// acks flush request N, all flush requests <= N are considered successful and
615// acked to the consumer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100616TEST_F(TracingServiceImplTest, BatchFlushes) {
Primiano Tuccid52e6272018-04-06 19:06:53 +0200617 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
618 consumer->Connect(svc.get());
619
620 std::unique_ptr<MockProducer> producer = CreateMockProducer();
621 producer->Connect(svc.get(), "mock_producer");
622 producer->RegisterDataSource("data_source");
623
624 TraceConfig trace_config;
625 trace_config.add_buffers()->set_size_kb(128);
626 auto* ds_config = trace_config.add_data_sources()->mutable_config();
627 ds_config->set_name("data_source");
628
629 consumer->EnableTracing(trace_config);
630 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100631 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +0200632 producer->WaitForDataSourceStart("data_source");
633
634 std::unique_ptr<TraceWriter> writer =
635 producer->CreateTraceWriter("data_source");
636 {
637 auto tp = writer->NewTracePacket();
638 tp->set_for_testing()->set_str("payload");
639 }
640
641 auto flush_req_1 = consumer->Flush();
642 auto flush_req_2 = consumer->Flush();
643 auto flush_req_3 = consumer->Flush();
644
645 // We'll deliberately let the 4th flush request timeout. Use a lower timeout
646 // to keep test time short.
647 auto flush_req_4 = consumer->Flush(/*timeout_ms=*/10);
648 ASSERT_EQ(4u, GetNumPendingFlushes());
649
650 // Make the producer reply only to the 3rd flush request.
651 testing::InSequence seq;
Eric Secklera01e28a2019-01-08 11:21:04 +0000652 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 1.
653 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 2.
654 producer->WaitForFlush(writer.get()); // Reply only to flush 3.
655 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 4.
Primiano Tuccid52e6272018-04-06 19:06:53 +0200656
657 // Even if the producer explicily replied only to flush ID == 3, all the
658 // previous flushed < 3 should be implicitly acked.
659 ASSERT_TRUE(flush_req_1.WaitForReply());
660 ASSERT_TRUE(flush_req_2.WaitForReply());
661 ASSERT_TRUE(flush_req_3.WaitForReply());
662
663 // At this point flush id == 4 should still be pending and should fail because
664 // of reaching its timeout.
Primiano Tuccid52e6272018-04-06 19:06:53 +0200665 ASSERT_FALSE(flush_req_4.WaitForReply());
666
667 consumer->DisableTracing();
668 producer->WaitForDataSourceStop("data_source");
669 consumer->WaitForTracingDisabled();
670 EXPECT_THAT(
671 consumer->ReadBuffers(),
672 Contains(Property(&protos::TracePacket::for_testing,
673 Property(&protos::TestEvent::str, Eq("payload")))));
674}
675
Primiano Tuccicaa57802018-11-25 11:07:07 +0000676TEST_F(TracingServiceImplTest, PeriodicFlush) {
677 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
678 consumer->Connect(svc.get());
679
680 std::unique_ptr<MockProducer> producer = CreateMockProducer();
681 producer->Connect(svc.get(), "mock_producer");
682 producer->RegisterDataSource("data_source");
683
684 TraceConfig trace_config;
685 trace_config.add_buffers()->set_size_kb(128);
686 trace_config.set_flush_period_ms(1);
687 auto* ds_config = trace_config.add_data_sources()->mutable_config();
688 ds_config->set_name("data_source");
689
690 consumer->EnableTracing(trace_config);
691 producer->WaitForTracingSetup();
692 producer->WaitForDataSourceSetup("data_source");
693 producer->WaitForDataSourceStart("data_source");
694
695 std::unique_ptr<TraceWriter> writer =
696 producer->CreateTraceWriter("data_source");
697
698 const int kNumFlushes = 3;
699 auto checkpoint = task_runner.CreateCheckpoint("all_flushes_done");
700 int flushes_seen = 0;
701 EXPECT_CALL(*producer, Flush(_, _, _))
702 .WillRepeatedly(Invoke([&producer, &writer, &flushes_seen, checkpoint](
703 FlushRequestID flush_req_id,
704 const DataSourceInstanceID*, size_t) {
705 {
706 auto tp = writer->NewTracePacket();
707 char payload[32];
708 sprintf(payload, "f_%d", flushes_seen);
709 tp->set_for_testing()->set_str(payload);
710 }
711 writer->Flush();
712 producer->endpoint()->NotifyFlushComplete(flush_req_id);
713 if (++flushes_seen == kNumFlushes)
714 checkpoint();
715 }));
716 task_runner.RunUntilCheckpoint("all_flushes_done");
717
718 consumer->DisableTracing();
719 producer->WaitForDataSourceStop("data_source");
720 consumer->WaitForTracingDisabled();
721 auto trace_packets = consumer->ReadBuffers();
722 for (int i = 0; i < kNumFlushes; i++) {
723 EXPECT_THAT(trace_packets,
724 Contains(Property(&protos::TracePacket::for_testing,
725 Property(&protos::TestEvent::str,
726 Eq("f_" + std::to_string(i))))));
727 }
728}
729
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100730// Creates a tracing session where some of the data sources set the
731// |will_notify_on_stop| flag and checks that the OnTracingDisabled notification
732// to the consumer is delayed until the acks are received.
733TEST_F(TracingServiceImplTest, OnTracingDisabledWaitsForDataSourceStopAcks) {
734 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
735 consumer->Connect(svc.get());
736
737 std::unique_ptr<MockProducer> producer = CreateMockProducer();
738 producer->Connect(svc.get(), "mock_producer");
739 producer->RegisterDataSource("ds_will_ack_1", /*ack_stop=*/true);
740 producer->RegisterDataSource("ds_wont_ack");
741 producer->RegisterDataSource("ds_will_ack_2", /*ack_stop=*/true);
742
743 TraceConfig trace_config;
744 trace_config.add_buffers()->set_size_kb(128);
745 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_1");
746 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
747 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_2");
748 trace_config.set_duration_ms(1);
749
750 consumer->EnableTracing(trace_config);
751 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100752
753 producer->WaitForDataSourceSetup("ds_will_ack_1");
754 producer->WaitForDataSourceSetup("ds_wont_ack");
755 producer->WaitForDataSourceSetup("ds_will_ack_2");
756
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100757 producer->WaitForDataSourceStart("ds_will_ack_1");
758 producer->WaitForDataSourceStart("ds_wont_ack");
759 producer->WaitForDataSourceStart("ds_will_ack_2");
760
761 std::unique_ptr<TraceWriter> writer =
762 producer->CreateTraceWriter("ds_wont_ack");
763 producer->WaitForFlush(writer.get());
764
765 DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_will_ack_1");
766 DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_will_ack_2");
767
768 producer->WaitForDataSourceStop("ds_will_ack_1");
769 producer->WaitForDataSourceStop("ds_wont_ack");
770 producer->WaitForDataSourceStop("ds_will_ack_2");
771
772 producer->endpoint()->NotifyDataSourceStopped(id1);
773 producer->endpoint()->NotifyDataSourceStopped(id2);
774
775 // Wait for at most half of the service timeout, so that this test fails if
776 // the service falls back on calling the OnTracingDisabled() because some of
777 // the expected acks weren't received.
778 consumer->WaitForTracingDisabled(
779 TracingServiceImpl::kDataSourceStopTimeoutMs / 2);
780}
781
Oystein Eftevaagf250e1c2018-08-23 16:10:52 -0700782// Creates a tracing session where a second data source
783// is added while the service is waiting for DisableTracing
784// acks; the service should not enable the new datasource
785// and should not hit any asserts when the consumer is
786// subsequently destroyed.
787TEST_F(TracingServiceImplTest, OnDataSourceAddedWhilePendingDisableAcks) {
788 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
789 consumer->Connect(svc.get());
790
791 std::unique_ptr<MockProducer> producer = CreateMockProducer();
792 producer->Connect(svc.get(), "mock_producer");
793 producer->RegisterDataSource("ds_will_ack", /*ack_stop=*/true);
794
795 TraceConfig trace_config;
796 trace_config.add_buffers()->set_size_kb(128);
797 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack");
798 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
799
800 consumer->EnableTracing(trace_config);
801 producer->WaitForTracingSetup();
802
803 consumer->DisableTracing();
804
805 producer->RegisterDataSource("ds_wont_ack");
806
807 consumer.reset();
808}
809
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100810// Similar to OnTracingDisabledWaitsForDataSourceStopAcks, but deliberately
811// skips the ack and checks that the service invokes the OnTracingDisabled()
812// after the timeout.
813TEST_F(TracingServiceImplTest, OnTracingDisabledCalledAnywaysInCaseOfTimeout) {
814 svc->override_data_source_test_timeout_ms_for_testing = 1;
815 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
816 consumer->Connect(svc.get());
817
818 std::unique_ptr<MockProducer> producer = CreateMockProducer();
819 producer->Connect(svc.get(), "mock_producer");
820 producer->RegisterDataSource("data_source", /*ack_stop=*/true);
821
822 TraceConfig trace_config;
823 trace_config.add_buffers()->set_size_kb(128);
824 trace_config.add_data_sources()->mutable_config()->set_name("data_source");
825 trace_config.set_duration_ms(1);
826
827 consumer->EnableTracing(trace_config);
828 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100829 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100830 producer->WaitForDataSourceStart("data_source");
831
832 std::unique_ptr<TraceWriter> writer =
833 producer->CreateTraceWriter("data_source");
834 producer->WaitForFlush(writer.get());
835
836 producer->WaitForDataSourceStop("data_source");
837 consumer->WaitForTracingDisabled();
838}
839
Primiano Tucci03de28f2018-08-01 11:29:46 +0100840// Tests the session_id logic. Two data sources in the same tracing session
841// should see the same session id.
842TEST_F(TracingServiceImplTest, SessionId) {
843 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
844 consumer->Connect(svc.get());
845
846 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
847 producer1->Connect(svc.get(), "mock_producer1");
848 producer1->RegisterDataSource("ds_1A");
849 producer1->RegisterDataSource("ds_1B");
850
851 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
852 producer2->Connect(svc.get(), "mock_producer2");
853 producer2->RegisterDataSource("ds_2A");
854
855 testing::InSequence seq;
856 TracingSessionID last_session_id = 0;
857 for (int i = 0; i < 3; i++) {
858 TraceConfig trace_config;
859 trace_config.add_buffers()->set_size_kb(128);
860 trace_config.add_data_sources()->mutable_config()->set_name("ds_1A");
861 trace_config.add_data_sources()->mutable_config()->set_name("ds_1B");
862 trace_config.add_data_sources()->mutable_config()->set_name("ds_2A");
863 trace_config.set_duration_ms(1);
864
865 consumer->EnableTracing(trace_config);
866
867 if (i == 0)
868 producer1->WaitForTracingSetup();
Primiano Tucci03de28f2018-08-01 11:29:46 +0100869
Primiano Tucci674076d2018-10-01 10:41:09 +0100870 producer1->WaitForDataSourceSetup("ds_1A");
871 producer1->WaitForDataSourceSetup("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +0100872 if (i == 0)
873 producer2->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100874 producer2->WaitForDataSourceSetup("ds_2A");
875
876 producer1->WaitForDataSourceStart("ds_1A");
877 producer1->WaitForDataSourceStart("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +0100878 producer2->WaitForDataSourceStart("ds_2A");
879
880 auto* ds1 = producer1->GetDataSourceInstance("ds_1A");
881 auto* ds2 = producer1->GetDataSourceInstance("ds_1B");
882 auto* ds3 = producer2->GetDataSourceInstance("ds_2A");
883 ASSERT_EQ(ds1->session_id, ds2->session_id);
884 ASSERT_EQ(ds1->session_id, ds3->session_id);
885 ASSERT_NE(ds1->session_id, last_session_id);
886 last_session_id = ds1->session_id;
887
888 auto writer1 = producer1->CreateTraceWriter("ds_1A");
889 producer1->WaitForFlush(writer1.get());
890
891 auto writer2 = producer2->CreateTraceWriter("ds_2A");
892 producer2->WaitForFlush(writer2.get());
893
894 producer1->WaitForDataSourceStop("ds_1A");
895 producer1->WaitForDataSourceStop("ds_1B");
896 producer2->WaitForDataSourceStop("ds_2A");
897 consumer->WaitForTracingDisabled();
898 consumer->FreeBuffers();
899 }
900}
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100901
902// Writes a long trace and then tests that the trace parsed in partitions
903// derived by the synchronization markers is identical to the whole trace parsed
904// in one go.
905TEST_F(TracingServiceImplTest, ResynchronizeTraceStreamUsingSyncMarker) {
906 // Setup tracing.
907 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
908 consumer->Connect(svc.get());
909 std::unique_ptr<MockProducer> producer = CreateMockProducer();
910 producer->Connect(svc.get(), "mock_producer");
911 producer->RegisterDataSource("data_source");
912 TraceConfig trace_config;
913 trace_config.add_buffers()->set_size_kb(4096);
914 auto* ds_config = trace_config.add_data_sources()->mutable_config();
915 ds_config->set_name("data_source");
916 trace_config.set_write_into_file(true);
917 trace_config.set_file_write_period_ms(1);
918 base::TempFile tmp_file = base::TempFile::Create();
919 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
920 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100921 producer->WaitForDataSourceSetup("data_source");
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100922 producer->WaitForDataSourceStart("data_source");
923
924 // Write some variable length payload, waiting for sync markers every now
925 // and then.
926 const int kNumMarkers = 5;
927 auto writer = producer->CreateTraceWriter("data_source");
928 for (int i = 1; i <= 100; i++) {
Florian Mayereff98042018-12-10 17:44:44 +0000929 std::string payload(static_cast<size_t>(i), 'A' + (i % 25));
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100930 writer->NewTracePacket()->set_for_testing()->set_str(payload.c_str());
931 if (i % (100 / kNumMarkers) == 0) {
932 writer->Flush();
933 WaitForNextSyncMarker();
934 }
935 }
936 writer->Flush();
937 writer.reset();
938 consumer->DisableTracing();
939 producer->WaitForDataSourceStop("data_source");
940 consumer->WaitForTracingDisabled();
941
942 std::string trace_raw;
943 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
944
945 const auto kMarkerSize = sizeof(TracingServiceImpl::kSyncMarker);
946 const std::string kSyncMarkerStr(
947 reinterpret_cast<const char*>(TracingServiceImpl::kSyncMarker),
948 kMarkerSize);
949
950 // Read back the trace in partitions derived from the marker.
951 // The trace should look like this:
952 // [uid, marker] [event] [event] [uid, marker] [event] [event]
953 size_t num_markers = 0;
954 size_t start = 0;
955 size_t end = 0;
956 protos::Trace merged_trace;
957 for (size_t pos = 0; pos != std::string::npos; start = end) {
958 pos = trace_raw.find(kSyncMarkerStr, pos + 1);
959 num_markers++;
960 end = (pos == std::string::npos) ? trace_raw.size() : pos + kMarkerSize;
961 int size = static_cast<int>(end - start);
962 ASSERT_GT(size, 0);
963 protos::Trace trace_partition;
964 ASSERT_TRUE(trace_partition.ParseFromArray(trace_raw.data() + start, size));
965 merged_trace.MergeFrom(trace_partition);
966 }
Lalit Maganti9bdc7ce2018-09-17 15:25:11 +0100967 EXPECT_GE(num_markers, static_cast<size_t>(kNumMarkers));
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100968
969 protos::Trace whole_trace;
970 ASSERT_TRUE(whole_trace.ParseFromString(trace_raw));
971
972 ASSERT_EQ(whole_trace.packet_size(), merged_trace.packet_size());
973 EXPECT_EQ(whole_trace.SerializeAsString(), merged_trace.SerializeAsString());
974}
975
Primiano Tucci674076d2018-10-01 10:41:09 +0100976// Creates a tracing session with |deferred_start| and checks that data sources
977// are started only after calling StartTracing().
978TEST_F(TracingServiceImplTest, DeferredStart) {
979 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
980 consumer->Connect(svc.get());
981
982 std::unique_ptr<MockProducer> producer = CreateMockProducer();
983 producer->Connect(svc.get(), "mock_producer");
984
985 // Create two data sources but enable only one of them.
986 producer->RegisterDataSource("ds_1");
987 producer->RegisterDataSource("ds_2");
988
989 TraceConfig trace_config;
990 trace_config.add_buffers()->set_size_kb(128);
991 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
992 trace_config.set_deferred_start(true);
993 trace_config.set_duration_ms(1);
994
995 consumer->EnableTracing(trace_config);
996 producer->WaitForTracingSetup();
997
998 producer->WaitForDataSourceSetup("ds_1");
999
1000 // Make sure we don't get unexpected DataSourceStart() notifications yet.
1001 task_runner.RunUntilIdle();
1002
1003 consumer->StartTracing();
1004
1005 producer->WaitForDataSourceStart("ds_1");
1006
1007 auto writer1 = producer->CreateTraceWriter("ds_1");
1008 producer->WaitForFlush(writer1.get());
1009
1010 producer->WaitForDataSourceStop("ds_1");
1011 consumer->WaitForTracingDisabled();
1012}
1013
Eric Secklerd0ac7ca2019-02-06 09:13:45 +00001014TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
1015 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1016 consumer->Connect(svc.get());
1017
1018 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1019 producer1->Connect(svc.get(), "mock_producer1", 123u /* uid */);
1020 producer1->RegisterDataSource("data_source");
1021
1022 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1023 producer2->Connect(svc.get(), "mock_producer2", 456u /* uid */);
1024 producer2->RegisterDataSource("data_source");
1025
1026 TraceConfig trace_config;
1027 trace_config.add_buffers()->set_size_kb(128);
1028 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1029 ds_config->set_name("data_source");
1030
1031 consumer->EnableTracing(trace_config);
1032 producer1->WaitForTracingSetup();
1033 producer1->WaitForDataSourceSetup("data_source");
1034 producer2->WaitForTracingSetup();
1035 producer2->WaitForDataSourceSetup("data_source");
1036 producer1->WaitForDataSourceStart("data_source");
1037 producer2->WaitForDataSourceStart("data_source");
1038
1039 std::unique_ptr<TraceWriter> writer1a =
1040 producer1->CreateTraceWriter("data_source");
1041 std::unique_ptr<TraceWriter> writer1b =
1042 producer1->CreateTraceWriter("data_source");
1043 std::unique_ptr<TraceWriter> writer2a =
1044 producer2->CreateTraceWriter("data_source");
1045 {
1046 auto tp = writer1a->NewTracePacket();
1047 tp->set_for_testing()->set_str("payload1a1");
1048 tp = writer1b->NewTracePacket();
1049 tp->set_for_testing()->set_str("payload1b1");
1050 tp = writer1a->NewTracePacket();
1051 tp->set_for_testing()->set_str("payload1a2");
1052 tp = writer2a->NewTracePacket();
1053 tp->set_for_testing()->set_str("payload2a1");
1054 tp = writer1b->NewTracePacket();
1055 tp->set_for_testing()->set_str("payload1b2");
1056 }
1057
1058 auto flush_request = consumer->Flush();
1059 producer1->WaitForFlush({writer1a.get(), writer1b.get()});
1060 producer2->WaitForFlush(writer2a.get());
1061 ASSERT_TRUE(flush_request.WaitForReply());
1062
1063 consumer->DisableTracing();
1064 producer1->WaitForDataSourceStop("data_source");
1065 producer2->WaitForDataSourceStop("data_source");
1066 consumer->WaitForTracingDisabled();
1067 auto packets = consumer->ReadBuffers();
1068 EXPECT_THAT(
1069 packets,
1070 Contains(AllOf(
1071 Property(&protos::TracePacket::for_testing,
1072 Property(&protos::TestEvent::str, Eq("payload1a1"))),
1073 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1074 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
1075 EXPECT_THAT(
1076 packets,
1077 Contains(AllOf(
1078 Property(&protos::TracePacket::for_testing,
1079 Property(&protos::TestEvent::str, Eq("payload1a2"))),
1080 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1081 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
1082 EXPECT_THAT(
1083 packets,
1084 Contains(AllOf(
1085 Property(&protos::TracePacket::for_testing,
1086 Property(&protos::TestEvent::str, Eq("payload1b1"))),
1087 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1088 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
1089 EXPECT_THAT(
1090 packets,
1091 Contains(AllOf(
1092 Property(&protos::TracePacket::for_testing,
1093 Property(&protos::TestEvent::str, Eq("payload1b2"))),
1094 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1095 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
1096 EXPECT_THAT(
1097 packets,
1098 Contains(AllOf(
1099 Property(&protos::TracePacket::for_testing,
1100 Property(&protos::TestEvent::str, Eq("payload2a1"))),
1101 Property(&protos::TracePacket::trusted_uid, Eq(456)),
1102 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(4u)))));
1103}
1104
Eric Seckler6dc23592018-11-30 10:59:06 +00001105TEST_F(TracingServiceImplTest, AllowedBuffers) {
1106 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1107 consumer->Connect(svc.get());
1108
1109 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1110 producer1->Connect(svc.get(), "mock_producer1");
1111 ProducerID producer1_id = *last_producer_id();
1112 producer1->RegisterDataSource("data_source1");
1113 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1114 producer2->Connect(svc.get(), "mock_producer2");
1115 ProducerID producer2_id = *last_producer_id();
1116 producer2->RegisterDataSource("data_source2.1");
1117 producer2->RegisterDataSource("data_source2.2");
1118 producer2->RegisterDataSource("data_source2.3");
1119
1120 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
1121 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
1122
1123 TraceConfig trace_config;
1124 trace_config.add_buffers()->set_size_kb(128);
1125 trace_config.add_buffers()->set_size_kb(128);
1126 trace_config.add_buffers()->set_size_kb(128);
1127 auto* ds_config1 = trace_config.add_data_sources()->mutable_config();
1128 ds_config1->set_name("data_source1");
1129 ds_config1->set_target_buffer(0);
1130 auto* ds_config21 = trace_config.add_data_sources()->mutable_config();
1131 ds_config21->set_name("data_source2.1");
1132 ds_config21->set_target_buffer(1);
1133 auto* ds_config22 = trace_config.add_data_sources()->mutable_config();
1134 ds_config22->set_name("data_source2.2");
1135 ds_config22->set_target_buffer(2);
1136 auto* ds_config23 = trace_config.add_data_sources()->mutable_config();
1137 ds_config23->set_name("data_source2.3");
1138 ds_config23->set_target_buffer(2); // same buffer as data_source2.2.
1139 consumer->EnableTracing(trace_config);
1140
Primiano Tucci2abd1152018-12-03 17:00:02 +01001141 ASSERT_EQ(3u, tracing_session()->num_buffers());
Eric Seckler6dc23592018-11-30 10:59:06 +00001142 std::set<BufferID> expected_buffers_producer1 = {
1143 tracing_session()->buffers_index[0]};
1144 std::set<BufferID> expected_buffers_producer2 = {
1145 tracing_session()->buffers_index[1], tracing_session()->buffers_index[2]};
1146 EXPECT_EQ(expected_buffers_producer1, GetAllowedTargetBuffers(producer1_id));
1147 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
1148
1149 producer1->WaitForTracingSetup();
1150 producer1->WaitForDataSourceSetup("data_source1");
1151
1152 producer2->WaitForTracingSetup();
1153 producer2->WaitForDataSourceSetup("data_source2.1");
1154 producer2->WaitForDataSourceSetup("data_source2.2");
1155 producer2->WaitForDataSourceSetup("data_source2.3");
1156
1157 producer1->WaitForDataSourceStart("data_source1");
1158 producer2->WaitForDataSourceStart("data_source2.1");
1159 producer2->WaitForDataSourceStart("data_source2.2");
1160 producer2->WaitForDataSourceStart("data_source2.3");
1161
1162 producer2->UnregisterDataSource("data_source2.3");
1163 producer2->WaitForDataSourceStop("data_source2.3");
1164
1165 // Should still be allowed to write to buffers 1 (data_source2.1) and 2
1166 // (data_source2.2).
1167 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
1168
1169 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1170 // trace config didn't have the |deferred_start| flag set.
1171 consumer->StartTracing();
1172
1173 consumer->DisableTracing();
1174 producer1->WaitForDataSourceStop("data_source1");
1175 producer2->WaitForDataSourceStop("data_source2.1");
1176 producer2->WaitForDataSourceStop("data_source2.2");
1177 consumer->WaitForTracingDisabled();
1178
1179 consumer->FreeBuffers();
1180 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
1181 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
1182}
1183
Eric Seckler6aa9ece2018-12-06 16:40:12 +00001184#if !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00001185TEST_F(TracingServiceImplTest, CommitToForbiddenBufferIsDiscarded) {
1186 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1187 consumer->Connect(svc.get());
1188
1189 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1190 producer->Connect(svc.get(), "mock_producer");
1191 ProducerID producer_id = *last_producer_id();
1192 producer->RegisterDataSource("data_source");
1193
1194 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
1195
1196 TraceConfig trace_config;
1197 trace_config.add_buffers()->set_size_kb(128);
1198 trace_config.add_buffers()->set_size_kb(128);
1199 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1200 ds_config->set_name("data_source");
1201 ds_config->set_target_buffer(0);
1202 consumer->EnableTracing(trace_config);
1203
1204 ASSERT_EQ(2u, tracing_session()->num_buffers());
1205 std::set<BufferID> expected_buffers = {tracing_session()->buffers_index[0]};
1206 EXPECT_EQ(expected_buffers, GetAllowedTargetBuffers(producer_id));
1207
1208 producer->WaitForTracingSetup();
1209 producer->WaitForDataSourceSetup("data_source");
1210 producer->WaitForDataSourceStart("data_source");
1211
1212 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1213 // trace config didn't have the |deferred_start| flag set.
1214 consumer->StartTracing();
1215
1216 // Try to write to the correct buffer.
1217 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1218 tracing_session()->buffers_index[0]);
1219 {
1220 auto tp = writer->NewTracePacket();
1221 tp->set_for_testing()->set_str("good_payload");
1222 }
1223
1224 auto flush_request = consumer->Flush();
1225 producer->WaitForFlush(writer.get());
1226 ASSERT_TRUE(flush_request.WaitForReply());
1227
1228 // Try to write to the wrong buffer.
1229 writer = producer->endpoint()->CreateTraceWriter(
1230 tracing_session()->buffers_index[1]);
1231 {
1232 auto tp = writer->NewTracePacket();
1233 tp->set_for_testing()->set_str("bad_payload");
1234 }
1235
1236 flush_request = consumer->Flush();
1237 producer->WaitForFlush(writer.get());
1238 ASSERT_TRUE(flush_request.WaitForReply());
1239
1240 consumer->DisableTracing();
1241 producer->WaitForDataSourceStop("data_source");
1242 consumer->WaitForTracingDisabled();
1243
1244 auto packets = consumer->ReadBuffers();
1245 EXPECT_THAT(packets, Contains(Property(&protos::TracePacket::for_testing,
1246 Property(&protos::TestEvent::str,
1247 Eq("good_payload")))));
1248 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1249 Property(&protos::TestEvent::str,
1250 Eq("bad_payload"))))));
1251
1252 consumer->FreeBuffers();
1253 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
1254}
Eric Seckler6aa9ece2018-12-06 16:40:12 +00001255#endif // !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00001256
Eric Secklerf3f524b2018-12-13 09:09:34 +00001257TEST_F(TracingServiceImplTest, RegisterAndUnregisterTraceWriter) {
1258 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1259 consumer->Connect(svc.get());
1260
1261 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1262 producer->Connect(svc.get(), "mock_producer");
1263 ProducerID producer_id = *last_producer_id();
1264 producer->RegisterDataSource("data_source");
1265
1266 EXPECT_TRUE(GetWriters(producer_id).empty());
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 ds_config->set_target_buffer(0);
1273 consumer->EnableTracing(trace_config);
1274
1275 producer->WaitForTracingSetup();
1276 producer->WaitForDataSourceSetup("data_source");
1277 producer->WaitForDataSourceStart("data_source");
1278
1279 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1280 // trace config didn't have the |deferred_start| flag set.
1281 consumer->StartTracing();
1282
1283 // Creating the trace writer should register it with the service.
1284 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1285 tracing_session()->buffers_index[0]);
1286
1287 WaitForTraceWritersChanged(producer_id);
1288
1289 std::map<WriterID, BufferID> expected_writers;
1290 expected_writers[writer->writer_id()] = tracing_session()->buffers_index[0];
1291 EXPECT_EQ(expected_writers, GetWriters(producer_id));
1292
1293 // Verify writing works.
1294 {
1295 auto tp = writer->NewTracePacket();
1296 tp->set_for_testing()->set_str("payload");
1297 }
1298
1299 auto flush_request = consumer->Flush();
1300 producer->WaitForFlush(writer.get());
1301 ASSERT_TRUE(flush_request.WaitForReply());
1302
1303 // Destroying the writer should unregister it.
1304 writer.reset();
1305 WaitForTraceWritersChanged(producer_id);
1306 EXPECT_TRUE(GetWriters(producer_id).empty());
1307
1308 consumer->DisableTracing();
1309 producer->WaitForDataSourceStop("data_source");
1310 consumer->WaitForTracingDisabled();
1311
1312 auto packets = consumer->ReadBuffers();
1313 EXPECT_THAT(packets, Contains(Property(
1314 &protos::TracePacket::for_testing,
1315 Property(&protos::TestEvent::str, Eq("payload")))));
1316}
1317
Eric Secklera01e28a2019-01-08 11:21:04 +00001318TEST_F(TracingServiceImplTest, ScrapeBuffersOnFlush) {
1319 svc->SetSMBScrapingEnabled(true);
1320
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 ProducerID producer_id = *last_producer_id();
1327 producer->RegisterDataSource("data_source");
1328
1329 TraceConfig trace_config;
1330 trace_config.add_buffers()->set_size_kb(128);
1331 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1332 ds_config->set_name("data_source");
1333 ds_config->set_target_buffer(0);
1334 consumer->EnableTracing(trace_config);
1335
1336 producer->WaitForTracingSetup();
1337 producer->WaitForDataSourceSetup("data_source");
1338 producer->WaitForDataSourceStart("data_source");
1339
1340 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1341 // trace config didn't have the |deferred_start| flag set.
1342 consumer->StartTracing();
1343
1344 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1345 tracing_session()->buffers_index[0]);
1346 WaitForTraceWritersChanged(producer_id);
1347
1348 // Write a few trace packets.
1349 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
1350 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
1351 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
1352
1353 // Flush but don't actually flush the chunk from TraceWriter.
1354 auto flush_request = consumer->Flush();
1355 producer->WaitForFlush(nullptr, /*reply=*/true);
1356 ASSERT_TRUE(flush_request.WaitForReply());
1357
1358 // Chunk with the packets should have been scraped. The service can't know
1359 // whether the last packet was completed, so shouldn't read it.
1360 auto packets = consumer->ReadBuffers();
1361 EXPECT_THAT(packets, Contains(Property(
1362 &protos::TracePacket::for_testing,
1363 Property(&protos::TestEvent::str, Eq("payload1")))));
1364 EXPECT_THAT(packets, Contains(Property(
1365 &protos::TracePacket::for_testing,
1366 Property(&protos::TestEvent::str, Eq("payload2")))));
1367 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1368 Property(&protos::TestEvent::str,
1369 Eq("payload3"))))));
1370
1371 // Write some more packets.
1372 writer->NewTracePacket()->set_for_testing()->set_str("payload4");
1373 writer->NewTracePacket()->set_for_testing()->set_str("payload5");
1374
1375 // Don't reply to flush, causing a timeout. This should scrape again.
1376 flush_request = consumer->Flush(/*timeout=*/100);
1377 producer->WaitForFlush(nullptr, /*reply=*/false);
1378 ASSERT_FALSE(flush_request.WaitForReply());
1379
1380 // Chunk with the packets should have been scraped again, overriding the
1381 // original one. Again, the last packet should be ignored and the first two
1382 // should not be read twice.
1383 packets = consumer->ReadBuffers();
1384 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1385 Property(&protos::TestEvent::str,
1386 Eq("payload1"))))));
1387 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1388 Property(&protos::TestEvent::str,
1389 Eq("payload2"))))));
1390 EXPECT_THAT(packets, Contains(Property(
1391 &protos::TracePacket::for_testing,
1392 Property(&protos::TestEvent::str, Eq("payload3")))));
1393 EXPECT_THAT(packets, Contains(Property(
1394 &protos::TracePacket::for_testing,
1395 Property(&protos::TestEvent::str, Eq("payload4")))));
1396 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1397 Property(&protos::TestEvent::str,
1398 Eq("payload5"))))));
1399
1400 consumer->DisableTracing();
1401 producer->WaitForDataSourceStop("data_source");
1402 consumer->WaitForTracingDisabled();
1403}
1404
1405// Test scraping on producer disconnect.
1406TEST_F(TracingServiceImplTest, ScrapeBuffersOnProducerDisconnect) {
1407 svc->SetSMBScrapingEnabled(true);
1408
1409 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1410 consumer->Connect(svc.get());
1411
1412 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1413 producer->Connect(svc.get(), "mock_producer");
1414 ProducerID producer_id = *last_producer_id();
1415 producer->RegisterDataSource("data_source");
1416
1417 TraceConfig trace_config;
1418 trace_config.add_buffers()->set_size_kb(128);
1419 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1420 ds_config->set_name("data_source");
1421 ds_config->set_target_buffer(0);
1422 consumer->EnableTracing(trace_config);
1423
1424 producer->WaitForTracingSetup();
1425 producer->WaitForDataSourceSetup("data_source");
1426 producer->WaitForDataSourceStart("data_source");
1427
1428 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1429 // trace config didn't have the |deferred_start| flag set.
1430 consumer->StartTracing();
1431
1432 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1433 tracing_session()->buffers_index[0]);
1434 WaitForTraceWritersChanged(producer_id);
1435
1436 // Write a few trace packets.
1437 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
1438 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
1439 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
1440
1441 // Disconnect the producer without committing the chunk. This should cause a
1442 // scrape of the SMB. Avoid destroying the ShmemArbiter until writer is
1443 // destroyed.
1444 auto shmem_arbiter = TakeShmemArbiterForProducer(producer_id);
1445 producer.reset();
1446
1447 // Chunk with the packets should have been scraped. The service can't know
1448 // whether the last packet was completed, so shouldn't read it.
1449 auto packets = consumer->ReadBuffers();
1450 EXPECT_THAT(packets, Contains(Property(
1451 &protos::TracePacket::for_testing,
1452 Property(&protos::TestEvent::str, Eq("payload1")))));
1453 EXPECT_THAT(packets, Contains(Property(
1454 &protos::TracePacket::for_testing,
1455 Property(&protos::TestEvent::str, Eq("payload2")))));
1456 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1457 Property(&protos::TestEvent::str,
1458 Eq("payload3"))))));
1459
1460 // Cleanup writer without causing a crash because the producer already went
1461 // away.
1462 static_cast<TraceWriterImpl*>(writer.get())->ResetChunkForTesting();
1463 writer.reset();
1464 shmem_arbiter.reset();
1465
1466 consumer->DisableTracing();
1467 consumer->WaitForTracingDisabled();
1468}
1469
1470TEST_F(TracingServiceImplTest, ScrapeBuffersOnDisable) {
1471 svc->SetSMBScrapingEnabled(true);
1472
1473 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1474 consumer->Connect(svc.get());
1475
1476 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1477 producer->Connect(svc.get(), "mock_producer");
1478 ProducerID producer_id = *last_producer_id();
1479 producer->RegisterDataSource("data_source");
1480
1481 TraceConfig trace_config;
1482 trace_config.add_buffers()->set_size_kb(128);
1483 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1484 ds_config->set_name("data_source");
1485 ds_config->set_target_buffer(0);
1486 consumer->EnableTracing(trace_config);
1487
1488 producer->WaitForTracingSetup();
1489 producer->WaitForDataSourceSetup("data_source");
1490 producer->WaitForDataSourceStart("data_source");
1491
1492 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1493 // trace config didn't have the |deferred_start| flag set.
1494 consumer->StartTracing();
1495
1496 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1497 tracing_session()->buffers_index[0]);
1498 WaitForTraceWritersChanged(producer_id);
1499
1500 // Write a few trace packets.
1501 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
1502 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
1503 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
1504
1505 consumer->DisableTracing();
1506 producer->WaitForDataSourceStop("data_source");
1507 consumer->WaitForTracingDisabled();
1508
1509 // Chunk with the packets should have been scraped. The service can't know
1510 // whether the last packet was completed, so shouldn't read it.
1511 auto packets = consumer->ReadBuffers();
1512 EXPECT_THAT(packets, Contains(Property(
1513 &protos::TracePacket::for_testing,
1514 Property(&protos::TestEvent::str, Eq("payload1")))));
1515 EXPECT_THAT(packets, Contains(Property(
1516 &protos::TracePacket::for_testing,
1517 Property(&protos::TestEvent::str, Eq("payload2")))));
1518 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1519 Property(&protos::TestEvent::str,
1520 Eq("payload3"))))));
1521}
1522
Primiano Tucciff7beab2019-01-09 21:49:20 +00001523TEST_F(TracingServiceImplTest, AbortIfTraceDurationIsTooLong) {
1524 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1525 consumer->Connect(svc.get());
1526
1527 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1528 producer->Connect(svc.get(), "mock_producer");
1529 producer->RegisterDataSource("datasource");
1530
1531 TraceConfig trace_config;
1532 trace_config.add_buffers()->set_size_kb(128);
1533 trace_config.add_data_sources()->mutable_config()->set_name("datasource");
1534 trace_config.set_duration_ms(0x7fffffff);
1535
1536 EXPECT_CALL(*producer, SetupDataSource(_, _)).Times(0);
1537 consumer->EnableTracing(trace_config);
1538
1539 // The trace is aborted immediately, 5s here is just some slack for the thread
1540 // ping-pongs for slow devices.
1541 consumer->WaitForTracingDisabled(5000);
1542}
1543
Eric Secklereaf29ed2019-01-23 09:53:55 +00001544TEST_F(TracingServiceImplTest, GetTraceStats) {
1545 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1546 consumer->Connect(svc.get());
1547
1548 consumer->GetTraceStats();
1549 consumer->WaitForTraceStats(false);
1550
1551 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1552 producer->Connect(svc.get(), "mock_producer");
1553 producer->RegisterDataSource("data_source");
1554
1555 TraceConfig trace_config;
1556 trace_config.add_buffers()->set_size_kb(128);
1557 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1558 ds_config->set_name("data_source");
1559
1560 consumer->EnableTracing(trace_config);
1561 producer->WaitForTracingSetup();
1562 producer->WaitForDataSourceSetup("data_source");
1563 producer->WaitForDataSourceStart("data_source");
1564
1565 consumer->GetTraceStats();
1566 consumer->WaitForTraceStats(true);
1567
1568 consumer->DisableTracing();
1569 producer->WaitForDataSourceStop("data_source");
1570 consumer->WaitForTracingDisabled();
1571}
1572
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00001573} // namespace perfetto