blob: b30161216815ae4a2964257eab4848eea1fe8950 [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
Primiano Tucci2c5488f2019-06-01 03:27:28 +010021#include "perfetto/ext/base/file_utils.h"
22#include "perfetto/ext/base/temp_file.h"
23#include "perfetto/ext/base/utils.h"
24#include "perfetto/ext/tracing/core/consumer.h"
Primiano Tucci2c5488f2019-06-01 03:27:28 +010025#include "perfetto/ext/tracing/core/producer.h"
26#include "perfetto/ext/tracing/core/shared_memory.h"
27#include "perfetto/ext/tracing/core/trace_packet.h"
28#include "perfetto/ext/tracing/core/trace_writer.h"
Primiano Tucci0f9e0222019-06-05 09:36:41 +010029#include "perfetto/tracing/core/data_source_config.h"
30#include "perfetto/tracing/core/data_source_descriptor.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000031#include "src/base/test/test_task_runner.h"
Eric Secklera01e28a2019-01-08 11:21:04 +000032#include "src/tracing/core/shared_memory_arbiter_impl.h"
Eric Secklerf3f524b2018-12-13 09:09:34 +000033#include "src/tracing/core/trace_writer_impl.h"
Primiano Tuccidca727d2018-04-04 11:31:55 +020034#include "src/tracing/test/mock_consumer.h"
35#include "src/tracing/test/mock_producer.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000036#include "src/tracing/test/test_shared_memory.h"
Primiano Tucci919ca1e2019-08-21 20:26:58 +020037#include "test/gtest_and_gmock.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000038
Primiano Tucci355b8c82019-08-29 08:37:51 +020039#include "protos/perfetto/trace/test_event.pbzero.h"
40#include "protos/perfetto/trace/trace.pb.h"
41#include "protos/perfetto/trace/trace_packet.pb.h"
42#include "protos/perfetto/trace/trace_packet.pbzero.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010043
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000044using ::testing::_;
Hector Dearmanbb3bc482019-08-02 11:54:08 +010045using ::testing::AssertionFailure;
46using ::testing::AssertionResult;
47using ::testing::AssertionSuccess;
Primiano Tuccidca727d2018-04-04 11:31:55 +020048using ::testing::Contains;
Primiano Tucci1a1951d2018-04-04 21:08:16 +020049using ::testing::ElementsAreArray;
Primiano Tuccidca727d2018-04-04 11:31:55 +020050using ::testing::Eq;
Hector Dearmanbb3bc482019-08-02 11:54:08 +010051using ::testing::ExplainMatchResult;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000052using ::testing::InSequence;
Primiano Tucci081d46a2018-02-28 11:09:43 +000053using ::testing::Invoke;
Primiano Tuccidca727d2018-04-04 11:31:55 +020054using ::testing::InvokeWithoutArgs;
Hector Dearmanbb3bc482019-08-02 11:54:08 +010055using ::testing::IsEmpty;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000056using ::testing::Mock;
Eric Secklerdd0ad102018-12-06 11:32:04 +000057using ::testing::Not;
Primiano Tuccidca727d2018-04-04 11:31:55 +020058using ::testing::Property;
59using ::testing::StrictMock;
Hector Dearmanbb3bc482019-08-02 11:54:08 +010060using ::testing::StringMatchResultListener;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000061
Primiano Tuccidca727d2018-04-04 11:31:55 +020062namespace perfetto {
Sami Kyostila32e0b542018-02-14 08:55:43 +000063
Primiano Tucci1a1951d2018-04-04 21:08:16 +020064namespace {
Florian Mayer6a1a4d52018-06-08 16:47:07 +010065constexpr size_t kDefaultShmSizeKb = TracingServiceImpl::kDefaultShmSize / 1024;
Nicolò Mazzucato693f6aa2019-07-08 10:26:09 +010066constexpr size_t kDefaultShmPageSizeKb =
67 TracingServiceImpl::kDefaultShmPageSize / 1024;
Florian Mayer6a1a4d52018-06-08 16:47:07 +010068constexpr size_t kMaxShmSizeKb = TracingServiceImpl::kMaxShmSize / 1024;
Stephen Nusko1393ffd2019-03-22 13:54:58 +000069
Hector Dearmanbb3bc482019-08-02 11:54:08 +010070AssertionResult HasTriggerModeInternal(
Stephen Nusko1393ffd2019-03-22 13:54:58 +000071 const std::vector<protos::TracePacket>& packets,
72 protos::TraceConfig::TriggerConfig::TriggerMode mode) {
Hector Dearmanbb3bc482019-08-02 11:54:08 +010073 StringMatchResultListener matcher_result_string;
74 bool contains = ExplainMatchResult(
Stephen Nusko1393ffd2019-03-22 13:54:58 +000075 Contains(Property(
76 &protos::TracePacket::trace_config,
77 Property(&protos::TraceConfig::trigger_config,
78 Property(&protos::TraceConfig::TriggerConfig::trigger_mode,
79 Eq(mode))))),
80 packets, &matcher_result_string);
81 if (contains) {
Hector Dearmanbb3bc482019-08-02 11:54:08 +010082 return AssertionSuccess();
Stephen Nusko1393ffd2019-03-22 13:54:58 +000083 }
Hector Dearmanbb3bc482019-08-02 11:54:08 +010084 return AssertionFailure() << matcher_result_string.str();
Stephen Nusko1393ffd2019-03-22 13:54:58 +000085}
86
87MATCHER_P(HasTriggerMode, mode, "") {
88 return HasTriggerModeInternal(arg, mode);
89}
90
Primiano Tucci1a1951d2018-04-04 21:08:16 +020091} // namespace
92
Florian Mayer6a1a4d52018-06-08 16:47:07 +010093class TracingServiceImplTest : public testing::Test {
Sami Kyostila06487a22018-02-27 13:48:38 +000094 public:
Eric Seckler4ff03e52019-03-15 10:10:30 +000095 using DataSourceInstanceState =
96 TracingServiceImpl::DataSourceInstance::DataSourceInstanceState;
97
Florian Mayer6a1a4d52018-06-08 16:47:07 +010098 TracingServiceImplTest() {
Sami Kyostila06487a22018-02-27 13:48:38 +000099 auto shm_factory =
100 std::unique_ptr<SharedMemory::Factory>(new TestSharedMemory::Factory());
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100101 svc.reset(static_cast<TracingServiceImpl*>(
102 TracingService::CreateInstance(std::move(shm_factory), &task_runner)
Sami Kyostila06487a22018-02-27 13:48:38 +0000103 .release()));
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100104 svc->min_write_period_ms_ = 1;
Sami Kyostila06487a22018-02-27 13:48:38 +0000105 }
106
Primiano Tuccidca727d2018-04-04 11:31:55 +0200107 std::unique_ptr<MockProducer> CreateMockProducer() {
108 return std::unique_ptr<MockProducer>(
109 new StrictMock<MockProducer>(&task_runner));
110 }
111
112 std::unique_ptr<MockConsumer> CreateMockConsumer() {
113 return std::unique_ptr<MockConsumer>(
114 new StrictMock<MockConsumer>(&task_runner));
115 }
116
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200117 ProducerID* last_producer_id() { return &svc->last_producer_id_; }
118
119 uid_t GetProducerUid(ProducerID producer_id) {
120 return svc->GetProducer(producer_id)->uid_;
121 }
122
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000123 TracingServiceImpl::TracingSession* GetTracingSession(TracingSessionID tsid) {
124 auto* session = svc->GetTracingSession(tsid);
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100125 EXPECT_NE(nullptr, session);
126 return session;
127 }
128
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000129 TracingServiceImpl::TracingSession* tracing_session() {
130 return GetTracingSession(GetTracingSessionID());
131 }
132
133 TracingSessionID GetTracingSessionID() {
134 return svc->last_tracing_session_id_;
135 }
136
Eric Seckler6dc23592018-11-30 10:59:06 +0000137 const std::set<BufferID>& GetAllowedTargetBuffers(ProducerID producer_id) {
138 return svc->GetProducer(producer_id)->allowed_target_buffers_;
139 }
140
Eric Secklerf3f524b2018-12-13 09:09:34 +0000141 const std::map<WriterID, BufferID>& GetWriters(ProducerID producer_id) {
142 return svc->GetProducer(producer_id)->writers_;
143 }
144
Eric Secklera01e28a2019-01-08 11:21:04 +0000145 std::unique_ptr<SharedMemoryArbiterImpl> TakeShmemArbiterForProducer(
146 ProducerID producer_id) {
147 return std::move(svc->GetProducer(producer_id)->inproc_shmem_arbiter_);
148 }
149
Primiano Tuccid52e6272018-04-06 19:06:53 +0200150 size_t GetNumPendingFlushes() {
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100151 return tracing_session()->pending_flushes.size();
152 }
153
154 void WaitForNextSyncMarker() {
155 tracing_session()->last_snapshot_time = base::TimeMillis(0);
156 static int attempt = 0;
157 while (tracing_session()->last_snapshot_time == base::TimeMillis(0)) {
158 auto checkpoint_name = "wait_snapshot_" + std::to_string(attempt++);
159 auto timer_expired = task_runner.CreateCheckpoint(checkpoint_name);
160 task_runner.PostDelayedTask([timer_expired] { timer_expired(); }, 1);
161 task_runner.RunUntilCheckpoint(checkpoint_name);
162 }
Primiano Tuccid52e6272018-04-06 19:06:53 +0200163 }
164
Eric Secklerf3f524b2018-12-13 09:09:34 +0000165 void WaitForTraceWritersChanged(ProducerID producer_id) {
166 static int i = 0;
167 auto checkpoint_name = "writers_changed_" + std::to_string(producer_id) +
168 "_" + std::to_string(i++);
169 auto writers_changed = task_runner.CreateCheckpoint(checkpoint_name);
170 auto writers = GetWriters(producer_id);
171 std::function<void()> task;
172 task = [&task, writers, writers_changed, producer_id, this]() {
173 if (writers != GetWriters(producer_id)) {
174 writers_changed();
175 return;
176 }
177 task_runner.PostDelayedTask(task, 1);
178 };
179 task_runner.PostDelayedTask(task, 1);
180 task_runner.RunUntilCheckpoint(checkpoint_name);
181 }
182
Eric Seckler4ff03e52019-03-15 10:10:30 +0000183 DataSourceInstanceState GetDataSourceInstanceState(const std::string& name) {
184 for (const auto& kv : tracing_session()->data_source_instances) {
185 if (kv.second.data_source_name == name)
186 return kv.second.state;
187 }
188 PERFETTO_FATAL("Can't find data source instance with name %s",
189 name.c_str());
190 }
191
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000192 base::TestTaskRunner task_runner;
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100193 std::unique_ptr<TracingServiceImpl> svc;
Sami Kyostila06487a22018-02-27 13:48:38 +0000194};
195
Hector Dearmanfb4d0732019-05-19 15:44:56 +0100196TEST_F(TracingServiceImplTest, AtMostOneConfig) {
197 std::unique_ptr<MockConsumer> consumer_a = CreateMockConsumer();
198 std::unique_ptr<MockConsumer> consumer_b = CreateMockConsumer();
199
200 consumer_a->Connect(svc.get());
201 consumer_b->Connect(svc.get());
202
203 TraceConfig trace_config_a;
204 trace_config_a.add_buffers()->set_size_kb(128);
205 trace_config_a.set_duration_ms(0);
206 trace_config_a.set_unique_session_name("foo");
207
208 TraceConfig trace_config_b;
209 trace_config_b.add_buffers()->set_size_kb(128);
210 trace_config_b.set_duration_ms(0);
211 trace_config_b.set_unique_session_name("foo");
212
213 consumer_a->EnableTracing(trace_config_a);
214 consumer_b->EnableTracing(trace_config_b);
215
216 // This will stop immediately since it has the same unique session name.
217 consumer_b->WaitForTracingDisabled();
218
219 consumer_a->DisableTracing();
220 consumer_a->WaitForTracingDisabled();
Hector Dearmaneb5c71e2019-07-30 14:00:23 +0100221
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100222 EXPECT_THAT(consumer_b->ReadBuffers(), IsEmpty());
Hector Dearmanfb4d0732019-05-19 15:44:56 +0100223}
224
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100225TEST_F(TracingServiceImplTest, RegisterAndUnregister) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200226 std::unique_ptr<MockProducer> mock_producer_1 = CreateMockProducer();
227 std::unique_ptr<MockProducer> mock_producer_2 = CreateMockProducer();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000228
Primiano Tuccidca727d2018-04-04 11:31:55 +0200229 mock_producer_1->Connect(svc.get(), "mock_producer_1", 123u /* uid */);
230 mock_producer_2->Connect(svc.get(), "mock_producer_2", 456u /* uid */);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000231
232 ASSERT_EQ(2u, svc->num_producers());
Primiano Tuccidca727d2018-04-04 11:31:55 +0200233 ASSERT_EQ(mock_producer_1->endpoint(), svc->GetProducer(1));
234 ASSERT_EQ(mock_producer_2->endpoint(), svc->GetProducer(2));
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200235 ASSERT_EQ(123u, GetProducerUid(1));
236 ASSERT_EQ(456u, GetProducerUid(2));
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000237
Primiano Tuccidca727d2018-04-04 11:31:55 +0200238 mock_producer_1->RegisterDataSource("foo");
239 mock_producer_2->RegisterDataSource("bar");
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000240
Primiano Tuccidca727d2018-04-04 11:31:55 +0200241 mock_producer_1->UnregisterDataSource("foo");
242 mock_producer_2->UnregisterDataSource("bar");
Primiano Tucci9daa4832018-03-28 23:28:17 +0100243
Primiano Tuccidca727d2018-04-04 11:31:55 +0200244 mock_producer_1.reset();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000245 ASSERT_EQ(1u, svc->num_producers());
246 ASSERT_EQ(nullptr, svc->GetProducer(1));
247
Primiano Tuccidca727d2018-04-04 11:31:55 +0200248 mock_producer_2.reset();
249 ASSERT_EQ(nullptr, svc->GetProducer(2));
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000250
251 ASSERT_EQ(0u, svc->num_producers());
252}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100253
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100254TEST_F(TracingServiceImplTest, EnableAndDisableTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +0200255 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
256 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +0000257
Primiano Tuccidca727d2018-04-04 11:31:55 +0200258 std::unique_ptr<MockProducer> producer = CreateMockProducer();
259 producer->Connect(svc.get(), "mock_producer");
260 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +0000261
Sami Kyostila06487a22018-02-27 13:48:38 +0000262 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200263 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +0000264 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +0200265 ds_config->set_name("data_source");
266 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +0000267
Primiano Tuccidca727d2018-04-04 11:31:55 +0200268 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100269 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +0200270 producer->WaitForDataSourceStart("data_source");
271
Primiano Tucci674076d2018-10-01 10:41:09 +0100272 // Calling StartTracing() should be a noop (% a DLOG statement) because the
273 // trace config didn't have the |deferred_start| flag set.
274 consumer->StartTracing();
275
Primiano Tuccidca727d2018-04-04 11:31:55 +0200276 consumer->DisableTracing();
277 producer->WaitForDataSourceStop("data_source");
278 consumer->WaitForTracingDisabled();
Sami Kyostila06487a22018-02-27 13:48:38 +0000279}
280
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000281// Creates a tracing session with a START_TRACING trigger and checks that data
282// sources are started only after the service receives a trigger.
283TEST_F(TracingServiceImplTest, StartTracingTriggerDeferredStart) {
284 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
285 consumer->Connect(svc.get());
286
287 std::unique_ptr<MockProducer> producer = CreateMockProducer();
288 producer->Connect(svc.get(), "mock_producer");
289
290 // Create two data sources but enable only one of them.
291 producer->RegisterDataSource("ds_1");
292 producer->RegisterDataSource("ds_2");
293
294 TraceConfig trace_config;
295 trace_config.add_buffers()->set_size_kb(128);
296 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
297 auto* trigger_config = trace_config.mutable_trigger_config();
298 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
299 auto* trigger = trigger_config->add_triggers();
300 trigger->set_name("trigger_name");
301 trigger->set_stop_delay_ms(1);
302
303 trigger_config->set_trigger_timeout_ms(8.64e+7);
304
305 // Make sure we don't get unexpected DataSourceStart() notifications yet.
306 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
307
308 consumer->EnableTracing(trace_config);
309 producer->WaitForTracingSetup();
310
311 producer->WaitForDataSourceSetup("ds_1");
312
313 // The trace won't start until we send the trigger. since we have a
314 // START_TRACING trigger defined.
315 std::vector<std::string> req;
316 req.push_back("trigger_name");
317 producer->endpoint()->ActivateTriggers(req);
318
319 producer->WaitForDataSourceStart("ds_1");
320
321 auto writer1 = producer->CreateTraceWriter("ds_1");
322 producer->WaitForFlush(writer1.get());
323
324 producer->WaitForDataSourceStop("ds_1");
325 consumer->WaitForTracingDisabled();
326
327 ASSERT_EQ(1u, tracing_session()->received_triggers.size());
328 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100329 tracing_session()->received_triggers[0].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000330
331 EXPECT_THAT(
332 consumer->ReadBuffers(),
333 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
334}
335
336// Creates a tracing session with a START_TRACING trigger and checks that the
337// session is cleaned up when no trigger is received after |trigger_timeout_ms|.
338TEST_F(TracingServiceImplTest, StartTracingTriggerTimeOut) {
339 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
340 consumer->Connect(svc.get());
341
342 std::unique_ptr<MockProducer> producer = CreateMockProducer();
343 producer->Connect(svc.get(), "mock_producer");
344
345 // Create two data sources but enable only one of them.
346 producer->RegisterDataSource("ds_1");
347 producer->RegisterDataSource("ds_2");
348
349 TraceConfig trace_config;
350 trace_config.add_buffers()->set_size_kb(128);
351 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
352 auto* trigger_config = trace_config.mutable_trigger_config();
353 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
354 auto* trigger = trigger_config->add_triggers();
355 trigger->set_name("trigger_name");
356 trigger->set_stop_delay_ms(8.64e+7);
357
358 trigger_config->set_trigger_timeout_ms(1);
359
360 // Make sure we don't get unexpected DataSourceStart() notifications yet.
361 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
362
363 consumer->EnableTracing(trace_config);
364 producer->WaitForTracingSetup();
365
366 producer->WaitForDataSourceSetup("ds_1");
367
368 // The trace won't start until we send the trigger. since we have a
369 // START_TRACING trigger defined. This is where we'd expect to have an
370 // ActivateTriggers call to the producer->endpoint().
371
372 producer->WaitForDataSourceStop("ds_1");
373 consumer->WaitForTracingDisabled();
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100374 EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000375}
376
377// Creates a tracing session with a START_TRACING trigger and checks that
378// the session is not started when the configured trigger producer is different
379// than the producer that sent the trigger.
380TEST_F(TracingServiceImplTest, StartTracingTriggerDifferentProducer) {
381 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
382 consumer->Connect(svc.get());
383
384 std::unique_ptr<MockProducer> producer = CreateMockProducer();
385 producer->Connect(svc.get(), "mock_producer");
386
387 // Create two data sources but enable only one of them.
388 producer->RegisterDataSource("ds_1");
389 producer->RegisterDataSource("ds_2");
390
391 TraceConfig trace_config;
392 trace_config.add_buffers()->set_size_kb(128);
393 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
394 auto* trigger_config = trace_config.mutable_trigger_config();
395 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
396 auto* trigger = trigger_config->add_triggers();
397 trigger->set_name("trigger_name");
398 trigger->set_stop_delay_ms(8.64e+7);
399 trigger->set_producer_name_regex("correct_name");
400
401 trigger_config->set_trigger_timeout_ms(1);
402
403 // Make sure we don't get unexpected DataSourceStart() notifications yet.
404 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
405
406 consumer->EnableTracing(trace_config);
407 producer->WaitForTracingSetup();
408
409 producer->WaitForDataSourceSetup("ds_1");
410
411 // The trace won't start until we send the trigger called "trigger_name"
412 // coming from a producer called "correct_name", since we have a
413 // START_TRACING trigger defined. This is where we'd expect to have an
414 // ActivateTriggers call to the producer->endpoint(), but we send the trigger
415 // from a different producer so it is ignored.
416 std::vector<std::string> req;
417 req.push_back("trigger_name");
418 producer->endpoint()->ActivateTriggers(req);
419
420 producer->WaitForDataSourceStop("ds_1");
421 consumer->WaitForTracingDisabled();
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100422 EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000423}
424
425// Creates a tracing session with a START_TRACING trigger and checks that the
426// session is started when the trigger is received from the correct producer.
427TEST_F(TracingServiceImplTest, StartTracingTriggerCorrectProducer) {
428 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
429 consumer->Connect(svc.get());
430
431 std::unique_ptr<MockProducer> producer = CreateMockProducer();
432 producer->Connect(svc.get(), "mock_producer");
433
434 // Create two data sources but enable only one of them.
435 producer->RegisterDataSource("ds_1");
436 producer->RegisterDataSource("ds_2");
437
438 TraceConfig trace_config;
439 trace_config.add_buffers()->set_size_kb(128);
440 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
441 auto* trigger_config = trace_config.mutable_trigger_config();
442 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
443 auto* trigger = trigger_config->add_triggers();
444 trigger->set_name("trigger_name");
445 trigger->set_stop_delay_ms(1);
446 trigger->set_producer_name_regex("mock_produc[e-r]+");
447
448 trigger_config->set_trigger_timeout_ms(8.64e+7);
449
450 consumer->EnableTracing(trace_config);
451 producer->WaitForTracingSetup();
452
453 producer->WaitForDataSourceSetup("ds_1");
454
455 // Start the trace at this point with ActivateTriggers.
456 std::vector<std::string> req;
457 req.push_back("trigger_name");
458 producer->endpoint()->ActivateTriggers(req);
459
460 producer->WaitForDataSourceStart("ds_1");
461
462 auto writer = producer->CreateTraceWriter("ds_1");
463 producer->WaitForFlush(writer.get());
464
465 producer->WaitForDataSourceStop("ds_1");
466 consumer->WaitForTracingDisabled();
467 EXPECT_THAT(
468 consumer->ReadBuffers(),
469 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
470}
471
472// Creates a tracing session with a START_TRACING trigger and checks that the
473// session is cleaned up even when a different trigger is received.
474TEST_F(TracingServiceImplTest, StartTracingTriggerDifferentTrigger) {
475 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
476 consumer->Connect(svc.get());
477
478 std::unique_ptr<MockProducer> producer = CreateMockProducer();
479 producer->Connect(svc.get(), "mock_producer");
480
481 // Create two data sources but enable only one of them.
482 producer->RegisterDataSource("ds_1");
483 producer->RegisterDataSource("ds_2");
484
485 TraceConfig trace_config;
486 trace_config.add_buffers()->set_size_kb(128);
487 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
488 auto* trigger_config = trace_config.mutable_trigger_config();
489 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
490 auto* trigger = trigger_config->add_triggers();
491 trigger->set_name("trigger_name");
492 trigger->set_stop_delay_ms(8.64e+7);
493
494 trigger_config->set_trigger_timeout_ms(1);
495
496 // Make sure we don't get unexpected DataSourceStart() notifications yet.
497 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
498
499 consumer->EnableTracing(trace_config);
500 producer->WaitForTracingSetup();
501
502 producer->WaitForDataSourceSetup("ds_1");
503
504 // The trace won't start until we send the trigger called "trigger_name",
505 // since we have a START_TRACING trigger defined. This is where we'd expect to
506 // have an ActivateTriggers call to the producer->endpoint(), but we send a
507 // different trigger.
508 std::vector<std::string> req;
509 req.push_back("not_correct_trigger");
510 producer->endpoint()->ActivateTriggers(req);
511
512 producer->WaitForDataSourceStop("ds_1");
513 consumer->WaitForTracingDisabled();
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100514 EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000515}
516
517// Creates a tracing session with a START_TRACING trigger and checks that any
518// trigger can start the TracingSession.
519TEST_F(TracingServiceImplTest, StartTracingTriggerMultipleTriggers) {
520 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
521 consumer->Connect(svc.get());
522
523 std::unique_ptr<MockProducer> producer = CreateMockProducer();
524 producer->Connect(svc.get(), "mock_producer");
525
526 // Create two data sources but enable only one of them.
527 producer->RegisterDataSource("ds_1");
528 producer->RegisterDataSource("ds_2");
529
530 TraceConfig trace_config;
531 trace_config.add_buffers()->set_size_kb(128);
532 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
533 auto* trigger_config = trace_config.mutable_trigger_config();
534 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
535 auto* trigger = trigger_config->add_triggers();
536 trigger->set_name("trigger_name");
537 trigger->set_stop_delay_ms(1);
538
539 trigger_config->set_trigger_timeout_ms(8.64e+7);
540
541 consumer->EnableTracing(trace_config);
542 producer->WaitForTracingSetup();
543
544 producer->WaitForDataSourceSetup("ds_1");
545
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000546 std::vector<std::string> req;
547 req.push_back("not_correct_trigger");
548 req.push_back("trigger_name");
549 producer->endpoint()->ActivateTriggers(req);
550
551 producer->WaitForDataSourceStart("ds_1");
552
553 auto writer = producer->CreateTraceWriter("ds_1");
554 producer->WaitForFlush(writer.get());
555
556 producer->WaitForDataSourceStop("ds_1");
557 consumer->WaitForTracingDisabled();
558 EXPECT_THAT(
559 consumer->ReadBuffers(),
560 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
561}
562
563// Creates two tracing sessions with a START_TRACING trigger and checks that
564// both are able to be triggered simultaneously.
565TEST_F(TracingServiceImplTest, StartTracingTriggerMultipleTraces) {
566 std::unique_ptr<MockConsumer> consumer_1 = CreateMockConsumer();
567 consumer_1->Connect(svc.get());
568 std::unique_ptr<MockConsumer> consumer_2 = CreateMockConsumer();
569 consumer_2->Connect(svc.get());
570
571 std::unique_ptr<MockProducer> producer = CreateMockProducer();
572 producer->Connect(svc.get(), "mock_producer");
573
574 // Create two data sources but each TracingSession will only enable one of
575 // them.
576 producer->RegisterDataSource("ds_1");
577 producer->RegisterDataSource("ds_2");
578
579 TraceConfig trace_config;
580 trace_config.add_buffers()->set_size_kb(128);
581 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
582 auto* trigger_config = trace_config.mutable_trigger_config();
583 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
584 auto* trigger = trigger_config->add_triggers();
585 trigger->set_name("trigger_name");
586 trigger->set_stop_delay_ms(1);
587
588 trigger_config->set_trigger_timeout_ms(8.64e+7);
589
590 consumer_1->EnableTracing(trace_config);
591 producer->WaitForTracingSetup();
592
593 producer->WaitForDataSourceSetup("ds_1");
594
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000595 auto tracing_session_1_id = GetTracingSessionID();
596
597 (*trace_config.mutable_data_sources())[0].mutable_config()->set_name("ds_2");
598 trigger = trace_config.mutable_trigger_config()->add_triggers();
599 trigger->set_name("trigger_name_2");
600 trigger->set_stop_delay_ms(8.64e+7);
601
602 consumer_2->EnableTracing(trace_config);
603
604 producer->WaitForDataSourceSetup("ds_2");
605
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000606 auto tracing_session_2_id = GetTracingSessionID();
607 EXPECT_NE(tracing_session_1_id, tracing_session_2_id);
608
609 const DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_1");
610 const DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_2");
611
612 std::vector<std::string> req;
613 req.push_back("not_correct_trigger");
614 req.push_back("trigger_name");
615 req.push_back("trigger_name_2");
616 producer->endpoint()->ActivateTriggers(req);
617
618 // The order has to be the same as the triggers or else we're incorrectly wait
619 // on the wrong checkpoint in the |task_runner|.
620 producer->WaitForDataSourceStart("ds_1");
621 producer->WaitForDataSourceStart("ds_2");
622
623 // Now that they've started we can check the triggers they've seen.
624 auto* tracing_session_1 = GetTracingSession(tracing_session_1_id);
625 ASSERT_EQ(1u, tracing_session_1->received_triggers.size());
626 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100627 tracing_session_1->received_triggers[0].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000628
629 // This is actually dependent on the order in which the triggers were received
630 // but there isn't really a better way than iteration order so probably not to
631 // brittle of a test. And this caught a real bug in implementation.
632 auto* tracing_session_2 = GetTracingSession(tracing_session_2_id);
633 ASSERT_EQ(2u, tracing_session_2->received_triggers.size());
634
635 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100636 tracing_session_2->received_triggers[0].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000637
638 EXPECT_EQ("trigger_name_2",
Stephen Nusko70ea3302019-04-01 19:44:40 +0100639 tracing_session_2->received_triggers[1].trigger_name);
Stephen Nusko1393ffd2019-03-22 13:54:58 +0000640
641 auto writer1 = producer->CreateTraceWriter("ds_1");
642 auto writer2 = producer->CreateTraceWriter("ds_2");
643
644 // We can't use the standard WaitForX in the MockProducer and MockConsumer
645 // because they assume only a single trace is going on. So we perform our own
646 // expectations and wait at the end for the two consumers to receive
647 // OnTracingDisabled.
648 bool flushed_writer_1 = false;
649 bool flushed_writer_2 = false;
650 auto flush_correct_writer = [&](FlushRequestID flush_req_id,
651 const DataSourceInstanceID* id, size_t) {
652 if (*id == id1) {
653 flushed_writer_1 = true;
654 writer1->Flush();
655 producer->endpoint()->NotifyFlushComplete(flush_req_id);
656 } else if (*id == id2) {
657 flushed_writer_2 = true;
658 writer2->Flush();
659 producer->endpoint()->NotifyFlushComplete(flush_req_id);
660 }
661 };
662 EXPECT_CALL(*producer, Flush(_, _, _))
663 .WillOnce(Invoke(flush_correct_writer))
664 .WillOnce(Invoke(flush_correct_writer));
665
666 auto checkpoint_name = "on_tracing_disabled_consumer_1_and_2";
667 auto on_tracing_disabled = task_runner.CreateCheckpoint(checkpoint_name);
668 std::atomic<size_t> counter(0);
669 EXPECT_CALL(*consumer_1, OnTracingDisabled()).WillOnce(Invoke([&]() {
670 if (++counter == 2u) {
671 on_tracing_disabled();
672 }
673 }));
674 EXPECT_CALL(*consumer_2, OnTracingDisabled()).WillOnce(Invoke([&]() {
675 if (++counter == 2u) {
676 on_tracing_disabled();
677 }
678 }));
679
680 EXPECT_CALL(*producer, StopDataSource(id1));
681 EXPECT_CALL(*producer, StopDataSource(id2));
682
683 task_runner.RunUntilCheckpoint(checkpoint_name, 1000);
684
685 EXPECT_TRUE(flushed_writer_1);
686 EXPECT_TRUE(flushed_writer_2);
687 EXPECT_THAT(
688 consumer_1->ReadBuffers(),
689 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
690 EXPECT_THAT(
691 consumer_2->ReadBuffers(),
692 HasTriggerMode(protos::TraceConfig::TriggerConfig::START_TRACING));
693}
694
Stephen Nusko70ea3302019-04-01 19:44:40 +0100695// Creates a tracing session with a START_TRACING trigger and checks that the
696// received_triggers are emitted as packets.
697TEST_F(TracingServiceImplTest, EmitTriggersWithStartTracingTrigger) {
698 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
699 consumer->Connect(svc.get());
700
701 std::unique_ptr<MockProducer> producer = CreateMockProducer();
702 producer->Connect(svc.get(), "mock_producer", /* uid = */ 123u);
703
704 producer->RegisterDataSource("ds_1");
705
706 TraceConfig trace_config;
707 trace_config.add_buffers()->set_size_kb(128);
708 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
709 auto* trigger_config = trace_config.mutable_trigger_config();
710 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
711 auto* trigger = trigger_config->add_triggers();
712 trigger->set_name("trigger_name");
713 trigger->set_stop_delay_ms(1);
714 trigger->set_producer_name_regex("mock_produc[e-r]+");
715
716 trigger_config->set_trigger_timeout_ms(30000);
717
718 consumer->EnableTracing(trace_config);
719 producer->WaitForTracingSetup();
720 producer->WaitForDataSourceSetup("ds_1");
721
722 // The trace won't start until we send the trigger since we have a
723 // START_TRACING trigger defined.
724 std::vector<std::string> req;
725 req.push_back("trigger_name");
726 req.push_back("trigger_name_2");
727 req.push_back("trigger_name_3");
728 producer->endpoint()->ActivateTriggers(req);
729
730 producer->WaitForDataSourceStart("ds_1");
731 auto writer1 = producer->CreateTraceWriter("ds_1");
732 producer->WaitForFlush(writer1.get());
733 producer->WaitForDataSourceStop("ds_1");
734 consumer->WaitForTracingDisabled();
735
736 ASSERT_EQ(1u, tracing_session()->received_triggers.size());
737 EXPECT_EQ("trigger_name",
738 tracing_session()->received_triggers[0].trigger_name);
739
740 auto packets = consumer->ReadBuffers();
741 EXPECT_THAT(
742 packets,
743 Contains(Property(
744 &protos::TracePacket::trace_config,
745 Property(
746 &protos::TraceConfig::trigger_config,
747 Property(
748 &protos::TraceConfig::TriggerConfig::trigger_mode,
749 Eq(protos::TraceConfig::TriggerConfig::START_TRACING))))));
750 auto expect_received_trigger = [&](const std::string& name) {
751 return Contains(AllOf(
752 Property(
753 &protos::TracePacket::trigger,
754 AllOf(Property(&protos::Trigger::trigger_name, Eq(name)),
Eric Secklerc4024b22019-04-02 15:37:08 +0000755 Property(&protos::Trigger::trusted_producer_uid, Eq(123)),
Stephen Nusko70ea3302019-04-01 19:44:40 +0100756 Property(&protos::Trigger::producer_name,
757 Eq("mock_producer")))),
758 Property(&protos::TracePacket::trusted_packet_sequence_id,
759 Eq(kServicePacketSequenceID))));
760 };
761 EXPECT_THAT(packets, expect_received_trigger("trigger_name"));
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100762 EXPECT_THAT(packets, Not(expect_received_trigger("trigger_name_2")));
763 EXPECT_THAT(packets, Not(expect_received_trigger("trigger_name_3")));
Stephen Nusko70ea3302019-04-01 19:44:40 +0100764}
765
766// Creates a tracing session with a START_TRACING trigger and checks that the
767// received_triggers are emitted as packets.
768TEST_F(TracingServiceImplTest, EmitTriggersWithStopTracingTrigger) {
769 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
770 consumer->Connect(svc.get());
771
772 std::unique_ptr<MockProducer> producer = CreateMockProducer();
773 producer->Connect(svc.get(), "mock_producer", /* uid = */ 321u);
774
775 producer->RegisterDataSource("ds_1");
776
777 TraceConfig trace_config;
778 trace_config.add_buffers()->set_size_kb(128);
779 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
780 auto* trigger_config = trace_config.mutable_trigger_config();
781 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
782 auto* trigger = trigger_config->add_triggers();
783 trigger->set_name("trigger_name");
784 trigger->set_stop_delay_ms(1);
785 trigger = trigger_config->add_triggers();
786 trigger->set_name("trigger_name_3");
787 trigger->set_stop_delay_ms(30000);
788
789 trigger_config->set_trigger_timeout_ms(30000);
790
791 consumer->EnableTracing(trace_config);
792 producer->WaitForTracingSetup();
793 producer->WaitForDataSourceSetup("ds_1");
794 producer->WaitForDataSourceStart("ds_1");
795
796 // The trace won't start until we send the trigger since we have a
797 // START_TRACING trigger defined.
798 std::vector<std::string> req;
799 req.push_back("trigger_name");
800 req.push_back("trigger_name_2");
801 req.push_back("trigger_name_3");
802 producer->endpoint()->ActivateTriggers(req);
803
804 auto writer1 = producer->CreateTraceWriter("ds_1");
805 producer->WaitForFlush(writer1.get());
806 producer->WaitForDataSourceStop("ds_1");
807 consumer->WaitForTracingDisabled();
808
809 ASSERT_EQ(2u, tracing_session()->received_triggers.size());
810 EXPECT_EQ("trigger_name",
811 tracing_session()->received_triggers[0].trigger_name);
812 EXPECT_EQ("trigger_name_3",
813 tracing_session()->received_triggers[1].trigger_name);
814
815 auto packets = consumer->ReadBuffers();
816 EXPECT_THAT(
817 packets,
818 Contains(Property(
819 &protos::TracePacket::trace_config,
820 Property(
821 &protos::TraceConfig::trigger_config,
822 Property(
823 &protos::TraceConfig::TriggerConfig::trigger_mode,
824 Eq(protos::TraceConfig::TriggerConfig::STOP_TRACING))))));
825
826 auto expect_received_trigger = [&](const std::string& name) {
827 return Contains(AllOf(
828 Property(
829 &protos::TracePacket::trigger,
830 AllOf(Property(&protos::Trigger::trigger_name, Eq(name)),
Eric Secklerc4024b22019-04-02 15:37:08 +0000831 Property(&protos::Trigger::trusted_producer_uid, Eq(321)),
Stephen Nusko70ea3302019-04-01 19:44:40 +0100832 Property(&protos::Trigger::producer_name,
833 Eq("mock_producer")))),
834 Property(&protos::TracePacket::trusted_packet_sequence_id,
835 Eq(kServicePacketSequenceID))));
836 };
837 EXPECT_THAT(packets, expect_received_trigger("trigger_name"));
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100838 EXPECT_THAT(packets, Not(expect_received_trigger("trigger_name_2")));
Stephen Nusko70ea3302019-04-01 19:44:40 +0100839 EXPECT_THAT(packets, expect_received_trigger("trigger_name_3"));
840}
841
842// Creates a tracing session with a START_TRACING trigger and checks that the
843// received_triggers are emitted as packets even ones after the initial
844// ReadBuffers() call.
845TEST_F(TracingServiceImplTest, EmitTriggersRepeatedly) {
846 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
847 consumer->Connect(svc.get());
848
849 std::unique_ptr<MockProducer> producer = CreateMockProducer();
850 producer->Connect(svc.get(), "mock_producer");
851
852 // Create two data sources but enable only one of them.
853 producer->RegisterDataSource("ds_1");
854 producer->RegisterDataSource("ds_2");
855
856 TraceConfig trace_config;
857 trace_config.add_buffers()->set_size_kb(128);
858 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
859 auto* trigger_config = trace_config.mutable_trigger_config();
860 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
861 auto* trigger = trigger_config->add_triggers();
862 trigger->set_name("trigger_name");
863 trigger->set_stop_delay_ms(1);
864 trigger = trigger_config->add_triggers();
865 trigger->set_name("trigger_name_2");
866 trigger->set_stop_delay_ms(1);
867
868 trigger_config->set_trigger_timeout_ms(30000);
869
870 auto expect_received_trigger = [&](const std::string& name) {
871 return Contains(
872 AllOf(Property(&protos::TracePacket::trigger,
873 AllOf(Property(&protos::Trigger::trigger_name, Eq(name)),
874 Property(&protos::Trigger::producer_name,
875 Eq("mock_producer")))),
876 Property(&protos::TracePacket::trusted_packet_sequence_id,
877 Eq(kServicePacketSequenceID))));
878 };
879
880 consumer->EnableTracing(trace_config);
881 producer->WaitForTracingSetup();
882 producer->WaitForDataSourceSetup("ds_1");
883 producer->WaitForDataSourceStart("ds_1");
884
885 // The trace won't start until we send the trigger. since we have a
886 // START_TRACING trigger defined.
887 producer->endpoint()->ActivateTriggers({"trigger_name"});
888
889 auto packets = consumer->ReadBuffers();
890 EXPECT_THAT(
891 packets,
892 Contains(Property(
893 &protos::TracePacket::trace_config,
894 Property(
895 &protos::TraceConfig::trigger_config,
896 Property(
897 &protos::TraceConfig::TriggerConfig::trigger_mode,
898 Eq(protos::TraceConfig::TriggerConfig::STOP_TRACING))))));
899 EXPECT_THAT(packets, expect_received_trigger("trigger_name"));
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100900 EXPECT_THAT(packets, Not(expect_received_trigger("trigger_name_2")));
Stephen Nusko70ea3302019-04-01 19:44:40 +0100901
902 // Send a new trigger.
903 producer->endpoint()->ActivateTriggers({"trigger_name_2"});
904
905 auto writer1 = producer->CreateTraceWriter("ds_1");
906 producer->WaitForFlush(writer1.get());
907 producer->WaitForDataSourceStop("ds_1");
908 consumer->WaitForTracingDisabled();
909
910 ASSERT_EQ(2u, tracing_session()->received_triggers.size());
911 EXPECT_EQ("trigger_name",
912 tracing_session()->received_triggers[0].trigger_name);
913 EXPECT_EQ("trigger_name_2",
914 tracing_session()->received_triggers[1].trigger_name);
915
916 packets = consumer->ReadBuffers();
917 // We don't rewrite the old trigger.
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100918 EXPECT_THAT(packets, Not(expect_received_trigger("trigger_name")));
Stephen Nusko70ea3302019-04-01 19:44:40 +0100919 EXPECT_THAT(packets, expect_received_trigger("trigger_name_2"));
920}
921
Stephen Nuskod95a7512019-03-22 13:59:39 +0000922// Creates a tracing session with a STOP_TRACING trigger and checks that the
923// session is cleaned up after |trigger_timeout_ms|.
924TEST_F(TracingServiceImplTest, StopTracingTriggerTimeout) {
925 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
926 consumer->Connect(svc.get());
927
928 std::unique_ptr<MockProducer> producer = CreateMockProducer();
929 producer->Connect(svc.get(), "mock_producer");
930
931 // Create two data sources but enable only one of them.
932 producer->RegisterDataSource("ds_1");
933 producer->RegisterDataSource("ds_2");
934
935 TraceConfig trace_config;
936 trace_config.add_buffers()->set_size_kb(128);
937 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
938 auto* trigger_config = trace_config.mutable_trigger_config();
939 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
940 auto* trigger = trigger_config->add_triggers();
941 trigger->set_name("trigger_name");
942 trigger->set_stop_delay_ms(8.64e+7);
943
944 trigger_config->set_trigger_timeout_ms(1);
945
946 // Make sure we don't get unexpected DataSourceStart() notifications yet.
947 EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
948
949 consumer->EnableTracing(trace_config);
950 producer->WaitForTracingSetup();
951
952 producer->WaitForDataSourceSetup("ds_1");
953 producer->WaitForDataSourceStart("ds_1");
954
955 // The trace won't return data until unless we send a trigger at this point.
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100956 EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
Stephen Nuskod95a7512019-03-22 13:59:39 +0000957
958 auto writer = producer->CreateTraceWriter("ds_1");
959 producer->WaitForFlush(writer.get());
960
961 ASSERT_EQ(0u, tracing_session()->received_triggers.size());
962
963 producer->WaitForDataSourceStop("ds_1");
964 consumer->WaitForTracingDisabled();
Hector Dearmanbb3bc482019-08-02 11:54:08 +0100965 EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
Stephen Nuskod95a7512019-03-22 13:59:39 +0000966}
967
968// Creates a tracing session with a STOP_TRACING trigger and checks that the
969// session returns data after a trigger is received, but only what is currently
970// in the buffer.
971TEST_F(TracingServiceImplTest, StopTracingTriggerRingBuffer) {
972 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
973 consumer->Connect(svc.get());
974
975 std::unique_ptr<MockProducer> producer = CreateMockProducer();
976 producer->Connect(svc.get(), "mock_producer");
977
978 // Create two data sources but enable only one of them.
979 producer->RegisterDataSource("ds_1");
980 producer->RegisterDataSource("ds_2");
981
982 TraceConfig trace_config;
983 trace_config.add_buffers()->set_size_kb(128);
984 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
985 auto* trigger_config = trace_config.mutable_trigger_config();
986 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
987 auto* trigger = trigger_config->add_triggers();
988 trigger->set_name("trigger_name");
989 trigger->set_stop_delay_ms(1);
990
991 trigger_config->set_trigger_timeout_ms(8.64e+7);
992
993 consumer->EnableTracing(trace_config);
994 producer->WaitForTracingSetup();
995
996 producer->WaitForDataSourceSetup("ds_1");
997 producer->WaitForDataSourceStart("ds_1");
998
Stephen Nuskod95a7512019-03-22 13:59:39 +0000999 // The trace won't return data until unless we send a trigger at this point.
Hector Dearmanbb3bc482019-08-02 11:54:08 +01001000 EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
Stephen Nuskod95a7512019-03-22 13:59:39 +00001001
1002 // We write into the buffer a large packet which takes up the whole buffer. We
1003 // then add a bunch of smaller ones which causes the larger packet to be
1004 // dropped. After we activate the session we should only see a bunch of the
1005 // smaller ones.
Eric Secklera883e5f2019-04-02 22:51:29 +00001006 static const size_t kNumTestPackets = 10;
Stephen Nuskod95a7512019-03-22 13:59:39 +00001007 static const char kPayload[] = "1234567890abcdef-";
1008
1009 auto writer = producer->CreateTraceWriter("ds_1");
1010 // Buffer is 1kb so we write a packet which is slightly smaller so it fits in
1011 // the buffer.
1012 const std::string large_payload(1024 * 128 - 20, 'a');
1013 {
1014 auto tp = writer->NewTracePacket();
1015 tp->set_for_testing()->set_str(large_payload.c_str(), large_payload.size());
1016 }
1017
1018 // Now we add a bunch of data before the trigger and after.
Eric Secklera883e5f2019-04-02 22:51:29 +00001019 for (size_t i = 0; i < kNumTestPackets; i++) {
Stephen Nuskod95a7512019-03-22 13:59:39 +00001020 if (i == kNumTestPackets / 2) {
1021 std::vector<std::string> req;
1022 req.push_back("trigger_name");
1023 producer->endpoint()->ActivateTriggers(req);
1024 }
1025 auto tp = writer->NewTracePacket();
1026 std::string payload(kPayload);
1027 payload.append(std::to_string(i));
1028 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
1029 }
1030 producer->WaitForFlush(writer.get());
1031
1032 ASSERT_EQ(1u, tracing_session()->received_triggers.size());
1033 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +01001034 tracing_session()->received_triggers[0].trigger_name);
Stephen Nuskod95a7512019-03-22 13:59:39 +00001035
1036 producer->WaitForDataSourceStop("ds_1");
1037 consumer->WaitForTracingDisabled();
Stephen Nusko70ea3302019-04-01 19:44:40 +01001038
Stephen Nuskod95a7512019-03-22 13:59:39 +00001039 auto packets = consumer->ReadBuffers();
Stephen Nusko70ea3302019-04-01 19:44:40 +01001040 EXPECT_LT(kNumTestPackets, packets.size());
Stephen Nuskod95a7512019-03-22 13:59:39 +00001041 // We expect for the TraceConfig preamble packet to be there correctly and
1042 // then we expect each payload to be there, but not the |large_payload|
1043 // packet.
1044 EXPECT_THAT(packets,
1045 HasTriggerMode(protos::TraceConfig::TriggerConfig::STOP_TRACING));
Eric Secklera883e5f2019-04-02 22:51:29 +00001046 for (size_t i = 0; i < kNumTestPackets; i++) {
Stephen Nuskod95a7512019-03-22 13:59:39 +00001047 std::string payload = kPayload;
1048 payload += std::to_string(i);
1049 EXPECT_THAT(packets, Contains(Property(
1050 &protos::TracePacket::for_testing,
1051 Property(&protos::TestEvent::str, Eq(payload)))));
1052 }
1053
1054 // The large payload was overwritten before we trigger and ReadBuffers so it
1055 // should not be in the returned data.
Hector Dearmanbb3bc482019-08-02 11:54:08 +01001056 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
1057 Property(&protos::TestEvent::str,
1058 Eq(large_payload))))));
Stephen Nuskod95a7512019-03-22 13:59:39 +00001059}
1060
1061// Creates a tracing session with a STOP_TRACING trigger and checks that the
1062// session only cleans up once even with multiple triggers.
1063TEST_F(TracingServiceImplTest, StopTracingTriggerMultipleTriggers) {
1064 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1065 consumer->Connect(svc.get());
1066
1067 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1068 producer->Connect(svc.get(), "mock_producer");
1069
1070 // Create two data sources but enable only one of them.
1071 producer->RegisterDataSource("ds_1");
1072 producer->RegisterDataSource("ds_2");
1073
1074 TraceConfig trace_config;
1075 trace_config.add_buffers()->set_size_kb(128);
1076 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
1077 auto* trigger_config = trace_config.mutable_trigger_config();
1078 trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
1079 auto* trigger = trigger_config->add_triggers();
1080 trigger->set_name("trigger_name");
1081 trigger->set_stop_delay_ms(1);
1082 trigger = trigger_config->add_triggers();
1083 trigger->set_name("trigger_name_2");
1084 trigger->set_stop_delay_ms(8.64e+7);
1085
1086 trigger_config->set_trigger_timeout_ms(8.64e+7);
1087
1088 consumer->EnableTracing(trace_config);
1089 producer->WaitForTracingSetup();
1090
1091 producer->WaitForDataSourceSetup("ds_1");
1092 producer->WaitForDataSourceStart("ds_1");
1093
Stephen Nuskod95a7512019-03-22 13:59:39 +00001094 // The trace won't return data until unless we send a trigger at this point.
Hector Dearmanbb3bc482019-08-02 11:54:08 +01001095 EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
Stephen Nuskod95a7512019-03-22 13:59:39 +00001096
1097 std::vector<std::string> req;
1098 req.push_back("trigger_name");
1099 req.push_back("trigger_name_3");
1100 req.push_back("trigger_name_2");
1101 producer->endpoint()->ActivateTriggers(req);
1102
1103 auto writer = producer->CreateTraceWriter("ds_1");
1104 producer->WaitForFlush(writer.get());
1105
1106 ASSERT_EQ(2u, tracing_session()->received_triggers.size());
1107 EXPECT_EQ("trigger_name",
Stephen Nusko70ea3302019-04-01 19:44:40 +01001108 tracing_session()->received_triggers[0].trigger_name);
Stephen Nuskod95a7512019-03-22 13:59:39 +00001109 EXPECT_EQ("trigger_name_2",
Stephen Nusko70ea3302019-04-01 19:44:40 +01001110 tracing_session()->received_triggers[1].trigger_name);
Stephen Nuskod95a7512019-03-22 13:59:39 +00001111
1112 producer->WaitForDataSourceStop("ds_1");
1113 consumer->WaitForTracingDisabled();
1114 EXPECT_THAT(consumer->ReadBuffers(),
1115 HasTriggerMode(protos::TraceConfig::TriggerConfig::STOP_TRACING));
1116}
1117
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001118TEST_F(TracingServiceImplTest, LockdownMode) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001119 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1120 consumer->Connect(svc.get());
1121
1122 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1123 producer->Connect(svc.get(), "mock_producer_sameuid", geteuid());
1124 producer->RegisterDataSource("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +00001125
1126 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001127 trace_config.add_buffers()->set_size_kb(128);
1128 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1129 ds_config->set_name("data_source");
Primiano Tucci57dd66b2019-10-15 23:09:04 +01001130 trace_config.set_lockdown_mode(TraceConfig::LOCKDOWN_SET);
Primiano Tuccidca727d2018-04-04 11:31:55 +02001131 consumer->EnableTracing(trace_config);
1132
1133 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001134 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001135 producer->WaitForDataSourceStart("data_source");
1136
1137 std::unique_ptr<MockProducer> producer_otheruid = CreateMockProducer();
1138 auto x = svc->ConnectProducer(producer_otheruid.get(), geteuid() + 1,
1139 "mock_producer_ouid");
1140 EXPECT_CALL(*producer_otheruid, OnConnect()).Times(0);
Florian Mayer61c55482018-03-06 14:43:54 +00001141 task_runner.RunUntilIdle();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001142 Mock::VerifyAndClearExpectations(producer_otheruid.get());
Florian Mayer61c55482018-03-06 14:43:54 +00001143
Primiano Tuccidca727d2018-04-04 11:31:55 +02001144 consumer->DisableTracing();
1145 consumer->FreeBuffers();
1146 producer->WaitForDataSourceStop("data_source");
1147 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +00001148
Primiano Tucci57dd66b2019-10-15 23:09:04 +01001149 trace_config.set_lockdown_mode(TraceConfig::LOCKDOWN_CLEAR);
Primiano Tuccidca727d2018-04-04 11:31:55 +02001150 consumer->EnableTracing(trace_config);
Primiano Tucci674076d2018-10-01 10:41:09 +01001151 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001152 producer->WaitForDataSourceStart("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +00001153
Primiano Tuccidca727d2018-04-04 11:31:55 +02001154 std::unique_ptr<MockProducer> producer_otheruid2 = CreateMockProducer();
1155 producer_otheruid->Connect(svc.get(), "mock_producer_ouid2", geteuid() + 1);
Florian Mayer61c55482018-03-06 14:43:54 +00001156
Primiano Tuccidca727d2018-04-04 11:31:55 +02001157 consumer->DisableTracing();
1158 producer->WaitForDataSourceStop("data_source");
1159 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +00001160}
1161
Oystein Eftevaagcb6e4c82019-03-06 15:38:26 -08001162TEST_F(TracingServiceImplTest, ProducerNameFilterChange) {
1163 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1164 consumer->Connect(svc.get());
1165
1166 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1167 producer1->Connect(svc.get(), "mock_producer_1");
1168 producer1->RegisterDataSource("data_source");
1169
1170 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1171 producer2->Connect(svc.get(), "mock_producer_2");
1172 producer2->RegisterDataSource("data_source");
1173
1174 std::unique_ptr<MockProducer> producer3 = CreateMockProducer();
1175 producer3->Connect(svc.get(), "mock_producer_3");
1176 producer3->RegisterDataSource("data_source");
1177 producer3->RegisterDataSource("unused_data_source");
1178
1179 TraceConfig trace_config;
1180 trace_config.add_buffers()->set_size_kb(128);
1181 auto* data_source = trace_config.add_data_sources();
1182 data_source->mutable_config()->set_name("data_source");
1183 *data_source->add_producer_name_filter() = "mock_producer_1";
1184
1185 // Enable tracing with only mock_producer_1 enabled;
1186 // the rest should not start up.
1187 consumer->EnableTracing(trace_config);
1188
1189 producer1->WaitForTracingSetup();
1190 producer1->WaitForDataSourceSetup("data_source");
1191 producer1->WaitForDataSourceStart("data_source");
1192
1193 EXPECT_CALL(*producer2, OnConnect()).Times(0);
1194 EXPECT_CALL(*producer3, OnConnect()).Times(0);
1195 task_runner.RunUntilIdle();
1196 Mock::VerifyAndClearExpectations(producer2.get());
1197 Mock::VerifyAndClearExpectations(producer3.get());
1198
1199 // Enable mock_producer_2, the third one should still
1200 // not get connected.
1201 *data_source->add_producer_name_filter() = "mock_producer_2";
1202 consumer->ChangeTraceConfig(trace_config);
1203
1204 producer2->WaitForTracingSetup();
1205 producer2->WaitForDataSourceSetup("data_source");
1206 producer2->WaitForDataSourceStart("data_source");
1207
1208 // Enable mock_producer_3 but also try to do an
1209 // unsupported change (adding a new data source);
1210 // mock_producer_3 should get enabled but not
1211 // for the new data source.
1212 *data_source->add_producer_name_filter() = "mock_producer_3";
1213 auto* dummy_data_source = trace_config.add_data_sources();
1214 dummy_data_source->mutable_config()->set_name("unused_data_source");
1215 *dummy_data_source->add_producer_name_filter() = "mock_producer_3";
1216
1217 consumer->ChangeTraceConfig(trace_config);
1218
1219 producer3->WaitForTracingSetup();
1220 EXPECT_CALL(*producer3, SetupDataSource(_, _)).Times(1);
1221 EXPECT_CALL(*producer3, StartDataSource(_, _)).Times(1);
1222 task_runner.RunUntilIdle();
1223 Mock::VerifyAndClearExpectations(producer3.get());
1224
1225 consumer->DisableTracing();
1226 consumer->FreeBuffers();
1227 producer1->WaitForDataSourceStop("data_source");
1228 producer2->WaitForDataSourceStop("data_source");
1229
1230 EXPECT_CALL(*producer3, StopDataSource(_)).Times(1);
1231
1232 consumer->WaitForTracingDisabled();
1233
1234 task_runner.RunUntilIdle();
1235 Mock::VerifyAndClearExpectations(producer3.get());
1236}
1237
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001238TEST_F(TracingServiceImplTest, DisconnectConsumerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001239 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1240 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +00001241
Primiano Tuccidca727d2018-04-04 11:31:55 +02001242 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1243 producer->Connect(svc.get(), "mock_producer");
1244 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001245
Primiano Tuccidca727d2018-04-04 11:31:55 +02001246 TraceConfig trace_config;
1247 trace_config.add_buffers()->set_size_kb(128);
1248 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1249 ds_config->set_name("data_source");
1250 consumer->EnableTracing(trace_config);
1251
1252 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001253 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001254 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001255
1256 // Disconnecting the consumer while tracing should trigger data source
1257 // teardown.
Primiano Tuccidca727d2018-04-04 11:31:55 +02001258 consumer.reset();
1259 producer->WaitForDataSourceStop("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001260}
1261
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001262TEST_F(TracingServiceImplTest, ReconnectProducerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001263 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1264 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +00001265
Primiano Tuccidca727d2018-04-04 11:31:55 +02001266 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1267 producer->Connect(svc.get(), "mock_producer");
1268 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001269
Sami Kyostila06487a22018-02-27 13:48:38 +00001270 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001271 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +00001272 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001273 ds_config->set_name("data_source");
1274 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +00001275
Primiano Tuccidca727d2018-04-04 11:31:55 +02001276 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001277 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001278 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001279
Primiano Tuccidca727d2018-04-04 11:31:55 +02001280 // Disconnecting and reconnecting a producer with a matching data source.
1281 // The Producer should see that data source getting enabled again.
1282 producer.reset();
1283 producer = CreateMockProducer();
1284 producer->Connect(svc.get(), "mock_producer_2");
1285 producer->RegisterDataSource("data_source");
1286 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001287 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001288 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001289}
1290
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001291TEST_F(TracingServiceImplTest, ProducerIDWrapping) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001292 std::vector<std::unique_ptr<MockProducer>> producers;
1293 producers.push_back(nullptr);
Primiano Tucci081d46a2018-02-28 11:09:43 +00001294
Primiano Tuccidca727d2018-04-04 11:31:55 +02001295 auto connect_producer_and_get_id = [&producers,
1296 this](const std::string& name) {
1297 producers.emplace_back(CreateMockProducer());
1298 producers.back()->Connect(svc.get(), "mock_producer_" + name);
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001299 return *last_producer_id();
Primiano Tucci081d46a2018-02-28 11:09:43 +00001300 };
1301
1302 // Connect producers 1-4.
1303 for (ProducerID i = 1; i <= 4; i++)
Primiano Tuccidca727d2018-04-04 11:31:55 +02001304 ASSERT_EQ(i, connect_producer_and_get_id(std::to_string(i)));
Primiano Tucci081d46a2018-02-28 11:09:43 +00001305
1306 // Disconnect producers 1,3.
Primiano Tuccidca727d2018-04-04 11:31:55 +02001307 producers[1].reset();
1308 producers[3].reset();
Primiano Tucci081d46a2018-02-28 11:09:43 +00001309
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001310 *last_producer_id() = kMaxProducerID - 1;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001311 ASSERT_EQ(kMaxProducerID, connect_producer_and_get_id("maxid"));
1312 ASSERT_EQ(1u, connect_producer_and_get_id("1_again"));
1313 ASSERT_EQ(3u, connect_producer_and_get_id("3_again"));
1314 ASSERT_EQ(5u, connect_producer_and_get_id("5"));
1315 ASSERT_EQ(6u, connect_producer_and_get_id("6"));
Primiano Tucci081d46a2018-02-28 11:09:43 +00001316}
1317
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001318// Note: file_write_period_ms is set to a large enough to have exactly one flush
1319// of the tracing buffers (and therefore at most one synchronization section),
1320// unless the test runs unrealistically slowly, or the implementation of the
1321// tracing snapshot packets changes.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001322TEST_F(TracingServiceImplTest, WriteIntoFileAndStopOnMaxSize) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001323 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1324 consumer->Connect(svc.get());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001325
Primiano Tuccidca727d2018-04-04 11:31:55 +02001326 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1327 producer->Connect(svc.get(), "mock_producer");
1328 producer->RegisterDataSource("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001329
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001330 TraceConfig trace_config;
1331 trace_config.add_buffers()->set_size_kb(4096);
1332 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001333 ds_config->set_name("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001334 ds_config->set_target_buffer(0);
1335 trace_config.set_write_into_file(true);
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001336 trace_config.set_file_write_period_ms(100000); // 100s
1337 const uint64_t kMaxFileSize = 1024;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001338 trace_config.set_max_file_size_bytes(kMaxFileSize);
1339 base::TempFile tmp_file = base::TempFile::Create();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001340 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
1341
1342 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001343 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001344 producer->WaitForDataSourceStart("data_source");
1345
Hector Dearman685f7522019-03-12 14:28:56 +00001346 // The preamble packets are:
Hector Dearmane004a572019-05-13 17:51:43 +01001347 // Trace start clocksnapshot
Hector Dearman685f7522019-03-12 14:28:56 +00001348 // Config
1349 // SystemInfo
Hector Dearmane004a572019-05-13 17:51:43 +01001350 // Trace read clocksnapshot
1351 // Trace synchronisation
Eric Seckler667e0852019-06-06 14:56:07 +01001352 static const int kNumPreamblePackets = 5;
Hector Dearmane004a572019-05-13 17:51:43 +01001353 static const int kNumTestPackets = 9;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001354 static const char kPayload[] = "1234567890abcdef-";
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001355
1356 std::unique_ptr<TraceWriter> writer =
Primiano Tuccidca727d2018-04-04 11:31:55 +02001357 producer->CreateTraceWriter("data_source");
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001358 // Tracing service will emit a preamble of packets (a synchronization section,
1359 // followed by a tracing config packet). The preamble and these test packets
1360 // should fit within kMaxFileSize.
1361 for (int i = 0; i < kNumTestPackets; i++) {
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001362 auto tp = writer->NewTracePacket();
1363 std::string payload(kPayload);
1364 payload.append(std::to_string(i));
1365 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
1366 }
1367
1368 // Finally add a packet that overflows kMaxFileSize. This should cause the
1369 // implicit stop of the trace and should *not* be written in the trace.
1370 {
1371 auto tp = writer->NewTracePacket();
1372 char big_payload[kMaxFileSize] = "BIG!";
1373 tp->set_for_testing()->set_str(big_payload, sizeof(big_payload));
1374 }
1375 writer->Flush();
1376 writer.reset();
1377
Primiano Tuccidca727d2018-04-04 11:31:55 +02001378 consumer->DisableTracing();
1379 producer->WaitForDataSourceStop("data_source");
1380 consumer->WaitForTracingDisabled();
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001381
1382 // Verify the contents of the file.
1383 std::string trace_raw;
1384 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
1385 protos::Trace trace;
1386 ASSERT_TRUE(trace.ParseFromString(trace_raw));
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001387
1388 ASSERT_EQ(trace.packet_size(), kNumPreamblePackets + kNumTestPackets);
1389 for (int i = 0; i < kNumTestPackets; i++) {
1390 const protos::TracePacket& tp = trace.packet(kNumPreamblePackets + i);
1391 ASSERT_EQ(kPayload + std::to_string(i++), tp.for_testing().str());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001392 }
Primiano Tuccidca727d2018-04-04 11:31:55 +02001393}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001394
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001395// Test the logic that allows the trace config to set the shm total size and
1396// page size from the trace config. Also check that, if the config doesn't
1397// specify a value we fall back on the hint provided by the producer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001398TEST_F(TracingServiceImplTest, ProducerShmAndPageSizeOverriddenByTraceConfig) {
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001399 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1400 consumer->Connect(svc.get());
Nicolò Mazzucato693f6aa2019-07-08 10:26:09 +01001401 const size_t kMaxPageSizeKb = SharedMemoryABI::kMaxPageSize / 1024;
1402 const size_t kConfigPageSizesKb[] = /**/ {16, 0, 3, 2, 16, 8, 0, 4096, 0};
1403 const size_t kPageHintSizesKb[] = /****/ {0, 4, 0, 0, 8, 0, 4096, 0, 0};
1404 const size_t kExpectedPageSizesKb[] = {
1405 16, // Use config value.
1406 4, // Config is 0, use hint.
1407 kDefaultShmPageSizeKb, // Config % 4 != 0, take default.
1408 kDefaultShmPageSizeKb, // Less than page size, take default.
1409 16, // Ignore the hint.
1410 8, // Use config value.
1411 kMaxPageSizeKb, // Hint too big, take max value.
1412 kMaxPageSizeKb, // Config too high, take max value.
1413 4 // Fallback to default.
1414 };
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001415
1416 const size_t kConfigSizesKb[] = /**/ {0, 16, 0, 20, 32, 7, 0, 96, 4096000};
1417 const size_t kHintSizesKb[] = /****/ {0, 0, 16, 32, 16, 0, 7, 96, 4096000};
1418 const size_t kExpectedSizesKb[] = {
1419 kDefaultShmSizeKb, // Both hint and config are 0, use default.
1420 16, // Hint is 0, use config.
1421 16, // Config is 0, use hint.
1422 20, // Hint is takes precedence over the config.
1423 32, // Ditto, even if config is higher than hint.
1424 kDefaultShmSizeKb, // Config is invalid and hint is 0, use default.
1425 kDefaultShmSizeKb, // Config is 0 and hint is invalid, use default.
1426 kDefaultShmSizeKb, // 96 KB isn't a multiple of the page size (64 KB).
1427 kMaxShmSizeKb // Too big, cap at kMaxShmSize.
1428 };
1429
1430 const size_t kNumProducers = base::ArraySize(kHintSizesKb);
1431 std::unique_ptr<MockProducer> producer[kNumProducers];
1432 for (size_t i = 0; i < kNumProducers; i++) {
1433 auto name = "mock_producer_" + std::to_string(i);
1434 producer[i] = CreateMockProducer();
Nicolò Mazzucato693f6aa2019-07-08 10:26:09 +01001435 producer[i]->Connect(svc.get(), name, geteuid(), kHintSizesKb[i] * 1024,
1436 kPageHintSizesKb[i] * 1024);
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001437 producer[i]->RegisterDataSource("data_source");
1438 }
1439
1440 TraceConfig trace_config;
1441 trace_config.add_buffers()->set_size_kb(128);
1442 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1443 ds_config->set_name("data_source");
1444 for (size_t i = 0; i < kNumProducers; i++) {
1445 auto* producer_config = trace_config.add_producers();
1446 producer_config->set_producer_name("mock_producer_" + std::to_string(i));
Primiano Tucci3cbb10a2018-04-10 17:52:40 +01001447 producer_config->set_shm_size_kb(static_cast<uint32_t>(kConfigSizesKb[i]));
1448 producer_config->set_page_size_kb(
1449 static_cast<uint32_t>(kConfigPageSizesKb[i]));
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001450 }
1451
1452 consumer->EnableTracing(trace_config);
1453 size_t actual_shm_sizes_kb[kNumProducers]{};
1454 size_t actual_page_sizes_kb[kNumProducers]{};
1455 for (size_t i = 0; i < kNumProducers; i++) {
1456 producer[i]->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001457 producer[i]->WaitForDataSourceSetup("data_source");
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001458 actual_shm_sizes_kb[i] =
1459 producer[i]->endpoint()->shared_memory()->size() / 1024;
1460 actual_page_sizes_kb[i] =
1461 producer[i]->endpoint()->shared_buffer_page_size_kb();
1462 }
Primiano Tucci674076d2018-10-01 10:41:09 +01001463 for (size_t i = 0; i < kNumProducers; i++) {
1464 producer[i]->WaitForDataSourceStart("data_source");
1465 }
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001466 ASSERT_THAT(actual_page_sizes_kb, ElementsAreArray(kExpectedPageSizesKb));
1467 ASSERT_THAT(actual_shm_sizes_kb, ElementsAreArray(kExpectedSizesKb));
1468}
1469
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001470TEST_F(TracingServiceImplTest, ExplicitFlush) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001471 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1472 consumer->Connect(svc.get());
1473
1474 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1475 producer->Connect(svc.get(), "mock_producer");
1476 producer->RegisterDataSource("data_source");
1477
1478 TraceConfig trace_config;
1479 trace_config.add_buffers()->set_size_kb(128);
1480 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1481 ds_config->set_name("data_source");
1482
1483 consumer->EnableTracing(trace_config);
1484 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001485 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001486 producer->WaitForDataSourceStart("data_source");
1487
1488 std::unique_ptr<TraceWriter> writer =
1489 producer->CreateTraceWriter("data_source");
1490 {
1491 auto tp = writer->NewTracePacket();
1492 tp->set_for_testing()->set_str("payload");
1493 }
1494
1495 auto flush_request = consumer->Flush();
1496 producer->WaitForFlush(writer.get());
1497 ASSERT_TRUE(flush_request.WaitForReply());
1498
1499 consumer->DisableTracing();
1500 producer->WaitForDataSourceStop("data_source");
1501 consumer->WaitForTracingDisabled();
1502 EXPECT_THAT(
1503 consumer->ReadBuffers(),
1504 Contains(Property(&protos::TracePacket::for_testing,
1505 Property(&protos::TestEvent::str, Eq("payload")))));
1506}
1507
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001508TEST_F(TracingServiceImplTest, ImplicitFlushOnTimedTraces) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001509 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1510 consumer->Connect(svc.get());
1511
1512 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1513 producer->Connect(svc.get(), "mock_producer");
1514 producer->RegisterDataSource("data_source");
1515
1516 TraceConfig trace_config;
1517 trace_config.add_buffers()->set_size_kb(128);
1518 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1519 ds_config->set_name("data_source");
1520 trace_config.set_duration_ms(1);
1521
1522 consumer->EnableTracing(trace_config);
1523 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001524 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001525 producer->WaitForDataSourceStart("data_source");
1526
1527 std::unique_ptr<TraceWriter> writer =
1528 producer->CreateTraceWriter("data_source");
1529 {
1530 auto tp = writer->NewTracePacket();
1531 tp->set_for_testing()->set_str("payload");
1532 }
1533
1534 producer->WaitForFlush(writer.get());
1535
1536 producer->WaitForDataSourceStop("data_source");
1537 consumer->WaitForTracingDisabled();
1538
1539 EXPECT_THAT(
1540 consumer->ReadBuffers(),
1541 Contains(Property(&protos::TracePacket::for_testing,
1542 Property(&protos::TestEvent::str, Eq("payload")))));
1543}
1544
1545// Tests the monotonic semantic of flush request IDs, i.e., once a producer
1546// acks flush request N, all flush requests <= N are considered successful and
1547// acked to the consumer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001548TEST_F(TracingServiceImplTest, BatchFlushes) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001549 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1550 consumer->Connect(svc.get());
1551
1552 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1553 producer->Connect(svc.get(), "mock_producer");
1554 producer->RegisterDataSource("data_source");
1555
1556 TraceConfig trace_config;
1557 trace_config.add_buffers()->set_size_kb(128);
1558 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1559 ds_config->set_name("data_source");
1560
1561 consumer->EnableTracing(trace_config);
1562 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001563 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001564 producer->WaitForDataSourceStart("data_source");
1565
1566 std::unique_ptr<TraceWriter> writer =
1567 producer->CreateTraceWriter("data_source");
1568 {
1569 auto tp = writer->NewTracePacket();
1570 tp->set_for_testing()->set_str("payload");
1571 }
1572
1573 auto flush_req_1 = consumer->Flush();
1574 auto flush_req_2 = consumer->Flush();
1575 auto flush_req_3 = consumer->Flush();
1576
1577 // We'll deliberately let the 4th flush request timeout. Use a lower timeout
1578 // to keep test time short.
1579 auto flush_req_4 = consumer->Flush(/*timeout_ms=*/10);
1580 ASSERT_EQ(4u, GetNumPendingFlushes());
1581
1582 // Make the producer reply only to the 3rd flush request.
Hector Dearmanbb3bc482019-08-02 11:54:08 +01001583 InSequence seq;
Eric Secklera01e28a2019-01-08 11:21:04 +00001584 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 1.
1585 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 2.
1586 producer->WaitForFlush(writer.get()); // Reply only to flush 3.
1587 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 4.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001588
1589 // Even if the producer explicily replied only to flush ID == 3, all the
1590 // previous flushed < 3 should be implicitly acked.
1591 ASSERT_TRUE(flush_req_1.WaitForReply());
1592 ASSERT_TRUE(flush_req_2.WaitForReply());
1593 ASSERT_TRUE(flush_req_3.WaitForReply());
1594
1595 // At this point flush id == 4 should still be pending and should fail because
1596 // of reaching its timeout.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001597 ASSERT_FALSE(flush_req_4.WaitForReply());
1598
1599 consumer->DisableTracing();
1600 producer->WaitForDataSourceStop("data_source");
1601 consumer->WaitForTracingDisabled();
1602 EXPECT_THAT(
1603 consumer->ReadBuffers(),
1604 Contains(Property(&protos::TracePacket::for_testing,
1605 Property(&protos::TestEvent::str, Eq("payload")))));
1606}
1607
Primiano Tuccicaa57802018-11-25 11:07:07 +00001608TEST_F(TracingServiceImplTest, PeriodicFlush) {
1609 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1610 consumer->Connect(svc.get());
1611
1612 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1613 producer->Connect(svc.get(), "mock_producer");
1614 producer->RegisterDataSource("data_source");
1615
1616 TraceConfig trace_config;
1617 trace_config.add_buffers()->set_size_kb(128);
1618 trace_config.set_flush_period_ms(1);
1619 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1620 ds_config->set_name("data_source");
1621
1622 consumer->EnableTracing(trace_config);
1623 producer->WaitForTracingSetup();
1624 producer->WaitForDataSourceSetup("data_source");
1625 producer->WaitForDataSourceStart("data_source");
1626
1627 std::unique_ptr<TraceWriter> writer =
1628 producer->CreateTraceWriter("data_source");
1629
1630 const int kNumFlushes = 3;
1631 auto checkpoint = task_runner.CreateCheckpoint("all_flushes_done");
1632 int flushes_seen = 0;
1633 EXPECT_CALL(*producer, Flush(_, _, _))
1634 .WillRepeatedly(Invoke([&producer, &writer, &flushes_seen, checkpoint](
1635 FlushRequestID flush_req_id,
1636 const DataSourceInstanceID*, size_t) {
1637 {
1638 auto tp = writer->NewTracePacket();
1639 char payload[32];
1640 sprintf(payload, "f_%d", flushes_seen);
1641 tp->set_for_testing()->set_str(payload);
1642 }
1643 writer->Flush();
1644 producer->endpoint()->NotifyFlushComplete(flush_req_id);
1645 if (++flushes_seen == kNumFlushes)
1646 checkpoint();
1647 }));
1648 task_runner.RunUntilCheckpoint("all_flushes_done");
1649
1650 consumer->DisableTracing();
1651 producer->WaitForDataSourceStop("data_source");
1652 consumer->WaitForTracingDisabled();
1653 auto trace_packets = consumer->ReadBuffers();
1654 for (int i = 0; i < kNumFlushes; i++) {
1655 EXPECT_THAT(trace_packets,
1656 Contains(Property(&protos::TracePacket::for_testing,
1657 Property(&protos::TestEvent::str,
1658 Eq("f_" + std::to_string(i))))));
1659 }
1660}
1661
Ryan Savitski33868d52019-05-13 10:56:14 +01001662TEST_F(TracingServiceImplTest, PeriodicClearIncrementalState) {
1663 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1664 consumer->Connect(svc.get());
1665 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1666 producer->Connect(svc.get(), "mock_producer");
1667
1668 // Incremental data source that expects to receive the clear.
1669 producer->RegisterDataSource("ds_incremental1", false, false,
1670 /*handles_incremental_state_clear=*/true);
1671
1672 // Incremental data source that expects to receive the clear.
1673 producer->RegisterDataSource("ds_incremental2", false, false,
1674 /*handles_incremental_state_clear=*/true);
1675
Ryan Savitski0b4008a2019-05-13 17:55:53 +01001676 // Data source that does *not* advertise itself as supporting incremental
1677 // state clears.
Ryan Savitski33868d52019-05-13 10:56:14 +01001678 producer->RegisterDataSource("ds_selfcontained", false, false,
1679 /*handles_incremental_state_clear=*/false);
1680
1681 // Incremental data source that is registered, but won't be active within the
1682 // test's tracing session.
1683 producer->RegisterDataSource("ds_inactive", false, false,
1684 /*handles_incremental_state_clear=*/true);
1685
1686 TraceConfig trace_config;
1687 trace_config.add_buffers()->set_size_kb(128);
1688 trace_config.mutable_incremental_state_config()->set_clear_period_ms(1);
1689 trace_config.add_data_sources()->mutable_config()->set_name(
1690 "ds_selfcontained");
1691 trace_config.add_data_sources()->mutable_config()->set_name(
1692 "ds_incremental1");
1693 trace_config.add_data_sources()->mutable_config()->set_name(
1694 "ds_incremental2");
1695
1696 // note: the mocking is very brittle, and has to assume a specific order of
1697 // the data sources' setup/start.
1698 consumer->EnableTracing(trace_config);
1699 producer->WaitForTracingSetup();
1700 producer->WaitForDataSourceSetup("ds_selfcontained");
1701 producer->WaitForDataSourceSetup("ds_incremental1");
1702 producer->WaitForDataSourceSetup("ds_incremental2");
1703 producer->WaitForDataSourceStart("ds_selfcontained");
1704 producer->WaitForDataSourceStart("ds_incremental1");
1705 producer->WaitForDataSourceStart("ds_incremental2");
1706
1707 DataSourceInstanceID ds_incremental1 =
1708 producer->GetDataSourceInstanceId("ds_incremental1");
1709 DataSourceInstanceID ds_incremental2 =
1710 producer->GetDataSourceInstanceId("ds_incremental2");
1711
Ryan Savitskiba8a5f52019-05-14 11:58:21 +01001712 const size_t kNumClears = 3;
Ryan Savitski33868d52019-05-13 10:56:14 +01001713 std::function<void()> checkpoint =
1714 task_runner.CreateCheckpoint("clears_received");
1715 std::vector<std::vector<DataSourceInstanceID>> clears_seen;
1716 EXPECT_CALL(*producer, ClearIncrementalState(_, _))
1717 .WillRepeatedly(Invoke([&clears_seen, &checkpoint](
1718 const DataSourceInstanceID* data_source_ids,
1719 size_t num_data_sources) {
1720 std::vector<DataSourceInstanceID> ds_ids;
1721 for (size_t i = 0; i < num_data_sources; i++) {
1722 ds_ids.push_back(*data_source_ids++);
1723 }
1724 clears_seen.push_back(ds_ids);
1725 if (clears_seen.size() >= kNumClears)
1726 checkpoint();
1727 }));
1728 task_runner.RunUntilCheckpoint("clears_received");
1729
1730 consumer->DisableTracing();
1731
1732 // Assert that the clears were only for the active incremental data sources.
1733 ASSERT_EQ(clears_seen.size(), kNumClears);
1734 for (const std::vector<DataSourceInstanceID>& ds_ids : clears_seen) {
1735 ASSERT_THAT(ds_ids, ElementsAreArray({ds_incremental1, ds_incremental2}));
1736 }
1737}
1738
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001739// Creates a tracing session where some of the data sources set the
1740// |will_notify_on_stop| flag and checks that the OnTracingDisabled notification
1741// to the consumer is delayed until the acks are received.
1742TEST_F(TracingServiceImplTest, OnTracingDisabledWaitsForDataSourceStopAcks) {
1743 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1744 consumer->Connect(svc.get());
1745
1746 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1747 producer->Connect(svc.get(), "mock_producer");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001748 producer->RegisterDataSource("ds_will_ack_1", /*ack_stop=*/true,
1749 /*ack_start=*/true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001750 producer->RegisterDataSource("ds_wont_ack");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001751 producer->RegisterDataSource("ds_will_ack_2", /*ack_stop=*/true,
1752 /*ack_start=*/false);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001753
1754 TraceConfig trace_config;
1755 trace_config.add_buffers()->set_size_kb(128);
1756 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_1");
1757 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1758 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_2");
1759 trace_config.set_duration_ms(1);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001760 trace_config.set_deferred_start(true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001761
1762 consumer->EnableTracing(trace_config);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001763
1764 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1765 DataSourceInstanceState::CONFIGURED);
1766 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1767 DataSourceInstanceState::CONFIGURED);
1768 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1769 DataSourceInstanceState::CONFIGURED);
1770
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001771 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001772
1773 producer->WaitForDataSourceSetup("ds_will_ack_1");
1774 producer->WaitForDataSourceSetup("ds_wont_ack");
1775 producer->WaitForDataSourceSetup("ds_will_ack_2");
1776
Eric Seckler4ff03e52019-03-15 10:10:30 +00001777 DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_will_ack_1");
1778 DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_will_ack_2");
1779
1780 consumer->StartTracing();
1781
1782 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1783 DataSourceInstanceState::STARTING);
1784 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1785 DataSourceInstanceState::STARTED);
1786 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1787 DataSourceInstanceState::STARTED);
1788
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001789 producer->WaitForDataSourceStart("ds_will_ack_1");
1790 producer->WaitForDataSourceStart("ds_wont_ack");
1791 producer->WaitForDataSourceStart("ds_will_ack_2");
1792
Eric Seckler4ff03e52019-03-15 10:10:30 +00001793 producer->endpoint()->NotifyDataSourceStarted(id1);
1794
1795 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1796 DataSourceInstanceState::STARTED);
1797
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001798 std::unique_ptr<TraceWriter> writer =
1799 producer->CreateTraceWriter("ds_wont_ack");
1800 producer->WaitForFlush(writer.get());
1801
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001802 producer->WaitForDataSourceStop("ds_will_ack_1");
1803 producer->WaitForDataSourceStop("ds_wont_ack");
1804 producer->WaitForDataSourceStop("ds_will_ack_2");
1805
Eric Seckler4ff03e52019-03-15 10:10:30 +00001806 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1807 DataSourceInstanceState::STOPPING);
1808 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1809 DataSourceInstanceState::STOPPED);
1810 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1811 DataSourceInstanceState::STOPPING);
1812
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001813 producer->endpoint()->NotifyDataSourceStopped(id1);
1814 producer->endpoint()->NotifyDataSourceStopped(id2);
1815
Eric Seckler4ff03e52019-03-15 10:10:30 +00001816 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1817 DataSourceInstanceState::STOPPED);
1818 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1819 DataSourceInstanceState::STOPPED);
1820
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001821 // Wait for at most half of the service timeout, so that this test fails if
1822 // the service falls back on calling the OnTracingDisabled() because some of
1823 // the expected acks weren't received.
1824 consumer->WaitForTracingDisabled(
1825 TracingServiceImpl::kDataSourceStopTimeoutMs / 2);
1826}
1827
Oystein Eftevaagf250e1c2018-08-23 16:10:52 -07001828// Creates a tracing session where a second data source
1829// is added while the service is waiting for DisableTracing
1830// acks; the service should not enable the new datasource
1831// and should not hit any asserts when the consumer is
1832// subsequently destroyed.
1833TEST_F(TracingServiceImplTest, OnDataSourceAddedWhilePendingDisableAcks) {
1834 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1835 consumer->Connect(svc.get());
1836
1837 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1838 producer->Connect(svc.get(), "mock_producer");
1839 producer->RegisterDataSource("ds_will_ack", /*ack_stop=*/true);
1840
1841 TraceConfig trace_config;
1842 trace_config.add_buffers()->set_size_kb(128);
1843 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack");
1844 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1845
1846 consumer->EnableTracing(trace_config);
1847 producer->WaitForTracingSetup();
1848
1849 consumer->DisableTracing();
1850
1851 producer->RegisterDataSource("ds_wont_ack");
1852
1853 consumer.reset();
1854}
1855
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001856// Similar to OnTracingDisabledWaitsForDataSourceStopAcks, but deliberately
1857// skips the ack and checks that the service invokes the OnTracingDisabled()
1858// after the timeout.
1859TEST_F(TracingServiceImplTest, OnTracingDisabledCalledAnywaysInCaseOfTimeout) {
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001860 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1861 consumer->Connect(svc.get());
1862
1863 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1864 producer->Connect(svc.get(), "mock_producer");
1865 producer->RegisterDataSource("data_source", /*ack_stop=*/true);
1866
1867 TraceConfig trace_config;
1868 trace_config.add_buffers()->set_size_kb(128);
1869 trace_config.add_data_sources()->mutable_config()->set_name("data_source");
1870 trace_config.set_duration_ms(1);
Florian Mayer990e6d72019-06-03 11:34:52 +01001871 trace_config.set_data_source_stop_timeout_ms(1);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001872
1873 consumer->EnableTracing(trace_config);
1874 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001875 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001876 producer->WaitForDataSourceStart("data_source");
1877
1878 std::unique_ptr<TraceWriter> writer =
1879 producer->CreateTraceWriter("data_source");
1880 producer->WaitForFlush(writer.get());
1881
1882 producer->WaitForDataSourceStop("data_source");
1883 consumer->WaitForTracingDisabled();
1884}
1885
Primiano Tucci03de28f2018-08-01 11:29:46 +01001886// Tests the session_id logic. Two data sources in the same tracing session
1887// should see the same session id.
1888TEST_F(TracingServiceImplTest, SessionId) {
1889 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1890 consumer->Connect(svc.get());
1891
1892 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1893 producer1->Connect(svc.get(), "mock_producer1");
1894 producer1->RegisterDataSource("ds_1A");
1895 producer1->RegisterDataSource("ds_1B");
1896
1897 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1898 producer2->Connect(svc.get(), "mock_producer2");
1899 producer2->RegisterDataSource("ds_2A");
1900
Hector Dearmanbb3bc482019-08-02 11:54:08 +01001901 InSequence seq;
Primiano Tucci03de28f2018-08-01 11:29:46 +01001902 TracingSessionID last_session_id = 0;
1903 for (int i = 0; i < 3; i++) {
1904 TraceConfig trace_config;
1905 trace_config.add_buffers()->set_size_kb(128);
1906 trace_config.add_data_sources()->mutable_config()->set_name("ds_1A");
1907 trace_config.add_data_sources()->mutable_config()->set_name("ds_1B");
1908 trace_config.add_data_sources()->mutable_config()->set_name("ds_2A");
1909 trace_config.set_duration_ms(1);
1910
1911 consumer->EnableTracing(trace_config);
1912
1913 if (i == 0)
1914 producer1->WaitForTracingSetup();
Primiano Tucci03de28f2018-08-01 11:29:46 +01001915
Primiano Tucci674076d2018-10-01 10:41:09 +01001916 producer1->WaitForDataSourceSetup("ds_1A");
1917 producer1->WaitForDataSourceSetup("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001918 if (i == 0)
1919 producer2->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001920 producer2->WaitForDataSourceSetup("ds_2A");
1921
1922 producer1->WaitForDataSourceStart("ds_1A");
1923 producer1->WaitForDataSourceStart("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001924 producer2->WaitForDataSourceStart("ds_2A");
1925
1926 auto* ds1 = producer1->GetDataSourceInstance("ds_1A");
1927 auto* ds2 = producer1->GetDataSourceInstance("ds_1B");
1928 auto* ds3 = producer2->GetDataSourceInstance("ds_2A");
1929 ASSERT_EQ(ds1->session_id, ds2->session_id);
1930 ASSERT_EQ(ds1->session_id, ds3->session_id);
1931 ASSERT_NE(ds1->session_id, last_session_id);
1932 last_session_id = ds1->session_id;
1933
1934 auto writer1 = producer1->CreateTraceWriter("ds_1A");
1935 producer1->WaitForFlush(writer1.get());
1936
1937 auto writer2 = producer2->CreateTraceWriter("ds_2A");
1938 producer2->WaitForFlush(writer2.get());
1939
1940 producer1->WaitForDataSourceStop("ds_1A");
1941 producer1->WaitForDataSourceStop("ds_1B");
1942 producer2->WaitForDataSourceStop("ds_2A");
1943 consumer->WaitForTracingDisabled();
1944 consumer->FreeBuffers();
1945 }
1946}
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001947
1948// Writes a long trace and then tests that the trace parsed in partitions
1949// derived by the synchronization markers is identical to the whole trace parsed
1950// in one go.
1951TEST_F(TracingServiceImplTest, ResynchronizeTraceStreamUsingSyncMarker) {
1952 // Setup tracing.
1953 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1954 consumer->Connect(svc.get());
1955 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1956 producer->Connect(svc.get(), "mock_producer");
1957 producer->RegisterDataSource("data_source");
1958 TraceConfig trace_config;
1959 trace_config.add_buffers()->set_size_kb(4096);
1960 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1961 ds_config->set_name("data_source");
1962 trace_config.set_write_into_file(true);
1963 trace_config.set_file_write_period_ms(1);
1964 base::TempFile tmp_file = base::TempFile::Create();
1965 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
1966 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001967 producer->WaitForDataSourceSetup("data_source");
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001968 producer->WaitForDataSourceStart("data_source");
1969
1970 // Write some variable length payload, waiting for sync markers every now
1971 // and then.
1972 const int kNumMarkers = 5;
1973 auto writer = producer->CreateTraceWriter("data_source");
1974 for (int i = 1; i <= 100; i++) {
Florian Mayereff98042018-12-10 17:44:44 +00001975 std::string payload(static_cast<size_t>(i), 'A' + (i % 25));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001976 writer->NewTracePacket()->set_for_testing()->set_str(payload.c_str());
1977 if (i % (100 / kNumMarkers) == 0) {
1978 writer->Flush();
1979 WaitForNextSyncMarker();
1980 }
1981 }
1982 writer->Flush();
1983 writer.reset();
1984 consumer->DisableTracing();
1985 producer->WaitForDataSourceStop("data_source");
1986 consumer->WaitForTracingDisabled();
1987
1988 std::string trace_raw;
1989 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
1990
1991 const auto kMarkerSize = sizeof(TracingServiceImpl::kSyncMarker);
1992 const std::string kSyncMarkerStr(
1993 reinterpret_cast<const char*>(TracingServiceImpl::kSyncMarker),
1994 kMarkerSize);
1995
1996 // Read back the trace in partitions derived from the marker.
1997 // The trace should look like this:
1998 // [uid, marker] [event] [event] [uid, marker] [event] [event]
1999 size_t num_markers = 0;
2000 size_t start = 0;
2001 size_t end = 0;
2002 protos::Trace merged_trace;
2003 for (size_t pos = 0; pos != std::string::npos; start = end) {
2004 pos = trace_raw.find(kSyncMarkerStr, pos + 1);
2005 num_markers++;
2006 end = (pos == std::string::npos) ? trace_raw.size() : pos + kMarkerSize;
2007 int size = static_cast<int>(end - start);
2008 ASSERT_GT(size, 0);
2009 protos::Trace trace_partition;
2010 ASSERT_TRUE(trace_partition.ParseFromArray(trace_raw.data() + start, size));
2011 merged_trace.MergeFrom(trace_partition);
2012 }
Lalit Maganti9bdc7ce2018-09-17 15:25:11 +01002013 EXPECT_GE(num_markers, static_cast<size_t>(kNumMarkers));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01002014
2015 protos::Trace whole_trace;
2016 ASSERT_TRUE(whole_trace.ParseFromString(trace_raw));
2017
2018 ASSERT_EQ(whole_trace.packet_size(), merged_trace.packet_size());
2019 EXPECT_EQ(whole_trace.SerializeAsString(), merged_trace.SerializeAsString());
2020}
2021
Primiano Tucci674076d2018-10-01 10:41:09 +01002022// Creates a tracing session with |deferred_start| and checks that data sources
2023// are started only after calling StartTracing().
2024TEST_F(TracingServiceImplTest, DeferredStart) {
2025 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2026 consumer->Connect(svc.get());
2027
2028 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2029 producer->Connect(svc.get(), "mock_producer");
2030
2031 // Create two data sources but enable only one of them.
2032 producer->RegisterDataSource("ds_1");
2033 producer->RegisterDataSource("ds_2");
2034
2035 TraceConfig trace_config;
2036 trace_config.add_buffers()->set_size_kb(128);
2037 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
2038 trace_config.set_deferred_start(true);
2039 trace_config.set_duration_ms(1);
2040
2041 consumer->EnableTracing(trace_config);
2042 producer->WaitForTracingSetup();
2043
2044 producer->WaitForDataSourceSetup("ds_1");
2045
2046 // Make sure we don't get unexpected DataSourceStart() notifications yet.
2047 task_runner.RunUntilIdle();
2048
2049 consumer->StartTracing();
2050
2051 producer->WaitForDataSourceStart("ds_1");
2052
Stephen Nusko1393ffd2019-03-22 13:54:58 +00002053 auto writer = producer->CreateTraceWriter("ds_1");
2054 producer->WaitForFlush(writer.get());
Primiano Tucci674076d2018-10-01 10:41:09 +01002055
2056 producer->WaitForDataSourceStop("ds_1");
2057 consumer->WaitForTracingDisabled();
2058}
2059
Eric Secklerd0ac7ca2019-02-06 09:13:45 +00002060TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
2061 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2062 consumer->Connect(svc.get());
2063
2064 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2065 producer1->Connect(svc.get(), "mock_producer1", 123u /* uid */);
2066 producer1->RegisterDataSource("data_source");
2067
2068 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2069 producer2->Connect(svc.get(), "mock_producer2", 456u /* uid */);
2070 producer2->RegisterDataSource("data_source");
2071
2072 TraceConfig trace_config;
2073 trace_config.add_buffers()->set_size_kb(128);
2074 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2075 ds_config->set_name("data_source");
2076
2077 consumer->EnableTracing(trace_config);
2078 producer1->WaitForTracingSetup();
2079 producer1->WaitForDataSourceSetup("data_source");
2080 producer2->WaitForTracingSetup();
2081 producer2->WaitForDataSourceSetup("data_source");
2082 producer1->WaitForDataSourceStart("data_source");
2083 producer2->WaitForDataSourceStart("data_source");
2084
2085 std::unique_ptr<TraceWriter> writer1a =
2086 producer1->CreateTraceWriter("data_source");
2087 std::unique_ptr<TraceWriter> writer1b =
2088 producer1->CreateTraceWriter("data_source");
2089 std::unique_ptr<TraceWriter> writer2a =
2090 producer2->CreateTraceWriter("data_source");
2091 {
2092 auto tp = writer1a->NewTracePacket();
2093 tp->set_for_testing()->set_str("payload1a1");
2094 tp = writer1b->NewTracePacket();
2095 tp->set_for_testing()->set_str("payload1b1");
2096 tp = writer1a->NewTracePacket();
2097 tp->set_for_testing()->set_str("payload1a2");
2098 tp = writer2a->NewTracePacket();
2099 tp->set_for_testing()->set_str("payload2a1");
2100 tp = writer1b->NewTracePacket();
2101 tp->set_for_testing()->set_str("payload1b2");
2102 }
2103
2104 auto flush_request = consumer->Flush();
2105 producer1->WaitForFlush({writer1a.get(), writer1b.get()});
2106 producer2->WaitForFlush(writer2a.get());
2107 ASSERT_TRUE(flush_request.WaitForReply());
2108
2109 consumer->DisableTracing();
2110 producer1->WaitForDataSourceStop("data_source");
2111 producer2->WaitForDataSourceStop("data_source");
2112 consumer->WaitForTracingDisabled();
2113 auto packets = consumer->ReadBuffers();
2114 EXPECT_THAT(
2115 packets,
2116 Contains(AllOf(
2117 Property(&protos::TracePacket::for_testing,
2118 Property(&protos::TestEvent::str, Eq("payload1a1"))),
2119 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2120 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
2121 EXPECT_THAT(
2122 packets,
2123 Contains(AllOf(
2124 Property(&protos::TracePacket::for_testing,
2125 Property(&protos::TestEvent::str, Eq("payload1a2"))),
2126 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2127 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
2128 EXPECT_THAT(
2129 packets,
2130 Contains(AllOf(
2131 Property(&protos::TracePacket::for_testing,
2132 Property(&protos::TestEvent::str, Eq("payload1b1"))),
2133 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2134 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
2135 EXPECT_THAT(
2136 packets,
2137 Contains(AllOf(
2138 Property(&protos::TracePacket::for_testing,
2139 Property(&protos::TestEvent::str, Eq("payload1b2"))),
2140 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2141 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
2142 EXPECT_THAT(
2143 packets,
2144 Contains(AllOf(
2145 Property(&protos::TracePacket::for_testing,
2146 Property(&protos::TestEvent::str, Eq("payload2a1"))),
2147 Property(&protos::TracePacket::trusted_uid, Eq(456)),
2148 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(4u)))));
2149}
2150
Eric Seckler6dc23592018-11-30 10:59:06 +00002151TEST_F(TracingServiceImplTest, AllowedBuffers) {
2152 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2153 consumer->Connect(svc.get());
2154
2155 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2156 producer1->Connect(svc.get(), "mock_producer1");
2157 ProducerID producer1_id = *last_producer_id();
2158 producer1->RegisterDataSource("data_source1");
2159 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2160 producer2->Connect(svc.get(), "mock_producer2");
2161 ProducerID producer2_id = *last_producer_id();
2162 producer2->RegisterDataSource("data_source2.1");
2163 producer2->RegisterDataSource("data_source2.2");
2164 producer2->RegisterDataSource("data_source2.3");
2165
2166 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
2167 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
2168
2169 TraceConfig trace_config;
2170 trace_config.add_buffers()->set_size_kb(128);
2171 trace_config.add_buffers()->set_size_kb(128);
2172 trace_config.add_buffers()->set_size_kb(128);
2173 auto* ds_config1 = trace_config.add_data_sources()->mutable_config();
2174 ds_config1->set_name("data_source1");
2175 ds_config1->set_target_buffer(0);
2176 auto* ds_config21 = trace_config.add_data_sources()->mutable_config();
2177 ds_config21->set_name("data_source2.1");
2178 ds_config21->set_target_buffer(1);
2179 auto* ds_config22 = trace_config.add_data_sources()->mutable_config();
2180 ds_config22->set_name("data_source2.2");
2181 ds_config22->set_target_buffer(2);
2182 auto* ds_config23 = trace_config.add_data_sources()->mutable_config();
2183 ds_config23->set_name("data_source2.3");
2184 ds_config23->set_target_buffer(2); // same buffer as data_source2.2.
2185 consumer->EnableTracing(trace_config);
2186
Primiano Tucci2abd1152018-12-03 17:00:02 +01002187 ASSERT_EQ(3u, tracing_session()->num_buffers());
Eric Seckler6dc23592018-11-30 10:59:06 +00002188 std::set<BufferID> expected_buffers_producer1 = {
2189 tracing_session()->buffers_index[0]};
2190 std::set<BufferID> expected_buffers_producer2 = {
2191 tracing_session()->buffers_index[1], tracing_session()->buffers_index[2]};
2192 EXPECT_EQ(expected_buffers_producer1, GetAllowedTargetBuffers(producer1_id));
2193 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
2194
2195 producer1->WaitForTracingSetup();
2196 producer1->WaitForDataSourceSetup("data_source1");
2197
2198 producer2->WaitForTracingSetup();
2199 producer2->WaitForDataSourceSetup("data_source2.1");
2200 producer2->WaitForDataSourceSetup("data_source2.2");
2201 producer2->WaitForDataSourceSetup("data_source2.3");
2202
2203 producer1->WaitForDataSourceStart("data_source1");
2204 producer2->WaitForDataSourceStart("data_source2.1");
2205 producer2->WaitForDataSourceStart("data_source2.2");
2206 producer2->WaitForDataSourceStart("data_source2.3");
2207
2208 producer2->UnregisterDataSource("data_source2.3");
2209 producer2->WaitForDataSourceStop("data_source2.3");
2210
2211 // Should still be allowed to write to buffers 1 (data_source2.1) and 2
2212 // (data_source2.2).
2213 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
2214
2215 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2216 // trace config didn't have the |deferred_start| flag set.
2217 consumer->StartTracing();
2218
2219 consumer->DisableTracing();
2220 producer1->WaitForDataSourceStop("data_source1");
2221 producer2->WaitForDataSourceStop("data_source2.1");
2222 producer2->WaitForDataSourceStop("data_source2.2");
2223 consumer->WaitForTracingDisabled();
2224
2225 consumer->FreeBuffers();
2226 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
2227 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
2228}
2229
Eric Seckler6aa9ece2018-12-06 16:40:12 +00002230#if !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00002231TEST_F(TracingServiceImplTest, CommitToForbiddenBufferIsDiscarded) {
2232 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2233 consumer->Connect(svc.get());
2234
2235 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2236 producer->Connect(svc.get(), "mock_producer");
2237 ProducerID producer_id = *last_producer_id();
2238 producer->RegisterDataSource("data_source");
2239
2240 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
2241
2242 TraceConfig trace_config;
2243 trace_config.add_buffers()->set_size_kb(128);
2244 trace_config.add_buffers()->set_size_kb(128);
2245 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2246 ds_config->set_name("data_source");
2247 ds_config->set_target_buffer(0);
2248 consumer->EnableTracing(trace_config);
2249
2250 ASSERT_EQ(2u, tracing_session()->num_buffers());
2251 std::set<BufferID> expected_buffers = {tracing_session()->buffers_index[0]};
2252 EXPECT_EQ(expected_buffers, GetAllowedTargetBuffers(producer_id));
2253
2254 producer->WaitForTracingSetup();
2255 producer->WaitForDataSourceSetup("data_source");
2256 producer->WaitForDataSourceStart("data_source");
2257
2258 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2259 // trace config didn't have the |deferred_start| flag set.
2260 consumer->StartTracing();
2261
2262 // Try to write to the correct buffer.
2263 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2264 tracing_session()->buffers_index[0]);
2265 {
2266 auto tp = writer->NewTracePacket();
2267 tp->set_for_testing()->set_str("good_payload");
2268 }
2269
2270 auto flush_request = consumer->Flush();
2271 producer->WaitForFlush(writer.get());
2272 ASSERT_TRUE(flush_request.WaitForReply());
2273
2274 // Try to write to the wrong buffer.
2275 writer = producer->endpoint()->CreateTraceWriter(
2276 tracing_session()->buffers_index[1]);
2277 {
2278 auto tp = writer->NewTracePacket();
2279 tp->set_for_testing()->set_str("bad_payload");
2280 }
2281
2282 flush_request = consumer->Flush();
2283 producer->WaitForFlush(writer.get());
2284 ASSERT_TRUE(flush_request.WaitForReply());
2285
2286 consumer->DisableTracing();
2287 producer->WaitForDataSourceStop("data_source");
2288 consumer->WaitForTracingDisabled();
2289
2290 auto packets = consumer->ReadBuffers();
2291 EXPECT_THAT(packets, Contains(Property(&protos::TracePacket::for_testing,
2292 Property(&protos::TestEvent::str,
2293 Eq("good_payload")))));
2294 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2295 Property(&protos::TestEvent::str,
2296 Eq("bad_payload"))))));
2297
2298 consumer->FreeBuffers();
2299 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
2300}
Eric Seckler6aa9ece2018-12-06 16:40:12 +00002301#endif // !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00002302
Eric Secklerf3f524b2018-12-13 09:09:34 +00002303TEST_F(TracingServiceImplTest, RegisterAndUnregisterTraceWriter) {
2304 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2305 consumer->Connect(svc.get());
2306
2307 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2308 producer->Connect(svc.get(), "mock_producer");
2309 ProducerID producer_id = *last_producer_id();
2310 producer->RegisterDataSource("data_source");
2311
2312 EXPECT_TRUE(GetWriters(producer_id).empty());
2313
2314 TraceConfig trace_config;
2315 trace_config.add_buffers()->set_size_kb(128);
2316 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2317 ds_config->set_name("data_source");
2318 ds_config->set_target_buffer(0);
2319 consumer->EnableTracing(trace_config);
2320
2321 producer->WaitForTracingSetup();
2322 producer->WaitForDataSourceSetup("data_source");
2323 producer->WaitForDataSourceStart("data_source");
2324
2325 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2326 // trace config didn't have the |deferred_start| flag set.
2327 consumer->StartTracing();
2328
2329 // Creating the trace writer should register it with the service.
2330 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2331 tracing_session()->buffers_index[0]);
2332
2333 WaitForTraceWritersChanged(producer_id);
2334
2335 std::map<WriterID, BufferID> expected_writers;
2336 expected_writers[writer->writer_id()] = tracing_session()->buffers_index[0];
2337 EXPECT_EQ(expected_writers, GetWriters(producer_id));
2338
2339 // Verify writing works.
2340 {
2341 auto tp = writer->NewTracePacket();
2342 tp->set_for_testing()->set_str("payload");
2343 }
2344
2345 auto flush_request = consumer->Flush();
2346 producer->WaitForFlush(writer.get());
2347 ASSERT_TRUE(flush_request.WaitForReply());
2348
2349 // Destroying the writer should unregister it.
2350 writer.reset();
2351 WaitForTraceWritersChanged(producer_id);
2352 EXPECT_TRUE(GetWriters(producer_id).empty());
2353
2354 consumer->DisableTracing();
2355 producer->WaitForDataSourceStop("data_source");
2356 consumer->WaitForTracingDisabled();
2357
2358 auto packets = consumer->ReadBuffers();
2359 EXPECT_THAT(packets, Contains(Property(
2360 &protos::TracePacket::for_testing,
2361 Property(&protos::TestEvent::str, Eq("payload")))));
2362}
2363
Eric Secklera01e28a2019-01-08 11:21:04 +00002364TEST_F(TracingServiceImplTest, ScrapeBuffersOnFlush) {
2365 svc->SetSMBScrapingEnabled(true);
2366
2367 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2368 consumer->Connect(svc.get());
2369
2370 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2371 producer->Connect(svc.get(), "mock_producer");
2372 ProducerID producer_id = *last_producer_id();
2373 producer->RegisterDataSource("data_source");
2374
2375 TraceConfig trace_config;
2376 trace_config.add_buffers()->set_size_kb(128);
2377 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2378 ds_config->set_name("data_source");
2379 ds_config->set_target_buffer(0);
2380 consumer->EnableTracing(trace_config);
2381
2382 producer->WaitForTracingSetup();
2383 producer->WaitForDataSourceSetup("data_source");
2384 producer->WaitForDataSourceStart("data_source");
2385
2386 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2387 // trace config didn't have the |deferred_start| flag set.
2388 consumer->StartTracing();
2389
2390 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2391 tracing_session()->buffers_index[0]);
2392 WaitForTraceWritersChanged(producer_id);
2393
2394 // Write a few trace packets.
2395 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2396 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2397 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2398
2399 // Flush but don't actually flush the chunk from TraceWriter.
2400 auto flush_request = consumer->Flush();
2401 producer->WaitForFlush(nullptr, /*reply=*/true);
2402 ASSERT_TRUE(flush_request.WaitForReply());
2403
2404 // Chunk with the packets should have been scraped. The service can't know
2405 // whether the last packet was completed, so shouldn't read it.
2406 auto packets = consumer->ReadBuffers();
2407 EXPECT_THAT(packets, Contains(Property(
2408 &protos::TracePacket::for_testing,
2409 Property(&protos::TestEvent::str, Eq("payload1")))));
2410 EXPECT_THAT(packets, Contains(Property(
2411 &protos::TracePacket::for_testing,
2412 Property(&protos::TestEvent::str, Eq("payload2")))));
2413 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2414 Property(&protos::TestEvent::str,
2415 Eq("payload3"))))));
2416
2417 // Write some more packets.
2418 writer->NewTracePacket()->set_for_testing()->set_str("payload4");
2419 writer->NewTracePacket()->set_for_testing()->set_str("payload5");
2420
2421 // Don't reply to flush, causing a timeout. This should scrape again.
2422 flush_request = consumer->Flush(/*timeout=*/100);
2423 producer->WaitForFlush(nullptr, /*reply=*/false);
2424 ASSERT_FALSE(flush_request.WaitForReply());
2425
2426 // Chunk with the packets should have been scraped again, overriding the
2427 // original one. Again, the last packet should be ignored and the first two
2428 // should not be read twice.
2429 packets = consumer->ReadBuffers();
2430 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2431 Property(&protos::TestEvent::str,
2432 Eq("payload1"))))));
2433 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2434 Property(&protos::TestEvent::str,
2435 Eq("payload2"))))));
2436 EXPECT_THAT(packets, Contains(Property(
2437 &protos::TracePacket::for_testing,
2438 Property(&protos::TestEvent::str, Eq("payload3")))));
2439 EXPECT_THAT(packets, Contains(Property(
2440 &protos::TracePacket::for_testing,
2441 Property(&protos::TestEvent::str, Eq("payload4")))));
2442 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2443 Property(&protos::TestEvent::str,
2444 Eq("payload5"))))));
2445
2446 consumer->DisableTracing();
2447 producer->WaitForDataSourceStop("data_source");
2448 consumer->WaitForTracingDisabled();
2449}
2450
Sami Kyostilaf5ad4642019-05-16 10:46:15 +01002451TEST_F(TracingServiceImplTest, ScrapeBuffersFromAnotherThread) {
2452 // This test verifies that there are no reported TSAN races while scraping
2453 // buffers from a producer which is actively writing more trace data
2454 // concurrently.
2455 svc->SetSMBScrapingEnabled(true);
2456
2457 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2458 consumer->Connect(svc.get());
2459
2460 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2461 producer->Connect(svc.get(), "mock_producer");
2462 ProducerID producer_id = *last_producer_id();
2463 producer->RegisterDataSource("data_source");
2464
2465 TraceConfig trace_config;
2466 trace_config.add_buffers()->set_size_kb(128);
2467 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2468 ds_config->set_name("data_source");
2469 ds_config->set_target_buffer(0);
2470 consumer->EnableTracing(trace_config);
2471
2472 producer->WaitForTracingSetup();
2473 producer->WaitForDataSourceSetup("data_source");
2474 producer->WaitForDataSourceStart("data_source");
2475 consumer->StartTracing();
2476
2477 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2478 tracing_session()->buffers_index[0]);
2479 WaitForTraceWritersChanged(producer_id);
2480
2481 constexpr int kPacketCount = 10;
2482 std::atomic<int> packets_written{};
2483 std::thread writer_thread([&] {
2484 for (int i = 0; i < kPacketCount; i++) {
2485 writer->NewTracePacket()->set_for_testing()->set_str("payload");
2486 packets_written.store(i, std::memory_order_relaxed);
2487 }
2488 });
2489
2490 // Wait until the thread has had some time to write some packets.
2491 while (packets_written.load(std::memory_order_relaxed) < kPacketCount / 2)
2492 base::SleepMicroseconds(5000);
2493
2494 // Disabling tracing will trigger scraping.
2495 consumer->DisableTracing();
2496 writer_thread.join();
2497
2498 // Because we don't synchronize with the producer thread, we can't make any
2499 // guarantees about the number of packets we will successfully read. We just
2500 // verify that no TSAN races are reported.
2501 consumer->ReadBuffers();
2502
2503 producer->WaitForDataSourceStop("data_source");
2504 consumer->WaitForTracingDisabled();
2505}
2506
Eric Secklera01e28a2019-01-08 11:21:04 +00002507// Test scraping on producer disconnect.
2508TEST_F(TracingServiceImplTest, ScrapeBuffersOnProducerDisconnect) {
2509 svc->SetSMBScrapingEnabled(true);
2510
2511 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2512 consumer->Connect(svc.get());
2513
2514 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2515 producer->Connect(svc.get(), "mock_producer");
2516 ProducerID producer_id = *last_producer_id();
2517 producer->RegisterDataSource("data_source");
2518
2519 TraceConfig trace_config;
2520 trace_config.add_buffers()->set_size_kb(128);
2521 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2522 ds_config->set_name("data_source");
2523 ds_config->set_target_buffer(0);
2524 consumer->EnableTracing(trace_config);
2525
2526 producer->WaitForTracingSetup();
2527 producer->WaitForDataSourceSetup("data_source");
2528 producer->WaitForDataSourceStart("data_source");
2529
2530 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2531 // trace config didn't have the |deferred_start| flag set.
2532 consumer->StartTracing();
2533
2534 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2535 tracing_session()->buffers_index[0]);
2536 WaitForTraceWritersChanged(producer_id);
2537
2538 // Write a few trace packets.
2539 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2540 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2541 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2542
2543 // Disconnect the producer without committing the chunk. This should cause a
2544 // scrape of the SMB. Avoid destroying the ShmemArbiter until writer is
2545 // destroyed.
2546 auto shmem_arbiter = TakeShmemArbiterForProducer(producer_id);
2547 producer.reset();
2548
2549 // Chunk with the packets should have been scraped. The service can't know
2550 // whether the last packet was completed, so shouldn't read it.
2551 auto packets = consumer->ReadBuffers();
2552 EXPECT_THAT(packets, Contains(Property(
2553 &protos::TracePacket::for_testing,
2554 Property(&protos::TestEvent::str, Eq("payload1")))));
2555 EXPECT_THAT(packets, Contains(Property(
2556 &protos::TracePacket::for_testing,
2557 Property(&protos::TestEvent::str, Eq("payload2")))));
2558 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2559 Property(&protos::TestEvent::str,
2560 Eq("payload3"))))));
2561
2562 // Cleanup writer without causing a crash because the producer already went
2563 // away.
2564 static_cast<TraceWriterImpl*>(writer.get())->ResetChunkForTesting();
2565 writer.reset();
2566 shmem_arbiter.reset();
2567
2568 consumer->DisableTracing();
2569 consumer->WaitForTracingDisabled();
2570}
2571
2572TEST_F(TracingServiceImplTest, ScrapeBuffersOnDisable) {
2573 svc->SetSMBScrapingEnabled(true);
2574
2575 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2576 consumer->Connect(svc.get());
2577
2578 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2579 producer->Connect(svc.get(), "mock_producer");
2580 ProducerID producer_id = *last_producer_id();
2581 producer->RegisterDataSource("data_source");
2582
2583 TraceConfig trace_config;
2584 trace_config.add_buffers()->set_size_kb(128);
2585 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2586 ds_config->set_name("data_source");
2587 ds_config->set_target_buffer(0);
2588 consumer->EnableTracing(trace_config);
2589
2590 producer->WaitForTracingSetup();
2591 producer->WaitForDataSourceSetup("data_source");
2592 producer->WaitForDataSourceStart("data_source");
2593
2594 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2595 // trace config didn't have the |deferred_start| flag set.
2596 consumer->StartTracing();
2597
2598 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2599 tracing_session()->buffers_index[0]);
2600 WaitForTraceWritersChanged(producer_id);
2601
2602 // Write a few trace packets.
2603 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2604 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2605 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2606
2607 consumer->DisableTracing();
2608 producer->WaitForDataSourceStop("data_source");
2609 consumer->WaitForTracingDisabled();
2610
2611 // Chunk with the packets should have been scraped. The service can't know
2612 // whether the last packet was completed, so shouldn't read it.
2613 auto packets = consumer->ReadBuffers();
2614 EXPECT_THAT(packets, Contains(Property(
2615 &protos::TracePacket::for_testing,
2616 Property(&protos::TestEvent::str, Eq("payload1")))));
2617 EXPECT_THAT(packets, Contains(Property(
2618 &protos::TracePacket::for_testing,
2619 Property(&protos::TestEvent::str, Eq("payload2")))));
2620 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2621 Property(&protos::TestEvent::str,
2622 Eq("payload3"))))));
2623}
2624
Primiano Tucciff7beab2019-01-09 21:49:20 +00002625TEST_F(TracingServiceImplTest, AbortIfTraceDurationIsTooLong) {
2626 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2627 consumer->Connect(svc.get());
2628
2629 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2630 producer->Connect(svc.get(), "mock_producer");
2631 producer->RegisterDataSource("datasource");
2632
2633 TraceConfig trace_config;
2634 trace_config.add_buffers()->set_size_kb(128);
2635 trace_config.add_data_sources()->mutable_config()->set_name("datasource");
2636 trace_config.set_duration_ms(0x7fffffff);
2637
2638 EXPECT_CALL(*producer, SetupDataSource(_, _)).Times(0);
2639 consumer->EnableTracing(trace_config);
2640
2641 // The trace is aborted immediately, 5s here is just some slack for the thread
2642 // ping-pongs for slow devices.
2643 consumer->WaitForTracingDisabled(5000);
2644}
2645
Eric Secklereaf29ed2019-01-23 09:53:55 +00002646TEST_F(TracingServiceImplTest, GetTraceStats) {
2647 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2648 consumer->Connect(svc.get());
2649
2650 consumer->GetTraceStats();
2651 consumer->WaitForTraceStats(false);
2652
2653 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2654 producer->Connect(svc.get(), "mock_producer");
2655 producer->RegisterDataSource("data_source");
2656
2657 TraceConfig trace_config;
2658 trace_config.add_buffers()->set_size_kb(128);
2659 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2660 ds_config->set_name("data_source");
2661
2662 consumer->EnableTracing(trace_config);
2663 producer->WaitForTracingSetup();
2664 producer->WaitForDataSourceSetup("data_source");
2665 producer->WaitForDataSourceStart("data_source");
2666
2667 consumer->GetTraceStats();
2668 consumer->WaitForTraceStats(true);
2669
2670 consumer->DisableTracing();
2671 producer->WaitForDataSourceStop("data_source");
2672 consumer->WaitForTracingDisabled();
2673}
2674
Eric Seckler7b0c9452019-03-18 13:14:36 +00002675TEST_F(TracingServiceImplTest, ObserveEventsDataSourceInstances) {
2676 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2677 consumer->Connect(svc.get());
2678
2679 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2680 producer->Connect(svc.get(), "mock_producer");
2681 producer->RegisterDataSource("data_source");
2682
2683 TraceConfig trace_config;
2684 trace_config.add_buffers()->set_size_kb(128);
2685 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2686 ds_config->set_name("data_source");
2687
2688 // Start tracing before the consumer is interested in events. The consumer's
2689 // OnObservableEvents() should not be called yet.
2690 consumer->EnableTracing(trace_config);
2691 producer->WaitForTracingSetup();
2692 producer->WaitForDataSourceSetup("data_source");
2693 producer->WaitForDataSourceStart("data_source");
2694
2695 // Calling ObserveEvents should cause an event for the initial instance state.
2696 consumer->ObserveEvents(TracingService::ConsumerEndpoint::
2697 ObservableEventType::kDataSourceInstances);
2698 {
2699 auto events = consumer->WaitForObservableEvents();
2700
2701 ObservableEvents::DataSourceInstanceStateChange change;
2702 change.set_producer_name("mock_producer");
2703 change.set_data_source_name("data_source");
Primiano Tucci57dd66b2019-10-15 23:09:04 +01002704 change.set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED);
Eric Seckler7b0c9452019-03-18 13:14:36 +00002705 EXPECT_EQ(events.instance_state_changes_size(), 1);
2706 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2707 }
2708
2709 // Disabling should cause an instance state change to STOPPED.
2710 consumer->DisableTracing();
2711
2712 {
2713 auto events = consumer->WaitForObservableEvents();
2714
2715 ObservableEvents::DataSourceInstanceStateChange change;
2716 change.set_producer_name("mock_producer");
2717 change.set_data_source_name("data_source");
Primiano Tucci57dd66b2019-10-15 23:09:04 +01002718 change.set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STOPPED);
Eric Seckler7b0c9452019-03-18 13:14:36 +00002719 EXPECT_EQ(events.instance_state_changes_size(), 1);
2720 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2721 }
2722
2723 producer->WaitForDataSourceStop("data_source");
2724 consumer->WaitForTracingDisabled();
2725 consumer->FreeBuffers();
2726
2727 // Enable again, this should cause a state change for a new instance to
2728 // its initial state STOPPED.
2729 trace_config.set_deferred_start(true);
2730 consumer->EnableTracing(trace_config);
2731
2732 {
2733 auto events = consumer->WaitForObservableEvents();
2734
2735 ObservableEvents::DataSourceInstanceStateChange change;
2736 change.set_producer_name("mock_producer");
2737 change.set_data_source_name("data_source");
Primiano Tucci57dd66b2019-10-15 23:09:04 +01002738 change.set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STOPPED);
Eric Seckler7b0c9452019-03-18 13:14:36 +00002739 EXPECT_EQ(events.instance_state_changes_size(), 1);
2740 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2741 }
2742
2743 producer->WaitForDataSourceSetup("data_source");
2744
2745 // Should move the instance into STARTED state and thus cause an event.
2746 consumer->StartTracing();
2747
2748 {
2749 auto events = consumer->WaitForObservableEvents();
2750
2751 ObservableEvents::DataSourceInstanceStateChange change;
2752 change.set_producer_name("mock_producer");
2753 change.set_data_source_name("data_source");
Primiano Tucci57dd66b2019-10-15 23:09:04 +01002754 change.set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED);
Eric Seckler7b0c9452019-03-18 13:14:36 +00002755 EXPECT_EQ(events.instance_state_changes_size(), 1);
2756 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2757 }
2758
2759 producer->WaitForDataSourceStart("data_source");
2760
2761 // Stop observing events.
2762 consumer->ObserveEvents(
2763 TracingService::ConsumerEndpoint::ObservableEventType::kNone);
2764
2765 // Disabling should now no longer cause events to be sent to the consumer.
2766 consumer->DisableTracing();
2767 producer->WaitForDataSourceStop("data_source");
2768 consumer->WaitForTracingDisabled();
2769}
2770
Stephen Nusko6d4d5922019-08-06 15:38:25 +01002771TEST_F(TracingServiceImplTest, ObserveEventsDataSourceInstancesUnregister) {
2772 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2773 consumer->Connect(svc.get());
2774
2775 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2776 producer->Connect(svc.get(), "mock_producer");
2777 producer->RegisterDataSource("data_source");
2778
2779 TraceConfig trace_config;
2780 trace_config.add_buffers()->set_size_kb(128);
2781 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2782 ds_config->set_name("data_source");
2783
2784 // Start tracing before the consumer is interested in events. The consumer's
2785 // OnObservableEvents() should not be called yet.
2786 consumer->EnableTracing(trace_config);
2787 producer->WaitForTracingSetup();
2788 producer->WaitForDataSourceSetup("data_source");
2789 producer->WaitForDataSourceStart("data_source");
2790
2791 // Calling ObserveEvents should cause an event for the initial instance state.
2792 consumer->ObserveEvents(TracingService::ConsumerEndpoint::
2793 ObservableEventType::kDataSourceInstances);
2794 {
2795 ObservableEvents event;
2796 ObservableEvents::DataSourceInstanceStateChange* change =
2797 event.add_instance_state_changes();
2798 change->set_producer_name("mock_producer");
2799 change->set_data_source_name("data_source");
Primiano Tucci57dd66b2019-10-15 23:09:04 +01002800 change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED);
Stephen Nusko6d4d5922019-08-06 15:38:25 +01002801 EXPECT_CALL(*consumer, OnObservableEvents(Eq(event)))
2802 .WillOnce(InvokeWithoutArgs(
2803 task_runner.CreateCheckpoint("data_source_started")));
2804
2805 task_runner.RunUntilCheckpoint("data_source_started");
2806 }
2807 {
2808 ObservableEvents event;
2809 ObservableEvents::DataSourceInstanceStateChange* change =
2810 event.add_instance_state_changes();
2811 change->set_producer_name("mock_producer");
2812 change->set_data_source_name("data_source");
Primiano Tucci57dd66b2019-10-15 23:09:04 +01002813 change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STOPPED);
Stephen Nusko6d4d5922019-08-06 15:38:25 +01002814 EXPECT_CALL(*consumer, OnObservableEvents(Eq(event)))
2815 .WillOnce(InvokeWithoutArgs(
2816 task_runner.CreateCheckpoint("data_source_stopped")));
2817 }
2818 producer->UnregisterDataSource("data_source");
2819 producer->WaitForDataSourceStop("data_source");
2820 task_runner.RunUntilCheckpoint("data_source_stopped");
2821
2822 consumer->DisableTracing();
2823 consumer->WaitForTracingDisabled();
2824}
2825
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002826TEST_F(TracingServiceImplTest, QueryServiceState) {
2827 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2828 consumer->Connect(svc.get());
2829
2830 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2831 producer1->Connect(svc.get(), "producer1");
2832
2833 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2834 producer2->Connect(svc.get(), "producer2");
2835
2836 producer1->RegisterDataSource("common_ds");
2837 producer2->RegisterDataSource("common_ds");
2838
2839 producer1->RegisterDataSource("p1_ds");
2840 producer2->RegisterDataSource("p2_ds");
2841
2842 TracingServiceState svc_state = consumer->QueryServiceState();
2843
Eric Seckler4ffe6c22019-06-05 09:07:16 +01002844 EXPECT_EQ(svc_state.producers_size(), 2);
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002845 EXPECT_EQ(svc_state.producers().at(0).id(), 1);
2846 EXPECT_EQ(svc_state.producers().at(0).name(), "producer1");
2847 EXPECT_EQ(svc_state.producers().at(1).id(), 2);
2848 EXPECT_EQ(svc_state.producers().at(1).name(), "producer2");
2849
Eric Seckler4ffe6c22019-06-05 09:07:16 +01002850 EXPECT_EQ(svc_state.data_sources_size(), 4);
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002851
2852 EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 1);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002853 EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().name(), "common_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002854
2855 EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002856 EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().name(), "common_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002857
2858 EXPECT_EQ(svc_state.data_sources().at(2).producer_id(), 1);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002859 EXPECT_EQ(svc_state.data_sources().at(2).ds_descriptor().name(), "p1_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002860
2861 EXPECT_EQ(svc_state.data_sources().at(3).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002862 EXPECT_EQ(svc_state.data_sources().at(3).ds_descriptor().name(), "p2_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002863
2864 // Test that descriptors are cleared when a producer disconnects.
2865 producer1.reset();
2866 svc_state = consumer->QueryServiceState();
2867
Eric Seckler4ffe6c22019-06-05 09:07:16 +01002868 EXPECT_EQ(svc_state.producers_size(), 1);
2869 EXPECT_EQ(svc_state.data_sources_size(), 2);
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002870
2871 EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002872 EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().name(), "common_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002873 EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002874 EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().name(), "p2_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002875}
2876
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00002877} // namespace perfetto