blob: 7a26c2a54bae955f3ba5471ab4713d76b4085fe1 [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
Hector Dearmancdfd85b2019-05-31 16:49:14 +010021#include <gmock/gmock.h>
22#include <gtest/gtest.h>
Primiano Tucci2c5488f2019-06-01 03:27:28 +010023#include "perfetto/ext/base/file_utils.h"
24#include "perfetto/ext/base/temp_file.h"
25#include "perfetto/ext/base/utils.h"
26#include "perfetto/ext/tracing/core/consumer.h"
Primiano Tucci2c5488f2019-06-01 03:27:28 +010027#include "perfetto/ext/tracing/core/producer.h"
28#include "perfetto/ext/tracing/core/shared_memory.h"
29#include "perfetto/ext/tracing/core/trace_packet.h"
30#include "perfetto/ext/tracing/core/trace_writer.h"
Primiano Tucci0f9e0222019-06-05 09:36:41 +010031#include "perfetto/tracing/core/data_source_config.h"
32#include "perfetto/tracing/core/data_source_descriptor.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::_;
Hector Dearmanbb3bc482019-08-02 11:54:08 +010046using ::testing::AssertionFailure;
47using ::testing::AssertionResult;
48using ::testing::AssertionSuccess;
Primiano Tuccidca727d2018-04-04 11:31:55 +020049using ::testing::Contains;
Primiano Tucci1a1951d2018-04-04 21:08:16 +020050using ::testing::ElementsAreArray;
Primiano Tuccidca727d2018-04-04 11:31:55 +020051using ::testing::Eq;
Hector Dearmanbb3bc482019-08-02 11:54:08 +010052using ::testing::ExplainMatchResult;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000053using ::testing::InSequence;
Primiano Tucci081d46a2018-02-28 11:09:43 +000054using ::testing::Invoke;
Primiano Tuccidca727d2018-04-04 11:31:55 +020055using ::testing::InvokeWithoutArgs;
Hector Dearmanbb3bc482019-08-02 11:54:08 +010056using ::testing::IsEmpty;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000057using ::testing::Mock;
Eric Secklerdd0ad102018-12-06 11:32:04 +000058using ::testing::Not;
Primiano Tuccidca727d2018-04-04 11:31:55 +020059using ::testing::Property;
60using ::testing::StrictMock;
Hector Dearmanbb3bc482019-08-02 11:54:08 +010061using ::testing::StringMatchResultListener;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000062
Primiano Tuccidca727d2018-04-04 11:31:55 +020063namespace perfetto {
Sami Kyostila32e0b542018-02-14 08:55:43 +000064
Primiano Tucci1a1951d2018-04-04 21:08:16 +020065namespace {
Florian Mayer6a1a4d52018-06-08 16:47:07 +010066constexpr size_t kDefaultShmSizeKb = TracingServiceImpl::kDefaultShmSize / 1024;
Nicolò Mazzucato693f6aa2019-07-08 10:26:09 +010067constexpr size_t kDefaultShmPageSizeKb =
68 TracingServiceImpl::kDefaultShmPageSize / 1024;
Florian Mayer6a1a4d52018-06-08 16:47:07 +010069constexpr size_t kMaxShmSizeKb = TracingServiceImpl::kMaxShmSize / 1024;
Stephen Nusko1393ffd2019-03-22 13:54:58 +000070
Hector Dearmanbb3bc482019-08-02 11:54:08 +010071AssertionResult HasTriggerModeInternal(
Stephen Nusko1393ffd2019-03-22 13:54:58 +000072 const std::vector<protos::TracePacket>& packets,
73 protos::TraceConfig::TriggerConfig::TriggerMode mode) {
Hector Dearmanbb3bc482019-08-02 11:54:08 +010074 StringMatchResultListener matcher_result_string;
75 bool contains = ExplainMatchResult(
Stephen Nusko1393ffd2019-03-22 13:54:58 +000076 Contains(Property(
77 &protos::TracePacket::trace_config,
78 Property(&protos::TraceConfig::trigger_config,
79 Property(&protos::TraceConfig::TriggerConfig::trigger_mode,
80 Eq(mode))))),
81 packets, &matcher_result_string);
82 if (contains) {
Hector Dearmanbb3bc482019-08-02 11:54:08 +010083 return AssertionSuccess();
Stephen Nusko1393ffd2019-03-22 13:54:58 +000084 }
Hector Dearmanbb3bc482019-08-02 11:54:08 +010085 return AssertionFailure() << matcher_result_string.str();
Stephen Nusko1393ffd2019-03-22 13:54:58 +000086}
87
88MATCHER_P(HasTriggerMode, mode, "") {
89 return HasTriggerModeInternal(arg, mode);
90}
91
Primiano Tucci1a1951d2018-04-04 21:08:16 +020092} // namespace
93
Florian Mayer6a1a4d52018-06-08 16:47:07 +010094class TracingServiceImplTest : public testing::Test {
Sami Kyostila06487a22018-02-27 13:48:38 +000095 public:
Eric Seckler4ff03e52019-03-15 10:10:30 +000096 using DataSourceInstanceState =
97 TracingServiceImpl::DataSourceInstance::DataSourceInstanceState;
98
Florian Mayer6a1a4d52018-06-08 16:47:07 +010099 TracingServiceImplTest() {
Sami Kyostila06487a22018-02-27 13:48:38 +0000100 auto shm_factory =
101 std::unique_ptr<SharedMemory::Factory>(new TestSharedMemory::Factory());
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100102 svc.reset(static_cast<TracingServiceImpl*>(
103 TracingService::CreateInstance(std::move(shm_factory), &task_runner)
Sami Kyostila06487a22018-02-27 13:48:38 +0000104 .release()));
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100105 svc->min_write_period_ms_ = 1;
Sami Kyostila06487a22018-02-27 13:48:38 +0000106 }
107
Primiano Tuccidca727d2018-04-04 11:31:55 +0200108 std::unique_ptr<MockProducer> CreateMockProducer() {
109 return std::unique_ptr<MockProducer>(
110 new StrictMock<MockProducer>(&task_runner));
111 }
112
113 std::unique_ptr<MockConsumer> CreateMockConsumer() {
114 return std::unique_ptr<MockConsumer>(
115 new StrictMock<MockConsumer>(&task_runner));
116 }
117
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200118 ProducerID* last_producer_id() { return &svc->last_producer_id_; }
119
120 uid_t GetProducerUid(ProducerID producer_id) {
121 return svc->GetProducer(producer_id)->uid_;
122 }
123
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000124 TracingServiceImpl::TracingSession* GetTracingSession(TracingSessionID tsid) {
125 auto* session = svc->GetTracingSession(tsid);
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100126 EXPECT_NE(nullptr, session);
127 return session;
128 }
129
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000130 TracingServiceImpl::TracingSession* tracing_session() {
131 return GetTracingSession(GetTracingSessionID());
132 }
133
134 TracingSessionID GetTracingSessionID() {
135 return svc->last_tracing_session_id_;
136 }
137
Eric Seckler6dc23592018-11-30 10:59:06 +0000138 const std::set<BufferID>& GetAllowedTargetBuffers(ProducerID producer_id) {
139 return svc->GetProducer(producer_id)->allowed_target_buffers_;
140 }
141
Eric Secklerf3f524b2018-12-13 09:09:34 +0000142 const std::map<WriterID, BufferID>& GetWriters(ProducerID producer_id) {
143 return svc->GetProducer(producer_id)->writers_;
144 }
145
Eric Secklera01e28a2019-01-08 11:21:04 +0000146 std::unique_ptr<SharedMemoryArbiterImpl> TakeShmemArbiterForProducer(
147 ProducerID producer_id) {
148 return std::move(svc->GetProducer(producer_id)->inproc_shmem_arbiter_);
149 }
150
Primiano Tuccid52e6272018-04-06 19:06:53 +0200151 size_t GetNumPendingFlushes() {
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100152 return tracing_session()->pending_flushes.size();
153 }
154
155 void WaitForNextSyncMarker() {
156 tracing_session()->last_snapshot_time = base::TimeMillis(0);
157 static int attempt = 0;
158 while (tracing_session()->last_snapshot_time == base::TimeMillis(0)) {
159 auto checkpoint_name = "wait_snapshot_" + std::to_string(attempt++);
160 auto timer_expired = task_runner.CreateCheckpoint(checkpoint_name);
161 task_runner.PostDelayedTask([timer_expired] { timer_expired(); }, 1);
162 task_runner.RunUntilCheckpoint(checkpoint_name);
163 }
Primiano Tuccid52e6272018-04-06 19:06:53 +0200164 }
165
Eric Secklerf3f524b2018-12-13 09:09:34 +0000166 void WaitForTraceWritersChanged(ProducerID producer_id) {
167 static int i = 0;
168 auto checkpoint_name = "writers_changed_" + std::to_string(producer_id) +
169 "_" + std::to_string(i++);
170 auto writers_changed = task_runner.CreateCheckpoint(checkpoint_name);
171 auto writers = GetWriters(producer_id);
172 std::function<void()> task;
173 task = [&task, writers, writers_changed, producer_id, this]() {
174 if (writers != GetWriters(producer_id)) {
175 writers_changed();
176 return;
177 }
178 task_runner.PostDelayedTask(task, 1);
179 };
180 task_runner.PostDelayedTask(task, 1);
181 task_runner.RunUntilCheckpoint(checkpoint_name);
182 }
183
Eric Seckler4ff03e52019-03-15 10:10:30 +0000184 DataSourceInstanceState GetDataSourceInstanceState(const std::string& name) {
185 for (const auto& kv : tracing_session()->data_source_instances) {
186 if (kv.second.data_source_name == name)
187 return kv.second.state;
188 }
189 PERFETTO_FATAL("Can't find data source instance with name %s",
190 name.c_str());
191 }
192
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000193 base::TestTaskRunner task_runner;
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100194 std::unique_ptr<TracingServiceImpl> svc;
Sami Kyostila06487a22018-02-27 13:48:38 +0000195};
196
Hector Dearmanfb4d0732019-05-19 15:44:56 +0100197TEST_F(TracingServiceImplTest, AtMostOneConfig) {
198 std::unique_ptr<MockConsumer> consumer_a = CreateMockConsumer();
199 std::unique_ptr<MockConsumer> consumer_b = CreateMockConsumer();
200
201 consumer_a->Connect(svc.get());
202 consumer_b->Connect(svc.get());
203
204 TraceConfig trace_config_a;
205 trace_config_a.add_buffers()->set_size_kb(128);
206 trace_config_a.set_duration_ms(0);
207 trace_config_a.set_unique_session_name("foo");
208
209 TraceConfig trace_config_b;
210 trace_config_b.add_buffers()->set_size_kb(128);
211 trace_config_b.set_duration_ms(0);
212 trace_config_b.set_unique_session_name("foo");
213
214 consumer_a->EnableTracing(trace_config_a);
215 consumer_b->EnableTracing(trace_config_b);
216
217 // This will stop immediately since it has the same unique session name.
218 consumer_b->WaitForTracingDisabled();
219
220 consumer_a->DisableTracing();
221 consumer_a->WaitForTracingDisabled();
Hector Dearmaneb5c71e2019-07-30 14:00:23 +0100222
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100223 EXPECT_THAT(consumer_b->ReadBuffers(), IsEmpty());
Hector Dearmanfb4d0732019-05-19 15:44:56 +0100224}
225
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100226TEST_F(TracingServiceImplTest, RegisterAndUnregister) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200227 std::unique_ptr<MockProducer> mock_producer_1 = CreateMockProducer();
228 std::unique_ptr<MockProducer> mock_producer_2 = CreateMockProducer();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000229
Primiano Tuccidca727d2018-04-04 11:31:55 +0200230 mock_producer_1->Connect(svc.get(), "mock_producer_1", 123u /* uid */);
231 mock_producer_2->Connect(svc.get(), "mock_producer_2", 456u /* uid */);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000232
233 ASSERT_EQ(2u, svc->num_producers());
Primiano Tuccidca727d2018-04-04 11:31:55 +0200234 ASSERT_EQ(mock_producer_1->endpoint(), svc->GetProducer(1));
235 ASSERT_EQ(mock_producer_2->endpoint(), svc->GetProducer(2));
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200236 ASSERT_EQ(123u, GetProducerUid(1));
237 ASSERT_EQ(456u, GetProducerUid(2));
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000238
Primiano Tuccidca727d2018-04-04 11:31:55 +0200239 mock_producer_1->RegisterDataSource("foo");
240 mock_producer_2->RegisterDataSource("bar");
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000241
Primiano Tuccidca727d2018-04-04 11:31:55 +0200242 mock_producer_1->UnregisterDataSource("foo");
243 mock_producer_2->UnregisterDataSource("bar");
Primiano Tucci9daa4832018-03-28 23:28:17 +0100244
Primiano Tuccidca727d2018-04-04 11:31:55 +0200245 mock_producer_1.reset();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000246 ASSERT_EQ(1u, svc->num_producers());
247 ASSERT_EQ(nullptr, svc->GetProducer(1));
248
Primiano Tuccidca727d2018-04-04 11:31:55 +0200249 mock_producer_2.reset();
250 ASSERT_EQ(nullptr, svc->GetProducer(2));
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000251
252 ASSERT_EQ(0u, svc->num_producers());
253}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100254
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100255TEST_F(TracingServiceImplTest, EnableAndDisableTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200256 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
257 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +0000258
Primiano Tuccidca727d2018-04-04 11:31:55 +0200259 std::unique_ptr<MockProducer> producer = CreateMockProducer();
260 producer->Connect(svc.get(), "mock_producer");
261 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000262
Sami Kyostila06487a22018-02-27 13:48:38 +0000263 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200264 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +0000265 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200266 ds_config->set_name("data_source");
267 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +0000268
Primiano Tuccidca727d2018-04-04 11:31:55 +0200269 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100270 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200271 producer->WaitForDataSourceStart("data_source");
272
Primiano Tucci674076d2018-10-01 10:41:09 +0100273 // Calling StartTracing() should be a noop (% a DLOG statement) because the
274 // trace config didn't have the |deferred_start| flag set.
275 consumer->StartTracing();
276
Primiano Tuccidca727d2018-04-04 11:31:55 +0200277 consumer->DisableTracing();
278 producer->WaitForDataSourceStop("data_source");
279 consumer->WaitForTracingDisabled();
Sami Kyostila06487a22018-02-27 13:48:38 +0000280}
281
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000282// Creates a tracing session with a START_TRACING trigger and checks that data
283// sources are started only after the service receives a trigger.
284TEST_F(TracingServiceImplTest, StartTracingTriggerDeferredStart) {
285 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
286 consumer->Connect(svc.get());
287
288 std::unique_ptr<MockProducer> producer = CreateMockProducer();
289 producer->Connect(svc.get(), "mock_producer");
290
291 // Create two data sources but enable only one of them.
292 producer->RegisterDataSource("ds_1");
293 producer->RegisterDataSource("ds_2");
294
295 TraceConfig trace_config;
296 trace_config.add_buffers()->set_size_kb(128);
297 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
298 auto* trigger_config = trace_config.mutable_trigger_config();
299 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
300 auto* trigger = trigger_config->add_triggers();
301 trigger->set_name("trigger_name");
302 trigger->set_stop_delay_ms(1);
303
304 trigger_config->set_trigger_timeout_ms(8.64e+7);
305
306 // Make sure we don't get unexpected DataSourceStart() notifications yet.
307 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
308
309 consumer->EnableTracing(trace_config);
310 producer->WaitForTracingSetup();
311
312 producer->WaitForDataSourceSetup("ds_1");
313
314 // The trace won't start until we send the trigger. since we have a
315 // START_TRACING trigger defined.
316 std::vector<std::string> req;
317 req.push_back("trigger_name");
318 producer->endpoint()->ActivateTriggers(req);
319
320 producer->WaitForDataSourceStart("ds_1");
321
322 auto writer1 = producer->CreateTraceWriter("ds_1");
323 producer->WaitForFlush(writer1.get());
324
325 producer->WaitForDataSourceStop("ds_1");
326 consumer->WaitForTracingDisabled();
327
328 ASSERT_EQ(1u, tracing_session()->received_triggers.size());
329 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100330 tracing_session()->received_triggers[0].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000331
332 EXPECT_THAT(
333 consumer->ReadBuffers(),
334 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
335}
336
337// Creates a tracing session with a START_TRACING trigger and checks that the
338// session is cleaned up when no trigger is received after |trigger_timeout_ms|.
339TEST_F(TracingServiceImplTest, StartTracingTriggerTimeOut) {
340 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
341 consumer->Connect(svc.get());
342
343 std::unique_ptr<MockProducer> producer = CreateMockProducer();
344 producer->Connect(svc.get(), "mock_producer");
345
346 // Create two data sources but enable only one of them.
347 producer->RegisterDataSource("ds_1");
348 producer->RegisterDataSource("ds_2");
349
350 TraceConfig trace_config;
351 trace_config.add_buffers()->set_size_kb(128);
352 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
353 auto* trigger_config = trace_config.mutable_trigger_config();
354 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
355 auto* trigger = trigger_config->add_triggers();
356 trigger->set_name("trigger_name");
357 trigger->set_stop_delay_ms(8.64e+7);
358
359 trigger_config->set_trigger_timeout_ms(1);
360
361 // Make sure we don't get unexpected DataSourceStart() notifications yet.
362 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
363
364 consumer->EnableTracing(trace_config);
365 producer->WaitForTracingSetup();
366
367 producer->WaitForDataSourceSetup("ds_1");
368
369 // The trace won't start until we send the trigger. since we have a
370 // START_TRACING trigger defined. This is where we'd expect to have an
371 // ActivateTriggers call to the producer->endpoint().
372
373 producer->WaitForDataSourceStop("ds_1");
374 consumer->WaitForTracingDisabled();
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100375 EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000376}
377
378// Creates a tracing session with a START_TRACING trigger and checks that
379// the session is not started when the configured trigger producer is different
380// than the producer that sent the trigger.
381TEST_F(TracingServiceImplTest, StartTracingTriggerDifferentProducer) {
382 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
383 consumer->Connect(svc.get());
384
385 std::unique_ptr<MockProducer> producer = CreateMockProducer();
386 producer->Connect(svc.get(), "mock_producer");
387
388 // Create two data sources but enable only one of them.
389 producer->RegisterDataSource("ds_1");
390 producer->RegisterDataSource("ds_2");
391
392 TraceConfig trace_config;
393 trace_config.add_buffers()->set_size_kb(128);
394 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
395 auto* trigger_config = trace_config.mutable_trigger_config();
396 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
397 auto* trigger = trigger_config->add_triggers();
398 trigger->set_name("trigger_name");
399 trigger->set_stop_delay_ms(8.64e+7);
400 trigger->set_producer_name_regex("correct_name");
401
402 trigger_config->set_trigger_timeout_ms(1);
403
404 // Make sure we don't get unexpected DataSourceStart() notifications yet.
405 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
406
407 consumer->EnableTracing(trace_config);
408 producer->WaitForTracingSetup();
409
410 producer->WaitForDataSourceSetup("ds_1");
411
412 // The trace won't start until we send the trigger called "trigger_name"
413 // coming from a producer called "correct_name", since we have a
414 // START_TRACING trigger defined. This is where we'd expect to have an
415 // ActivateTriggers call to the producer->endpoint(), but we send the trigger
416 // from a different producer so it is ignored.
417 std::vector<std::string> req;
418 req.push_back("trigger_name");
419 producer->endpoint()->ActivateTriggers(req);
420
421 producer->WaitForDataSourceStop("ds_1");
422 consumer->WaitForTracingDisabled();
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100423 EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000424}
425
426// Creates a tracing session with a START_TRACING trigger and checks that the
427// session is started when the trigger is received from the correct producer.
428TEST_F(TracingServiceImplTest, StartTracingTriggerCorrectProducer) {
429 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
430 consumer->Connect(svc.get());
431
432 std::unique_ptr<MockProducer> producer = CreateMockProducer();
433 producer->Connect(svc.get(), "mock_producer");
434
435 // Create two data sources but enable only one of them.
436 producer->RegisterDataSource("ds_1");
437 producer->RegisterDataSource("ds_2");
438
439 TraceConfig trace_config;
440 trace_config.add_buffers()->set_size_kb(128);
441 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
442 auto* trigger_config = trace_config.mutable_trigger_config();
443 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
444 auto* trigger = trigger_config->add_triggers();
445 trigger->set_name("trigger_name");
446 trigger->set_stop_delay_ms(1);
447 trigger->set_producer_name_regex("mock_produc[e-r]+");
448
449 trigger_config->set_trigger_timeout_ms(8.64e+7);
450
451 consumer->EnableTracing(trace_config);
452 producer->WaitForTracingSetup();
453
454 producer->WaitForDataSourceSetup("ds_1");
455
456 // Start the trace at this point with ActivateTriggers.
457 std::vector<std::string> req;
458 req.push_back("trigger_name");
459 producer->endpoint()->ActivateTriggers(req);
460
461 producer->WaitForDataSourceStart("ds_1");
462
463 auto writer = producer->CreateTraceWriter("ds_1");
464 producer->WaitForFlush(writer.get());
465
466 producer->WaitForDataSourceStop("ds_1");
467 consumer->WaitForTracingDisabled();
468 EXPECT_THAT(
469 consumer->ReadBuffers(),
470 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
471}
472
473// Creates a tracing session with a START_TRACING trigger and checks that the
474// session is cleaned up even when a different trigger is received.
475TEST_F(TracingServiceImplTest, StartTracingTriggerDifferentTrigger) {
476 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
477 consumer->Connect(svc.get());
478
479 std::unique_ptr<MockProducer> producer = CreateMockProducer();
480 producer->Connect(svc.get(), "mock_producer");
481
482 // Create two data sources but enable only one of them.
483 producer->RegisterDataSource("ds_1");
484 producer->RegisterDataSource("ds_2");
485
486 TraceConfig trace_config;
487 trace_config.add_buffers()->set_size_kb(128);
488 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
489 auto* trigger_config = trace_config.mutable_trigger_config();
490 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
491 auto* trigger = trigger_config->add_triggers();
492 trigger->set_name("trigger_name");
493 trigger->set_stop_delay_ms(8.64e+7);
494
495 trigger_config->set_trigger_timeout_ms(1);
496
497 // Make sure we don't get unexpected DataSourceStart() notifications yet.
498 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
499
500 consumer->EnableTracing(trace_config);
501 producer->WaitForTracingSetup();
502
503 producer->WaitForDataSourceSetup("ds_1");
504
505 // The trace won't start until we send the trigger called "trigger_name",
506 // since we have a START_TRACING trigger defined. This is where we'd expect to
507 // have an ActivateTriggers call to the producer->endpoint(), but we send a
508 // different trigger.
509 std::vector<std::string> req;
510 req.push_back("not_correct_trigger");
511 producer->endpoint()->ActivateTriggers(req);
512
513 producer->WaitForDataSourceStop("ds_1");
514 consumer->WaitForTracingDisabled();
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100515 EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000516}
517
518// Creates a tracing session with a START_TRACING trigger and checks that any
519// trigger can start the TracingSession.
520TEST_F(TracingServiceImplTest, StartTracingTriggerMultipleTriggers) {
521 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
522 consumer->Connect(svc.get());
523
524 std::unique_ptr<MockProducer> producer = CreateMockProducer();
525 producer->Connect(svc.get(), "mock_producer");
526
527 // Create two data sources but enable only one of them.
528 producer->RegisterDataSource("ds_1");
529 producer->RegisterDataSource("ds_2");
530
531 TraceConfig trace_config;
532 trace_config.add_buffers()->set_size_kb(128);
533 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
534 auto* trigger_config = trace_config.mutable_trigger_config();
535 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
536 auto* trigger = trigger_config->add_triggers();
537 trigger->set_name("trigger_name");
538 trigger->set_stop_delay_ms(1);
539
540 trigger_config->set_trigger_timeout_ms(8.64e+7);
541
542 consumer->EnableTracing(trace_config);
543 producer->WaitForTracingSetup();
544
545 producer->WaitForDataSourceSetup("ds_1");
546
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000547 std::vector<std::string> req;
548 req.push_back("not_correct_trigger");
549 req.push_back("trigger_name");
550 producer->endpoint()->ActivateTriggers(req);
551
552 producer->WaitForDataSourceStart("ds_1");
553
554 auto writer = producer->CreateTraceWriter("ds_1");
555 producer->WaitForFlush(writer.get());
556
557 producer->WaitForDataSourceStop("ds_1");
558 consumer->WaitForTracingDisabled();
559 EXPECT_THAT(
560 consumer->ReadBuffers(),
561 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
562}
563
564// Creates two tracing sessions with a START_TRACING trigger and checks that
565// both are able to be triggered simultaneously.
566TEST_F(TracingServiceImplTest, StartTracingTriggerMultipleTraces) {
567 std::unique_ptr<MockConsumer> consumer_1 = CreateMockConsumer();
568 consumer_1->Connect(svc.get());
569 std::unique_ptr<MockConsumer> consumer_2 = CreateMockConsumer();
570 consumer_2->Connect(svc.get());
571
572 std::unique_ptr<MockProducer> producer = CreateMockProducer();
573 producer->Connect(svc.get(), "mock_producer");
574
575 // Create two data sources but each TracingSession will only enable one of
576 // them.
577 producer->RegisterDataSource("ds_1");
578 producer->RegisterDataSource("ds_2");
579
580 TraceConfig trace_config;
581 trace_config.add_buffers()->set_size_kb(128);
582 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
583 auto* trigger_config = trace_config.mutable_trigger_config();
584 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
585 auto* trigger = trigger_config->add_triggers();
586 trigger->set_name("trigger_name");
587 trigger->set_stop_delay_ms(1);
588
589 trigger_config->set_trigger_timeout_ms(8.64e+7);
590
591 consumer_1->EnableTracing(trace_config);
592 producer->WaitForTracingSetup();
593
594 producer->WaitForDataSourceSetup("ds_1");
595
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000596 auto tracing_session_1_id = GetTracingSessionID();
597
598 (*trace_config.mutable_data_sources())[0].mutable_config()->set_name("ds_2");
599 trigger = trace_config.mutable_trigger_config()->add_triggers();
600 trigger->set_name("trigger_name_2");
601 trigger->set_stop_delay_ms(8.64e+7);
602
603 consumer_2->EnableTracing(trace_config);
604
605 producer->WaitForDataSourceSetup("ds_2");
606
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000607 auto tracing_session_2_id = GetTracingSessionID();
608 EXPECT_NE(tracing_session_1_id, tracing_session_2_id);
609
610 const DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_1");
611 const DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_2");
612
613 std::vector<std::string> req;
614 req.push_back("not_correct_trigger");
615 req.push_back("trigger_name");
616 req.push_back("trigger_name_2");
617 producer->endpoint()->ActivateTriggers(req);
618
619 // The order has to be the same as the triggers or else we're incorrectly wait
620 // on the wrong checkpoint in the |task_runner|.
621 producer->WaitForDataSourceStart("ds_1");
622 producer->WaitForDataSourceStart("ds_2");
623
624 // Now that they've started we can check the triggers they've seen.
625 auto* tracing_session_1 = GetTracingSession(tracing_session_1_id);
626 ASSERT_EQ(1u, tracing_session_1->received_triggers.size());
627 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100628 tracing_session_1->received_triggers[0].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000629
630 // This is actually dependent on the order in which the triggers were received
631 // but there isn't really a better way than iteration order so probably not to
632 // brittle of a test. And this caught a real bug in implementation.
633 auto* tracing_session_2 = GetTracingSession(tracing_session_2_id);
634 ASSERT_EQ(2u, tracing_session_2->received_triggers.size());
635
636 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100637 tracing_session_2->received_triggers[0].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000638
639 EXPECT_EQ("trigger_name_2",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100640 tracing_session_2->received_triggers[1].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000641
642 auto writer1 = producer->CreateTraceWriter("ds_1");
643 auto writer2 = producer->CreateTraceWriter("ds_2");
644
645 // We can't use the standard WaitForX in the MockProducer and MockConsumer
646 // because they assume only a single trace is going on. So we perform our own
647 // expectations and wait at the end for the two consumers to receive
648 // OnTracingDisabled.
649 bool flushed_writer_1 = false;
650 bool flushed_writer_2 = false;
651 auto flush_correct_writer = [&](FlushRequestID flush_req_id,
652 const DataSourceInstanceID* id, size_t) {
653 if (*id == id1) {
654 flushed_writer_1 = true;
655 writer1->Flush();
656 producer->endpoint()->NotifyFlushComplete(flush_req_id);
657 } else if (*id == id2) {
658 flushed_writer_2 = true;
659 writer2->Flush();
660 producer->endpoint()->NotifyFlushComplete(flush_req_id);
661 }
662 };
663 EXPECT_CALL(*producer, Flush(_, _, _))
664 .WillOnce(Invoke(flush_correct_writer))
665 .WillOnce(Invoke(flush_correct_writer));
666
667 auto checkpoint_name = "on_tracing_disabled_consumer_1_and_2";
668 auto on_tracing_disabled = task_runner.CreateCheckpoint(checkpoint_name);
669 std::atomic<size_t> counter(0);
670 EXPECT_CALL(*consumer_1, OnTracingDisabled()).WillOnce(Invoke([&]() {
671 if (++counter == 2u) {
672 on_tracing_disabled();
673 }
674 }));
675 EXPECT_CALL(*consumer_2, OnTracingDisabled()).WillOnce(Invoke([&]() {
676 if (++counter == 2u) {
677 on_tracing_disabled();
678 }
679 }));
680
681 EXPECT_CALL(*producer, StopDataSource(id1));
682 EXPECT_CALL(*producer, StopDataSource(id2));
683
684 task_runner.RunUntilCheckpoint(checkpoint_name, 1000);
685
686 EXPECT_TRUE(flushed_writer_1);
687 EXPECT_TRUE(flushed_writer_2);
688 EXPECT_THAT(
689 consumer_1->ReadBuffers(),
690 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
691 EXPECT_THAT(
692 consumer_2->ReadBuffers(),
693 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
694}
695
Stephen Nusko70ea3302019-04-01 19:44:40 +0100696// Creates a tracing session with a START_TRACING trigger and checks that the
697// received_triggers are emitted as packets.
698TEST_F(TracingServiceImplTest, EmitTriggersWithStartTracingTrigger) {
699 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
700 consumer->Connect(svc.get());
701
702 std::unique_ptr<MockProducer> producer = CreateMockProducer();
703 producer->Connect(svc.get(), "mock_producer", /* uid = */ 123u);
704
705 producer->RegisterDataSource("ds_1");
706
707 TraceConfig trace_config;
708 trace_config.add_buffers()->set_size_kb(128);
709 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
710 auto* trigger_config = trace_config.mutable_trigger_config();
711 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
712 auto* trigger = trigger_config->add_triggers();
713 trigger->set_name("trigger_name");
714 trigger->set_stop_delay_ms(1);
715 trigger->set_producer_name_regex("mock_produc[e-r]+");
716
717 trigger_config->set_trigger_timeout_ms(30000);
718
719 consumer->EnableTracing(trace_config);
720 producer->WaitForTracingSetup();
721 producer->WaitForDataSourceSetup("ds_1");
722
723 // The trace won't start until we send the trigger since we have a
724 // START_TRACING trigger defined.
725 std::vector<std::string> req;
726 req.push_back("trigger_name");
727 req.push_back("trigger_name_2");
728 req.push_back("trigger_name_3");
729 producer->endpoint()->ActivateTriggers(req);
730
731 producer->WaitForDataSourceStart("ds_1");
732 auto writer1 = producer->CreateTraceWriter("ds_1");
733 producer->WaitForFlush(writer1.get());
734 producer->WaitForDataSourceStop("ds_1");
735 consumer->WaitForTracingDisabled();
736
737 ASSERT_EQ(1u, tracing_session()->received_triggers.size());
738 EXPECT_EQ("trigger_name",
739 tracing_session()->received_triggers[0].trigger_name);
740
741 auto packets = consumer->ReadBuffers();
742 EXPECT_THAT(
743 packets,
744 Contains(Property(
745 &protos::TracePacket::trace_config,
746 Property(
747 &protos::TraceConfig::trigger_config,
748 Property(
749 &protos::TraceConfig::TriggerConfig::trigger_mode,
750 Eq(protos::TraceConfig::TriggerConfig::START_TRACING))))));
751 auto expect_received_trigger = [&](const std::string& name) {
752 return Contains(AllOf(
753 Property(
754 &protos::TracePacket::trigger,
755 AllOf(Property(&protos::Trigger::trigger_name, Eq(name)),
Eric Secklerc4024b22019-04-02 15:37:08 +0000756 Property(&protos::Trigger::trusted_producer_uid, Eq(123)),
Stephen Nusko70ea3302019-04-01 19:44:40 +0100757 Property(&protos::Trigger::producer_name,
758 Eq("mock_producer")))),
759 Property(&protos::TracePacket::trusted_packet_sequence_id,
760 Eq(kServicePacketSequenceID))));
761 };
762 EXPECT_THAT(packets, expect_received_trigger("trigger_name"));
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100763 EXPECT_THAT(packets, Not(expect_received_trigger("trigger_name_2")));
764 EXPECT_THAT(packets, Not(expect_received_trigger("trigger_name_3")));
Stephen Nusko70ea3302019-04-01 19:44:40 +0100765}
766
767// Creates a tracing session with a START_TRACING trigger and checks that the
768// received_triggers are emitted as packets.
769TEST_F(TracingServiceImplTest, EmitTriggersWithStopTracingTrigger) {
770 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
771 consumer->Connect(svc.get());
772
773 std::unique_ptr<MockProducer> producer = CreateMockProducer();
774 producer->Connect(svc.get(), "mock_producer", /* uid = */ 321u);
775
776 producer->RegisterDataSource("ds_1");
777
778 TraceConfig trace_config;
779 trace_config.add_buffers()->set_size_kb(128);
780 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
781 auto* trigger_config = trace_config.mutable_trigger_config();
782 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
783 auto* trigger = trigger_config->add_triggers();
784 trigger->set_name("trigger_name");
785 trigger->set_stop_delay_ms(1);
786 trigger = trigger_config->add_triggers();
787 trigger->set_name("trigger_name_3");
788 trigger->set_stop_delay_ms(30000);
789
790 trigger_config->set_trigger_timeout_ms(30000);
791
792 consumer->EnableTracing(trace_config);
793 producer->WaitForTracingSetup();
794 producer->WaitForDataSourceSetup("ds_1");
795 producer->WaitForDataSourceStart("ds_1");
796
797 // The trace won't start until we send the trigger since we have a
798 // START_TRACING trigger defined.
799 std::vector<std::string> req;
800 req.push_back("trigger_name");
801 req.push_back("trigger_name_2");
802 req.push_back("trigger_name_3");
803 producer->endpoint()->ActivateTriggers(req);
804
805 auto writer1 = producer->CreateTraceWriter("ds_1");
806 producer->WaitForFlush(writer1.get());
807 producer->WaitForDataSourceStop("ds_1");
808 consumer->WaitForTracingDisabled();
809
810 ASSERT_EQ(2u, tracing_session()->received_triggers.size());
811 EXPECT_EQ("trigger_name",
812 tracing_session()->received_triggers[0].trigger_name);
813 EXPECT_EQ("trigger_name_3",
814 tracing_session()->received_triggers[1].trigger_name);
815
816 auto packets = consumer->ReadBuffers();
817 EXPECT_THAT(
818 packets,
819 Contains(Property(
820 &protos::TracePacket::trace_config,
821 Property(
822 &protos::TraceConfig::trigger_config,
823 Property(
824 &protos::TraceConfig::TriggerConfig::trigger_mode,
825 Eq(protos::TraceConfig::TriggerConfig::STOP_TRACING))))));
826
827 auto expect_received_trigger = [&](const std::string& name) {
828 return Contains(AllOf(
829 Property(
830 &protos::TracePacket::trigger,
831 AllOf(Property(&protos::Trigger::trigger_name, Eq(name)),
Eric Secklerc4024b22019-04-02 15:37:08 +0000832 Property(&protos::Trigger::trusted_producer_uid, Eq(321)),
Stephen Nusko70ea3302019-04-01 19:44:40 +0100833 Property(&protos::Trigger::producer_name,
834 Eq("mock_producer")))),
835 Property(&protos::TracePacket::trusted_packet_sequence_id,
836 Eq(kServicePacketSequenceID))));
837 };
838 EXPECT_THAT(packets, expect_received_trigger("trigger_name"));
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100839 EXPECT_THAT(packets, Not(expect_received_trigger("trigger_name_2")));
Stephen Nusko70ea3302019-04-01 19:44:40 +0100840 EXPECT_THAT(packets, expect_received_trigger("trigger_name_3"));
841}
842
843// Creates a tracing session with a START_TRACING trigger and checks that the
844// received_triggers are emitted as packets even ones after the initial
845// ReadBuffers() call.
846TEST_F(TracingServiceImplTest, EmitTriggersRepeatedly) {
847 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
848 consumer->Connect(svc.get());
849
850 std::unique_ptr<MockProducer> producer = CreateMockProducer();
851 producer->Connect(svc.get(), "mock_producer");
852
853 // Create two data sources but enable only one of them.
854 producer->RegisterDataSource("ds_1");
855 producer->RegisterDataSource("ds_2");
856
857 TraceConfig trace_config;
858 trace_config.add_buffers()->set_size_kb(128);
859 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
860 auto* trigger_config = trace_config.mutable_trigger_config();
861 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
862 auto* trigger = trigger_config->add_triggers();
863 trigger->set_name("trigger_name");
864 trigger->set_stop_delay_ms(1);
865 trigger = trigger_config->add_triggers();
866 trigger->set_name("trigger_name_2");
867 trigger->set_stop_delay_ms(1);
868
869 trigger_config->set_trigger_timeout_ms(30000);
870
871 auto expect_received_trigger = [&](const std::string& name) {
872 return Contains(
873 AllOf(Property(&protos::TracePacket::trigger,
874 AllOf(Property(&protos::Trigger::trigger_name, Eq(name)),
875 Property(&protos::Trigger::producer_name,
876 Eq("mock_producer")))),
877 Property(&protos::TracePacket::trusted_packet_sequence_id,
878 Eq(kServicePacketSequenceID))));
879 };
880
881 consumer->EnableTracing(trace_config);
882 producer->WaitForTracingSetup();
883 producer->WaitForDataSourceSetup("ds_1");
884 producer->WaitForDataSourceStart("ds_1");
885
886 // The trace won't start until we send the trigger. since we have a
887 // START_TRACING trigger defined.
888 producer->endpoint()->ActivateTriggers({"trigger_name"});
889
890 auto packets = consumer->ReadBuffers();
891 EXPECT_THAT(
892 packets,
893 Contains(Property(
894 &protos::TracePacket::trace_config,
895 Property(
896 &protos::TraceConfig::trigger_config,
897 Property(
898 &protos::TraceConfig::TriggerConfig::trigger_mode,
899 Eq(protos::TraceConfig::TriggerConfig::STOP_TRACING))))));
900 EXPECT_THAT(packets, expect_received_trigger("trigger_name"));
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100901 EXPECT_THAT(packets, Not(expect_received_trigger("trigger_name_2")));
Stephen Nusko70ea3302019-04-01 19:44:40 +0100902
903 // Send a new trigger.
904 producer->endpoint()->ActivateTriggers({"trigger_name_2"});
905
906 auto writer1 = producer->CreateTraceWriter("ds_1");
907 producer->WaitForFlush(writer1.get());
908 producer->WaitForDataSourceStop("ds_1");
909 consumer->WaitForTracingDisabled();
910
911 ASSERT_EQ(2u, tracing_session()->received_triggers.size());
912 EXPECT_EQ("trigger_name",
913 tracing_session()->received_triggers[0].trigger_name);
914 EXPECT_EQ("trigger_name_2",
915 tracing_session()->received_triggers[1].trigger_name);
916
917 packets = consumer->ReadBuffers();
918 // We don't rewrite the old trigger.
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100919 EXPECT_THAT(packets, Not(expect_received_trigger("trigger_name")));
Stephen Nusko70ea3302019-04-01 19:44:40 +0100920 EXPECT_THAT(packets, expect_received_trigger("trigger_name_2"));
921}
922
Stephen Nuskod95a7512019-03-22 13:59:39 +0000923// Creates a tracing session with a STOP_TRACING trigger and checks that the
924// session is cleaned up after |trigger_timeout_ms|.
925TEST_F(TracingServiceImplTest, StopTracingTriggerTimeout) {
926 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
927 consumer->Connect(svc.get());
928
929 std::unique_ptr<MockProducer> producer = CreateMockProducer();
930 producer->Connect(svc.get(), "mock_producer");
931
932 // Create two data sources but enable only one of them.
933 producer->RegisterDataSource("ds_1");
934 producer->RegisterDataSource("ds_2");
935
936 TraceConfig trace_config;
937 trace_config.add_buffers()->set_size_kb(128);
938 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
939 auto* trigger_config = trace_config.mutable_trigger_config();
940 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
941 auto* trigger = trigger_config->add_triggers();
942 trigger->set_name("trigger_name");
943 trigger->set_stop_delay_ms(8.64e+7);
944
945 trigger_config->set_trigger_timeout_ms(1);
946
947 // Make sure we don't get unexpected DataSourceStart() notifications yet.
948 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
949
950 consumer->EnableTracing(trace_config);
951 producer->WaitForTracingSetup();
952
953 producer->WaitForDataSourceSetup("ds_1");
954 producer->WaitForDataSourceStart("ds_1");
955
956 // The trace won't return data until unless we send a trigger at this point.
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100957 EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
Stephen Nuskod95a7512019-03-22 13:59:39 +0000958
959 auto writer = producer->CreateTraceWriter("ds_1");
960 producer->WaitForFlush(writer.get());
961
962 ASSERT_EQ(0u, tracing_session()->received_triggers.size());
963
964 producer->WaitForDataSourceStop("ds_1");
965 consumer->WaitForTracingDisabled();
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100966 EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
Stephen Nuskod95a7512019-03-22 13:59:39 +0000967}
968
969// Creates a tracing session with a STOP_TRACING trigger and checks that the
970// session returns data after a trigger is received, but only what is currently
971// in the buffer.
972TEST_F(TracingServiceImplTest, StopTracingTriggerRingBuffer) {
973 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
974 consumer->Connect(svc.get());
975
976 std::unique_ptr<MockProducer> producer = CreateMockProducer();
977 producer->Connect(svc.get(), "mock_producer");
978
979 // Create two data sources but enable only one of them.
980 producer->RegisterDataSource("ds_1");
981 producer->RegisterDataSource("ds_2");
982
983 TraceConfig trace_config;
984 trace_config.add_buffers()->set_size_kb(128);
985 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
986 auto* trigger_config = trace_config.mutable_trigger_config();
987 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
988 auto* trigger = trigger_config->add_triggers();
989 trigger->set_name("trigger_name");
990 trigger->set_stop_delay_ms(1);
991
992 trigger_config->set_trigger_timeout_ms(8.64e+7);
993
994 consumer->EnableTracing(trace_config);
995 producer->WaitForTracingSetup();
996
997 producer->WaitForDataSourceSetup("ds_1");
998 producer->WaitForDataSourceStart("ds_1");
999
Stephen Nuskod95a7512019-03-22 13:59:39 +00001000 // The trace won't return data until unless we send a trigger at this point.
Hector Dearmanbb3bc482019-08-02 11:54:08 +01001001 EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
Stephen Nuskod95a7512019-03-22 13:59:39 +00001002
1003 // We write into the buffer a large packet which takes up the whole buffer. We
1004 // then add a bunch of smaller ones which causes the larger packet to be
1005 // dropped. After we activate the session we should only see a bunch of the
1006 // smaller ones.
Eric Secklera883e5f2019-04-02 22:51:29 +00001007 static const size_t kNumTestPackets = 10;
Stephen Nuskod95a7512019-03-22 13:59:39 +00001008 static const char kPayload[] = "1234567890abcdef-";
1009
1010 auto writer = producer->CreateTraceWriter("ds_1");
1011 // Buffer is 1kb so we write a packet which is slightly smaller so it fits in
1012 // the buffer.
1013 const std::string large_payload(1024 * 128 - 20, 'a');
1014 {
1015 auto tp = writer->NewTracePacket();
1016 tp->set_for_testing()->set_str(large_payload.c_str(), large_payload.size());
1017 }
1018
1019 // Now we add a bunch of data before the trigger and after.
Eric Secklera883e5f2019-04-02 22:51:29 +00001020 for (size_t i = 0; i < kNumTestPackets; i++) {
Stephen Nuskod95a7512019-03-22 13:59:39 +00001021 if (i == kNumTestPackets / 2) {
1022 std::vector<std::string> req;
1023 req.push_back("trigger_name");
1024 producer->endpoint()->ActivateTriggers(req);
1025 }
1026 auto tp = writer->NewTracePacket();
1027 std::string payload(kPayload);
1028 payload.append(std::to_string(i));
1029 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
1030 }
1031 producer->WaitForFlush(writer.get());
1032
1033 ASSERT_EQ(1u, tracing_session()->received_triggers.size());
1034 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +01001035 tracing_session()->received_triggers[0].trigger_name);
Stephen Nuskod95a7512019-03-22 13:59:39 +00001036
1037 producer->WaitForDataSourceStop("ds_1");
1038 consumer->WaitForTracingDisabled();
Stephen Nusko70ea3302019-04-01 19:44:40 +01001039
Stephen Nuskod95a7512019-03-22 13:59:39 +00001040 auto packets = consumer->ReadBuffers();
Stephen Nusko70ea3302019-04-01 19:44:40 +01001041 EXPECT_LT(kNumTestPackets, packets.size());
Stephen Nuskod95a7512019-03-22 13:59:39 +00001042 // We expect for the TraceConfig preamble packet to be there correctly and
1043 // then we expect each payload to be there, but not the |large_payload|
1044 // packet.
1045 EXPECT_THAT(packets,
1046 HasTriggerMode(protos::TraceConfig::TriggerConfig::STOP_TRACING));
Eric Secklera883e5f2019-04-02 22:51:29 +00001047 for (size_t i = 0; i < kNumTestPackets; i++) {
Stephen Nuskod95a7512019-03-22 13:59:39 +00001048 std::string payload = kPayload;
1049 payload += std::to_string(i);
1050 EXPECT_THAT(packets, Contains(Property(
1051 &protos::TracePacket::for_testing,
1052 Property(&protos::TestEvent::str, Eq(payload)))));
1053 }
1054
1055 // The large payload was overwritten before we trigger and ReadBuffers so it
1056 // should not be in the returned data.
Hector Dearmanbb3bc482019-08-02 11:54:08 +01001057 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1058 Property(&protos::TestEvent::str,
1059 Eq(large_payload))))));
Stephen Nuskod95a7512019-03-22 13:59:39 +00001060}
1061
1062// Creates a tracing session with a STOP_TRACING trigger and checks that the
1063// session only cleans up once even with multiple triggers.
1064TEST_F(TracingServiceImplTest, StopTracingTriggerMultipleTriggers) {
1065 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1066 consumer->Connect(svc.get());
1067
1068 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1069 producer->Connect(svc.get(), "mock_producer");
1070
1071 // Create two data sources but enable only one of them.
1072 producer->RegisterDataSource("ds_1");
1073 producer->RegisterDataSource("ds_2");
1074
1075 TraceConfig trace_config;
1076 trace_config.add_buffers()->set_size_kb(128);
1077 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
1078 auto* trigger_config = trace_config.mutable_trigger_config();
1079 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
1080 auto* trigger = trigger_config->add_triggers();
1081 trigger->set_name("trigger_name");
1082 trigger->set_stop_delay_ms(1);
1083 trigger = trigger_config->add_triggers();
1084 trigger->set_name("trigger_name_2");
1085 trigger->set_stop_delay_ms(8.64e+7);
1086
1087 trigger_config->set_trigger_timeout_ms(8.64e+7);
1088
1089 consumer->EnableTracing(trace_config);
1090 producer->WaitForTracingSetup();
1091
1092 producer->WaitForDataSourceSetup("ds_1");
1093 producer->WaitForDataSourceStart("ds_1");
1094
Stephen Nuskod95a7512019-03-22 13:59:39 +00001095 // The trace won't return data until unless we send a trigger at this point.
Hector Dearmanbb3bc482019-08-02 11:54:08 +01001096 EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
Stephen Nuskod95a7512019-03-22 13:59:39 +00001097
1098 std::vector<std::string> req;
1099 req.push_back("trigger_name");
1100 req.push_back("trigger_name_3");
1101 req.push_back("trigger_name_2");
1102 producer->endpoint()->ActivateTriggers(req);
1103
1104 auto writer = producer->CreateTraceWriter("ds_1");
1105 producer->WaitForFlush(writer.get());
1106
1107 ASSERT_EQ(2u, tracing_session()->received_triggers.size());
1108 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +01001109 tracing_session()->received_triggers[0].trigger_name);
Stephen Nuskod95a7512019-03-22 13:59:39 +00001110 EXPECT_EQ("trigger_name_2",
Stephen Nusko70ea3302019-04-01 19:44:40 +01001111 tracing_session()->received_triggers[1].trigger_name);
Stephen Nuskod95a7512019-03-22 13:59:39 +00001112
1113 producer->WaitForDataSourceStop("ds_1");
1114 consumer->WaitForTracingDisabled();
1115 EXPECT_THAT(consumer->ReadBuffers(),
1116 HasTriggerMode(protos::TraceConfig::TriggerConfig::STOP_TRACING));
1117}
1118
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001119TEST_F(TracingServiceImplTest, LockdownMode) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001120 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1121 consumer->Connect(svc.get());
1122
1123 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1124 producer->Connect(svc.get(), "mock_producer_sameuid", geteuid());
1125 producer->RegisterDataSource("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +00001126
1127 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001128 trace_config.add_buffers()->set_size_kb(128);
1129 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1130 ds_config->set_name("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +00001131 trace_config.set_lockdown_mode(
1132 TraceConfig::LockdownModeOperation::LOCKDOWN_SET);
Primiano Tuccidca727d2018-04-04 11:31:55 +02001133 consumer->EnableTracing(trace_config);
1134
1135 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001136 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001137 producer->WaitForDataSourceStart("data_source");
1138
1139 std::unique_ptr<MockProducer> producer_otheruid = CreateMockProducer();
1140 auto x = svc->ConnectProducer(producer_otheruid.get(), geteuid() + 1,
1141 "mock_producer_ouid");
1142 EXPECT_CALL(*producer_otheruid, OnConnect()).Times(0);
Florian Mayer61c55482018-03-06 14:43:54 +00001143 task_runner.RunUntilIdle();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001144 Mock::VerifyAndClearExpectations(producer_otheruid.get());
Florian Mayer61c55482018-03-06 14:43:54 +00001145
Primiano Tuccidca727d2018-04-04 11:31:55 +02001146 consumer->DisableTracing();
1147 consumer->FreeBuffers();
1148 producer->WaitForDataSourceStop("data_source");
1149 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +00001150
1151 trace_config.set_lockdown_mode(
1152 TraceConfig::LockdownModeOperation::LOCKDOWN_CLEAR);
Primiano Tuccidca727d2018-04-04 11:31:55 +02001153 consumer->EnableTracing(trace_config);
Primiano Tucci674076d2018-10-01 10:41:09 +01001154 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001155 producer->WaitForDataSourceStart("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +00001156
Primiano Tuccidca727d2018-04-04 11:31:55 +02001157 std::unique_ptr<MockProducer> producer_otheruid2 = CreateMockProducer();
1158 producer_otheruid->Connect(svc.get(), "mock_producer_ouid2", geteuid() + 1);
Florian Mayer61c55482018-03-06 14:43:54 +00001159
Primiano Tuccidca727d2018-04-04 11:31:55 +02001160 consumer->DisableTracing();
1161 producer->WaitForDataSourceStop("data_source");
1162 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +00001163}
1164
Oystein Eftevaagcb6e4c82019-03-06 15:38:26 -08001165TEST_F(TracingServiceImplTest, ProducerNameFilterChange) {
1166 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1167 consumer->Connect(svc.get());
1168
1169 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1170 producer1->Connect(svc.get(), "mock_producer_1");
1171 producer1->RegisterDataSource("data_source");
1172
1173 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1174 producer2->Connect(svc.get(), "mock_producer_2");
1175 producer2->RegisterDataSource("data_source");
1176
1177 std::unique_ptr<MockProducer> producer3 = CreateMockProducer();
1178 producer3->Connect(svc.get(), "mock_producer_3");
1179 producer3->RegisterDataSource("data_source");
1180 producer3->RegisterDataSource("unused_data_source");
1181
1182 TraceConfig trace_config;
1183 trace_config.add_buffers()->set_size_kb(128);
1184 auto* data_source = trace_config.add_data_sources();
1185 data_source->mutable_config()->set_name("data_source");
1186 *data_source->add_producer_name_filter() = "mock_producer_1";
1187
1188 // Enable tracing with only mock_producer_1 enabled;
1189 // the rest should not start up.
1190 consumer->EnableTracing(trace_config);
1191
1192 producer1->WaitForTracingSetup();
1193 producer1->WaitForDataSourceSetup("data_source");
1194 producer1->WaitForDataSourceStart("data_source");
1195
1196 EXPECT_CALL(*producer2, OnConnect()).Times(0);
1197 EXPECT_CALL(*producer3, OnConnect()).Times(0);
1198 task_runner.RunUntilIdle();
1199 Mock::VerifyAndClearExpectations(producer2.get());
1200 Mock::VerifyAndClearExpectations(producer3.get());
1201
1202 // Enable mock_producer_2, the third one should still
1203 // not get connected.
1204 *data_source->add_producer_name_filter() = "mock_producer_2";
1205 consumer->ChangeTraceConfig(trace_config);
1206
1207 producer2->WaitForTracingSetup();
1208 producer2->WaitForDataSourceSetup("data_source");
1209 producer2->WaitForDataSourceStart("data_source");
1210
1211 // Enable mock_producer_3 but also try to do an
1212 // unsupported change (adding a new data source);
1213 // mock_producer_3 should get enabled but not
1214 // for the new data source.
1215 *data_source->add_producer_name_filter() = "mock_producer_3";
1216 auto* dummy_data_source = trace_config.add_data_sources();
1217 dummy_data_source->mutable_config()->set_name("unused_data_source");
1218 *dummy_data_source->add_producer_name_filter() = "mock_producer_3";
1219
1220 consumer->ChangeTraceConfig(trace_config);
1221
1222 producer3->WaitForTracingSetup();
1223 EXPECT_CALL(*producer3, SetupDataSource(_, _)).Times(1);
1224 EXPECT_CALL(*producer3, StartDataSource(_, _)).Times(1);
1225 task_runner.RunUntilIdle();
1226 Mock::VerifyAndClearExpectations(producer3.get());
1227
1228 consumer->DisableTracing();
1229 consumer->FreeBuffers();
1230 producer1->WaitForDataSourceStop("data_source");
1231 producer2->WaitForDataSourceStop("data_source");
1232
1233 EXPECT_CALL(*producer3, StopDataSource(_)).Times(1);
1234
1235 consumer->WaitForTracingDisabled();
1236
1237 task_runner.RunUntilIdle();
1238 Mock::VerifyAndClearExpectations(producer3.get());
1239}
1240
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001241TEST_F(TracingServiceImplTest, DisconnectConsumerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001242 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1243 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +00001244
Primiano Tuccidca727d2018-04-04 11:31:55 +02001245 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1246 producer->Connect(svc.get(), "mock_producer");
1247 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001248
Primiano Tuccidca727d2018-04-04 11:31:55 +02001249 TraceConfig trace_config;
1250 trace_config.add_buffers()->set_size_kb(128);
1251 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1252 ds_config->set_name("data_source");
1253 consumer->EnableTracing(trace_config);
1254
1255 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001256 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001257 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001258
1259 // Disconnecting the consumer while tracing should trigger data source
1260 // teardown.
Primiano Tuccidca727d2018-04-04 11:31:55 +02001261 consumer.reset();
1262 producer->WaitForDataSourceStop("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001263}
1264
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001265TEST_F(TracingServiceImplTest, ReconnectProducerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001266 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1267 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +00001268
Primiano Tuccidca727d2018-04-04 11:31:55 +02001269 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1270 producer->Connect(svc.get(), "mock_producer");
1271 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001272
Sami Kyostila06487a22018-02-27 13:48:38 +00001273 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001274 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +00001275 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001276 ds_config->set_name("data_source");
1277 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +00001278
Primiano Tuccidca727d2018-04-04 11:31:55 +02001279 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001280 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001281 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001282
Primiano Tuccidca727d2018-04-04 11:31:55 +02001283 // Disconnecting and reconnecting a producer with a matching data source.
1284 // The Producer should see that data source getting enabled again.
1285 producer.reset();
1286 producer = CreateMockProducer();
1287 producer->Connect(svc.get(), "mock_producer_2");
1288 producer->RegisterDataSource("data_source");
1289 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001290 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001291 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001292}
1293
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001294TEST_F(TracingServiceImplTest, ProducerIDWrapping) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001295 std::vector<std::unique_ptr<MockProducer>> producers;
1296 producers.push_back(nullptr);
Primiano Tucci081d46a2018-02-28 11:09:43 +00001297
Primiano Tuccidca727d2018-04-04 11:31:55 +02001298 auto connect_producer_and_get_id = [&producers,
1299 this](const std::string& name) {
1300 producers.emplace_back(CreateMockProducer());
1301 producers.back()->Connect(svc.get(), "mock_producer_" + name);
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001302 return *last_producer_id();
Primiano Tucci081d46a2018-02-28 11:09:43 +00001303 };
1304
1305 // Connect producers 1-4.
1306 for (ProducerID i = 1; i <= 4; i++)
Primiano Tuccidca727d2018-04-04 11:31:55 +02001307 ASSERT_EQ(i, connect_producer_and_get_id(std::to_string(i)));
Primiano Tucci081d46a2018-02-28 11:09:43 +00001308
1309 // Disconnect producers 1,3.
Primiano Tuccidca727d2018-04-04 11:31:55 +02001310 producers[1].reset();
1311 producers[3].reset();
Primiano Tucci081d46a2018-02-28 11:09:43 +00001312
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001313 *last_producer_id() = kMaxProducerID - 1;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001314 ASSERT_EQ(kMaxProducerID, connect_producer_and_get_id("maxid"));
1315 ASSERT_EQ(1u, connect_producer_and_get_id("1_again"));
1316 ASSERT_EQ(3u, connect_producer_and_get_id("3_again"));
1317 ASSERT_EQ(5u, connect_producer_and_get_id("5"));
1318 ASSERT_EQ(6u, connect_producer_and_get_id("6"));
Primiano Tucci081d46a2018-02-28 11:09:43 +00001319}
1320
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001321// Note: file_write_period_ms is set to a large enough to have exactly one flush
1322// of the tracing buffers (and therefore at most one synchronization section),
1323// unless the test runs unrealistically slowly, or the implementation of the
1324// tracing snapshot packets changes.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001325TEST_F(TracingServiceImplTest, WriteIntoFileAndStopOnMaxSize) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001326 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1327 consumer->Connect(svc.get());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001328
Primiano Tuccidca727d2018-04-04 11:31:55 +02001329 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1330 producer->Connect(svc.get(), "mock_producer");
1331 producer->RegisterDataSource("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001332
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001333 TraceConfig trace_config;
1334 trace_config.add_buffers()->set_size_kb(4096);
1335 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001336 ds_config->set_name("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001337 ds_config->set_target_buffer(0);
1338 trace_config.set_write_into_file(true);
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001339 trace_config.set_file_write_period_ms(100000); // 100s
1340 const uint64_t kMaxFileSize = 1024;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001341 trace_config.set_max_file_size_bytes(kMaxFileSize);
1342 base::TempFile tmp_file = base::TempFile::Create();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001343 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
1344
1345 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001346 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001347 producer->WaitForDataSourceStart("data_source");
1348
Hector Dearman685f7522019-03-12 14:28:56 +00001349 // The preamble packets are:
Hector Dearmane004a572019-05-13 17:51:43 +01001350 // Trace start clocksnapshot
Hector Dearman685f7522019-03-12 14:28:56 +00001351 // Config
1352 // SystemInfo
Hector Dearmane004a572019-05-13 17:51:43 +01001353 // Trace read clocksnapshot
1354 // Trace synchronisation
Eric Seckler667e0852019-06-06 14:56:07 +01001355 static const int kNumPreamblePackets = 5;
Hector Dearmane004a572019-05-13 17:51:43 +01001356 static const int kNumTestPackets = 9;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001357 static const char kPayload[] = "1234567890abcdef-";
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001358
1359 std::unique_ptr<TraceWriter> writer =
Primiano Tuccidca727d2018-04-04 11:31:55 +02001360 producer->CreateTraceWriter("data_source");
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001361 // Tracing service will emit a preamble of packets (a synchronization section,
1362 // followed by a tracing config packet). The preamble and these test packets
1363 // should fit within kMaxFileSize.
1364 for (int i = 0; i < kNumTestPackets; i++) {
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001365 auto tp = writer->NewTracePacket();
1366 std::string payload(kPayload);
1367 payload.append(std::to_string(i));
1368 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
1369 }
1370
1371 // Finally add a packet that overflows kMaxFileSize. This should cause the
1372 // implicit stop of the trace and should *not* be written in the trace.
1373 {
1374 auto tp = writer->NewTracePacket();
1375 char big_payload[kMaxFileSize] = "BIG!";
1376 tp->set_for_testing()->set_str(big_payload, sizeof(big_payload));
1377 }
1378 writer->Flush();
1379 writer.reset();
1380
Primiano Tuccidca727d2018-04-04 11:31:55 +02001381 consumer->DisableTracing();
1382 producer->WaitForDataSourceStop("data_source");
1383 consumer->WaitForTracingDisabled();
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001384
1385 // Verify the contents of the file.
1386 std::string trace_raw;
1387 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
1388 protos::Trace trace;
1389 ASSERT_TRUE(trace.ParseFromString(trace_raw));
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001390
1391 ASSERT_EQ(trace.packet_size(), kNumPreamblePackets + kNumTestPackets);
1392 for (int i = 0; i < kNumTestPackets; i++) {
1393 const protos::TracePacket& tp = trace.packet(kNumPreamblePackets + i);
1394 ASSERT_EQ(kPayload + std::to_string(i++), tp.for_testing().str());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001395 }
Primiano Tuccidca727d2018-04-04 11:31:55 +02001396}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001397
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001398// Test the logic that allows the trace config to set the shm total size and
1399// page size from the trace config. Also check that, if the config doesn't
1400// specify a value we fall back on the hint provided by the producer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001401TEST_F(TracingServiceImplTest, ProducerShmAndPageSizeOverriddenByTraceConfig) {
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001402 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1403 consumer->Connect(svc.get());
Nicolò Mazzucato693f6aa2019-07-08 10:26:09 +01001404 const size_t kMaxPageSizeKb = SharedMemoryABI::kMaxPageSize / 1024;
1405 const size_t kConfigPageSizesKb[] = /**/ {16, 0, 3, 2, 16, 8, 0, 4096, 0};
1406 const size_t kPageHintSizesKb[] = /****/ {0, 4, 0, 0, 8, 0, 4096, 0, 0};
1407 const size_t kExpectedPageSizesKb[] = {
1408 16, // Use config value.
1409 4, // Config is 0, use hint.
1410 kDefaultShmPageSizeKb, // Config % 4 != 0, take default.
1411 kDefaultShmPageSizeKb, // Less than page size, take default.
1412 16, // Ignore the hint.
1413 8, // Use config value.
1414 kMaxPageSizeKb, // Hint too big, take max value.
1415 kMaxPageSizeKb, // Config too high, take max value.
1416 4 // Fallback to default.
1417 };
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001418
1419 const size_t kConfigSizesKb[] = /**/ {0, 16, 0, 20, 32, 7, 0, 96, 4096000};
1420 const size_t kHintSizesKb[] = /****/ {0, 0, 16, 32, 16, 0, 7, 96, 4096000};
1421 const size_t kExpectedSizesKb[] = {
1422 kDefaultShmSizeKb, // Both hint and config are 0, use default.
1423 16, // Hint is 0, use config.
1424 16, // Config is 0, use hint.
1425 20, // Hint is takes precedence over the config.
1426 32, // Ditto, even if config is higher than hint.
1427 kDefaultShmSizeKb, // Config is invalid and hint is 0, use default.
1428 kDefaultShmSizeKb, // Config is 0 and hint is invalid, use default.
1429 kDefaultShmSizeKb, // 96 KB isn't a multiple of the page size (64 KB).
1430 kMaxShmSizeKb // Too big, cap at kMaxShmSize.
1431 };
1432
1433 const size_t kNumProducers = base::ArraySize(kHintSizesKb);
1434 std::unique_ptr<MockProducer> producer[kNumProducers];
1435 for (size_t i = 0; i < kNumProducers; i++) {
1436 auto name = "mock_producer_" + std::to_string(i);
1437 producer[i] = CreateMockProducer();
Nicolò Mazzucato693f6aa2019-07-08 10:26:09 +01001438 producer[i]->Connect(svc.get(), name, geteuid(), kHintSizesKb[i] * 1024,
1439 kPageHintSizesKb[i] * 1024);
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001440 producer[i]->RegisterDataSource("data_source");
1441 }
1442
1443 TraceConfig trace_config;
1444 trace_config.add_buffers()->set_size_kb(128);
1445 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1446 ds_config->set_name("data_source");
1447 for (size_t i = 0; i < kNumProducers; i++) {
1448 auto* producer_config = trace_config.add_producers();
1449 producer_config->set_producer_name("mock_producer_" + std::to_string(i));
Primiano Tucci3cbb10a2018-04-10 17:52:40 +01001450 producer_config->set_shm_size_kb(static_cast<uint32_t>(kConfigSizesKb[i]));
1451 producer_config->set_page_size_kb(
1452 static_cast<uint32_t>(kConfigPageSizesKb[i]));
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001453 }
1454
1455 consumer->EnableTracing(trace_config);
1456 size_t actual_shm_sizes_kb[kNumProducers]{};
1457 size_t actual_page_sizes_kb[kNumProducers]{};
1458 for (size_t i = 0; i < kNumProducers; i++) {
1459 producer[i]->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001460 producer[i]->WaitForDataSourceSetup("data_source");
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001461 actual_shm_sizes_kb[i] =
1462 producer[i]->endpoint()->shared_memory()->size() / 1024;
1463 actual_page_sizes_kb[i] =
1464 producer[i]->endpoint()->shared_buffer_page_size_kb();
1465 }
Primiano Tucci674076d2018-10-01 10:41:09 +01001466 for (size_t i = 0; i < kNumProducers; i++) {
1467 producer[i]->WaitForDataSourceStart("data_source");
1468 }
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001469 ASSERT_THAT(actual_page_sizes_kb, ElementsAreArray(kExpectedPageSizesKb));
1470 ASSERT_THAT(actual_shm_sizes_kb, ElementsAreArray(kExpectedSizesKb));
1471}
1472
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001473TEST_F(TracingServiceImplTest, ExplicitFlush) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001474 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1475 consumer->Connect(svc.get());
1476
1477 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1478 producer->Connect(svc.get(), "mock_producer");
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
1486 consumer->EnableTracing(trace_config);
1487 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001488 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001489 producer->WaitForDataSourceStart("data_source");
1490
1491 std::unique_ptr<TraceWriter> writer =
1492 producer->CreateTraceWriter("data_source");
1493 {
1494 auto tp = writer->NewTracePacket();
1495 tp->set_for_testing()->set_str("payload");
1496 }
1497
1498 auto flush_request = consumer->Flush();
1499 producer->WaitForFlush(writer.get());
1500 ASSERT_TRUE(flush_request.WaitForReply());
1501
1502 consumer->DisableTracing();
1503 producer->WaitForDataSourceStop("data_source");
1504 consumer->WaitForTracingDisabled();
1505 EXPECT_THAT(
1506 consumer->ReadBuffers(),
1507 Contains(Property(&protos::TracePacket::for_testing,
1508 Property(&protos::TestEvent::str, Eq("payload")))));
1509}
1510
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001511TEST_F(TracingServiceImplTest, ImplicitFlushOnTimedTraces) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001512 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1513 consumer->Connect(svc.get());
1514
1515 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1516 producer->Connect(svc.get(), "mock_producer");
1517 producer->RegisterDataSource("data_source");
1518
1519 TraceConfig trace_config;
1520 trace_config.add_buffers()->set_size_kb(128);
1521 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1522 ds_config->set_name("data_source");
1523 trace_config.set_duration_ms(1);
1524
1525 consumer->EnableTracing(trace_config);
1526 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001527 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001528 producer->WaitForDataSourceStart("data_source");
1529
1530 std::unique_ptr<TraceWriter> writer =
1531 producer->CreateTraceWriter("data_source");
1532 {
1533 auto tp = writer->NewTracePacket();
1534 tp->set_for_testing()->set_str("payload");
1535 }
1536
1537 producer->WaitForFlush(writer.get());
1538
1539 producer->WaitForDataSourceStop("data_source");
1540 consumer->WaitForTracingDisabled();
1541
1542 EXPECT_THAT(
1543 consumer->ReadBuffers(),
1544 Contains(Property(&protos::TracePacket::for_testing,
1545 Property(&protos::TestEvent::str, Eq("payload")))));
1546}
1547
1548// Tests the monotonic semantic of flush request IDs, i.e., once a producer
1549// acks flush request N, all flush requests <= N are considered successful and
1550// acked to the consumer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001551TEST_F(TracingServiceImplTest, BatchFlushes) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001552 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1553 consumer->Connect(svc.get());
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();
Primiano Tucci674076d2018-10-01 10:41:09 +01001566 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001567 producer->WaitForDataSourceStart("data_source");
1568
1569 std::unique_ptr<TraceWriter> writer =
1570 producer->CreateTraceWriter("data_source");
1571 {
1572 auto tp = writer->NewTracePacket();
1573 tp->set_for_testing()->set_str("payload");
1574 }
1575
1576 auto flush_req_1 = consumer->Flush();
1577 auto flush_req_2 = consumer->Flush();
1578 auto flush_req_3 = consumer->Flush();
1579
1580 // We'll deliberately let the 4th flush request timeout. Use a lower timeout
1581 // to keep test time short.
1582 auto flush_req_4 = consumer->Flush(/*timeout_ms=*/10);
1583 ASSERT_EQ(4u, GetNumPendingFlushes());
1584
1585 // Make the producer reply only to the 3rd flush request.
Hector Dearmanbb3bc482019-08-02 11:54:08 +01001586 InSequence seq;
Eric Secklera01e28a2019-01-08 11:21:04 +00001587 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 1.
1588 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 2.
1589 producer->WaitForFlush(writer.get()); // Reply only to flush 3.
1590 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 4.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001591
1592 // Even if the producer explicily replied only to flush ID == 3, all the
1593 // previous flushed < 3 should be implicitly acked.
1594 ASSERT_TRUE(flush_req_1.WaitForReply());
1595 ASSERT_TRUE(flush_req_2.WaitForReply());
1596 ASSERT_TRUE(flush_req_3.WaitForReply());
1597
1598 // At this point flush id == 4 should still be pending and should fail because
1599 // of reaching its timeout.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001600 ASSERT_FALSE(flush_req_4.WaitForReply());
1601
1602 consumer->DisableTracing();
1603 producer->WaitForDataSourceStop("data_source");
1604 consumer->WaitForTracingDisabled();
1605 EXPECT_THAT(
1606 consumer->ReadBuffers(),
1607 Contains(Property(&protos::TracePacket::for_testing,
1608 Property(&protos::TestEvent::str, Eq("payload")))));
1609}
1610
Primiano Tuccicaa57802018-11-25 11:07:07 +00001611TEST_F(TracingServiceImplTest, PeriodicFlush) {
1612 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1613 consumer->Connect(svc.get());
1614
1615 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1616 producer->Connect(svc.get(), "mock_producer");
1617 producer->RegisterDataSource("data_source");
1618
1619 TraceConfig trace_config;
1620 trace_config.add_buffers()->set_size_kb(128);
1621 trace_config.set_flush_period_ms(1);
1622 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1623 ds_config->set_name("data_source");
1624
1625 consumer->EnableTracing(trace_config);
1626 producer->WaitForTracingSetup();
1627 producer->WaitForDataSourceSetup("data_source");
1628 producer->WaitForDataSourceStart("data_source");
1629
1630 std::unique_ptr<TraceWriter> writer =
1631 producer->CreateTraceWriter("data_source");
1632
1633 const int kNumFlushes = 3;
1634 auto checkpoint = task_runner.CreateCheckpoint("all_flushes_done");
1635 int flushes_seen = 0;
1636 EXPECT_CALL(*producer, Flush(_, _, _))
1637 .WillRepeatedly(Invoke([&producer, &writer, &flushes_seen, checkpoint](
1638 FlushRequestID flush_req_id,
1639 const DataSourceInstanceID*, size_t) {
1640 {
1641 auto tp = writer->NewTracePacket();
1642 char payload[32];
1643 sprintf(payload, "f_%d", flushes_seen);
1644 tp->set_for_testing()->set_str(payload);
1645 }
1646 writer->Flush();
1647 producer->endpoint()->NotifyFlushComplete(flush_req_id);
1648 if (++flushes_seen == kNumFlushes)
1649 checkpoint();
1650 }));
1651 task_runner.RunUntilCheckpoint("all_flushes_done");
1652
1653 consumer->DisableTracing();
1654 producer->WaitForDataSourceStop("data_source");
1655 consumer->WaitForTracingDisabled();
1656 auto trace_packets = consumer->ReadBuffers();
1657 for (int i = 0; i < kNumFlushes; i++) {
1658 EXPECT_THAT(trace_packets,
1659 Contains(Property(&protos::TracePacket::for_testing,
1660 Property(&protos::TestEvent::str,
1661 Eq("f_" + std::to_string(i))))));
1662 }
1663}
1664
Ryan Savitski33868d52019-05-13 10:56:14 +01001665TEST_F(TracingServiceImplTest, PeriodicClearIncrementalState) {
1666 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1667 consumer->Connect(svc.get());
1668 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1669 producer->Connect(svc.get(), "mock_producer");
1670
1671 // Incremental data source that expects to receive the clear.
1672 producer->RegisterDataSource("ds_incremental1", false, false,
1673 /*handles_incremental_state_clear=*/true);
1674
1675 // Incremental data source that expects to receive the clear.
1676 producer->RegisterDataSource("ds_incremental2", false, false,
1677 /*handles_incremental_state_clear=*/true);
1678
Ryan Savitski0b4008a2019-05-13 17:55:53 +01001679 // Data source that does *not* advertise itself as supporting incremental
1680 // state clears.
Ryan Savitski33868d52019-05-13 10:56:14 +01001681 producer->RegisterDataSource("ds_selfcontained", false, false,
1682 /*handles_incremental_state_clear=*/false);
1683
1684 // Incremental data source that is registered, but won't be active within the
1685 // test's tracing session.
1686 producer->RegisterDataSource("ds_inactive", false, false,
1687 /*handles_incremental_state_clear=*/true);
1688
1689 TraceConfig trace_config;
1690 trace_config.add_buffers()->set_size_kb(128);
1691 trace_config.mutable_incremental_state_config()->set_clear_period_ms(1);
1692 trace_config.add_data_sources()->mutable_config()->set_name(
1693 "ds_selfcontained");
1694 trace_config.add_data_sources()->mutable_config()->set_name(
1695 "ds_incremental1");
1696 trace_config.add_data_sources()->mutable_config()->set_name(
1697 "ds_incremental2");
1698
1699 // note: the mocking is very brittle, and has to assume a specific order of
1700 // the data sources' setup/start.
1701 consumer->EnableTracing(trace_config);
1702 producer->WaitForTracingSetup();
1703 producer->WaitForDataSourceSetup("ds_selfcontained");
1704 producer->WaitForDataSourceSetup("ds_incremental1");
1705 producer->WaitForDataSourceSetup("ds_incremental2");
1706 producer->WaitForDataSourceStart("ds_selfcontained");
1707 producer->WaitForDataSourceStart("ds_incremental1");
1708 producer->WaitForDataSourceStart("ds_incremental2");
1709
1710 DataSourceInstanceID ds_incremental1 =
1711 producer->GetDataSourceInstanceId("ds_incremental1");
1712 DataSourceInstanceID ds_incremental2 =
1713 producer->GetDataSourceInstanceId("ds_incremental2");
1714
Ryan Savitskiba8a5f52019-05-14 11:58:21 +01001715 const size_t kNumClears = 3;
Ryan Savitski33868d52019-05-13 10:56:14 +01001716 std::function<void()> checkpoint =
1717 task_runner.CreateCheckpoint("clears_received");
1718 std::vector<std::vector<DataSourceInstanceID>> clears_seen;
1719 EXPECT_CALL(*producer, ClearIncrementalState(_, _))
1720 .WillRepeatedly(Invoke([&clears_seen, &checkpoint](
1721 const DataSourceInstanceID* data_source_ids,
1722 size_t num_data_sources) {
1723 std::vector<DataSourceInstanceID> ds_ids;
1724 for (size_t i = 0; i < num_data_sources; i++) {
1725 ds_ids.push_back(*data_source_ids++);
1726 }
1727 clears_seen.push_back(ds_ids);
1728 if (clears_seen.size() >= kNumClears)
1729 checkpoint();
1730 }));
1731 task_runner.RunUntilCheckpoint("clears_received");
1732
1733 consumer->DisableTracing();
1734
1735 // Assert that the clears were only for the active incremental data sources.
1736 ASSERT_EQ(clears_seen.size(), kNumClears);
1737 for (const std::vector<DataSourceInstanceID>& ds_ids : clears_seen) {
1738 ASSERT_THAT(ds_ids, ElementsAreArray({ds_incremental1, ds_incremental2}));
1739 }
1740}
1741
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001742// Creates a tracing session where some of the data sources set the
1743// |will_notify_on_stop| flag and checks that the OnTracingDisabled notification
1744// to the consumer is delayed until the acks are received.
1745TEST_F(TracingServiceImplTest, OnTracingDisabledWaitsForDataSourceStopAcks) {
1746 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1747 consumer->Connect(svc.get());
1748
1749 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1750 producer->Connect(svc.get(), "mock_producer");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001751 producer->RegisterDataSource("ds_will_ack_1", /*ack_stop=*/true,
1752 /*ack_start=*/true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001753 producer->RegisterDataSource("ds_wont_ack");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001754 producer->RegisterDataSource("ds_will_ack_2", /*ack_stop=*/true,
1755 /*ack_start=*/false);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001756
1757 TraceConfig trace_config;
1758 trace_config.add_buffers()->set_size_kb(128);
1759 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_1");
1760 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1761 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_2");
1762 trace_config.set_duration_ms(1);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001763 trace_config.set_deferred_start(true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001764
1765 consumer->EnableTracing(trace_config);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001766
1767 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1768 DataSourceInstanceState::CONFIGURED);
1769 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1770 DataSourceInstanceState::CONFIGURED);
1771 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1772 DataSourceInstanceState::CONFIGURED);
1773
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001774 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001775
1776 producer->WaitForDataSourceSetup("ds_will_ack_1");
1777 producer->WaitForDataSourceSetup("ds_wont_ack");
1778 producer->WaitForDataSourceSetup("ds_will_ack_2");
1779
Eric Seckler4ff03e52019-03-15 10:10:30 +00001780 DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_will_ack_1");
1781 DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_will_ack_2");
1782
1783 consumer->StartTracing();
1784
1785 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1786 DataSourceInstanceState::STARTING);
1787 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1788 DataSourceInstanceState::STARTED);
1789 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1790 DataSourceInstanceState::STARTED);
1791
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001792 producer->WaitForDataSourceStart("ds_will_ack_1");
1793 producer->WaitForDataSourceStart("ds_wont_ack");
1794 producer->WaitForDataSourceStart("ds_will_ack_2");
1795
Eric Seckler4ff03e52019-03-15 10:10:30 +00001796 producer->endpoint()->NotifyDataSourceStarted(id1);
1797
1798 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1799 DataSourceInstanceState::STARTED);
1800
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001801 std::unique_ptr<TraceWriter> writer =
1802 producer->CreateTraceWriter("ds_wont_ack");
1803 producer->WaitForFlush(writer.get());
1804
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001805 producer->WaitForDataSourceStop("ds_will_ack_1");
1806 producer->WaitForDataSourceStop("ds_wont_ack");
1807 producer->WaitForDataSourceStop("ds_will_ack_2");
1808
Eric Seckler4ff03e52019-03-15 10:10:30 +00001809 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1810 DataSourceInstanceState::STOPPING);
1811 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1812 DataSourceInstanceState::STOPPED);
1813 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1814 DataSourceInstanceState::STOPPING);
1815
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001816 producer->endpoint()->NotifyDataSourceStopped(id1);
1817 producer->endpoint()->NotifyDataSourceStopped(id2);
1818
Eric Seckler4ff03e52019-03-15 10:10:30 +00001819 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1820 DataSourceInstanceState::STOPPED);
1821 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1822 DataSourceInstanceState::STOPPED);
1823
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001824 // Wait for at most half of the service timeout, so that this test fails if
1825 // the service falls back on calling the OnTracingDisabled() because some of
1826 // the expected acks weren't received.
1827 consumer->WaitForTracingDisabled(
1828 TracingServiceImpl::kDataSourceStopTimeoutMs / 2);
1829}
1830
Oystein Eftevaagf250e1c2018-08-23 16:10:52 -07001831// Creates a tracing session where a second data source
1832// is added while the service is waiting for DisableTracing
1833// acks; the service should not enable the new datasource
1834// and should not hit any asserts when the consumer is
1835// subsequently destroyed.
1836TEST_F(TracingServiceImplTest, OnDataSourceAddedWhilePendingDisableAcks) {
1837 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1838 consumer->Connect(svc.get());
1839
1840 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1841 producer->Connect(svc.get(), "mock_producer");
1842 producer->RegisterDataSource("ds_will_ack", /*ack_stop=*/true);
1843
1844 TraceConfig trace_config;
1845 trace_config.add_buffers()->set_size_kb(128);
1846 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack");
1847 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1848
1849 consumer->EnableTracing(trace_config);
1850 producer->WaitForTracingSetup();
1851
1852 consumer->DisableTracing();
1853
1854 producer->RegisterDataSource("ds_wont_ack");
1855
1856 consumer.reset();
1857}
1858
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001859// Similar to OnTracingDisabledWaitsForDataSourceStopAcks, but deliberately
1860// skips the ack and checks that the service invokes the OnTracingDisabled()
1861// after the timeout.
1862TEST_F(TracingServiceImplTest, OnTracingDisabledCalledAnywaysInCaseOfTimeout) {
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001863 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1864 consumer->Connect(svc.get());
1865
1866 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1867 producer->Connect(svc.get(), "mock_producer");
1868 producer->RegisterDataSource("data_source", /*ack_stop=*/true);
1869
1870 TraceConfig trace_config;
1871 trace_config.add_buffers()->set_size_kb(128);
1872 trace_config.add_data_sources()->mutable_config()->set_name("data_source");
1873 trace_config.set_duration_ms(1);
Florian Mayer990e6d72019-06-03 11:34:52 +01001874 trace_config.set_data_source_stop_timeout_ms(1);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001875
1876 consumer->EnableTracing(trace_config);
1877 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001878 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001879 producer->WaitForDataSourceStart("data_source");
1880
1881 std::unique_ptr<TraceWriter> writer =
1882 producer->CreateTraceWriter("data_source");
1883 producer->WaitForFlush(writer.get());
1884
1885 producer->WaitForDataSourceStop("data_source");
1886 consumer->WaitForTracingDisabled();
1887}
1888
Primiano Tucci03de28f2018-08-01 11:29:46 +01001889// Tests the session_id logic. Two data sources in the same tracing session
1890// should see the same session id.
1891TEST_F(TracingServiceImplTest, SessionId) {
1892 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1893 consumer->Connect(svc.get());
1894
1895 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1896 producer1->Connect(svc.get(), "mock_producer1");
1897 producer1->RegisterDataSource("ds_1A");
1898 producer1->RegisterDataSource("ds_1B");
1899
1900 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1901 producer2->Connect(svc.get(), "mock_producer2");
1902 producer2->RegisterDataSource("ds_2A");
1903
Hector Dearmanbb3bc482019-08-02 11:54:08 +01001904 InSequence seq;
Primiano Tucci03de28f2018-08-01 11:29:46 +01001905 TracingSessionID last_session_id = 0;
1906 for (int i = 0; i < 3; i++) {
1907 TraceConfig trace_config;
1908 trace_config.add_buffers()->set_size_kb(128);
1909 trace_config.add_data_sources()->mutable_config()->set_name("ds_1A");
1910 trace_config.add_data_sources()->mutable_config()->set_name("ds_1B");
1911 trace_config.add_data_sources()->mutable_config()->set_name("ds_2A");
1912 trace_config.set_duration_ms(1);
1913
1914 consumer->EnableTracing(trace_config);
1915
1916 if (i == 0)
1917 producer1->WaitForTracingSetup();
Primiano Tucci03de28f2018-08-01 11:29:46 +01001918
Primiano Tucci674076d2018-10-01 10:41:09 +01001919 producer1->WaitForDataSourceSetup("ds_1A");
1920 producer1->WaitForDataSourceSetup("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001921 if (i == 0)
1922 producer2->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001923 producer2->WaitForDataSourceSetup("ds_2A");
1924
1925 producer1->WaitForDataSourceStart("ds_1A");
1926 producer1->WaitForDataSourceStart("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001927 producer2->WaitForDataSourceStart("ds_2A");
1928
1929 auto* ds1 = producer1->GetDataSourceInstance("ds_1A");
1930 auto* ds2 = producer1->GetDataSourceInstance("ds_1B");
1931 auto* ds3 = producer2->GetDataSourceInstance("ds_2A");
1932 ASSERT_EQ(ds1->session_id, ds2->session_id);
1933 ASSERT_EQ(ds1->session_id, ds3->session_id);
1934 ASSERT_NE(ds1->session_id, last_session_id);
1935 last_session_id = ds1->session_id;
1936
1937 auto writer1 = producer1->CreateTraceWriter("ds_1A");
1938 producer1->WaitForFlush(writer1.get());
1939
1940 auto writer2 = producer2->CreateTraceWriter("ds_2A");
1941 producer2->WaitForFlush(writer2.get());
1942
1943 producer1->WaitForDataSourceStop("ds_1A");
1944 producer1->WaitForDataSourceStop("ds_1B");
1945 producer2->WaitForDataSourceStop("ds_2A");
1946 consumer->WaitForTracingDisabled();
1947 consumer->FreeBuffers();
1948 }
1949}
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001950
1951// Writes a long trace and then tests that the trace parsed in partitions
1952// derived by the synchronization markers is identical to the whole trace parsed
1953// in one go.
1954TEST_F(TracingServiceImplTest, ResynchronizeTraceStreamUsingSyncMarker) {
1955 // Setup tracing.
1956 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1957 consumer->Connect(svc.get());
1958 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1959 producer->Connect(svc.get(), "mock_producer");
1960 producer->RegisterDataSource("data_source");
1961 TraceConfig trace_config;
1962 trace_config.add_buffers()->set_size_kb(4096);
1963 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1964 ds_config->set_name("data_source");
1965 trace_config.set_write_into_file(true);
1966 trace_config.set_file_write_period_ms(1);
1967 base::TempFile tmp_file = base::TempFile::Create();
1968 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
1969 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001970 producer->WaitForDataSourceSetup("data_source");
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001971 producer->WaitForDataSourceStart("data_source");
1972
1973 // Write some variable length payload, waiting for sync markers every now
1974 // and then.
1975 const int kNumMarkers = 5;
1976 auto writer = producer->CreateTraceWriter("data_source");
1977 for (int i = 1; i <= 100; i++) {
Florian Mayereff98042018-12-10 17:44:44 +00001978 std::string payload(static_cast<size_t>(i), 'A' + (i % 25));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001979 writer->NewTracePacket()->set_for_testing()->set_str(payload.c_str());
1980 if (i % (100 / kNumMarkers) == 0) {
1981 writer->Flush();
1982 WaitForNextSyncMarker();
1983 }
1984 }
1985 writer->Flush();
1986 writer.reset();
1987 consumer->DisableTracing();
1988 producer->WaitForDataSourceStop("data_source");
1989 consumer->WaitForTracingDisabled();
1990
1991 std::string trace_raw;
1992 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
1993
1994 const auto kMarkerSize = sizeof(TracingServiceImpl::kSyncMarker);
1995 const std::string kSyncMarkerStr(
1996 reinterpret_cast<const char*>(TracingServiceImpl::kSyncMarker),
1997 kMarkerSize);
1998
1999 // Read back the trace in partitions derived from the marker.
2000 // The trace should look like this:
2001 // [uid, marker] [event] [event] [uid, marker] [event] [event]
2002 size_t num_markers = 0;
2003 size_t start = 0;
2004 size_t end = 0;
2005 protos::Trace merged_trace;
2006 for (size_t pos = 0; pos != std::string::npos; start = end) {
2007 pos = trace_raw.find(kSyncMarkerStr, pos + 1);
2008 num_markers++;
2009 end = (pos == std::string::npos) ? trace_raw.size() : pos + kMarkerSize;
2010 int size = static_cast<int>(end - start);
2011 ASSERT_GT(size, 0);
2012 protos::Trace trace_partition;
2013 ASSERT_TRUE(trace_partition.ParseFromArray(trace_raw.data() + start, size));
2014 merged_trace.MergeFrom(trace_partition);
2015 }
Lalit Maganti9bdc7ce2018-09-17 15:25:11 +01002016 EXPECT_GE(num_markers, static_cast<size_t>(kNumMarkers));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01002017
2018 protos::Trace whole_trace;
2019 ASSERT_TRUE(whole_trace.ParseFromString(trace_raw));
2020
2021 ASSERT_EQ(whole_trace.packet_size(), merged_trace.packet_size());
2022 EXPECT_EQ(whole_trace.SerializeAsString(), merged_trace.SerializeAsString());
2023}
2024
Primiano Tucci674076d2018-10-01 10:41:09 +01002025// Creates a tracing session with |deferred_start| and checks that data sources
2026// are started only after calling StartTracing().
2027TEST_F(TracingServiceImplTest, DeferredStart) {
2028 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2029 consumer->Connect(svc.get());
2030
2031 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2032 producer->Connect(svc.get(), "mock_producer");
2033
2034 // Create two data sources but enable only one of them.
2035 producer->RegisterDataSource("ds_1");
2036 producer->RegisterDataSource("ds_2");
2037
2038 TraceConfig trace_config;
2039 trace_config.add_buffers()->set_size_kb(128);
2040 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
2041 trace_config.set_deferred_start(true);
2042 trace_config.set_duration_ms(1);
2043
2044 consumer->EnableTracing(trace_config);
2045 producer->WaitForTracingSetup();
2046
2047 producer->WaitForDataSourceSetup("ds_1");
2048
2049 // Make sure we don't get unexpected DataSourceStart() notifications yet.
2050 task_runner.RunUntilIdle();
2051
2052 consumer->StartTracing();
2053
2054 producer->WaitForDataSourceStart("ds_1");
2055
Stephen Nusko1393ffd2019-03-22 13:54:58 +00002056 auto writer = producer->CreateTraceWriter("ds_1");
2057 producer->WaitForFlush(writer.get());
Primiano Tucci674076d2018-10-01 10:41:09 +01002058
2059 producer->WaitForDataSourceStop("ds_1");
2060 consumer->WaitForTracingDisabled();
2061}
2062
Eric Secklerd0ac7ca2019-02-06 09:13:45 +00002063TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
2064 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2065 consumer->Connect(svc.get());
2066
2067 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2068 producer1->Connect(svc.get(), "mock_producer1", 123u /* uid */);
2069 producer1->RegisterDataSource("data_source");
2070
2071 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2072 producer2->Connect(svc.get(), "mock_producer2", 456u /* uid */);
2073 producer2->RegisterDataSource("data_source");
2074
2075 TraceConfig trace_config;
2076 trace_config.add_buffers()->set_size_kb(128);
2077 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2078 ds_config->set_name("data_source");
2079
2080 consumer->EnableTracing(trace_config);
2081 producer1->WaitForTracingSetup();
2082 producer1->WaitForDataSourceSetup("data_source");
2083 producer2->WaitForTracingSetup();
2084 producer2->WaitForDataSourceSetup("data_source");
2085 producer1->WaitForDataSourceStart("data_source");
2086 producer2->WaitForDataSourceStart("data_source");
2087
2088 std::unique_ptr<TraceWriter> writer1a =
2089 producer1->CreateTraceWriter("data_source");
2090 std::unique_ptr<TraceWriter> writer1b =
2091 producer1->CreateTraceWriter("data_source");
2092 std::unique_ptr<TraceWriter> writer2a =
2093 producer2->CreateTraceWriter("data_source");
2094 {
2095 auto tp = writer1a->NewTracePacket();
2096 tp->set_for_testing()->set_str("payload1a1");
2097 tp = writer1b->NewTracePacket();
2098 tp->set_for_testing()->set_str("payload1b1");
2099 tp = writer1a->NewTracePacket();
2100 tp->set_for_testing()->set_str("payload1a2");
2101 tp = writer2a->NewTracePacket();
2102 tp->set_for_testing()->set_str("payload2a1");
2103 tp = writer1b->NewTracePacket();
2104 tp->set_for_testing()->set_str("payload1b2");
2105 }
2106
2107 auto flush_request = consumer->Flush();
2108 producer1->WaitForFlush({writer1a.get(), writer1b.get()});
2109 producer2->WaitForFlush(writer2a.get());
2110 ASSERT_TRUE(flush_request.WaitForReply());
2111
2112 consumer->DisableTracing();
2113 producer1->WaitForDataSourceStop("data_source");
2114 producer2->WaitForDataSourceStop("data_source");
2115 consumer->WaitForTracingDisabled();
2116 auto packets = consumer->ReadBuffers();
2117 EXPECT_THAT(
2118 packets,
2119 Contains(AllOf(
2120 Property(&protos::TracePacket::for_testing,
2121 Property(&protos::TestEvent::str, Eq("payload1a1"))),
2122 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2123 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
2124 EXPECT_THAT(
2125 packets,
2126 Contains(AllOf(
2127 Property(&protos::TracePacket::for_testing,
2128 Property(&protos::TestEvent::str, Eq("payload1a2"))),
2129 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2130 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
2131 EXPECT_THAT(
2132 packets,
2133 Contains(AllOf(
2134 Property(&protos::TracePacket::for_testing,
2135 Property(&protos::TestEvent::str, Eq("payload1b1"))),
2136 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2137 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
2138 EXPECT_THAT(
2139 packets,
2140 Contains(AllOf(
2141 Property(&protos::TracePacket::for_testing,
2142 Property(&protos::TestEvent::str, Eq("payload1b2"))),
2143 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2144 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
2145 EXPECT_THAT(
2146 packets,
2147 Contains(AllOf(
2148 Property(&protos::TracePacket::for_testing,
2149 Property(&protos::TestEvent::str, Eq("payload2a1"))),
2150 Property(&protos::TracePacket::trusted_uid, Eq(456)),
2151 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(4u)))));
2152}
2153
Eric Seckler6dc23592018-11-30 10:59:06 +00002154TEST_F(TracingServiceImplTest, AllowedBuffers) {
2155 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2156 consumer->Connect(svc.get());
2157
2158 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2159 producer1->Connect(svc.get(), "mock_producer1");
2160 ProducerID producer1_id = *last_producer_id();
2161 producer1->RegisterDataSource("data_source1");
2162 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2163 producer2->Connect(svc.get(), "mock_producer2");
2164 ProducerID producer2_id = *last_producer_id();
2165 producer2->RegisterDataSource("data_source2.1");
2166 producer2->RegisterDataSource("data_source2.2");
2167 producer2->RegisterDataSource("data_source2.3");
2168
2169 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
2170 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
2171
2172 TraceConfig trace_config;
2173 trace_config.add_buffers()->set_size_kb(128);
2174 trace_config.add_buffers()->set_size_kb(128);
2175 trace_config.add_buffers()->set_size_kb(128);
2176 auto* ds_config1 = trace_config.add_data_sources()->mutable_config();
2177 ds_config1->set_name("data_source1");
2178 ds_config1->set_target_buffer(0);
2179 auto* ds_config21 = trace_config.add_data_sources()->mutable_config();
2180 ds_config21->set_name("data_source2.1");
2181 ds_config21->set_target_buffer(1);
2182 auto* ds_config22 = trace_config.add_data_sources()->mutable_config();
2183 ds_config22->set_name("data_source2.2");
2184 ds_config22->set_target_buffer(2);
2185 auto* ds_config23 = trace_config.add_data_sources()->mutable_config();
2186 ds_config23->set_name("data_source2.3");
2187 ds_config23->set_target_buffer(2); // same buffer as data_source2.2.
2188 consumer->EnableTracing(trace_config);
2189
Primiano Tucci2abd1152018-12-03 17:00:02 +01002190 ASSERT_EQ(3u, tracing_session()->num_buffers());
Eric Seckler6dc23592018-11-30 10:59:06 +00002191 std::set<BufferID> expected_buffers_producer1 = {
2192 tracing_session()->buffers_index[0]};
2193 std::set<BufferID> expected_buffers_producer2 = {
2194 tracing_session()->buffers_index[1], tracing_session()->buffers_index[2]};
2195 EXPECT_EQ(expected_buffers_producer1, GetAllowedTargetBuffers(producer1_id));
2196 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
2197
2198 producer1->WaitForTracingSetup();
2199 producer1->WaitForDataSourceSetup("data_source1");
2200
2201 producer2->WaitForTracingSetup();
2202 producer2->WaitForDataSourceSetup("data_source2.1");
2203 producer2->WaitForDataSourceSetup("data_source2.2");
2204 producer2->WaitForDataSourceSetup("data_source2.3");
2205
2206 producer1->WaitForDataSourceStart("data_source1");
2207 producer2->WaitForDataSourceStart("data_source2.1");
2208 producer2->WaitForDataSourceStart("data_source2.2");
2209 producer2->WaitForDataSourceStart("data_source2.3");
2210
2211 producer2->UnregisterDataSource("data_source2.3");
2212 producer2->WaitForDataSourceStop("data_source2.3");
2213
2214 // Should still be allowed to write to buffers 1 (data_source2.1) and 2
2215 // (data_source2.2).
2216 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
2217
2218 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2219 // trace config didn't have the |deferred_start| flag set.
2220 consumer->StartTracing();
2221
2222 consumer->DisableTracing();
2223 producer1->WaitForDataSourceStop("data_source1");
2224 producer2->WaitForDataSourceStop("data_source2.1");
2225 producer2->WaitForDataSourceStop("data_source2.2");
2226 consumer->WaitForTracingDisabled();
2227
2228 consumer->FreeBuffers();
2229 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
2230 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
2231}
2232
Eric Seckler6aa9ece2018-12-06 16:40:12 +00002233#if !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00002234TEST_F(TracingServiceImplTest, CommitToForbiddenBufferIsDiscarded) {
2235 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2236 consumer->Connect(svc.get());
2237
2238 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2239 producer->Connect(svc.get(), "mock_producer");
2240 ProducerID producer_id = *last_producer_id();
2241 producer->RegisterDataSource("data_source");
2242
2243 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
2244
2245 TraceConfig trace_config;
2246 trace_config.add_buffers()->set_size_kb(128);
2247 trace_config.add_buffers()->set_size_kb(128);
2248 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2249 ds_config->set_name("data_source");
2250 ds_config->set_target_buffer(0);
2251 consumer->EnableTracing(trace_config);
2252
2253 ASSERT_EQ(2u, tracing_session()->num_buffers());
2254 std::set<BufferID> expected_buffers = {tracing_session()->buffers_index[0]};
2255 EXPECT_EQ(expected_buffers, GetAllowedTargetBuffers(producer_id));
2256
2257 producer->WaitForTracingSetup();
2258 producer->WaitForDataSourceSetup("data_source");
2259 producer->WaitForDataSourceStart("data_source");
2260
2261 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2262 // trace config didn't have the |deferred_start| flag set.
2263 consumer->StartTracing();
2264
2265 // Try to write to the correct buffer.
2266 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2267 tracing_session()->buffers_index[0]);
2268 {
2269 auto tp = writer->NewTracePacket();
2270 tp->set_for_testing()->set_str("good_payload");
2271 }
2272
2273 auto flush_request = consumer->Flush();
2274 producer->WaitForFlush(writer.get());
2275 ASSERT_TRUE(flush_request.WaitForReply());
2276
2277 // Try to write to the wrong buffer.
2278 writer = producer->endpoint()->CreateTraceWriter(
2279 tracing_session()->buffers_index[1]);
2280 {
2281 auto tp = writer->NewTracePacket();
2282 tp->set_for_testing()->set_str("bad_payload");
2283 }
2284
2285 flush_request = consumer->Flush();
2286 producer->WaitForFlush(writer.get());
2287 ASSERT_TRUE(flush_request.WaitForReply());
2288
2289 consumer->DisableTracing();
2290 producer->WaitForDataSourceStop("data_source");
2291 consumer->WaitForTracingDisabled();
2292
2293 auto packets = consumer->ReadBuffers();
2294 EXPECT_THAT(packets, Contains(Property(&protos::TracePacket::for_testing,
2295 Property(&protos::TestEvent::str,
2296 Eq("good_payload")))));
2297 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2298 Property(&protos::TestEvent::str,
2299 Eq("bad_payload"))))));
2300
2301 consumer->FreeBuffers();
2302 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
2303}
Eric Seckler6aa9ece2018-12-06 16:40:12 +00002304#endif // !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00002305
Eric Secklerf3f524b2018-12-13 09:09:34 +00002306TEST_F(TracingServiceImplTest, RegisterAndUnregisterTraceWriter) {
2307 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2308 consumer->Connect(svc.get());
2309
2310 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2311 producer->Connect(svc.get(), "mock_producer");
2312 ProducerID producer_id = *last_producer_id();
2313 producer->RegisterDataSource("data_source");
2314
2315 EXPECT_TRUE(GetWriters(producer_id).empty());
2316
2317 TraceConfig trace_config;
2318 trace_config.add_buffers()->set_size_kb(128);
2319 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2320 ds_config->set_name("data_source");
2321 ds_config->set_target_buffer(0);
2322 consumer->EnableTracing(trace_config);
2323
2324 producer->WaitForTracingSetup();
2325 producer->WaitForDataSourceSetup("data_source");
2326 producer->WaitForDataSourceStart("data_source");
2327
2328 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2329 // trace config didn't have the |deferred_start| flag set.
2330 consumer->StartTracing();
2331
2332 // Creating the trace writer should register it with the service.
2333 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2334 tracing_session()->buffers_index[0]);
2335
2336 WaitForTraceWritersChanged(producer_id);
2337
2338 std::map<WriterID, BufferID> expected_writers;
2339 expected_writers[writer->writer_id()] = tracing_session()->buffers_index[0];
2340 EXPECT_EQ(expected_writers, GetWriters(producer_id));
2341
2342 // Verify writing works.
2343 {
2344 auto tp = writer->NewTracePacket();
2345 tp->set_for_testing()->set_str("payload");
2346 }
2347
2348 auto flush_request = consumer->Flush();
2349 producer->WaitForFlush(writer.get());
2350 ASSERT_TRUE(flush_request.WaitForReply());
2351
2352 // Destroying the writer should unregister it.
2353 writer.reset();
2354 WaitForTraceWritersChanged(producer_id);
2355 EXPECT_TRUE(GetWriters(producer_id).empty());
2356
2357 consumer->DisableTracing();
2358 producer->WaitForDataSourceStop("data_source");
2359 consumer->WaitForTracingDisabled();
2360
2361 auto packets = consumer->ReadBuffers();
2362 EXPECT_THAT(packets, Contains(Property(
2363 &protos::TracePacket::for_testing,
2364 Property(&protos::TestEvent::str, Eq("payload")))));
2365}
2366
Eric Secklera01e28a2019-01-08 11:21:04 +00002367TEST_F(TracingServiceImplTest, ScrapeBuffersOnFlush) {
2368 svc->SetSMBScrapingEnabled(true);
2369
2370 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2371 consumer->Connect(svc.get());
2372
2373 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2374 producer->Connect(svc.get(), "mock_producer");
2375 ProducerID producer_id = *last_producer_id();
2376 producer->RegisterDataSource("data_source");
2377
2378 TraceConfig trace_config;
2379 trace_config.add_buffers()->set_size_kb(128);
2380 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2381 ds_config->set_name("data_source");
2382 ds_config->set_target_buffer(0);
2383 consumer->EnableTracing(trace_config);
2384
2385 producer->WaitForTracingSetup();
2386 producer->WaitForDataSourceSetup("data_source");
2387 producer->WaitForDataSourceStart("data_source");
2388
2389 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2390 // trace config didn't have the |deferred_start| flag set.
2391 consumer->StartTracing();
2392
2393 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2394 tracing_session()->buffers_index[0]);
2395 WaitForTraceWritersChanged(producer_id);
2396
2397 // Write a few trace packets.
2398 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2399 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2400 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2401
2402 // Flush but don't actually flush the chunk from TraceWriter.
2403 auto flush_request = consumer->Flush();
2404 producer->WaitForFlush(nullptr, /*reply=*/true);
2405 ASSERT_TRUE(flush_request.WaitForReply());
2406
2407 // Chunk with the packets should have been scraped. The service can't know
2408 // whether the last packet was completed, so shouldn't read it.
2409 auto packets = consumer->ReadBuffers();
2410 EXPECT_THAT(packets, Contains(Property(
2411 &protos::TracePacket::for_testing,
2412 Property(&protos::TestEvent::str, Eq("payload1")))));
2413 EXPECT_THAT(packets, Contains(Property(
2414 &protos::TracePacket::for_testing,
2415 Property(&protos::TestEvent::str, Eq("payload2")))));
2416 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2417 Property(&protos::TestEvent::str,
2418 Eq("payload3"))))));
2419
2420 // Write some more packets.
2421 writer->NewTracePacket()->set_for_testing()->set_str("payload4");
2422 writer->NewTracePacket()->set_for_testing()->set_str("payload5");
2423
2424 // Don't reply to flush, causing a timeout. This should scrape again.
2425 flush_request = consumer->Flush(/*timeout=*/100);
2426 producer->WaitForFlush(nullptr, /*reply=*/false);
2427 ASSERT_FALSE(flush_request.WaitForReply());
2428
2429 // Chunk with the packets should have been scraped again, overriding the
2430 // original one. Again, the last packet should be ignored and the first two
2431 // should not be read twice.
2432 packets = consumer->ReadBuffers();
2433 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2434 Property(&protos::TestEvent::str,
2435 Eq("payload1"))))));
2436 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2437 Property(&protos::TestEvent::str,
2438 Eq("payload2"))))));
2439 EXPECT_THAT(packets, Contains(Property(
2440 &protos::TracePacket::for_testing,
2441 Property(&protos::TestEvent::str, Eq("payload3")))));
2442 EXPECT_THAT(packets, Contains(Property(
2443 &protos::TracePacket::for_testing,
2444 Property(&protos::TestEvent::str, Eq("payload4")))));
2445 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2446 Property(&protos::TestEvent::str,
2447 Eq("payload5"))))));
2448
2449 consumer->DisableTracing();
2450 producer->WaitForDataSourceStop("data_source");
2451 consumer->WaitForTracingDisabled();
2452}
2453
Sami Kyostilaf5ad4642019-05-16 10:46:15 +01002454TEST_F(TracingServiceImplTest, ScrapeBuffersFromAnotherThread) {
2455 // This test verifies that there are no reported TSAN races while scraping
2456 // buffers from a producer which is actively writing more trace data
2457 // concurrently.
2458 svc->SetSMBScrapingEnabled(true);
2459
2460 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2461 consumer->Connect(svc.get());
2462
2463 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2464 producer->Connect(svc.get(), "mock_producer");
2465 ProducerID producer_id = *last_producer_id();
2466 producer->RegisterDataSource("data_source");
2467
2468 TraceConfig trace_config;
2469 trace_config.add_buffers()->set_size_kb(128);
2470 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2471 ds_config->set_name("data_source");
2472 ds_config->set_target_buffer(0);
2473 consumer->EnableTracing(trace_config);
2474
2475 producer->WaitForTracingSetup();
2476 producer->WaitForDataSourceSetup("data_source");
2477 producer->WaitForDataSourceStart("data_source");
2478 consumer->StartTracing();
2479
2480 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2481 tracing_session()->buffers_index[0]);
2482 WaitForTraceWritersChanged(producer_id);
2483
2484 constexpr int kPacketCount = 10;
2485 std::atomic<int> packets_written{};
2486 std::thread writer_thread([&] {
2487 for (int i = 0; i < kPacketCount; i++) {
2488 writer->NewTracePacket()->set_for_testing()->set_str("payload");
2489 packets_written.store(i, std::memory_order_relaxed);
2490 }
2491 });
2492
2493 // Wait until the thread has had some time to write some packets.
2494 while (packets_written.load(std::memory_order_relaxed) < kPacketCount / 2)
2495 base::SleepMicroseconds(5000);
2496
2497 // Disabling tracing will trigger scraping.
2498 consumer->DisableTracing();
2499 writer_thread.join();
2500
2501 // Because we don't synchronize with the producer thread, we can't make any
2502 // guarantees about the number of packets we will successfully read. We just
2503 // verify that no TSAN races are reported.
2504 consumer->ReadBuffers();
2505
2506 producer->WaitForDataSourceStop("data_source");
2507 consumer->WaitForTracingDisabled();
2508}
2509
Eric Secklera01e28a2019-01-08 11:21:04 +00002510// Test scraping on producer disconnect.
2511TEST_F(TracingServiceImplTest, ScrapeBuffersOnProducerDisconnect) {
2512 svc->SetSMBScrapingEnabled(true);
2513
2514 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2515 consumer->Connect(svc.get());
2516
2517 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2518 producer->Connect(svc.get(), "mock_producer");
2519 ProducerID producer_id = *last_producer_id();
2520 producer->RegisterDataSource("data_source");
2521
2522 TraceConfig trace_config;
2523 trace_config.add_buffers()->set_size_kb(128);
2524 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2525 ds_config->set_name("data_source");
2526 ds_config->set_target_buffer(0);
2527 consumer->EnableTracing(trace_config);
2528
2529 producer->WaitForTracingSetup();
2530 producer->WaitForDataSourceSetup("data_source");
2531 producer->WaitForDataSourceStart("data_source");
2532
2533 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2534 // trace config didn't have the |deferred_start| flag set.
2535 consumer->StartTracing();
2536
2537 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2538 tracing_session()->buffers_index[0]);
2539 WaitForTraceWritersChanged(producer_id);
2540
2541 // Write a few trace packets.
2542 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2543 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2544 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2545
2546 // Disconnect the producer without committing the chunk. This should cause a
2547 // scrape of the SMB. Avoid destroying the ShmemArbiter until writer is
2548 // destroyed.
2549 auto shmem_arbiter = TakeShmemArbiterForProducer(producer_id);
2550 producer.reset();
2551
2552 // Chunk with the packets should have been scraped. The service can't know
2553 // whether the last packet was completed, so shouldn't read it.
2554 auto packets = consumer->ReadBuffers();
2555 EXPECT_THAT(packets, Contains(Property(
2556 &protos::TracePacket::for_testing,
2557 Property(&protos::TestEvent::str, Eq("payload1")))));
2558 EXPECT_THAT(packets, Contains(Property(
2559 &protos::TracePacket::for_testing,
2560 Property(&protos::TestEvent::str, Eq("payload2")))));
2561 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2562 Property(&protos::TestEvent::str,
2563 Eq("payload3"))))));
2564
2565 // Cleanup writer without causing a crash because the producer already went
2566 // away.
2567 static_cast<TraceWriterImpl*>(writer.get())->ResetChunkForTesting();
2568 writer.reset();
2569 shmem_arbiter.reset();
2570
2571 consumer->DisableTracing();
2572 consumer->WaitForTracingDisabled();
2573}
2574
2575TEST_F(TracingServiceImplTest, ScrapeBuffersOnDisable) {
2576 svc->SetSMBScrapingEnabled(true);
2577
2578 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2579 consumer->Connect(svc.get());
2580
2581 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2582 producer->Connect(svc.get(), "mock_producer");
2583 ProducerID producer_id = *last_producer_id();
2584 producer->RegisterDataSource("data_source");
2585
2586 TraceConfig trace_config;
2587 trace_config.add_buffers()->set_size_kb(128);
2588 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2589 ds_config->set_name("data_source");
2590 ds_config->set_target_buffer(0);
2591 consumer->EnableTracing(trace_config);
2592
2593 producer->WaitForTracingSetup();
2594 producer->WaitForDataSourceSetup("data_source");
2595 producer->WaitForDataSourceStart("data_source");
2596
2597 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2598 // trace config didn't have the |deferred_start| flag set.
2599 consumer->StartTracing();
2600
2601 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2602 tracing_session()->buffers_index[0]);
2603 WaitForTraceWritersChanged(producer_id);
2604
2605 // Write a few trace packets.
2606 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2607 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2608 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2609
2610 consumer->DisableTracing();
2611 producer->WaitForDataSourceStop("data_source");
2612 consumer->WaitForTracingDisabled();
2613
2614 // Chunk with the packets should have been scraped. The service can't know
2615 // whether the last packet was completed, so shouldn't read it.
2616 auto packets = consumer->ReadBuffers();
2617 EXPECT_THAT(packets, Contains(Property(
2618 &protos::TracePacket::for_testing,
2619 Property(&protos::TestEvent::str, Eq("payload1")))));
2620 EXPECT_THAT(packets, Contains(Property(
2621 &protos::TracePacket::for_testing,
2622 Property(&protos::TestEvent::str, Eq("payload2")))));
2623 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2624 Property(&protos::TestEvent::str,
2625 Eq("payload3"))))));
2626}
2627
Primiano Tucciff7beab2019-01-09 21:49:20 +00002628TEST_F(TracingServiceImplTest, AbortIfTraceDurationIsTooLong) {
2629 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2630 consumer->Connect(svc.get());
2631
2632 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2633 producer->Connect(svc.get(), "mock_producer");
2634 producer->RegisterDataSource("datasource");
2635
2636 TraceConfig trace_config;
2637 trace_config.add_buffers()->set_size_kb(128);
2638 trace_config.add_data_sources()->mutable_config()->set_name("datasource");
2639 trace_config.set_duration_ms(0x7fffffff);
2640
2641 EXPECT_CALL(*producer, SetupDataSource(_, _)).Times(0);
2642 consumer->EnableTracing(trace_config);
2643
2644 // The trace is aborted immediately, 5s here is just some slack for the thread
2645 // ping-pongs for slow devices.
2646 consumer->WaitForTracingDisabled(5000);
2647}
2648
Eric Secklereaf29ed2019-01-23 09:53:55 +00002649TEST_F(TracingServiceImplTest, GetTraceStats) {
2650 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2651 consumer->Connect(svc.get());
2652
2653 consumer->GetTraceStats();
2654 consumer->WaitForTraceStats(false);
2655
2656 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2657 producer->Connect(svc.get(), "mock_producer");
2658 producer->RegisterDataSource("data_source");
2659
2660 TraceConfig trace_config;
2661 trace_config.add_buffers()->set_size_kb(128);
2662 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2663 ds_config->set_name("data_source");
2664
2665 consumer->EnableTracing(trace_config);
2666 producer->WaitForTracingSetup();
2667 producer->WaitForDataSourceSetup("data_source");
2668 producer->WaitForDataSourceStart("data_source");
2669
2670 consumer->GetTraceStats();
2671 consumer->WaitForTraceStats(true);
2672
2673 consumer->DisableTracing();
2674 producer->WaitForDataSourceStop("data_source");
2675 consumer->WaitForTracingDisabled();
2676}
2677
Eric Seckler7b0c9452019-03-18 13:14:36 +00002678TEST_F(TracingServiceImplTest, ObserveEventsDataSourceInstances) {
2679 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2680 consumer->Connect(svc.get());
2681
2682 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2683 producer->Connect(svc.get(), "mock_producer");
2684 producer->RegisterDataSource("data_source");
2685
2686 TraceConfig trace_config;
2687 trace_config.add_buffers()->set_size_kb(128);
2688 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2689 ds_config->set_name("data_source");
2690
2691 // Start tracing before the consumer is interested in events. The consumer's
2692 // OnObservableEvents() should not be called yet.
2693 consumer->EnableTracing(trace_config);
2694 producer->WaitForTracingSetup();
2695 producer->WaitForDataSourceSetup("data_source");
2696 producer->WaitForDataSourceStart("data_source");
2697
2698 // Calling ObserveEvents should cause an event for the initial instance state.
2699 consumer->ObserveEvents(TracingService::ConsumerEndpoint::
2700 ObservableEventType::kDataSourceInstances);
2701 {
2702 auto events = consumer->WaitForObservableEvents();
2703
2704 ObservableEvents::DataSourceInstanceStateChange change;
2705 change.set_producer_name("mock_producer");
2706 change.set_data_source_name("data_source");
2707 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2708 DATA_SOURCE_INSTANCE_STATE_STARTED);
2709 EXPECT_EQ(events.instance_state_changes_size(), 1);
2710 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2711 }
2712
2713 // Disabling should cause an instance state change to STOPPED.
2714 consumer->DisableTracing();
2715
2716 {
2717 auto events = consumer->WaitForObservableEvents();
2718
2719 ObservableEvents::DataSourceInstanceStateChange change;
2720 change.set_producer_name("mock_producer");
2721 change.set_data_source_name("data_source");
2722 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2723 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2724 EXPECT_EQ(events.instance_state_changes_size(), 1);
2725 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2726 }
2727
2728 producer->WaitForDataSourceStop("data_source");
2729 consumer->WaitForTracingDisabled();
2730 consumer->FreeBuffers();
2731
2732 // Enable again, this should cause a state change for a new instance to
2733 // its initial state STOPPED.
2734 trace_config.set_deferred_start(true);
2735 consumer->EnableTracing(trace_config);
2736
2737 {
2738 auto events = consumer->WaitForObservableEvents();
2739
2740 ObservableEvents::DataSourceInstanceStateChange change;
2741 change.set_producer_name("mock_producer");
2742 change.set_data_source_name("data_source");
2743 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2744 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2745 EXPECT_EQ(events.instance_state_changes_size(), 1);
2746 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2747 }
2748
2749 producer->WaitForDataSourceSetup("data_source");
2750
2751 // Should move the instance into STARTED state and thus cause an event.
2752 consumer->StartTracing();
2753
2754 {
2755 auto events = consumer->WaitForObservableEvents();
2756
2757 ObservableEvents::DataSourceInstanceStateChange change;
2758 change.set_producer_name("mock_producer");
2759 change.set_data_source_name("data_source");
2760 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2761 DATA_SOURCE_INSTANCE_STATE_STARTED);
2762 EXPECT_EQ(events.instance_state_changes_size(), 1);
2763 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2764 }
2765
2766 producer->WaitForDataSourceStart("data_source");
2767
2768 // Stop observing events.
2769 consumer->ObserveEvents(
2770 TracingService::ConsumerEndpoint::ObservableEventType::kNone);
2771
2772 // Disabling should now no longer cause events to be sent to the consumer.
2773 consumer->DisableTracing();
2774 producer->WaitForDataSourceStop("data_source");
2775 consumer->WaitForTracingDisabled();
2776}
2777
Stephen Nusko6d4d5922019-08-06 15:38:25 +01002778TEST_F(TracingServiceImplTest, ObserveEventsDataSourceInstancesUnregister) {
2779 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2780 consumer->Connect(svc.get());
2781
2782 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2783 producer->Connect(svc.get(), "mock_producer");
2784 producer->RegisterDataSource("data_source");
2785
2786 TraceConfig trace_config;
2787 trace_config.add_buffers()->set_size_kb(128);
2788 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2789 ds_config->set_name("data_source");
2790
2791 // Start tracing before the consumer is interested in events. The consumer's
2792 // OnObservableEvents() should not be called yet.
2793 consumer->EnableTracing(trace_config);
2794 producer->WaitForTracingSetup();
2795 producer->WaitForDataSourceSetup("data_source");
2796 producer->WaitForDataSourceStart("data_source");
2797
2798 // Calling ObserveEvents should cause an event for the initial instance state.
2799 consumer->ObserveEvents(TracingService::ConsumerEndpoint::
2800 ObservableEventType::kDataSourceInstances);
2801 {
2802 ObservableEvents event;
2803 ObservableEvents::DataSourceInstanceStateChange* change =
2804 event.add_instance_state_changes();
2805 change->set_producer_name("mock_producer");
2806 change->set_data_source_name("data_source");
2807 change->set_state(ObservableEvents::DataSourceInstanceStateChange::
2808 DATA_SOURCE_INSTANCE_STATE_STARTED);
2809 EXPECT_CALL(*consumer, OnObservableEvents(Eq(event)))
2810 .WillOnce(InvokeWithoutArgs(
2811 task_runner.CreateCheckpoint("data_source_started")));
2812
2813 task_runner.RunUntilCheckpoint("data_source_started");
2814 }
2815 {
2816 ObservableEvents event;
2817 ObservableEvents::DataSourceInstanceStateChange* change =
2818 event.add_instance_state_changes();
2819 change->set_producer_name("mock_producer");
2820 change->set_data_source_name("data_source");
2821 change->set_state(ObservableEvents::DataSourceInstanceStateChange::
2822 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2823 EXPECT_CALL(*consumer, OnObservableEvents(Eq(event)))
2824 .WillOnce(InvokeWithoutArgs(
2825 task_runner.CreateCheckpoint("data_source_stopped")));
2826 }
2827 producer->UnregisterDataSource("data_source");
2828 producer->WaitForDataSourceStop("data_source");
2829 task_runner.RunUntilCheckpoint("data_source_stopped");
2830
2831 consumer->DisableTracing();
2832 consumer->WaitForTracingDisabled();
2833}
2834
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002835TEST_F(TracingServiceImplTest, QueryServiceState) {
2836 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2837 consumer->Connect(svc.get());
2838
2839 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2840 producer1->Connect(svc.get(), "producer1");
2841
2842 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2843 producer2->Connect(svc.get(), "producer2");
2844
2845 producer1->RegisterDataSource("common_ds");
2846 producer2->RegisterDataSource("common_ds");
2847
2848 producer1->RegisterDataSource("p1_ds");
2849 producer2->RegisterDataSource("p2_ds");
2850
2851 TracingServiceState svc_state = consumer->QueryServiceState();
2852
Eric Seckler4ffe6c22019-06-05 09:07:16 +01002853 EXPECT_EQ(svc_state.producers_size(), 2);
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002854 EXPECT_EQ(svc_state.producers().at(0).id(), 1);
2855 EXPECT_EQ(svc_state.producers().at(0).name(), "producer1");
2856 EXPECT_EQ(svc_state.producers().at(1).id(), 2);
2857 EXPECT_EQ(svc_state.producers().at(1).name(), "producer2");
2858
Eric Seckler4ffe6c22019-06-05 09:07:16 +01002859 EXPECT_EQ(svc_state.data_sources_size(), 4);
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002860
2861 EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 1);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002862 EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().name(), "common_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002863
2864 EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002865 EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().name(), "common_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002866
2867 EXPECT_EQ(svc_state.data_sources().at(2).producer_id(), 1);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002868 EXPECT_EQ(svc_state.data_sources().at(2).ds_descriptor().name(), "p1_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002869
2870 EXPECT_EQ(svc_state.data_sources().at(3).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002871 EXPECT_EQ(svc_state.data_sources().at(3).ds_descriptor().name(), "p2_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002872
2873 // Test that descriptors are cleared when a producer disconnects.
2874 producer1.reset();
2875 svc_state = consumer->QueryServiceState();
2876
Eric Seckler4ffe6c22019-06-05 09:07:16 +01002877 EXPECT_EQ(svc_state.producers_size(), 1);
2878 EXPECT_EQ(svc_state.data_sources_size(), 2);
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002879
2880 EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002881 EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().name(), "common_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002882 EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002883 EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().name(), "p2_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002884}
2885
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00002886} // namespace perfetto