blob: eca7d6dc2701d344495d5a9795e65777c845c65f [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
Hector Dearman685f7522019-03-12 14:28:56 +0000433 // The preamble packets are:
434 // Config
435 // SystemInfo
436 // 3x unknown
437 static const int kNumPreamblePackets = 5;
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000438 static const int kNumTestPackets = 10;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200439 static const char kPayload[] = "1234567890abcdef-";
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100440
441 std::unique_ptr<TraceWriter> writer =
Primiano Tuccidca727d2018-04-04 11:31:55 +0200442 producer->CreateTraceWriter("data_source");
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000443 // Tracing service will emit a preamble of packets (a synchronization section,
444 // followed by a tracing config packet). The preamble and these test packets
445 // should fit within kMaxFileSize.
446 for (int i = 0; i < kNumTestPackets; i++) {
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100447 auto tp = writer->NewTracePacket();
448 std::string payload(kPayload);
449 payload.append(std::to_string(i));
450 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
451 }
452
453 // Finally add a packet that overflows kMaxFileSize. This should cause the
454 // implicit stop of the trace and should *not* be written in the trace.
455 {
456 auto tp = writer->NewTracePacket();
457 char big_payload[kMaxFileSize] = "BIG!";
458 tp->set_for_testing()->set_str(big_payload, sizeof(big_payload));
459 }
460 writer->Flush();
461 writer.reset();
462
Primiano Tuccidca727d2018-04-04 11:31:55 +0200463 consumer->DisableTracing();
464 producer->WaitForDataSourceStop("data_source");
465 consumer->WaitForTracingDisabled();
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100466
467 // Verify the contents of the file.
468 std::string trace_raw;
469 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
470 protos::Trace trace;
471 ASSERT_TRUE(trace.ParseFromString(trace_raw));
Ryan Savitskicc28cbf2018-11-09 22:55:12 +0000472
473 ASSERT_EQ(trace.packet_size(), kNumPreamblePackets + kNumTestPackets);
474 for (int i = 0; i < kNumTestPackets; i++) {
475 const protos::TracePacket& tp = trace.packet(kNumPreamblePackets + i);
476 ASSERT_EQ(kPayload + std::to_string(i++), tp.for_testing().str());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100477 }
Primiano Tuccidca727d2018-04-04 11:31:55 +0200478}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100479
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200480// Test the logic that allows the trace config to set the shm total size and
481// page size from the trace config. Also check that, if the config doesn't
482// specify a value we fall back on the hint provided by the producer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100483TEST_F(TracingServiceImplTest, ProducerShmAndPageSizeOverriddenByTraceConfig) {
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200484 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
485 consumer->Connect(svc.get());
486 const size_t kConfigPageSizesKb[] = /****/ {16, 16, 4, 0, 16, 8, 3, 4096, 4};
487 const size_t kExpectedPageSizesKb[] = /**/ {16, 16, 4, 4, 16, 8, 4, 64, 4};
488
489 const size_t kConfigSizesKb[] = /**/ {0, 16, 0, 20, 32, 7, 0, 96, 4096000};
490 const size_t kHintSizesKb[] = /****/ {0, 0, 16, 32, 16, 0, 7, 96, 4096000};
491 const size_t kExpectedSizesKb[] = {
492 kDefaultShmSizeKb, // Both hint and config are 0, use default.
493 16, // Hint is 0, use config.
494 16, // Config is 0, use hint.
495 20, // Hint is takes precedence over the config.
496 32, // Ditto, even if config is higher than hint.
497 kDefaultShmSizeKb, // Config is invalid and hint is 0, use default.
498 kDefaultShmSizeKb, // Config is 0 and hint is invalid, use default.
499 kDefaultShmSizeKb, // 96 KB isn't a multiple of the page size (64 KB).
500 kMaxShmSizeKb // Too big, cap at kMaxShmSize.
501 };
502
503 const size_t kNumProducers = base::ArraySize(kHintSizesKb);
504 std::unique_ptr<MockProducer> producer[kNumProducers];
505 for (size_t i = 0; i < kNumProducers; i++) {
506 auto name = "mock_producer_" + std::to_string(i);
507 producer[i] = CreateMockProducer();
508 producer[i]->Connect(svc.get(), name, geteuid(), kHintSizesKb[i] * 1024);
509 producer[i]->RegisterDataSource("data_source");
510 }
511
512 TraceConfig trace_config;
513 trace_config.add_buffers()->set_size_kb(128);
514 auto* ds_config = trace_config.add_data_sources()->mutable_config();
515 ds_config->set_name("data_source");
516 for (size_t i = 0; i < kNumProducers; i++) {
517 auto* producer_config = trace_config.add_producers();
518 producer_config->set_producer_name("mock_producer_" + std::to_string(i));
Primiano Tucci3cbb10a2018-04-10 17:52:40 +0100519 producer_config->set_shm_size_kb(static_cast<uint32_t>(kConfigSizesKb[i]));
520 producer_config->set_page_size_kb(
521 static_cast<uint32_t>(kConfigPageSizesKb[i]));
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200522 }
523
524 consumer->EnableTracing(trace_config);
525 size_t actual_shm_sizes_kb[kNumProducers]{};
526 size_t actual_page_sizes_kb[kNumProducers]{};
527 for (size_t i = 0; i < kNumProducers; i++) {
528 producer[i]->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100529 producer[i]->WaitForDataSourceSetup("data_source");
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200530 actual_shm_sizes_kb[i] =
531 producer[i]->endpoint()->shared_memory()->size() / 1024;
532 actual_page_sizes_kb[i] =
533 producer[i]->endpoint()->shared_buffer_page_size_kb();
534 }
Primiano Tucci674076d2018-10-01 10:41:09 +0100535 for (size_t i = 0; i < kNumProducers; i++) {
536 producer[i]->WaitForDataSourceStart("data_source");
537 }
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200538 ASSERT_THAT(actual_page_sizes_kb, ElementsAreArray(kExpectedPageSizesKb));
539 ASSERT_THAT(actual_shm_sizes_kb, ElementsAreArray(kExpectedSizesKb));
540}
541
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100542TEST_F(TracingServiceImplTest, ExplicitFlush) {
Primiano Tuccid52e6272018-04-06 19:06:53 +0200543 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
544 consumer->Connect(svc.get());
545
546 std::unique_ptr<MockProducer> producer = CreateMockProducer();
547 producer->Connect(svc.get(), "mock_producer");
548 producer->RegisterDataSource("data_source");
549
550 TraceConfig trace_config;
551 trace_config.add_buffers()->set_size_kb(128);
552 auto* ds_config = trace_config.add_data_sources()->mutable_config();
553 ds_config->set_name("data_source");
554
555 consumer->EnableTracing(trace_config);
556 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100557 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +0200558 producer->WaitForDataSourceStart("data_source");
559
560 std::unique_ptr<TraceWriter> writer =
561 producer->CreateTraceWriter("data_source");
562 {
563 auto tp = writer->NewTracePacket();
564 tp->set_for_testing()->set_str("payload");
565 }
566
567 auto flush_request = consumer->Flush();
568 producer->WaitForFlush(writer.get());
569 ASSERT_TRUE(flush_request.WaitForReply());
570
571 consumer->DisableTracing();
572 producer->WaitForDataSourceStop("data_source");
573 consumer->WaitForTracingDisabled();
574 EXPECT_THAT(
575 consumer->ReadBuffers(),
576 Contains(Property(&protos::TracePacket::for_testing,
577 Property(&protos::TestEvent::str, Eq("payload")))));
578}
579
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100580TEST_F(TracingServiceImplTest, ImplicitFlushOnTimedTraces) {
Primiano Tuccid52e6272018-04-06 19:06:53 +0200581 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
582 consumer->Connect(svc.get());
583
584 std::unique_ptr<MockProducer> producer = CreateMockProducer();
585 producer->Connect(svc.get(), "mock_producer");
586 producer->RegisterDataSource("data_source");
587
588 TraceConfig trace_config;
589 trace_config.add_buffers()->set_size_kb(128);
590 auto* ds_config = trace_config.add_data_sources()->mutable_config();
591 ds_config->set_name("data_source");
592 trace_config.set_duration_ms(1);
593
594 consumer->EnableTracing(trace_config);
595 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100596 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +0200597 producer->WaitForDataSourceStart("data_source");
598
599 std::unique_ptr<TraceWriter> writer =
600 producer->CreateTraceWriter("data_source");
601 {
602 auto tp = writer->NewTracePacket();
603 tp->set_for_testing()->set_str("payload");
604 }
605
606 producer->WaitForFlush(writer.get());
607
608 producer->WaitForDataSourceStop("data_source");
609 consumer->WaitForTracingDisabled();
610
611 EXPECT_THAT(
612 consumer->ReadBuffers(),
613 Contains(Property(&protos::TracePacket::for_testing,
614 Property(&protos::TestEvent::str, Eq("payload")))));
615}
616
617// Tests the monotonic semantic of flush request IDs, i.e., once a producer
618// acks flush request N, all flush requests <= N are considered successful and
619// acked to the consumer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100620TEST_F(TracingServiceImplTest, BatchFlushes) {
Primiano Tuccid52e6272018-04-06 19:06:53 +0200621 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
622 consumer->Connect(svc.get());
623
624 std::unique_ptr<MockProducer> producer = CreateMockProducer();
625 producer->Connect(svc.get(), "mock_producer");
626 producer->RegisterDataSource("data_source");
627
628 TraceConfig trace_config;
629 trace_config.add_buffers()->set_size_kb(128);
630 auto* ds_config = trace_config.add_data_sources()->mutable_config();
631 ds_config->set_name("data_source");
632
633 consumer->EnableTracing(trace_config);
634 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100635 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +0200636 producer->WaitForDataSourceStart("data_source");
637
638 std::unique_ptr<TraceWriter> writer =
639 producer->CreateTraceWriter("data_source");
640 {
641 auto tp = writer->NewTracePacket();
642 tp->set_for_testing()->set_str("payload");
643 }
644
645 auto flush_req_1 = consumer->Flush();
646 auto flush_req_2 = consumer->Flush();
647 auto flush_req_3 = consumer->Flush();
648
649 // We'll deliberately let the 4th flush request timeout. Use a lower timeout
650 // to keep test time short.
651 auto flush_req_4 = consumer->Flush(/*timeout_ms=*/10);
652 ASSERT_EQ(4u, GetNumPendingFlushes());
653
654 // Make the producer reply only to the 3rd flush request.
655 testing::InSequence seq;
Eric Secklera01e28a2019-01-08 11:21:04 +0000656 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 1.
657 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 2.
658 producer->WaitForFlush(writer.get()); // Reply only to flush 3.
659 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 4.
Primiano Tuccid52e6272018-04-06 19:06:53 +0200660
661 // Even if the producer explicily replied only to flush ID == 3, all the
662 // previous flushed < 3 should be implicitly acked.
663 ASSERT_TRUE(flush_req_1.WaitForReply());
664 ASSERT_TRUE(flush_req_2.WaitForReply());
665 ASSERT_TRUE(flush_req_3.WaitForReply());
666
667 // At this point flush id == 4 should still be pending and should fail because
668 // of reaching its timeout.
Primiano Tuccid52e6272018-04-06 19:06:53 +0200669 ASSERT_FALSE(flush_req_4.WaitForReply());
670
671 consumer->DisableTracing();
672 producer->WaitForDataSourceStop("data_source");
673 consumer->WaitForTracingDisabled();
674 EXPECT_THAT(
675 consumer->ReadBuffers(),
676 Contains(Property(&protos::TracePacket::for_testing,
677 Property(&protos::TestEvent::str, Eq("payload")))));
678}
679
Primiano Tuccicaa57802018-11-25 11:07:07 +0000680TEST_F(TracingServiceImplTest, PeriodicFlush) {
681 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
682 consumer->Connect(svc.get());
683
684 std::unique_ptr<MockProducer> producer = CreateMockProducer();
685 producer->Connect(svc.get(), "mock_producer");
686 producer->RegisterDataSource("data_source");
687
688 TraceConfig trace_config;
689 trace_config.add_buffers()->set_size_kb(128);
690 trace_config.set_flush_period_ms(1);
691 auto* ds_config = trace_config.add_data_sources()->mutable_config();
692 ds_config->set_name("data_source");
693
694 consumer->EnableTracing(trace_config);
695 producer->WaitForTracingSetup();
696 producer->WaitForDataSourceSetup("data_source");
697 producer->WaitForDataSourceStart("data_source");
698
699 std::unique_ptr<TraceWriter> writer =
700 producer->CreateTraceWriter("data_source");
701
702 const int kNumFlushes = 3;
703 auto checkpoint = task_runner.CreateCheckpoint("all_flushes_done");
704 int flushes_seen = 0;
705 EXPECT_CALL(*producer, Flush(_, _, _))
706 .WillRepeatedly(Invoke([&producer, &writer, &flushes_seen, checkpoint](
707 FlushRequestID flush_req_id,
708 const DataSourceInstanceID*, size_t) {
709 {
710 auto tp = writer->NewTracePacket();
711 char payload[32];
712 sprintf(payload, "f_%d", flushes_seen);
713 tp->set_for_testing()->set_str(payload);
714 }
715 writer->Flush();
716 producer->endpoint()->NotifyFlushComplete(flush_req_id);
717 if (++flushes_seen == kNumFlushes)
718 checkpoint();
719 }));
720 task_runner.RunUntilCheckpoint("all_flushes_done");
721
722 consumer->DisableTracing();
723 producer->WaitForDataSourceStop("data_source");
724 consumer->WaitForTracingDisabled();
725 auto trace_packets = consumer->ReadBuffers();
726 for (int i = 0; i < kNumFlushes; i++) {
727 EXPECT_THAT(trace_packets,
728 Contains(Property(&protos::TracePacket::for_testing,
729 Property(&protos::TestEvent::str,
730 Eq("f_" + std::to_string(i))))));
731 }
732}
733
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100734// Creates a tracing session where some of the data sources set the
735// |will_notify_on_stop| flag and checks that the OnTracingDisabled notification
736// to the consumer is delayed until the acks are received.
737TEST_F(TracingServiceImplTest, OnTracingDisabledWaitsForDataSourceStopAcks) {
738 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
739 consumer->Connect(svc.get());
740
741 std::unique_ptr<MockProducer> producer = CreateMockProducer();
742 producer->Connect(svc.get(), "mock_producer");
743 producer->RegisterDataSource("ds_will_ack_1", /*ack_stop=*/true);
744 producer->RegisterDataSource("ds_wont_ack");
745 producer->RegisterDataSource("ds_will_ack_2", /*ack_stop=*/true);
746
747 TraceConfig trace_config;
748 trace_config.add_buffers()->set_size_kb(128);
749 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_1");
750 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
751 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_2");
752 trace_config.set_duration_ms(1);
753
754 consumer->EnableTracing(trace_config);
755 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100756
757 producer->WaitForDataSourceSetup("ds_will_ack_1");
758 producer->WaitForDataSourceSetup("ds_wont_ack");
759 producer->WaitForDataSourceSetup("ds_will_ack_2");
760
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100761 producer->WaitForDataSourceStart("ds_will_ack_1");
762 producer->WaitForDataSourceStart("ds_wont_ack");
763 producer->WaitForDataSourceStart("ds_will_ack_2");
764
765 std::unique_ptr<TraceWriter> writer =
766 producer->CreateTraceWriter("ds_wont_ack");
767 producer->WaitForFlush(writer.get());
768
769 DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_will_ack_1");
770 DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_will_ack_2");
771
772 producer->WaitForDataSourceStop("ds_will_ack_1");
773 producer->WaitForDataSourceStop("ds_wont_ack");
774 producer->WaitForDataSourceStop("ds_will_ack_2");
775
776 producer->endpoint()->NotifyDataSourceStopped(id1);
777 producer->endpoint()->NotifyDataSourceStopped(id2);
778
779 // Wait for at most half of the service timeout, so that this test fails if
780 // the service falls back on calling the OnTracingDisabled() because some of
781 // the expected acks weren't received.
782 consumer->WaitForTracingDisabled(
783 TracingServiceImpl::kDataSourceStopTimeoutMs / 2);
784}
785
Oystein Eftevaagf250e1c2018-08-23 16:10:52 -0700786// Creates a tracing session where a second data source
787// is added while the service is waiting for DisableTracing
788// acks; the service should not enable the new datasource
789// and should not hit any asserts when the consumer is
790// subsequently destroyed.
791TEST_F(TracingServiceImplTest, OnDataSourceAddedWhilePendingDisableAcks) {
792 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
793 consumer->Connect(svc.get());
794
795 std::unique_ptr<MockProducer> producer = CreateMockProducer();
796 producer->Connect(svc.get(), "mock_producer");
797 producer->RegisterDataSource("ds_will_ack", /*ack_stop=*/true);
798
799 TraceConfig trace_config;
800 trace_config.add_buffers()->set_size_kb(128);
801 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack");
802 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
803
804 consumer->EnableTracing(trace_config);
805 producer->WaitForTracingSetup();
806
807 consumer->DisableTracing();
808
809 producer->RegisterDataSource("ds_wont_ack");
810
811 consumer.reset();
812}
813
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100814// Similar to OnTracingDisabledWaitsForDataSourceStopAcks, but deliberately
815// skips the ack and checks that the service invokes the OnTracingDisabled()
816// after the timeout.
817TEST_F(TracingServiceImplTest, OnTracingDisabledCalledAnywaysInCaseOfTimeout) {
818 svc->override_data_source_test_timeout_ms_for_testing = 1;
819 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
820 consumer->Connect(svc.get());
821
822 std::unique_ptr<MockProducer> producer = CreateMockProducer();
823 producer->Connect(svc.get(), "mock_producer");
824 producer->RegisterDataSource("data_source", /*ack_stop=*/true);
825
826 TraceConfig trace_config;
827 trace_config.add_buffers()->set_size_kb(128);
828 trace_config.add_data_sources()->mutable_config()->set_name("data_source");
829 trace_config.set_duration_ms(1);
830
831 consumer->EnableTracing(trace_config);
832 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100833 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100834 producer->WaitForDataSourceStart("data_source");
835
836 std::unique_ptr<TraceWriter> writer =
837 producer->CreateTraceWriter("data_source");
838 producer->WaitForFlush(writer.get());
839
840 producer->WaitForDataSourceStop("data_source");
841 consumer->WaitForTracingDisabled();
842}
843
Primiano Tucci03de28f2018-08-01 11:29:46 +0100844// Tests the session_id logic. Two data sources in the same tracing session
845// should see the same session id.
846TEST_F(TracingServiceImplTest, SessionId) {
847 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
848 consumer->Connect(svc.get());
849
850 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
851 producer1->Connect(svc.get(), "mock_producer1");
852 producer1->RegisterDataSource("ds_1A");
853 producer1->RegisterDataSource("ds_1B");
854
855 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
856 producer2->Connect(svc.get(), "mock_producer2");
857 producer2->RegisterDataSource("ds_2A");
858
859 testing::InSequence seq;
860 TracingSessionID last_session_id = 0;
861 for (int i = 0; i < 3; i++) {
862 TraceConfig trace_config;
863 trace_config.add_buffers()->set_size_kb(128);
864 trace_config.add_data_sources()->mutable_config()->set_name("ds_1A");
865 trace_config.add_data_sources()->mutable_config()->set_name("ds_1B");
866 trace_config.add_data_sources()->mutable_config()->set_name("ds_2A");
867 trace_config.set_duration_ms(1);
868
869 consumer->EnableTracing(trace_config);
870
871 if (i == 0)
872 producer1->WaitForTracingSetup();
Primiano Tucci03de28f2018-08-01 11:29:46 +0100873
Primiano Tucci674076d2018-10-01 10:41:09 +0100874 producer1->WaitForDataSourceSetup("ds_1A");
875 producer1->WaitForDataSourceSetup("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +0100876 if (i == 0)
877 producer2->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100878 producer2->WaitForDataSourceSetup("ds_2A");
879
880 producer1->WaitForDataSourceStart("ds_1A");
881 producer1->WaitForDataSourceStart("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +0100882 producer2->WaitForDataSourceStart("ds_2A");
883
884 auto* ds1 = producer1->GetDataSourceInstance("ds_1A");
885 auto* ds2 = producer1->GetDataSourceInstance("ds_1B");
886 auto* ds3 = producer2->GetDataSourceInstance("ds_2A");
887 ASSERT_EQ(ds1->session_id, ds2->session_id);
888 ASSERT_EQ(ds1->session_id, ds3->session_id);
889 ASSERT_NE(ds1->session_id, last_session_id);
890 last_session_id = ds1->session_id;
891
892 auto writer1 = producer1->CreateTraceWriter("ds_1A");
893 producer1->WaitForFlush(writer1.get());
894
895 auto writer2 = producer2->CreateTraceWriter("ds_2A");
896 producer2->WaitForFlush(writer2.get());
897
898 producer1->WaitForDataSourceStop("ds_1A");
899 producer1->WaitForDataSourceStop("ds_1B");
900 producer2->WaitForDataSourceStop("ds_2A");
901 consumer->WaitForTracingDisabled();
902 consumer->FreeBuffers();
903 }
904}
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100905
906// Writes a long trace and then tests that the trace parsed in partitions
907// derived by the synchronization markers is identical to the whole trace parsed
908// in one go.
909TEST_F(TracingServiceImplTest, ResynchronizeTraceStreamUsingSyncMarker) {
910 // Setup tracing.
911 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
912 consumer->Connect(svc.get());
913 std::unique_ptr<MockProducer> producer = CreateMockProducer();
914 producer->Connect(svc.get(), "mock_producer");
915 producer->RegisterDataSource("data_source");
916 TraceConfig trace_config;
917 trace_config.add_buffers()->set_size_kb(4096);
918 auto* ds_config = trace_config.add_data_sources()->mutable_config();
919 ds_config->set_name("data_source");
920 trace_config.set_write_into_file(true);
921 trace_config.set_file_write_period_ms(1);
922 base::TempFile tmp_file = base::TempFile::Create();
923 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
924 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100925 producer->WaitForDataSourceSetup("data_source");
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100926 producer->WaitForDataSourceStart("data_source");
927
928 // Write some variable length payload, waiting for sync markers every now
929 // and then.
930 const int kNumMarkers = 5;
931 auto writer = producer->CreateTraceWriter("data_source");
932 for (int i = 1; i <= 100; i++) {
Florian Mayereff98042018-12-10 17:44:44 +0000933 std::string payload(static_cast<size_t>(i), 'A' + (i % 25));
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100934 writer->NewTracePacket()->set_for_testing()->set_str(payload.c_str());
935 if (i % (100 / kNumMarkers) == 0) {
936 writer->Flush();
937 WaitForNextSyncMarker();
938 }
939 }
940 writer->Flush();
941 writer.reset();
942 consumer->DisableTracing();
943 producer->WaitForDataSourceStop("data_source");
944 consumer->WaitForTracingDisabled();
945
946 std::string trace_raw;
947 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
948
949 const auto kMarkerSize = sizeof(TracingServiceImpl::kSyncMarker);
950 const std::string kSyncMarkerStr(
951 reinterpret_cast<const char*>(TracingServiceImpl::kSyncMarker),
952 kMarkerSize);
953
954 // Read back the trace in partitions derived from the marker.
955 // The trace should look like this:
956 // [uid, marker] [event] [event] [uid, marker] [event] [event]
957 size_t num_markers = 0;
958 size_t start = 0;
959 size_t end = 0;
960 protos::Trace merged_trace;
961 for (size_t pos = 0; pos != std::string::npos; start = end) {
962 pos = trace_raw.find(kSyncMarkerStr, pos + 1);
963 num_markers++;
964 end = (pos == std::string::npos) ? trace_raw.size() : pos + kMarkerSize;
965 int size = static_cast<int>(end - start);
966 ASSERT_GT(size, 0);
967 protos::Trace trace_partition;
968 ASSERT_TRUE(trace_partition.ParseFromArray(trace_raw.data() + start, size));
969 merged_trace.MergeFrom(trace_partition);
970 }
Lalit Maganti9bdc7ce2018-09-17 15:25:11 +0100971 EXPECT_GE(num_markers, static_cast<size_t>(kNumMarkers));
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100972
973 protos::Trace whole_trace;
974 ASSERT_TRUE(whole_trace.ParseFromString(trace_raw));
975
976 ASSERT_EQ(whole_trace.packet_size(), merged_trace.packet_size());
977 EXPECT_EQ(whole_trace.SerializeAsString(), merged_trace.SerializeAsString());
978}
979
Primiano Tucci674076d2018-10-01 10:41:09 +0100980// Creates a tracing session with |deferred_start| and checks that data sources
981// are started only after calling StartTracing().
982TEST_F(TracingServiceImplTest, DeferredStart) {
983 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
984 consumer->Connect(svc.get());
985
986 std::unique_ptr<MockProducer> producer = CreateMockProducer();
987 producer->Connect(svc.get(), "mock_producer");
988
989 // Create two data sources but enable only one of them.
990 producer->RegisterDataSource("ds_1");
991 producer->RegisterDataSource("ds_2");
992
993 TraceConfig trace_config;
994 trace_config.add_buffers()->set_size_kb(128);
995 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
996 trace_config.set_deferred_start(true);
997 trace_config.set_duration_ms(1);
998
999 consumer->EnableTracing(trace_config);
1000 producer->WaitForTracingSetup();
1001
1002 producer->WaitForDataSourceSetup("ds_1");
1003
1004 // Make sure we don't get unexpected DataSourceStart() notifications yet.
1005 task_runner.RunUntilIdle();
1006
1007 consumer->StartTracing();
1008
1009 producer->WaitForDataSourceStart("ds_1");
1010
1011 auto writer1 = producer->CreateTraceWriter("ds_1");
1012 producer->WaitForFlush(writer1.get());
1013
1014 producer->WaitForDataSourceStop("ds_1");
1015 consumer->WaitForTracingDisabled();
1016}
1017
Eric Secklerd0ac7ca2019-02-06 09:13:45 +00001018TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
1019 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1020 consumer->Connect(svc.get());
1021
1022 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1023 producer1->Connect(svc.get(), "mock_producer1", 123u /* uid */);
1024 producer1->RegisterDataSource("data_source");
1025
1026 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1027 producer2->Connect(svc.get(), "mock_producer2", 456u /* uid */);
1028 producer2->RegisterDataSource("data_source");
1029
1030 TraceConfig trace_config;
1031 trace_config.add_buffers()->set_size_kb(128);
1032 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1033 ds_config->set_name("data_source");
1034
1035 consumer->EnableTracing(trace_config);
1036 producer1->WaitForTracingSetup();
1037 producer1->WaitForDataSourceSetup("data_source");
1038 producer2->WaitForTracingSetup();
1039 producer2->WaitForDataSourceSetup("data_source");
1040 producer1->WaitForDataSourceStart("data_source");
1041 producer2->WaitForDataSourceStart("data_source");
1042
1043 std::unique_ptr<TraceWriter> writer1a =
1044 producer1->CreateTraceWriter("data_source");
1045 std::unique_ptr<TraceWriter> writer1b =
1046 producer1->CreateTraceWriter("data_source");
1047 std::unique_ptr<TraceWriter> writer2a =
1048 producer2->CreateTraceWriter("data_source");
1049 {
1050 auto tp = writer1a->NewTracePacket();
1051 tp->set_for_testing()->set_str("payload1a1");
1052 tp = writer1b->NewTracePacket();
1053 tp->set_for_testing()->set_str("payload1b1");
1054 tp = writer1a->NewTracePacket();
1055 tp->set_for_testing()->set_str("payload1a2");
1056 tp = writer2a->NewTracePacket();
1057 tp->set_for_testing()->set_str("payload2a1");
1058 tp = writer1b->NewTracePacket();
1059 tp->set_for_testing()->set_str("payload1b2");
1060 }
1061
1062 auto flush_request = consumer->Flush();
1063 producer1->WaitForFlush({writer1a.get(), writer1b.get()});
1064 producer2->WaitForFlush(writer2a.get());
1065 ASSERT_TRUE(flush_request.WaitForReply());
1066
1067 consumer->DisableTracing();
1068 producer1->WaitForDataSourceStop("data_source");
1069 producer2->WaitForDataSourceStop("data_source");
1070 consumer->WaitForTracingDisabled();
1071 auto packets = consumer->ReadBuffers();
1072 EXPECT_THAT(
1073 packets,
1074 Contains(AllOf(
1075 Property(&protos::TracePacket::for_testing,
1076 Property(&protos::TestEvent::str, Eq("payload1a1"))),
1077 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1078 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
1079 EXPECT_THAT(
1080 packets,
1081 Contains(AllOf(
1082 Property(&protos::TracePacket::for_testing,
1083 Property(&protos::TestEvent::str, Eq("payload1a2"))),
1084 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1085 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
1086 EXPECT_THAT(
1087 packets,
1088 Contains(AllOf(
1089 Property(&protos::TracePacket::for_testing,
1090 Property(&protos::TestEvent::str, Eq("payload1b1"))),
1091 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1092 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
1093 EXPECT_THAT(
1094 packets,
1095 Contains(AllOf(
1096 Property(&protos::TracePacket::for_testing,
1097 Property(&protos::TestEvent::str, Eq("payload1b2"))),
1098 Property(&protos::TracePacket::trusted_uid, Eq(123)),
1099 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
1100 EXPECT_THAT(
1101 packets,
1102 Contains(AllOf(
1103 Property(&protos::TracePacket::for_testing,
1104 Property(&protos::TestEvent::str, Eq("payload2a1"))),
1105 Property(&protos::TracePacket::trusted_uid, Eq(456)),
1106 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(4u)))));
1107}
1108
Eric Seckler6dc23592018-11-30 10:59:06 +00001109TEST_F(TracingServiceImplTest, AllowedBuffers) {
1110 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1111 consumer->Connect(svc.get());
1112
1113 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1114 producer1->Connect(svc.get(), "mock_producer1");
1115 ProducerID producer1_id = *last_producer_id();
1116 producer1->RegisterDataSource("data_source1");
1117 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1118 producer2->Connect(svc.get(), "mock_producer2");
1119 ProducerID producer2_id = *last_producer_id();
1120 producer2->RegisterDataSource("data_source2.1");
1121 producer2->RegisterDataSource("data_source2.2");
1122 producer2->RegisterDataSource("data_source2.3");
1123
1124 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
1125 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
1126
1127 TraceConfig trace_config;
1128 trace_config.add_buffers()->set_size_kb(128);
1129 trace_config.add_buffers()->set_size_kb(128);
1130 trace_config.add_buffers()->set_size_kb(128);
1131 auto* ds_config1 = trace_config.add_data_sources()->mutable_config();
1132 ds_config1->set_name("data_source1");
1133 ds_config1->set_target_buffer(0);
1134 auto* ds_config21 = trace_config.add_data_sources()->mutable_config();
1135 ds_config21->set_name("data_source2.1");
1136 ds_config21->set_target_buffer(1);
1137 auto* ds_config22 = trace_config.add_data_sources()->mutable_config();
1138 ds_config22->set_name("data_source2.2");
1139 ds_config22->set_target_buffer(2);
1140 auto* ds_config23 = trace_config.add_data_sources()->mutable_config();
1141 ds_config23->set_name("data_source2.3");
1142 ds_config23->set_target_buffer(2); // same buffer as data_source2.2.
1143 consumer->EnableTracing(trace_config);
1144
Primiano Tucci2abd1152018-12-03 17:00:02 +01001145 ASSERT_EQ(3u, tracing_session()->num_buffers());
Eric Seckler6dc23592018-11-30 10:59:06 +00001146 std::set<BufferID> expected_buffers_producer1 = {
1147 tracing_session()->buffers_index[0]};
1148 std::set<BufferID> expected_buffers_producer2 = {
1149 tracing_session()->buffers_index[1], tracing_session()->buffers_index[2]};
1150 EXPECT_EQ(expected_buffers_producer1, GetAllowedTargetBuffers(producer1_id));
1151 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
1152
1153 producer1->WaitForTracingSetup();
1154 producer1->WaitForDataSourceSetup("data_source1");
1155
1156 producer2->WaitForTracingSetup();
1157 producer2->WaitForDataSourceSetup("data_source2.1");
1158 producer2->WaitForDataSourceSetup("data_source2.2");
1159 producer2->WaitForDataSourceSetup("data_source2.3");
1160
1161 producer1->WaitForDataSourceStart("data_source1");
1162 producer2->WaitForDataSourceStart("data_source2.1");
1163 producer2->WaitForDataSourceStart("data_source2.2");
1164 producer2->WaitForDataSourceStart("data_source2.3");
1165
1166 producer2->UnregisterDataSource("data_source2.3");
1167 producer2->WaitForDataSourceStop("data_source2.3");
1168
1169 // Should still be allowed to write to buffers 1 (data_source2.1) and 2
1170 // (data_source2.2).
1171 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
1172
1173 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1174 // trace config didn't have the |deferred_start| flag set.
1175 consumer->StartTracing();
1176
1177 consumer->DisableTracing();
1178 producer1->WaitForDataSourceStop("data_source1");
1179 producer2->WaitForDataSourceStop("data_source2.1");
1180 producer2->WaitForDataSourceStop("data_source2.2");
1181 consumer->WaitForTracingDisabled();
1182
1183 consumer->FreeBuffers();
1184 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
1185 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
1186}
1187
Eric Seckler6aa9ece2018-12-06 16:40:12 +00001188#if !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00001189TEST_F(TracingServiceImplTest, CommitToForbiddenBufferIsDiscarded) {
1190 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1191 consumer->Connect(svc.get());
1192
1193 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1194 producer->Connect(svc.get(), "mock_producer");
1195 ProducerID producer_id = *last_producer_id();
1196 producer->RegisterDataSource("data_source");
1197
1198 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
1199
1200 TraceConfig trace_config;
1201 trace_config.add_buffers()->set_size_kb(128);
1202 trace_config.add_buffers()->set_size_kb(128);
1203 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1204 ds_config->set_name("data_source");
1205 ds_config->set_target_buffer(0);
1206 consumer->EnableTracing(trace_config);
1207
1208 ASSERT_EQ(2u, tracing_session()->num_buffers());
1209 std::set<BufferID> expected_buffers = {tracing_session()->buffers_index[0]};
1210 EXPECT_EQ(expected_buffers, GetAllowedTargetBuffers(producer_id));
1211
1212 producer->WaitForTracingSetup();
1213 producer->WaitForDataSourceSetup("data_source");
1214 producer->WaitForDataSourceStart("data_source");
1215
1216 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1217 // trace config didn't have the |deferred_start| flag set.
1218 consumer->StartTracing();
1219
1220 // Try to write to the correct buffer.
1221 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1222 tracing_session()->buffers_index[0]);
1223 {
1224 auto tp = writer->NewTracePacket();
1225 tp->set_for_testing()->set_str("good_payload");
1226 }
1227
1228 auto flush_request = consumer->Flush();
1229 producer->WaitForFlush(writer.get());
1230 ASSERT_TRUE(flush_request.WaitForReply());
1231
1232 // Try to write to the wrong buffer.
1233 writer = producer->endpoint()->CreateTraceWriter(
1234 tracing_session()->buffers_index[1]);
1235 {
1236 auto tp = writer->NewTracePacket();
1237 tp->set_for_testing()->set_str("bad_payload");
1238 }
1239
1240 flush_request = consumer->Flush();
1241 producer->WaitForFlush(writer.get());
1242 ASSERT_TRUE(flush_request.WaitForReply());
1243
1244 consumer->DisableTracing();
1245 producer->WaitForDataSourceStop("data_source");
1246 consumer->WaitForTracingDisabled();
1247
1248 auto packets = consumer->ReadBuffers();
1249 EXPECT_THAT(packets, Contains(Property(&protos::TracePacket::for_testing,
1250 Property(&protos::TestEvent::str,
1251 Eq("good_payload")))));
1252 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1253 Property(&protos::TestEvent::str,
1254 Eq("bad_payload"))))));
1255
1256 consumer->FreeBuffers();
1257 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
1258}
Eric Seckler6aa9ece2018-12-06 16:40:12 +00001259#endif // !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00001260
Eric Secklerf3f524b2018-12-13 09:09:34 +00001261TEST_F(TracingServiceImplTest, RegisterAndUnregisterTraceWriter) {
1262 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1263 consumer->Connect(svc.get());
1264
1265 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1266 producer->Connect(svc.get(), "mock_producer");
1267 ProducerID producer_id = *last_producer_id();
1268 producer->RegisterDataSource("data_source");
1269
1270 EXPECT_TRUE(GetWriters(producer_id).empty());
1271
1272 TraceConfig trace_config;
1273 trace_config.add_buffers()->set_size_kb(128);
1274 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1275 ds_config->set_name("data_source");
1276 ds_config->set_target_buffer(0);
1277 consumer->EnableTracing(trace_config);
1278
1279 producer->WaitForTracingSetup();
1280 producer->WaitForDataSourceSetup("data_source");
1281 producer->WaitForDataSourceStart("data_source");
1282
1283 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1284 // trace config didn't have the |deferred_start| flag set.
1285 consumer->StartTracing();
1286
1287 // Creating the trace writer should register it with the service.
1288 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1289 tracing_session()->buffers_index[0]);
1290
1291 WaitForTraceWritersChanged(producer_id);
1292
1293 std::map<WriterID, BufferID> expected_writers;
1294 expected_writers[writer->writer_id()] = tracing_session()->buffers_index[0];
1295 EXPECT_EQ(expected_writers, GetWriters(producer_id));
1296
1297 // Verify writing works.
1298 {
1299 auto tp = writer->NewTracePacket();
1300 tp->set_for_testing()->set_str("payload");
1301 }
1302
1303 auto flush_request = consumer->Flush();
1304 producer->WaitForFlush(writer.get());
1305 ASSERT_TRUE(flush_request.WaitForReply());
1306
1307 // Destroying the writer should unregister it.
1308 writer.reset();
1309 WaitForTraceWritersChanged(producer_id);
1310 EXPECT_TRUE(GetWriters(producer_id).empty());
1311
1312 consumer->DisableTracing();
1313 producer->WaitForDataSourceStop("data_source");
1314 consumer->WaitForTracingDisabled();
1315
1316 auto packets = consumer->ReadBuffers();
1317 EXPECT_THAT(packets, Contains(Property(
1318 &protos::TracePacket::for_testing,
1319 Property(&protos::TestEvent::str, Eq("payload")))));
1320}
1321
Eric Secklera01e28a2019-01-08 11:21:04 +00001322TEST_F(TracingServiceImplTest, ScrapeBuffersOnFlush) {
1323 svc->SetSMBScrapingEnabled(true);
1324
1325 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1326 consumer->Connect(svc.get());
1327
1328 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1329 producer->Connect(svc.get(), "mock_producer");
1330 ProducerID producer_id = *last_producer_id();
1331 producer->RegisterDataSource("data_source");
1332
1333 TraceConfig trace_config;
1334 trace_config.add_buffers()->set_size_kb(128);
1335 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1336 ds_config->set_name("data_source");
1337 ds_config->set_target_buffer(0);
1338 consumer->EnableTracing(trace_config);
1339
1340 producer->WaitForTracingSetup();
1341 producer->WaitForDataSourceSetup("data_source");
1342 producer->WaitForDataSourceStart("data_source");
1343
1344 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1345 // trace config didn't have the |deferred_start| flag set.
1346 consumer->StartTracing();
1347
1348 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1349 tracing_session()->buffers_index[0]);
1350 WaitForTraceWritersChanged(producer_id);
1351
1352 // Write a few trace packets.
1353 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
1354 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
1355 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
1356
1357 // Flush but don't actually flush the chunk from TraceWriter.
1358 auto flush_request = consumer->Flush();
1359 producer->WaitForFlush(nullptr, /*reply=*/true);
1360 ASSERT_TRUE(flush_request.WaitForReply());
1361
1362 // Chunk with the packets should have been scraped. The service can't know
1363 // whether the last packet was completed, so shouldn't read it.
1364 auto packets = consumer->ReadBuffers();
1365 EXPECT_THAT(packets, Contains(Property(
1366 &protos::TracePacket::for_testing,
1367 Property(&protos::TestEvent::str, Eq("payload1")))));
1368 EXPECT_THAT(packets, Contains(Property(
1369 &protos::TracePacket::for_testing,
1370 Property(&protos::TestEvent::str, Eq("payload2")))));
1371 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1372 Property(&protos::TestEvent::str,
1373 Eq("payload3"))))));
1374
1375 // Write some more packets.
1376 writer->NewTracePacket()->set_for_testing()->set_str("payload4");
1377 writer->NewTracePacket()->set_for_testing()->set_str("payload5");
1378
1379 // Don't reply to flush, causing a timeout. This should scrape again.
1380 flush_request = consumer->Flush(/*timeout=*/100);
1381 producer->WaitForFlush(nullptr, /*reply=*/false);
1382 ASSERT_FALSE(flush_request.WaitForReply());
1383
1384 // Chunk with the packets should have been scraped again, overriding the
1385 // original one. Again, the last packet should be ignored and the first two
1386 // should not be read twice.
1387 packets = consumer->ReadBuffers();
1388 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1389 Property(&protos::TestEvent::str,
1390 Eq("payload1"))))));
1391 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1392 Property(&protos::TestEvent::str,
1393 Eq("payload2"))))));
1394 EXPECT_THAT(packets, Contains(Property(
1395 &protos::TracePacket::for_testing,
1396 Property(&protos::TestEvent::str, Eq("payload3")))));
1397 EXPECT_THAT(packets, Contains(Property(
1398 &protos::TracePacket::for_testing,
1399 Property(&protos::TestEvent::str, Eq("payload4")))));
1400 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1401 Property(&protos::TestEvent::str,
1402 Eq("payload5"))))));
1403
1404 consumer->DisableTracing();
1405 producer->WaitForDataSourceStop("data_source");
1406 consumer->WaitForTracingDisabled();
1407}
1408
1409// Test scraping on producer disconnect.
1410TEST_F(TracingServiceImplTest, ScrapeBuffersOnProducerDisconnect) {
1411 svc->SetSMBScrapingEnabled(true);
1412
1413 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1414 consumer->Connect(svc.get());
1415
1416 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1417 producer->Connect(svc.get(), "mock_producer");
1418 ProducerID producer_id = *last_producer_id();
1419 producer->RegisterDataSource("data_source");
1420
1421 TraceConfig trace_config;
1422 trace_config.add_buffers()->set_size_kb(128);
1423 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1424 ds_config->set_name("data_source");
1425 ds_config->set_target_buffer(0);
1426 consumer->EnableTracing(trace_config);
1427
1428 producer->WaitForTracingSetup();
1429 producer->WaitForDataSourceSetup("data_source");
1430 producer->WaitForDataSourceStart("data_source");
1431
1432 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1433 // trace config didn't have the |deferred_start| flag set.
1434 consumer->StartTracing();
1435
1436 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1437 tracing_session()->buffers_index[0]);
1438 WaitForTraceWritersChanged(producer_id);
1439
1440 // Write a few trace packets.
1441 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
1442 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
1443 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
1444
1445 // Disconnect the producer without committing the chunk. This should cause a
1446 // scrape of the SMB. Avoid destroying the ShmemArbiter until writer is
1447 // destroyed.
1448 auto shmem_arbiter = TakeShmemArbiterForProducer(producer_id);
1449 producer.reset();
1450
1451 // Chunk with the packets should have been scraped. The service can't know
1452 // whether the last packet was completed, so shouldn't read it.
1453 auto packets = consumer->ReadBuffers();
1454 EXPECT_THAT(packets, Contains(Property(
1455 &protos::TracePacket::for_testing,
1456 Property(&protos::TestEvent::str, Eq("payload1")))));
1457 EXPECT_THAT(packets, Contains(Property(
1458 &protos::TracePacket::for_testing,
1459 Property(&protos::TestEvent::str, Eq("payload2")))));
1460 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1461 Property(&protos::TestEvent::str,
1462 Eq("payload3"))))));
1463
1464 // Cleanup writer without causing a crash because the producer already went
1465 // away.
1466 static_cast<TraceWriterImpl*>(writer.get())->ResetChunkForTesting();
1467 writer.reset();
1468 shmem_arbiter.reset();
1469
1470 consumer->DisableTracing();
1471 consumer->WaitForTracingDisabled();
1472}
1473
1474TEST_F(TracingServiceImplTest, ScrapeBuffersOnDisable) {
1475 svc->SetSMBScrapingEnabled(true);
1476
1477 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1478 consumer->Connect(svc.get());
1479
1480 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1481 producer->Connect(svc.get(), "mock_producer");
1482 ProducerID producer_id = *last_producer_id();
1483 producer->RegisterDataSource("data_source");
1484
1485 TraceConfig trace_config;
1486 trace_config.add_buffers()->set_size_kb(128);
1487 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1488 ds_config->set_name("data_source");
1489 ds_config->set_target_buffer(0);
1490 consumer->EnableTracing(trace_config);
1491
1492 producer->WaitForTracingSetup();
1493 producer->WaitForDataSourceSetup("data_source");
1494 producer->WaitForDataSourceStart("data_source");
1495
1496 // Calling StartTracing() should be a noop (% a DLOG statement) because the
1497 // trace config didn't have the |deferred_start| flag set.
1498 consumer->StartTracing();
1499
1500 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
1501 tracing_session()->buffers_index[0]);
1502 WaitForTraceWritersChanged(producer_id);
1503
1504 // Write a few trace packets.
1505 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
1506 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
1507 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
1508
1509 consumer->DisableTracing();
1510 producer->WaitForDataSourceStop("data_source");
1511 consumer->WaitForTracingDisabled();
1512
1513 // Chunk with the packets should have been scraped. The service can't know
1514 // whether the last packet was completed, so shouldn't read it.
1515 auto packets = consumer->ReadBuffers();
1516 EXPECT_THAT(packets, Contains(Property(
1517 &protos::TracePacket::for_testing,
1518 Property(&protos::TestEvent::str, Eq("payload1")))));
1519 EXPECT_THAT(packets, Contains(Property(
1520 &protos::TracePacket::for_testing,
1521 Property(&protos::TestEvent::str, Eq("payload2")))));
1522 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1523 Property(&protos::TestEvent::str,
1524 Eq("payload3"))))));
1525}
1526
Primiano Tucciff7beab2019-01-09 21:49:20 +00001527TEST_F(TracingServiceImplTest, AbortIfTraceDurationIsTooLong) {
1528 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1529 consumer->Connect(svc.get());
1530
1531 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1532 producer->Connect(svc.get(), "mock_producer");
1533 producer->RegisterDataSource("datasource");
1534
1535 TraceConfig trace_config;
1536 trace_config.add_buffers()->set_size_kb(128);
1537 trace_config.add_data_sources()->mutable_config()->set_name("datasource");
1538 trace_config.set_duration_ms(0x7fffffff);
1539
1540 EXPECT_CALL(*producer, SetupDataSource(_, _)).Times(0);
1541 consumer->EnableTracing(trace_config);
1542
1543 // The trace is aborted immediately, 5s here is just some slack for the thread
1544 // ping-pongs for slow devices.
1545 consumer->WaitForTracingDisabled(5000);
1546}
1547
Eric Secklereaf29ed2019-01-23 09:53:55 +00001548TEST_F(TracingServiceImplTest, GetTraceStats) {
1549 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1550 consumer->Connect(svc.get());
1551
1552 consumer->GetTraceStats();
1553 consumer->WaitForTraceStats(false);
1554
1555 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1556 producer->Connect(svc.get(), "mock_producer");
1557 producer->RegisterDataSource("data_source");
1558
1559 TraceConfig trace_config;
1560 trace_config.add_buffers()->set_size_kb(128);
1561 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1562 ds_config->set_name("data_source");
1563
1564 consumer->EnableTracing(trace_config);
1565 producer->WaitForTracingSetup();
1566 producer->WaitForDataSourceSetup("data_source");
1567 producer->WaitForDataSourceStart("data_source");
1568
1569 consumer->GetTraceStats();
1570 consumer->WaitForTraceStats(true);
1571
1572 consumer->DisableTracing();
1573 producer->WaitForDataSourceStop("data_source");
1574 consumer->WaitForTracingDisabled();
1575}
1576
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00001577} // namespace perfetto