blob: 3479e1e246a35d613887df9004cf388dfbe3a67a [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");
Florian Mayer61c55482018-03-06 14:43:54 +00001130 trace_config.set_lockdown_mode(
1131 TraceConfig::LockdownModeOperation::LOCKDOWN_SET);
Primiano Tuccidca727d2018-04-04 11:31:55 +02001132 consumer->EnableTracing(trace_config);
1133
1134 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001135 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001136 producer->WaitForDataSourceStart("data_source");
1137
1138 std::unique_ptr<MockProducer> producer_otheruid = CreateMockProducer();
1139 auto x = svc->ConnectProducer(producer_otheruid.get(), geteuid() + 1,
1140 "mock_producer_ouid");
1141 EXPECT_CALL(*producer_otheruid, OnConnect()).Times(0);
Florian Mayer61c55482018-03-06 14:43:54 +00001142 task_runner.RunUntilIdle();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001143 Mock::VerifyAndClearExpectations(producer_otheruid.get());
Florian Mayer61c55482018-03-06 14:43:54 +00001144
Primiano Tuccidca727d2018-04-04 11:31:55 +02001145 consumer->DisableTracing();
1146 consumer->FreeBuffers();
1147 producer->WaitForDataSourceStop("data_source");
1148 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +00001149
1150 trace_config.set_lockdown_mode(
1151 TraceConfig::LockdownModeOperation::LOCKDOWN_CLEAR);
Primiano Tuccidca727d2018-04-04 11:31:55 +02001152 consumer->EnableTracing(trace_config);
Primiano Tucci674076d2018-10-01 10:41:09 +01001153 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001154 producer->WaitForDataSourceStart("data_source");
Florian Mayer61c55482018-03-06 14:43:54 +00001155
Primiano Tuccidca727d2018-04-04 11:31:55 +02001156 std::unique_ptr<MockProducer> producer_otheruid2 = CreateMockProducer();
1157 producer_otheruid->Connect(svc.get(), "mock_producer_ouid2", geteuid() + 1);
Florian Mayer61c55482018-03-06 14:43:54 +00001158
Primiano Tuccidca727d2018-04-04 11:31:55 +02001159 consumer->DisableTracing();
1160 producer->WaitForDataSourceStop("data_source");
1161 consumer->WaitForTracingDisabled();
Florian Mayer61c55482018-03-06 14:43:54 +00001162}
1163
Oystein Eftevaagcb6e4c82019-03-06 15:38:26 -08001164TEST_F(TracingServiceImplTest, ProducerNameFilterChange) {
1165 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1166 consumer->Connect(svc.get());
1167
1168 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1169 producer1->Connect(svc.get(), "mock_producer_1");
1170 producer1->RegisterDataSource("data_source");
1171
1172 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1173 producer2->Connect(svc.get(), "mock_producer_2");
1174 producer2->RegisterDataSource("data_source");
1175
1176 std::unique_ptr<MockProducer> producer3 = CreateMockProducer();
1177 producer3->Connect(svc.get(), "mock_producer_3");
1178 producer3->RegisterDataSource("data_source");
1179 producer3->RegisterDataSource("unused_data_source");
1180
1181 TraceConfig trace_config;
1182 trace_config.add_buffers()->set_size_kb(128);
1183 auto* data_source = trace_config.add_data_sources();
1184 data_source->mutable_config()->set_name("data_source");
1185 *data_source->add_producer_name_filter() = "mock_producer_1";
1186
1187 // Enable tracing with only mock_producer_1 enabled;
1188 // the rest should not start up.
1189 consumer->EnableTracing(trace_config);
1190
1191 producer1->WaitForTracingSetup();
1192 producer1->WaitForDataSourceSetup("data_source");
1193 producer1->WaitForDataSourceStart("data_source");
1194
1195 EXPECT_CALL(*producer2, OnConnect()).Times(0);
1196 EXPECT_CALL(*producer3, OnConnect()).Times(0);
1197 task_runner.RunUntilIdle();
1198 Mock::VerifyAndClearExpectations(producer2.get());
1199 Mock::VerifyAndClearExpectations(producer3.get());
1200
1201 // Enable mock_producer_2, the third one should still
1202 // not get connected.
1203 *data_source->add_producer_name_filter() = "mock_producer_2";
1204 consumer->ChangeTraceConfig(trace_config);
1205
1206 producer2->WaitForTracingSetup();
1207 producer2->WaitForDataSourceSetup("data_source");
1208 producer2->WaitForDataSourceStart("data_source");
1209
1210 // Enable mock_producer_3 but also try to do an
1211 // unsupported change (adding a new data source);
1212 // mock_producer_3 should get enabled but not
1213 // for the new data source.
1214 *data_source->add_producer_name_filter() = "mock_producer_3";
1215 auto* dummy_data_source = trace_config.add_data_sources();
1216 dummy_data_source->mutable_config()->set_name("unused_data_source");
1217 *dummy_data_source->add_producer_name_filter() = "mock_producer_3";
1218
1219 consumer->ChangeTraceConfig(trace_config);
1220
1221 producer3->WaitForTracingSetup();
1222 EXPECT_CALL(*producer3, SetupDataSource(_, _)).Times(1);
1223 EXPECT_CALL(*producer3, StartDataSource(_, _)).Times(1);
1224 task_runner.RunUntilIdle();
1225 Mock::VerifyAndClearExpectations(producer3.get());
1226
1227 consumer->DisableTracing();
1228 consumer->FreeBuffers();
1229 producer1->WaitForDataSourceStop("data_source");
1230 producer2->WaitForDataSourceStop("data_source");
1231
1232 EXPECT_CALL(*producer3, StopDataSource(_)).Times(1);
1233
1234 consumer->WaitForTracingDisabled();
1235
1236 task_runner.RunUntilIdle();
1237 Mock::VerifyAndClearExpectations(producer3.get());
1238}
1239
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001240TEST_F(TracingServiceImplTest, DisconnectConsumerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001241 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1242 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +00001243
Primiano Tuccidca727d2018-04-04 11:31:55 +02001244 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1245 producer->Connect(svc.get(), "mock_producer");
1246 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001247
Primiano Tuccidca727d2018-04-04 11:31:55 +02001248 TraceConfig trace_config;
1249 trace_config.add_buffers()->set_size_kb(128);
1250 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1251 ds_config->set_name("data_source");
1252 consumer->EnableTracing(trace_config);
1253
1254 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001255 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001256 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001257
1258 // Disconnecting the consumer while tracing should trigger data source
1259 // teardown.
Primiano Tuccidca727d2018-04-04 11:31:55 +02001260 consumer.reset();
1261 producer->WaitForDataSourceStop("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001262}
1263
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001264TEST_F(TracingServiceImplTest, ReconnectProducerWhileTracing) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001265 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1266 consumer->Connect(svc.get());
Sami Kyostila06487a22018-02-27 13:48:38 +00001267
Primiano Tuccidca727d2018-04-04 11:31:55 +02001268 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1269 producer->Connect(svc.get(), "mock_producer");
1270 producer->RegisterDataSource("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001271
Sami Kyostila06487a22018-02-27 13:48:38 +00001272 TraceConfig trace_config;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001273 trace_config.add_buffers()->set_size_kb(128);
Sami Kyostila06487a22018-02-27 13:48:38 +00001274 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001275 ds_config->set_name("data_source");
1276 consumer->EnableTracing(trace_config);
Sami Kyostila06487a22018-02-27 13:48:38 +00001277
Primiano Tuccidca727d2018-04-04 11:31:55 +02001278 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001279 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001280 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001281
Primiano Tuccidca727d2018-04-04 11:31:55 +02001282 // Disconnecting and reconnecting a producer with a matching data source.
1283 // The Producer should see that data source getting enabled again.
1284 producer.reset();
1285 producer = CreateMockProducer();
1286 producer->Connect(svc.get(), "mock_producer_2");
1287 producer->RegisterDataSource("data_source");
1288 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001289 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001290 producer->WaitForDataSourceStart("data_source");
Sami Kyostila06487a22018-02-27 13:48:38 +00001291}
1292
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001293TEST_F(TracingServiceImplTest, ProducerIDWrapping) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001294 std::vector<std::unique_ptr<MockProducer>> producers;
1295 producers.push_back(nullptr);
Primiano Tucci081d46a2018-02-28 11:09:43 +00001296
Primiano Tuccidca727d2018-04-04 11:31:55 +02001297 auto connect_producer_and_get_id = [&producers,
1298 this](const std::string& name) {
1299 producers.emplace_back(CreateMockProducer());
1300 producers.back()->Connect(svc.get(), "mock_producer_" + name);
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001301 return *last_producer_id();
Primiano Tucci081d46a2018-02-28 11:09:43 +00001302 };
1303
1304 // Connect producers 1-4.
1305 for (ProducerID i = 1; i <= 4; i++)
Primiano Tuccidca727d2018-04-04 11:31:55 +02001306 ASSERT_EQ(i, connect_producer_and_get_id(std::to_string(i)));
Primiano Tucci081d46a2018-02-28 11:09:43 +00001307
1308 // Disconnect producers 1,3.
Primiano Tuccidca727d2018-04-04 11:31:55 +02001309 producers[1].reset();
1310 producers[3].reset();
Primiano Tucci081d46a2018-02-28 11:09:43 +00001311
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001312 *last_producer_id() = kMaxProducerID - 1;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001313 ASSERT_EQ(kMaxProducerID, connect_producer_and_get_id("maxid"));
1314 ASSERT_EQ(1u, connect_producer_and_get_id("1_again"));
1315 ASSERT_EQ(3u, connect_producer_and_get_id("3_again"));
1316 ASSERT_EQ(5u, connect_producer_and_get_id("5"));
1317 ASSERT_EQ(6u, connect_producer_and_get_id("6"));
Primiano Tucci081d46a2018-02-28 11:09:43 +00001318}
1319
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001320// Note: file_write_period_ms is set to a large enough to have exactly one flush
1321// of the tracing buffers (and therefore at most one synchronization section),
1322// unless the test runs unrealistically slowly, or the implementation of the
1323// tracing snapshot packets changes.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001324TEST_F(TracingServiceImplTest, WriteIntoFileAndStopOnMaxSize) {
Primiano Tuccidca727d2018-04-04 11:31:55 +02001325 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1326 consumer->Connect(svc.get());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001327
Primiano Tuccidca727d2018-04-04 11:31:55 +02001328 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1329 producer->Connect(svc.get(), "mock_producer");
1330 producer->RegisterDataSource("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001331
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001332 TraceConfig trace_config;
1333 trace_config.add_buffers()->set_size_kb(4096);
1334 auto* ds_config = trace_config.add_data_sources()->mutable_config();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001335 ds_config->set_name("data_source");
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001336 ds_config->set_target_buffer(0);
1337 trace_config.set_write_into_file(true);
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001338 trace_config.set_file_write_period_ms(100000); // 100s
1339 const uint64_t kMaxFileSize = 1024;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001340 trace_config.set_max_file_size_bytes(kMaxFileSize);
1341 base::TempFile tmp_file = base::TempFile::Create();
Primiano Tuccidca727d2018-04-04 11:31:55 +02001342 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
1343
1344 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001345 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccidca727d2018-04-04 11:31:55 +02001346 producer->WaitForDataSourceStart("data_source");
1347
Hector Dearman685f7522019-03-12 14:28:56 +00001348 // The preamble packets are:
Hector Dearmane004a572019-05-13 17:51:43 +01001349 // Trace start clocksnapshot
Hector Dearman685f7522019-03-12 14:28:56 +00001350 // Config
1351 // SystemInfo
Hector Dearmane004a572019-05-13 17:51:43 +01001352 // Trace read clocksnapshot
1353 // Trace synchronisation
Eric Seckler667e0852019-06-06 14:56:07 +01001354 static const int kNumPreamblePackets = 5;
Hector Dearmane004a572019-05-13 17:51:43 +01001355 static const int kNumTestPackets = 9;
Primiano Tuccidca727d2018-04-04 11:31:55 +02001356 static const char kPayload[] = "1234567890abcdef-";
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001357
1358 std::unique_ptr<TraceWriter> writer =
Primiano Tuccidca727d2018-04-04 11:31:55 +02001359 producer->CreateTraceWriter("data_source");
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001360 // Tracing service will emit a preamble of packets (a synchronization section,
1361 // followed by a tracing config packet). The preamble and these test packets
1362 // should fit within kMaxFileSize.
1363 for (int i = 0; i < kNumTestPackets; i++) {
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001364 auto tp = writer->NewTracePacket();
1365 std::string payload(kPayload);
1366 payload.append(std::to_string(i));
1367 tp->set_for_testing()->set_str(payload.c_str(), payload.size());
1368 }
1369
1370 // Finally add a packet that overflows kMaxFileSize. This should cause the
1371 // implicit stop of the trace and should *not* be written in the trace.
1372 {
1373 auto tp = writer->NewTracePacket();
1374 char big_payload[kMaxFileSize] = "BIG!";
1375 tp->set_for_testing()->set_str(big_payload, sizeof(big_payload));
1376 }
1377 writer->Flush();
1378 writer.reset();
1379
Primiano Tuccidca727d2018-04-04 11:31:55 +02001380 consumer->DisableTracing();
1381 producer->WaitForDataSourceStop("data_source");
1382 consumer->WaitForTracingDisabled();
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001383
1384 // Verify the contents of the file.
1385 std::string trace_raw;
1386 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
1387 protos::Trace trace;
1388 ASSERT_TRUE(trace.ParseFromString(trace_raw));
Ryan Savitskicc28cbf2018-11-09 22:55:12 +00001389
1390 ASSERT_EQ(trace.packet_size(), kNumPreamblePackets + kNumTestPackets);
1391 for (int i = 0; i < kNumTestPackets; i++) {
1392 const protos::TracePacket& tp = trace.packet(kNumPreamblePackets + i);
1393 ASSERT_EQ(kPayload + std::to_string(i++), tp.for_testing().str());
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001394 }
Primiano Tuccidca727d2018-04-04 11:31:55 +02001395}
Primiano Tucci2ffd1a52018-03-27 01:01:30 +01001396
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001397// Test the logic that allows the trace config to set the shm total size and
1398// page size from the trace config. Also check that, if the config doesn't
1399// specify a value we fall back on the hint provided by the producer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001400TEST_F(TracingServiceImplTest, ProducerShmAndPageSizeOverriddenByTraceConfig) {
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001401 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1402 consumer->Connect(svc.get());
Nicolò Mazzucato693f6aa2019-07-08 10:26:09 +01001403 const size_t kMaxPageSizeKb = SharedMemoryABI::kMaxPageSize / 1024;
1404 const size_t kConfigPageSizesKb[] = /**/ {16, 0, 3, 2, 16, 8, 0, 4096, 0};
1405 const size_t kPageHintSizesKb[] = /****/ {0, 4, 0, 0, 8, 0, 4096, 0, 0};
1406 const size_t kExpectedPageSizesKb[] = {
1407 16, // Use config value.
1408 4, // Config is 0, use hint.
1409 kDefaultShmPageSizeKb, // Config % 4 != 0, take default.
1410 kDefaultShmPageSizeKb, // Less than page size, take default.
1411 16, // Ignore the hint.
1412 8, // Use config value.
1413 kMaxPageSizeKb, // Hint too big, take max value.
1414 kMaxPageSizeKb, // Config too high, take max value.
1415 4 // Fallback to default.
1416 };
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001417
1418 const size_t kConfigSizesKb[] = /**/ {0, 16, 0, 20, 32, 7, 0, 96, 4096000};
1419 const size_t kHintSizesKb[] = /****/ {0, 0, 16, 32, 16, 0, 7, 96, 4096000};
1420 const size_t kExpectedSizesKb[] = {
1421 kDefaultShmSizeKb, // Both hint and config are 0, use default.
1422 16, // Hint is 0, use config.
1423 16, // Config is 0, use hint.
1424 20, // Hint is takes precedence over the config.
1425 32, // Ditto, even if config is higher than hint.
1426 kDefaultShmSizeKb, // Config is invalid and hint is 0, use default.
1427 kDefaultShmSizeKb, // Config is 0 and hint is invalid, use default.
1428 kDefaultShmSizeKb, // 96 KB isn't a multiple of the page size (64 KB).
1429 kMaxShmSizeKb // Too big, cap at kMaxShmSize.
1430 };
1431
1432 const size_t kNumProducers = base::ArraySize(kHintSizesKb);
1433 std::unique_ptr<MockProducer> producer[kNumProducers];
1434 for (size_t i = 0; i < kNumProducers; i++) {
1435 auto name = "mock_producer_" + std::to_string(i);
1436 producer[i] = CreateMockProducer();
Nicolò Mazzucato693f6aa2019-07-08 10:26:09 +01001437 producer[i]->Connect(svc.get(), name, geteuid(), kHintSizesKb[i] * 1024,
1438 kPageHintSizesKb[i] * 1024);
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001439 producer[i]->RegisterDataSource("data_source");
1440 }
1441
1442 TraceConfig trace_config;
1443 trace_config.add_buffers()->set_size_kb(128);
1444 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1445 ds_config->set_name("data_source");
1446 for (size_t i = 0; i < kNumProducers; i++) {
1447 auto* producer_config = trace_config.add_producers();
1448 producer_config->set_producer_name("mock_producer_" + std::to_string(i));
Primiano Tucci3cbb10a2018-04-10 17:52:40 +01001449 producer_config->set_shm_size_kb(static_cast<uint32_t>(kConfigSizesKb[i]));
1450 producer_config->set_page_size_kb(
1451 static_cast<uint32_t>(kConfigPageSizesKb[i]));
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001452 }
1453
1454 consumer->EnableTracing(trace_config);
1455 size_t actual_shm_sizes_kb[kNumProducers]{};
1456 size_t actual_page_sizes_kb[kNumProducers]{};
1457 for (size_t i = 0; i < kNumProducers; i++) {
1458 producer[i]->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001459 producer[i]->WaitForDataSourceSetup("data_source");
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001460 actual_shm_sizes_kb[i] =
1461 producer[i]->endpoint()->shared_memory()->size() / 1024;
1462 actual_page_sizes_kb[i] =
1463 producer[i]->endpoint()->shared_buffer_page_size_kb();
1464 }
Primiano Tucci674076d2018-10-01 10:41:09 +01001465 for (size_t i = 0; i < kNumProducers; i++) {
1466 producer[i]->WaitForDataSourceStart("data_source");
1467 }
Primiano Tucci1a1951d2018-04-04 21:08:16 +02001468 ASSERT_THAT(actual_page_sizes_kb, ElementsAreArray(kExpectedPageSizesKb));
1469 ASSERT_THAT(actual_shm_sizes_kb, ElementsAreArray(kExpectedSizesKb));
1470}
1471
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001472TEST_F(TracingServiceImplTest, ExplicitFlush) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001473 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1474 consumer->Connect(svc.get());
1475
1476 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1477 producer->Connect(svc.get(), "mock_producer");
1478 producer->RegisterDataSource("data_source");
1479
1480 TraceConfig trace_config;
1481 trace_config.add_buffers()->set_size_kb(128);
1482 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1483 ds_config->set_name("data_source");
1484
1485 consumer->EnableTracing(trace_config);
1486 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001487 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001488 producer->WaitForDataSourceStart("data_source");
1489
1490 std::unique_ptr<TraceWriter> writer =
1491 producer->CreateTraceWriter("data_source");
1492 {
1493 auto tp = writer->NewTracePacket();
1494 tp->set_for_testing()->set_str("payload");
1495 }
1496
1497 auto flush_request = consumer->Flush();
1498 producer->WaitForFlush(writer.get());
1499 ASSERT_TRUE(flush_request.WaitForReply());
1500
1501 consumer->DisableTracing();
1502 producer->WaitForDataSourceStop("data_source");
1503 consumer->WaitForTracingDisabled();
1504 EXPECT_THAT(
1505 consumer->ReadBuffers(),
1506 Contains(Property(&protos::TracePacket::for_testing,
1507 Property(&protos::TestEvent::str, Eq("payload")))));
1508}
1509
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001510TEST_F(TracingServiceImplTest, ImplicitFlushOnTimedTraces) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001511 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1512 consumer->Connect(svc.get());
1513
1514 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1515 producer->Connect(svc.get(), "mock_producer");
1516 producer->RegisterDataSource("data_source");
1517
1518 TraceConfig trace_config;
1519 trace_config.add_buffers()->set_size_kb(128);
1520 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1521 ds_config->set_name("data_source");
1522 trace_config.set_duration_ms(1);
1523
1524 consumer->EnableTracing(trace_config);
1525 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001526 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001527 producer->WaitForDataSourceStart("data_source");
1528
1529 std::unique_ptr<TraceWriter> writer =
1530 producer->CreateTraceWriter("data_source");
1531 {
1532 auto tp = writer->NewTracePacket();
1533 tp->set_for_testing()->set_str("payload");
1534 }
1535
1536 producer->WaitForFlush(writer.get());
1537
1538 producer->WaitForDataSourceStop("data_source");
1539 consumer->WaitForTracingDisabled();
1540
1541 EXPECT_THAT(
1542 consumer->ReadBuffers(),
1543 Contains(Property(&protos::TracePacket::for_testing,
1544 Property(&protos::TestEvent::str, Eq("payload")))));
1545}
1546
1547// Tests the monotonic semantic of flush request IDs, i.e., once a producer
1548// acks flush request N, all flush requests <= N are considered successful and
1549// acked to the consumer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +01001550TEST_F(TracingServiceImplTest, BatchFlushes) {
Primiano Tuccid52e6272018-04-06 19:06:53 +02001551 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1552 consumer->Connect(svc.get());
1553
1554 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1555 producer->Connect(svc.get(), "mock_producer");
1556 producer->RegisterDataSource("data_source");
1557
1558 TraceConfig trace_config;
1559 trace_config.add_buffers()->set_size_kb(128);
1560 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1561 ds_config->set_name("data_source");
1562
1563 consumer->EnableTracing(trace_config);
1564 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001565 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccid52e6272018-04-06 19:06:53 +02001566 producer->WaitForDataSourceStart("data_source");
1567
1568 std::unique_ptr<TraceWriter> writer =
1569 producer->CreateTraceWriter("data_source");
1570 {
1571 auto tp = writer->NewTracePacket();
1572 tp->set_for_testing()->set_str("payload");
1573 }
1574
1575 auto flush_req_1 = consumer->Flush();
1576 auto flush_req_2 = consumer->Flush();
1577 auto flush_req_3 = consumer->Flush();
1578
1579 // We'll deliberately let the 4th flush request timeout. Use a lower timeout
1580 // to keep test time short.
1581 auto flush_req_4 = consumer->Flush(/*timeout_ms=*/10);
1582 ASSERT_EQ(4u, GetNumPendingFlushes());
1583
1584 // Make the producer reply only to the 3rd flush request.
Hector Dearmanbb3bc482019-08-02 11:54:08 +01001585 InSequence seq;
Eric Secklera01e28a2019-01-08 11:21:04 +00001586 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 1.
1587 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 2.
1588 producer->WaitForFlush(writer.get()); // Reply only to flush 3.
1589 producer->WaitForFlush(nullptr, /*reply=*/false); // Do NOT reply to flush 4.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001590
1591 // Even if the producer explicily replied only to flush ID == 3, all the
1592 // previous flushed < 3 should be implicitly acked.
1593 ASSERT_TRUE(flush_req_1.WaitForReply());
1594 ASSERT_TRUE(flush_req_2.WaitForReply());
1595 ASSERT_TRUE(flush_req_3.WaitForReply());
1596
1597 // At this point flush id == 4 should still be pending and should fail because
1598 // of reaching its timeout.
Primiano Tuccid52e6272018-04-06 19:06:53 +02001599 ASSERT_FALSE(flush_req_4.WaitForReply());
1600
1601 consumer->DisableTracing();
1602 producer->WaitForDataSourceStop("data_source");
1603 consumer->WaitForTracingDisabled();
1604 EXPECT_THAT(
1605 consumer->ReadBuffers(),
1606 Contains(Property(&protos::TracePacket::for_testing,
1607 Property(&protos::TestEvent::str, Eq("payload")))));
1608}
1609
Primiano Tuccicaa57802018-11-25 11:07:07 +00001610TEST_F(TracingServiceImplTest, PeriodicFlush) {
1611 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1612 consumer->Connect(svc.get());
1613
1614 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1615 producer->Connect(svc.get(), "mock_producer");
1616 producer->RegisterDataSource("data_source");
1617
1618 TraceConfig trace_config;
1619 trace_config.add_buffers()->set_size_kb(128);
1620 trace_config.set_flush_period_ms(1);
1621 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1622 ds_config->set_name("data_source");
1623
1624 consumer->EnableTracing(trace_config);
1625 producer->WaitForTracingSetup();
1626 producer->WaitForDataSourceSetup("data_source");
1627 producer->WaitForDataSourceStart("data_source");
1628
1629 std::unique_ptr<TraceWriter> writer =
1630 producer->CreateTraceWriter("data_source");
1631
1632 const int kNumFlushes = 3;
1633 auto checkpoint = task_runner.CreateCheckpoint("all_flushes_done");
1634 int flushes_seen = 0;
1635 EXPECT_CALL(*producer, Flush(_, _, _))
1636 .WillRepeatedly(Invoke([&producer, &writer, &flushes_seen, checkpoint](
1637 FlushRequestID flush_req_id,
1638 const DataSourceInstanceID*, size_t) {
1639 {
1640 auto tp = writer->NewTracePacket();
1641 char payload[32];
1642 sprintf(payload, "f_%d", flushes_seen);
1643 tp->set_for_testing()->set_str(payload);
1644 }
1645 writer->Flush();
1646 producer->endpoint()->NotifyFlushComplete(flush_req_id);
1647 if (++flushes_seen == kNumFlushes)
1648 checkpoint();
1649 }));
1650 task_runner.RunUntilCheckpoint("all_flushes_done");
1651
1652 consumer->DisableTracing();
1653 producer->WaitForDataSourceStop("data_source");
1654 consumer->WaitForTracingDisabled();
1655 auto trace_packets = consumer->ReadBuffers();
1656 for (int i = 0; i < kNumFlushes; i++) {
1657 EXPECT_THAT(trace_packets,
1658 Contains(Property(&protos::TracePacket::for_testing,
1659 Property(&protos::TestEvent::str,
1660 Eq("f_" + std::to_string(i))))));
1661 }
1662}
1663
Ryan Savitski33868d52019-05-13 10:56:14 +01001664TEST_F(TracingServiceImplTest, PeriodicClearIncrementalState) {
1665 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1666 consumer->Connect(svc.get());
1667 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1668 producer->Connect(svc.get(), "mock_producer");
1669
1670 // Incremental data source that expects to receive the clear.
1671 producer->RegisterDataSource("ds_incremental1", false, false,
1672 /*handles_incremental_state_clear=*/true);
1673
1674 // Incremental data source that expects to receive the clear.
1675 producer->RegisterDataSource("ds_incremental2", false, false,
1676 /*handles_incremental_state_clear=*/true);
1677
Ryan Savitski0b4008a2019-05-13 17:55:53 +01001678 // Data source that does *not* advertise itself as supporting incremental
1679 // state clears.
Ryan Savitski33868d52019-05-13 10:56:14 +01001680 producer->RegisterDataSource("ds_selfcontained", false, false,
1681 /*handles_incremental_state_clear=*/false);
1682
1683 // Incremental data source that is registered, but won't be active within the
1684 // test's tracing session.
1685 producer->RegisterDataSource("ds_inactive", false, false,
1686 /*handles_incremental_state_clear=*/true);
1687
1688 TraceConfig trace_config;
1689 trace_config.add_buffers()->set_size_kb(128);
1690 trace_config.mutable_incremental_state_config()->set_clear_period_ms(1);
1691 trace_config.add_data_sources()->mutable_config()->set_name(
1692 "ds_selfcontained");
1693 trace_config.add_data_sources()->mutable_config()->set_name(
1694 "ds_incremental1");
1695 trace_config.add_data_sources()->mutable_config()->set_name(
1696 "ds_incremental2");
1697
1698 // note: the mocking is very brittle, and has to assume a specific order of
1699 // the data sources' setup/start.
1700 consumer->EnableTracing(trace_config);
1701 producer->WaitForTracingSetup();
1702 producer->WaitForDataSourceSetup("ds_selfcontained");
1703 producer->WaitForDataSourceSetup("ds_incremental1");
1704 producer->WaitForDataSourceSetup("ds_incremental2");
1705 producer->WaitForDataSourceStart("ds_selfcontained");
1706 producer->WaitForDataSourceStart("ds_incremental1");
1707 producer->WaitForDataSourceStart("ds_incremental2");
1708
1709 DataSourceInstanceID ds_incremental1 =
1710 producer->GetDataSourceInstanceId("ds_incremental1");
1711 DataSourceInstanceID ds_incremental2 =
1712 producer->GetDataSourceInstanceId("ds_incremental2");
1713
Ryan Savitskiba8a5f52019-05-14 11:58:21 +01001714 const size_t kNumClears = 3;
Ryan Savitski33868d52019-05-13 10:56:14 +01001715 std::function<void()> checkpoint =
1716 task_runner.CreateCheckpoint("clears_received");
1717 std::vector<std::vector<DataSourceInstanceID>> clears_seen;
1718 EXPECT_CALL(*producer, ClearIncrementalState(_, _))
1719 .WillRepeatedly(Invoke([&clears_seen, &checkpoint](
1720 const DataSourceInstanceID* data_source_ids,
1721 size_t num_data_sources) {
1722 std::vector<DataSourceInstanceID> ds_ids;
1723 for (size_t i = 0; i < num_data_sources; i++) {
1724 ds_ids.push_back(*data_source_ids++);
1725 }
1726 clears_seen.push_back(ds_ids);
1727 if (clears_seen.size() >= kNumClears)
1728 checkpoint();
1729 }));
1730 task_runner.RunUntilCheckpoint("clears_received");
1731
1732 consumer->DisableTracing();
1733
1734 // Assert that the clears were only for the active incremental data sources.
1735 ASSERT_EQ(clears_seen.size(), kNumClears);
1736 for (const std::vector<DataSourceInstanceID>& ds_ids : clears_seen) {
1737 ASSERT_THAT(ds_ids, ElementsAreArray({ds_incremental1, ds_incremental2}));
1738 }
1739}
1740
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001741// Creates a tracing session where some of the data sources set the
1742// |will_notify_on_stop| flag and checks that the OnTracingDisabled notification
1743// to the consumer is delayed until the acks are received.
1744TEST_F(TracingServiceImplTest, OnTracingDisabledWaitsForDataSourceStopAcks) {
1745 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1746 consumer->Connect(svc.get());
1747
1748 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1749 producer->Connect(svc.get(), "mock_producer");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001750 producer->RegisterDataSource("ds_will_ack_1", /*ack_stop=*/true,
1751 /*ack_start=*/true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001752 producer->RegisterDataSource("ds_wont_ack");
Eric Seckler4ff03e52019-03-15 10:10:30 +00001753 producer->RegisterDataSource("ds_will_ack_2", /*ack_stop=*/true,
1754 /*ack_start=*/false);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001755
1756 TraceConfig trace_config;
1757 trace_config.add_buffers()->set_size_kb(128);
1758 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_1");
1759 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1760 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_2");
1761 trace_config.set_duration_ms(1);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001762 trace_config.set_deferred_start(true);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001763
1764 consumer->EnableTracing(trace_config);
Eric Seckler4ff03e52019-03-15 10:10:30 +00001765
1766 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1767 DataSourceInstanceState::CONFIGURED);
1768 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1769 DataSourceInstanceState::CONFIGURED);
1770 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1771 DataSourceInstanceState::CONFIGURED);
1772
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001773 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001774
1775 producer->WaitForDataSourceSetup("ds_will_ack_1");
1776 producer->WaitForDataSourceSetup("ds_wont_ack");
1777 producer->WaitForDataSourceSetup("ds_will_ack_2");
1778
Eric Seckler4ff03e52019-03-15 10:10:30 +00001779 DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_will_ack_1");
1780 DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_will_ack_2");
1781
1782 consumer->StartTracing();
1783
1784 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1785 DataSourceInstanceState::STARTING);
1786 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1787 DataSourceInstanceState::STARTED);
1788 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1789 DataSourceInstanceState::STARTED);
1790
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001791 producer->WaitForDataSourceStart("ds_will_ack_1");
1792 producer->WaitForDataSourceStart("ds_wont_ack");
1793 producer->WaitForDataSourceStart("ds_will_ack_2");
1794
Eric Seckler4ff03e52019-03-15 10:10:30 +00001795 producer->endpoint()->NotifyDataSourceStarted(id1);
1796
1797 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1798 DataSourceInstanceState::STARTED);
1799
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001800 std::unique_ptr<TraceWriter> writer =
1801 producer->CreateTraceWriter("ds_wont_ack");
1802 producer->WaitForFlush(writer.get());
1803
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001804 producer->WaitForDataSourceStop("ds_will_ack_1");
1805 producer->WaitForDataSourceStop("ds_wont_ack");
1806 producer->WaitForDataSourceStop("ds_will_ack_2");
1807
Eric Seckler4ff03e52019-03-15 10:10:30 +00001808 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1809 DataSourceInstanceState::STOPPING);
1810 EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
1811 DataSourceInstanceState::STOPPED);
1812 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1813 DataSourceInstanceState::STOPPING);
1814
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001815 producer->endpoint()->NotifyDataSourceStopped(id1);
1816 producer->endpoint()->NotifyDataSourceStopped(id2);
1817
Eric Seckler4ff03e52019-03-15 10:10:30 +00001818 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
1819 DataSourceInstanceState::STOPPED);
1820 EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
1821 DataSourceInstanceState::STOPPED);
1822
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001823 // Wait for at most half of the service timeout, so that this test fails if
1824 // the service falls back on calling the OnTracingDisabled() because some of
1825 // the expected acks weren't received.
1826 consumer->WaitForTracingDisabled(
1827 TracingServiceImpl::kDataSourceStopTimeoutMs / 2);
1828}
1829
Oystein Eftevaagf250e1c2018-08-23 16:10:52 -07001830// Creates a tracing session where a second data source
1831// is added while the service is waiting for DisableTracing
1832// acks; the service should not enable the new datasource
1833// and should not hit any asserts when the consumer is
1834// subsequently destroyed.
1835TEST_F(TracingServiceImplTest, OnDataSourceAddedWhilePendingDisableAcks) {
1836 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1837 consumer->Connect(svc.get());
1838
1839 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1840 producer->Connect(svc.get(), "mock_producer");
1841 producer->RegisterDataSource("ds_will_ack", /*ack_stop=*/true);
1842
1843 TraceConfig trace_config;
1844 trace_config.add_buffers()->set_size_kb(128);
1845 trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack");
1846 trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
1847
1848 consumer->EnableTracing(trace_config);
1849 producer->WaitForTracingSetup();
1850
1851 consumer->DisableTracing();
1852
1853 producer->RegisterDataSource("ds_wont_ack");
1854
1855 consumer.reset();
1856}
1857
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001858// Similar to OnTracingDisabledWaitsForDataSourceStopAcks, but deliberately
1859// skips the ack and checks that the service invokes the OnTracingDisabled()
1860// after the timeout.
1861TEST_F(TracingServiceImplTest, OnTracingDisabledCalledAnywaysInCaseOfTimeout) {
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001862 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1863 consumer->Connect(svc.get());
1864
1865 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1866 producer->Connect(svc.get(), "mock_producer");
1867 producer->RegisterDataSource("data_source", /*ack_stop=*/true);
1868
1869 TraceConfig trace_config;
1870 trace_config.add_buffers()->set_size_kb(128);
1871 trace_config.add_data_sources()->mutable_config()->set_name("data_source");
1872 trace_config.set_duration_ms(1);
Florian Mayer990e6d72019-06-03 11:34:52 +01001873 trace_config.set_data_source_stop_timeout_ms(1);
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001874
1875 consumer->EnableTracing(trace_config);
1876 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001877 producer->WaitForDataSourceSetup("data_source");
Primiano Tuccibaeecf12018-07-25 12:02:20 +01001878 producer->WaitForDataSourceStart("data_source");
1879
1880 std::unique_ptr<TraceWriter> writer =
1881 producer->CreateTraceWriter("data_source");
1882 producer->WaitForFlush(writer.get());
1883
1884 producer->WaitForDataSourceStop("data_source");
1885 consumer->WaitForTracingDisabled();
1886}
1887
Primiano Tucci03de28f2018-08-01 11:29:46 +01001888// Tests the session_id logic. Two data sources in the same tracing session
1889// should see the same session id.
1890TEST_F(TracingServiceImplTest, SessionId) {
1891 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1892 consumer->Connect(svc.get());
1893
1894 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1895 producer1->Connect(svc.get(), "mock_producer1");
1896 producer1->RegisterDataSource("ds_1A");
1897 producer1->RegisterDataSource("ds_1B");
1898
1899 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1900 producer2->Connect(svc.get(), "mock_producer2");
1901 producer2->RegisterDataSource("ds_2A");
1902
Hector Dearmanbb3bc482019-08-02 11:54:08 +01001903 InSequence seq;
Primiano Tucci03de28f2018-08-01 11:29:46 +01001904 TracingSessionID last_session_id = 0;
1905 for (int i = 0; i < 3; i++) {
1906 TraceConfig trace_config;
1907 trace_config.add_buffers()->set_size_kb(128);
1908 trace_config.add_data_sources()->mutable_config()->set_name("ds_1A");
1909 trace_config.add_data_sources()->mutable_config()->set_name("ds_1B");
1910 trace_config.add_data_sources()->mutable_config()->set_name("ds_2A");
1911 trace_config.set_duration_ms(1);
1912
1913 consumer->EnableTracing(trace_config);
1914
1915 if (i == 0)
1916 producer1->WaitForTracingSetup();
Primiano Tucci03de28f2018-08-01 11:29:46 +01001917
Primiano Tucci674076d2018-10-01 10:41:09 +01001918 producer1->WaitForDataSourceSetup("ds_1A");
1919 producer1->WaitForDataSourceSetup("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001920 if (i == 0)
1921 producer2->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001922 producer2->WaitForDataSourceSetup("ds_2A");
1923
1924 producer1->WaitForDataSourceStart("ds_1A");
1925 producer1->WaitForDataSourceStart("ds_1B");
Primiano Tucci03de28f2018-08-01 11:29:46 +01001926 producer2->WaitForDataSourceStart("ds_2A");
1927
1928 auto* ds1 = producer1->GetDataSourceInstance("ds_1A");
1929 auto* ds2 = producer1->GetDataSourceInstance("ds_1B");
1930 auto* ds3 = producer2->GetDataSourceInstance("ds_2A");
1931 ASSERT_EQ(ds1->session_id, ds2->session_id);
1932 ASSERT_EQ(ds1->session_id, ds3->session_id);
1933 ASSERT_NE(ds1->session_id, last_session_id);
1934 last_session_id = ds1->session_id;
1935
1936 auto writer1 = producer1->CreateTraceWriter("ds_1A");
1937 producer1->WaitForFlush(writer1.get());
1938
1939 auto writer2 = producer2->CreateTraceWriter("ds_2A");
1940 producer2->WaitForFlush(writer2.get());
1941
1942 producer1->WaitForDataSourceStop("ds_1A");
1943 producer1->WaitForDataSourceStop("ds_1B");
1944 producer2->WaitForDataSourceStop("ds_2A");
1945 consumer->WaitForTracingDisabled();
1946 consumer->FreeBuffers();
1947 }
1948}
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001949
1950// Writes a long trace and then tests that the trace parsed in partitions
1951// derived by the synchronization markers is identical to the whole trace parsed
1952// in one go.
1953TEST_F(TracingServiceImplTest, ResynchronizeTraceStreamUsingSyncMarker) {
1954 // Setup tracing.
1955 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1956 consumer->Connect(svc.get());
1957 std::unique_ptr<MockProducer> producer = CreateMockProducer();
1958 producer->Connect(svc.get(), "mock_producer");
1959 producer->RegisterDataSource("data_source");
1960 TraceConfig trace_config;
1961 trace_config.add_buffers()->set_size_kb(4096);
1962 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1963 ds_config->set_name("data_source");
1964 trace_config.set_write_into_file(true);
1965 trace_config.set_file_write_period_ms(1);
1966 base::TempFile tmp_file = base::TempFile::Create();
1967 consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
1968 producer->WaitForTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +01001969 producer->WaitForDataSourceSetup("data_source");
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001970 producer->WaitForDataSourceStart("data_source");
1971
1972 // Write some variable length payload, waiting for sync markers every now
1973 // and then.
1974 const int kNumMarkers = 5;
1975 auto writer = producer->CreateTraceWriter("data_source");
1976 for (int i = 1; i <= 100; i++) {
Florian Mayereff98042018-12-10 17:44:44 +00001977 std::string payload(static_cast<size_t>(i), 'A' + (i % 25));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01001978 writer->NewTracePacket()->set_for_testing()->set_str(payload.c_str());
1979 if (i % (100 / kNumMarkers) == 0) {
1980 writer->Flush();
1981 WaitForNextSyncMarker();
1982 }
1983 }
1984 writer->Flush();
1985 writer.reset();
1986 consumer->DisableTracing();
1987 producer->WaitForDataSourceStop("data_source");
1988 consumer->WaitForTracingDisabled();
1989
1990 std::string trace_raw;
1991 ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
1992
1993 const auto kMarkerSize = sizeof(TracingServiceImpl::kSyncMarker);
1994 const std::string kSyncMarkerStr(
1995 reinterpret_cast<const char*>(TracingServiceImpl::kSyncMarker),
1996 kMarkerSize);
1997
1998 // Read back the trace in partitions derived from the marker.
1999 // The trace should look like this:
2000 // [uid, marker] [event] [event] [uid, marker] [event] [event]
2001 size_t num_markers = 0;
2002 size_t start = 0;
2003 size_t end = 0;
2004 protos::Trace merged_trace;
2005 for (size_t pos = 0; pos != std::string::npos; start = end) {
2006 pos = trace_raw.find(kSyncMarkerStr, pos + 1);
2007 num_markers++;
2008 end = (pos == std::string::npos) ? trace_raw.size() : pos + kMarkerSize;
2009 int size = static_cast<int>(end - start);
2010 ASSERT_GT(size, 0);
2011 protos::Trace trace_partition;
2012 ASSERT_TRUE(trace_partition.ParseFromArray(trace_raw.data() + start, size));
2013 merged_trace.MergeFrom(trace_partition);
2014 }
Lalit Maganti9bdc7ce2018-09-17 15:25:11 +01002015 EXPECT_GE(num_markers, static_cast<size_t>(kNumMarkers));
Primiano Tucci9754d0d2018-09-15 12:41:46 +01002016
2017 protos::Trace whole_trace;
2018 ASSERT_TRUE(whole_trace.ParseFromString(trace_raw));
2019
2020 ASSERT_EQ(whole_trace.packet_size(), merged_trace.packet_size());
2021 EXPECT_EQ(whole_trace.SerializeAsString(), merged_trace.SerializeAsString());
2022}
2023
Primiano Tucci674076d2018-10-01 10:41:09 +01002024// Creates a tracing session with |deferred_start| and checks that data sources
2025// are started only after calling StartTracing().
2026TEST_F(TracingServiceImplTest, DeferredStart) {
2027 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2028 consumer->Connect(svc.get());
2029
2030 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2031 producer->Connect(svc.get(), "mock_producer");
2032
2033 // Create two data sources but enable only one of them.
2034 producer->RegisterDataSource("ds_1");
2035 producer->RegisterDataSource("ds_2");
2036
2037 TraceConfig trace_config;
2038 trace_config.add_buffers()->set_size_kb(128);
2039 trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
2040 trace_config.set_deferred_start(true);
2041 trace_config.set_duration_ms(1);
2042
2043 consumer->EnableTracing(trace_config);
2044 producer->WaitForTracingSetup();
2045
2046 producer->WaitForDataSourceSetup("ds_1");
2047
2048 // Make sure we don't get unexpected DataSourceStart() notifications yet.
2049 task_runner.RunUntilIdle();
2050
2051 consumer->StartTracing();
2052
2053 producer->WaitForDataSourceStart("ds_1");
2054
Stephen Nusko1393ffd2019-03-22 13:54:58 +00002055 auto writer = producer->CreateTraceWriter("ds_1");
2056 producer->WaitForFlush(writer.get());
Primiano Tucci674076d2018-10-01 10:41:09 +01002057
2058 producer->WaitForDataSourceStop("ds_1");
2059 consumer->WaitForTracingDisabled();
2060}
2061
Eric Secklerd0ac7ca2019-02-06 09:13:45 +00002062TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
2063 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2064 consumer->Connect(svc.get());
2065
2066 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2067 producer1->Connect(svc.get(), "mock_producer1", 123u /* uid */);
2068 producer1->RegisterDataSource("data_source");
2069
2070 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2071 producer2->Connect(svc.get(), "mock_producer2", 456u /* uid */);
2072 producer2->RegisterDataSource("data_source");
2073
2074 TraceConfig trace_config;
2075 trace_config.add_buffers()->set_size_kb(128);
2076 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2077 ds_config->set_name("data_source");
2078
2079 consumer->EnableTracing(trace_config);
2080 producer1->WaitForTracingSetup();
2081 producer1->WaitForDataSourceSetup("data_source");
2082 producer2->WaitForTracingSetup();
2083 producer2->WaitForDataSourceSetup("data_source");
2084 producer1->WaitForDataSourceStart("data_source");
2085 producer2->WaitForDataSourceStart("data_source");
2086
2087 std::unique_ptr<TraceWriter> writer1a =
2088 producer1->CreateTraceWriter("data_source");
2089 std::unique_ptr<TraceWriter> writer1b =
2090 producer1->CreateTraceWriter("data_source");
2091 std::unique_ptr<TraceWriter> writer2a =
2092 producer2->CreateTraceWriter("data_source");
2093 {
2094 auto tp = writer1a->NewTracePacket();
2095 tp->set_for_testing()->set_str("payload1a1");
2096 tp = writer1b->NewTracePacket();
2097 tp->set_for_testing()->set_str("payload1b1");
2098 tp = writer1a->NewTracePacket();
2099 tp->set_for_testing()->set_str("payload1a2");
2100 tp = writer2a->NewTracePacket();
2101 tp->set_for_testing()->set_str("payload2a1");
2102 tp = writer1b->NewTracePacket();
2103 tp->set_for_testing()->set_str("payload1b2");
2104 }
2105
2106 auto flush_request = consumer->Flush();
2107 producer1->WaitForFlush({writer1a.get(), writer1b.get()});
2108 producer2->WaitForFlush(writer2a.get());
2109 ASSERT_TRUE(flush_request.WaitForReply());
2110
2111 consumer->DisableTracing();
2112 producer1->WaitForDataSourceStop("data_source");
2113 producer2->WaitForDataSourceStop("data_source");
2114 consumer->WaitForTracingDisabled();
2115 auto packets = consumer->ReadBuffers();
2116 EXPECT_THAT(
2117 packets,
2118 Contains(AllOf(
2119 Property(&protos::TracePacket::for_testing,
2120 Property(&protos::TestEvent::str, Eq("payload1a1"))),
2121 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2122 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
2123 EXPECT_THAT(
2124 packets,
2125 Contains(AllOf(
2126 Property(&protos::TracePacket::for_testing,
2127 Property(&protos::TestEvent::str, Eq("payload1a2"))),
2128 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2129 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(2u)))));
2130 EXPECT_THAT(
2131 packets,
2132 Contains(AllOf(
2133 Property(&protos::TracePacket::for_testing,
2134 Property(&protos::TestEvent::str, Eq("payload1b1"))),
2135 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2136 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
2137 EXPECT_THAT(
2138 packets,
2139 Contains(AllOf(
2140 Property(&protos::TracePacket::for_testing,
2141 Property(&protos::TestEvent::str, Eq("payload1b2"))),
2142 Property(&protos::TracePacket::trusted_uid, Eq(123)),
2143 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(3u)))));
2144 EXPECT_THAT(
2145 packets,
2146 Contains(AllOf(
2147 Property(&protos::TracePacket::for_testing,
2148 Property(&protos::TestEvent::str, Eq("payload2a1"))),
2149 Property(&protos::TracePacket::trusted_uid, Eq(456)),
2150 Property(&protos::TracePacket::trusted_packet_sequence_id, Eq(4u)))));
2151}
2152
Eric Seckler6dc23592018-11-30 10:59:06 +00002153TEST_F(TracingServiceImplTest, AllowedBuffers) {
2154 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2155 consumer->Connect(svc.get());
2156
2157 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2158 producer1->Connect(svc.get(), "mock_producer1");
2159 ProducerID producer1_id = *last_producer_id();
2160 producer1->RegisterDataSource("data_source1");
2161 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2162 producer2->Connect(svc.get(), "mock_producer2");
2163 ProducerID producer2_id = *last_producer_id();
2164 producer2->RegisterDataSource("data_source2.1");
2165 producer2->RegisterDataSource("data_source2.2");
2166 producer2->RegisterDataSource("data_source2.3");
2167
2168 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
2169 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
2170
2171 TraceConfig trace_config;
2172 trace_config.add_buffers()->set_size_kb(128);
2173 trace_config.add_buffers()->set_size_kb(128);
2174 trace_config.add_buffers()->set_size_kb(128);
2175 auto* ds_config1 = trace_config.add_data_sources()->mutable_config();
2176 ds_config1->set_name("data_source1");
2177 ds_config1->set_target_buffer(0);
2178 auto* ds_config21 = trace_config.add_data_sources()->mutable_config();
2179 ds_config21->set_name("data_source2.1");
2180 ds_config21->set_target_buffer(1);
2181 auto* ds_config22 = trace_config.add_data_sources()->mutable_config();
2182 ds_config22->set_name("data_source2.2");
2183 ds_config22->set_target_buffer(2);
2184 auto* ds_config23 = trace_config.add_data_sources()->mutable_config();
2185 ds_config23->set_name("data_source2.3");
2186 ds_config23->set_target_buffer(2); // same buffer as data_source2.2.
2187 consumer->EnableTracing(trace_config);
2188
Primiano Tucci2abd1152018-12-03 17:00:02 +01002189 ASSERT_EQ(3u, tracing_session()->num_buffers());
Eric Seckler6dc23592018-11-30 10:59:06 +00002190 std::set<BufferID> expected_buffers_producer1 = {
2191 tracing_session()->buffers_index[0]};
2192 std::set<BufferID> expected_buffers_producer2 = {
2193 tracing_session()->buffers_index[1], tracing_session()->buffers_index[2]};
2194 EXPECT_EQ(expected_buffers_producer1, GetAllowedTargetBuffers(producer1_id));
2195 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
2196
2197 producer1->WaitForTracingSetup();
2198 producer1->WaitForDataSourceSetup("data_source1");
2199
2200 producer2->WaitForTracingSetup();
2201 producer2->WaitForDataSourceSetup("data_source2.1");
2202 producer2->WaitForDataSourceSetup("data_source2.2");
2203 producer2->WaitForDataSourceSetup("data_source2.3");
2204
2205 producer1->WaitForDataSourceStart("data_source1");
2206 producer2->WaitForDataSourceStart("data_source2.1");
2207 producer2->WaitForDataSourceStart("data_source2.2");
2208 producer2->WaitForDataSourceStart("data_source2.3");
2209
2210 producer2->UnregisterDataSource("data_source2.3");
2211 producer2->WaitForDataSourceStop("data_source2.3");
2212
2213 // Should still be allowed to write to buffers 1 (data_source2.1) and 2
2214 // (data_source2.2).
2215 EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
2216
2217 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2218 // trace config didn't have the |deferred_start| flag set.
2219 consumer->StartTracing();
2220
2221 consumer->DisableTracing();
2222 producer1->WaitForDataSourceStop("data_source1");
2223 producer2->WaitForDataSourceStop("data_source2.1");
2224 producer2->WaitForDataSourceStop("data_source2.2");
2225 consumer->WaitForTracingDisabled();
2226
2227 consumer->FreeBuffers();
2228 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
2229 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
2230}
2231
Eric Seckler6aa9ece2018-12-06 16:40:12 +00002232#if !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00002233TEST_F(TracingServiceImplTest, CommitToForbiddenBufferIsDiscarded) {
2234 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2235 consumer->Connect(svc.get());
2236
2237 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2238 producer->Connect(svc.get(), "mock_producer");
2239 ProducerID producer_id = *last_producer_id();
2240 producer->RegisterDataSource("data_source");
2241
2242 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
2243
2244 TraceConfig trace_config;
2245 trace_config.add_buffers()->set_size_kb(128);
2246 trace_config.add_buffers()->set_size_kb(128);
2247 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2248 ds_config->set_name("data_source");
2249 ds_config->set_target_buffer(0);
2250 consumer->EnableTracing(trace_config);
2251
2252 ASSERT_EQ(2u, tracing_session()->num_buffers());
2253 std::set<BufferID> expected_buffers = {tracing_session()->buffers_index[0]};
2254 EXPECT_EQ(expected_buffers, GetAllowedTargetBuffers(producer_id));
2255
2256 producer->WaitForTracingSetup();
2257 producer->WaitForDataSourceSetup("data_source");
2258 producer->WaitForDataSourceStart("data_source");
2259
2260 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2261 // trace config didn't have the |deferred_start| flag set.
2262 consumer->StartTracing();
2263
2264 // Try to write to the correct buffer.
2265 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2266 tracing_session()->buffers_index[0]);
2267 {
2268 auto tp = writer->NewTracePacket();
2269 tp->set_for_testing()->set_str("good_payload");
2270 }
2271
2272 auto flush_request = consumer->Flush();
2273 producer->WaitForFlush(writer.get());
2274 ASSERT_TRUE(flush_request.WaitForReply());
2275
2276 // Try to write to the wrong buffer.
2277 writer = producer->endpoint()->CreateTraceWriter(
2278 tracing_session()->buffers_index[1]);
2279 {
2280 auto tp = writer->NewTracePacket();
2281 tp->set_for_testing()->set_str("bad_payload");
2282 }
2283
2284 flush_request = consumer->Flush();
2285 producer->WaitForFlush(writer.get());
2286 ASSERT_TRUE(flush_request.WaitForReply());
2287
2288 consumer->DisableTracing();
2289 producer->WaitForDataSourceStop("data_source");
2290 consumer->WaitForTracingDisabled();
2291
2292 auto packets = consumer->ReadBuffers();
2293 EXPECT_THAT(packets, Contains(Property(&protos::TracePacket::for_testing,
2294 Property(&protos::TestEvent::str,
2295 Eq("good_payload")))));
2296 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2297 Property(&protos::TestEvent::str,
2298 Eq("bad_payload"))))));
2299
2300 consumer->FreeBuffers();
2301 EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
2302}
Eric Seckler6aa9ece2018-12-06 16:40:12 +00002303#endif // !PERFETTO_DCHECK_IS_ON()
Eric Secklerdd0ad102018-12-06 11:32:04 +00002304
Eric Secklerf3f524b2018-12-13 09:09:34 +00002305TEST_F(TracingServiceImplTest, RegisterAndUnregisterTraceWriter) {
2306 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2307 consumer->Connect(svc.get());
2308
2309 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2310 producer->Connect(svc.get(), "mock_producer");
2311 ProducerID producer_id = *last_producer_id();
2312 producer->RegisterDataSource("data_source");
2313
2314 EXPECT_TRUE(GetWriters(producer_id).empty());
2315
2316 TraceConfig trace_config;
2317 trace_config.add_buffers()->set_size_kb(128);
2318 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2319 ds_config->set_name("data_source");
2320 ds_config->set_target_buffer(0);
2321 consumer->EnableTracing(trace_config);
2322
2323 producer->WaitForTracingSetup();
2324 producer->WaitForDataSourceSetup("data_source");
2325 producer->WaitForDataSourceStart("data_source");
2326
2327 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2328 // trace config didn't have the |deferred_start| flag set.
2329 consumer->StartTracing();
2330
2331 // Creating the trace writer should register it with the service.
2332 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2333 tracing_session()->buffers_index[0]);
2334
2335 WaitForTraceWritersChanged(producer_id);
2336
2337 std::map<WriterID, BufferID> expected_writers;
2338 expected_writers[writer->writer_id()] = tracing_session()->buffers_index[0];
2339 EXPECT_EQ(expected_writers, GetWriters(producer_id));
2340
2341 // Verify writing works.
2342 {
2343 auto tp = writer->NewTracePacket();
2344 tp->set_for_testing()->set_str("payload");
2345 }
2346
2347 auto flush_request = consumer->Flush();
2348 producer->WaitForFlush(writer.get());
2349 ASSERT_TRUE(flush_request.WaitForReply());
2350
2351 // Destroying the writer should unregister it.
2352 writer.reset();
2353 WaitForTraceWritersChanged(producer_id);
2354 EXPECT_TRUE(GetWriters(producer_id).empty());
2355
2356 consumer->DisableTracing();
2357 producer->WaitForDataSourceStop("data_source");
2358 consumer->WaitForTracingDisabled();
2359
2360 auto packets = consumer->ReadBuffers();
2361 EXPECT_THAT(packets, Contains(Property(
2362 &protos::TracePacket::for_testing,
2363 Property(&protos::TestEvent::str, Eq("payload")))));
2364}
2365
Eric Secklera01e28a2019-01-08 11:21:04 +00002366TEST_F(TracingServiceImplTest, ScrapeBuffersOnFlush) {
2367 svc->SetSMBScrapingEnabled(true);
2368
2369 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2370 consumer->Connect(svc.get());
2371
2372 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2373 producer->Connect(svc.get(), "mock_producer");
2374 ProducerID producer_id = *last_producer_id();
2375 producer->RegisterDataSource("data_source");
2376
2377 TraceConfig trace_config;
2378 trace_config.add_buffers()->set_size_kb(128);
2379 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2380 ds_config->set_name("data_source");
2381 ds_config->set_target_buffer(0);
2382 consumer->EnableTracing(trace_config);
2383
2384 producer->WaitForTracingSetup();
2385 producer->WaitForDataSourceSetup("data_source");
2386 producer->WaitForDataSourceStart("data_source");
2387
2388 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2389 // trace config didn't have the |deferred_start| flag set.
2390 consumer->StartTracing();
2391
2392 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2393 tracing_session()->buffers_index[0]);
2394 WaitForTraceWritersChanged(producer_id);
2395
2396 // Write a few trace packets.
2397 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2398 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2399 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2400
2401 // Flush but don't actually flush the chunk from TraceWriter.
2402 auto flush_request = consumer->Flush();
2403 producer->WaitForFlush(nullptr, /*reply=*/true);
2404 ASSERT_TRUE(flush_request.WaitForReply());
2405
2406 // Chunk with the packets should have been scraped. The service can't know
2407 // whether the last packet was completed, so shouldn't read it.
2408 auto packets = consumer->ReadBuffers();
2409 EXPECT_THAT(packets, Contains(Property(
2410 &protos::TracePacket::for_testing,
2411 Property(&protos::TestEvent::str, Eq("payload1")))));
2412 EXPECT_THAT(packets, Contains(Property(
2413 &protos::TracePacket::for_testing,
2414 Property(&protos::TestEvent::str, Eq("payload2")))));
2415 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2416 Property(&protos::TestEvent::str,
2417 Eq("payload3"))))));
2418
2419 // Write some more packets.
2420 writer->NewTracePacket()->set_for_testing()->set_str("payload4");
2421 writer->NewTracePacket()->set_for_testing()->set_str("payload5");
2422
2423 // Don't reply to flush, causing a timeout. This should scrape again.
2424 flush_request = consumer->Flush(/*timeout=*/100);
2425 producer->WaitForFlush(nullptr, /*reply=*/false);
2426 ASSERT_FALSE(flush_request.WaitForReply());
2427
2428 // Chunk with the packets should have been scraped again, overriding the
2429 // original one. Again, the last packet should be ignored and the first two
2430 // should not be read twice.
2431 packets = consumer->ReadBuffers();
2432 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2433 Property(&protos::TestEvent::str,
2434 Eq("payload1"))))));
2435 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2436 Property(&protos::TestEvent::str,
2437 Eq("payload2"))))));
2438 EXPECT_THAT(packets, Contains(Property(
2439 &protos::TracePacket::for_testing,
2440 Property(&protos::TestEvent::str, Eq("payload3")))));
2441 EXPECT_THAT(packets, Contains(Property(
2442 &protos::TracePacket::for_testing,
2443 Property(&protos::TestEvent::str, Eq("payload4")))));
2444 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2445 Property(&protos::TestEvent::str,
2446 Eq("payload5"))))));
2447
2448 consumer->DisableTracing();
2449 producer->WaitForDataSourceStop("data_source");
2450 consumer->WaitForTracingDisabled();
2451}
2452
Sami Kyostilaf5ad4642019-05-16 10:46:15 +01002453TEST_F(TracingServiceImplTest, ScrapeBuffersFromAnotherThread) {
2454 // This test verifies that there are no reported TSAN races while scraping
2455 // buffers from a producer which is actively writing more trace data
2456 // concurrently.
2457 svc->SetSMBScrapingEnabled(true);
2458
2459 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2460 consumer->Connect(svc.get());
2461
2462 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2463 producer->Connect(svc.get(), "mock_producer");
2464 ProducerID producer_id = *last_producer_id();
2465 producer->RegisterDataSource("data_source");
2466
2467 TraceConfig trace_config;
2468 trace_config.add_buffers()->set_size_kb(128);
2469 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2470 ds_config->set_name("data_source");
2471 ds_config->set_target_buffer(0);
2472 consumer->EnableTracing(trace_config);
2473
2474 producer->WaitForTracingSetup();
2475 producer->WaitForDataSourceSetup("data_source");
2476 producer->WaitForDataSourceStart("data_source");
2477 consumer->StartTracing();
2478
2479 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2480 tracing_session()->buffers_index[0]);
2481 WaitForTraceWritersChanged(producer_id);
2482
2483 constexpr int kPacketCount = 10;
2484 std::atomic<int> packets_written{};
2485 std::thread writer_thread([&] {
2486 for (int i = 0; i < kPacketCount; i++) {
2487 writer->NewTracePacket()->set_for_testing()->set_str("payload");
2488 packets_written.store(i, std::memory_order_relaxed);
2489 }
2490 });
2491
2492 // Wait until the thread has had some time to write some packets.
2493 while (packets_written.load(std::memory_order_relaxed) < kPacketCount / 2)
2494 base::SleepMicroseconds(5000);
2495
2496 // Disabling tracing will trigger scraping.
2497 consumer->DisableTracing();
2498 writer_thread.join();
2499
2500 // Because we don't synchronize with the producer thread, we can't make any
2501 // guarantees about the number of packets we will successfully read. We just
2502 // verify that no TSAN races are reported.
2503 consumer->ReadBuffers();
2504
2505 producer->WaitForDataSourceStop("data_source");
2506 consumer->WaitForTracingDisabled();
2507}
2508
Eric Secklera01e28a2019-01-08 11:21:04 +00002509// Test scraping on producer disconnect.
2510TEST_F(TracingServiceImplTest, ScrapeBuffersOnProducerDisconnect) {
2511 svc->SetSMBScrapingEnabled(true);
2512
2513 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2514 consumer->Connect(svc.get());
2515
2516 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2517 producer->Connect(svc.get(), "mock_producer");
2518 ProducerID producer_id = *last_producer_id();
2519 producer->RegisterDataSource("data_source");
2520
2521 TraceConfig trace_config;
2522 trace_config.add_buffers()->set_size_kb(128);
2523 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2524 ds_config->set_name("data_source");
2525 ds_config->set_target_buffer(0);
2526 consumer->EnableTracing(trace_config);
2527
2528 producer->WaitForTracingSetup();
2529 producer->WaitForDataSourceSetup("data_source");
2530 producer->WaitForDataSourceStart("data_source");
2531
2532 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2533 // trace config didn't have the |deferred_start| flag set.
2534 consumer->StartTracing();
2535
2536 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2537 tracing_session()->buffers_index[0]);
2538 WaitForTraceWritersChanged(producer_id);
2539
2540 // Write a few trace packets.
2541 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2542 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2543 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2544
2545 // Disconnect the producer without committing the chunk. This should cause a
2546 // scrape of the SMB. Avoid destroying the ShmemArbiter until writer is
2547 // destroyed.
2548 auto shmem_arbiter = TakeShmemArbiterForProducer(producer_id);
2549 producer.reset();
2550
2551 // Chunk with the packets should have been scraped. The service can't know
2552 // whether the last packet was completed, so shouldn't read it.
2553 auto packets = consumer->ReadBuffers();
2554 EXPECT_THAT(packets, Contains(Property(
2555 &protos::TracePacket::for_testing,
2556 Property(&protos::TestEvent::str, Eq("payload1")))));
2557 EXPECT_THAT(packets, Contains(Property(
2558 &protos::TracePacket::for_testing,
2559 Property(&protos::TestEvent::str, Eq("payload2")))));
2560 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2561 Property(&protos::TestEvent::str,
2562 Eq("payload3"))))));
2563
2564 // Cleanup writer without causing a crash because the producer already went
2565 // away.
2566 static_cast<TraceWriterImpl*>(writer.get())->ResetChunkForTesting();
2567 writer.reset();
2568 shmem_arbiter.reset();
2569
2570 consumer->DisableTracing();
2571 consumer->WaitForTracingDisabled();
2572}
2573
2574TEST_F(TracingServiceImplTest, ScrapeBuffersOnDisable) {
2575 svc->SetSMBScrapingEnabled(true);
2576
2577 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2578 consumer->Connect(svc.get());
2579
2580 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2581 producer->Connect(svc.get(), "mock_producer");
2582 ProducerID producer_id = *last_producer_id();
2583 producer->RegisterDataSource("data_source");
2584
2585 TraceConfig trace_config;
2586 trace_config.add_buffers()->set_size_kb(128);
2587 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2588 ds_config->set_name("data_source");
2589 ds_config->set_target_buffer(0);
2590 consumer->EnableTracing(trace_config);
2591
2592 producer->WaitForTracingSetup();
2593 producer->WaitForDataSourceSetup("data_source");
2594 producer->WaitForDataSourceStart("data_source");
2595
2596 // Calling StartTracing() should be a noop (% a DLOG statement) because the
2597 // trace config didn't have the |deferred_start| flag set.
2598 consumer->StartTracing();
2599
2600 std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
2601 tracing_session()->buffers_index[0]);
2602 WaitForTraceWritersChanged(producer_id);
2603
2604 // Write a few trace packets.
2605 writer->NewTracePacket()->set_for_testing()->set_str("payload1");
2606 writer->NewTracePacket()->set_for_testing()->set_str("payload2");
2607 writer->NewTracePacket()->set_for_testing()->set_str("payload3");
2608
2609 consumer->DisableTracing();
2610 producer->WaitForDataSourceStop("data_source");
2611 consumer->WaitForTracingDisabled();
2612
2613 // Chunk with the packets should have been scraped. The service can't know
2614 // whether the last packet was completed, so shouldn't read it.
2615 auto packets = consumer->ReadBuffers();
2616 EXPECT_THAT(packets, Contains(Property(
2617 &protos::TracePacket::for_testing,
2618 Property(&protos::TestEvent::str, Eq("payload1")))));
2619 EXPECT_THAT(packets, Contains(Property(
2620 &protos::TracePacket::for_testing,
2621 Property(&protos::TestEvent::str, Eq("payload2")))));
2622 EXPECT_THAT(packets, Not(Contains(Property(&protos::TracePacket::for_testing,
2623 Property(&protos::TestEvent::str,
2624 Eq("payload3"))))));
2625}
2626
Primiano Tucciff7beab2019-01-09 21:49:20 +00002627TEST_F(TracingServiceImplTest, AbortIfTraceDurationIsTooLong) {
2628 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2629 consumer->Connect(svc.get());
2630
2631 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2632 producer->Connect(svc.get(), "mock_producer");
2633 producer->RegisterDataSource("datasource");
2634
2635 TraceConfig trace_config;
2636 trace_config.add_buffers()->set_size_kb(128);
2637 trace_config.add_data_sources()->mutable_config()->set_name("datasource");
2638 trace_config.set_duration_ms(0x7fffffff);
2639
2640 EXPECT_CALL(*producer, SetupDataSource(_, _)).Times(0);
2641 consumer->EnableTracing(trace_config);
2642
2643 // The trace is aborted immediately, 5s here is just some slack for the thread
2644 // ping-pongs for slow devices.
2645 consumer->WaitForTracingDisabled(5000);
2646}
2647
Eric Secklereaf29ed2019-01-23 09:53:55 +00002648TEST_F(TracingServiceImplTest, GetTraceStats) {
2649 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2650 consumer->Connect(svc.get());
2651
2652 consumer->GetTraceStats();
2653 consumer->WaitForTraceStats(false);
2654
2655 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2656 producer->Connect(svc.get(), "mock_producer");
2657 producer->RegisterDataSource("data_source");
2658
2659 TraceConfig trace_config;
2660 trace_config.add_buffers()->set_size_kb(128);
2661 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2662 ds_config->set_name("data_source");
2663
2664 consumer->EnableTracing(trace_config);
2665 producer->WaitForTracingSetup();
2666 producer->WaitForDataSourceSetup("data_source");
2667 producer->WaitForDataSourceStart("data_source");
2668
2669 consumer->GetTraceStats();
2670 consumer->WaitForTraceStats(true);
2671
2672 consumer->DisableTracing();
2673 producer->WaitForDataSourceStop("data_source");
2674 consumer->WaitForTracingDisabled();
2675}
2676
Eric Seckler7b0c9452019-03-18 13:14:36 +00002677TEST_F(TracingServiceImplTest, ObserveEventsDataSourceInstances) {
2678 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2679 consumer->Connect(svc.get());
2680
2681 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2682 producer->Connect(svc.get(), "mock_producer");
2683 producer->RegisterDataSource("data_source");
2684
2685 TraceConfig trace_config;
2686 trace_config.add_buffers()->set_size_kb(128);
2687 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2688 ds_config->set_name("data_source");
2689
2690 // Start tracing before the consumer is interested in events. The consumer's
2691 // OnObservableEvents() should not be called yet.
2692 consumer->EnableTracing(trace_config);
2693 producer->WaitForTracingSetup();
2694 producer->WaitForDataSourceSetup("data_source");
2695 producer->WaitForDataSourceStart("data_source");
2696
2697 // Calling ObserveEvents should cause an event for the initial instance state.
2698 consumer->ObserveEvents(TracingService::ConsumerEndpoint::
2699 ObservableEventType::kDataSourceInstances);
2700 {
2701 auto events = consumer->WaitForObservableEvents();
2702
2703 ObservableEvents::DataSourceInstanceStateChange change;
2704 change.set_producer_name("mock_producer");
2705 change.set_data_source_name("data_source");
2706 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2707 DATA_SOURCE_INSTANCE_STATE_STARTED);
2708 EXPECT_EQ(events.instance_state_changes_size(), 1);
2709 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2710 }
2711
2712 // Disabling should cause an instance state change to STOPPED.
2713 consumer->DisableTracing();
2714
2715 {
2716 auto events = consumer->WaitForObservableEvents();
2717
2718 ObservableEvents::DataSourceInstanceStateChange change;
2719 change.set_producer_name("mock_producer");
2720 change.set_data_source_name("data_source");
2721 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2722 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2723 EXPECT_EQ(events.instance_state_changes_size(), 1);
2724 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2725 }
2726
2727 producer->WaitForDataSourceStop("data_source");
2728 consumer->WaitForTracingDisabled();
2729 consumer->FreeBuffers();
2730
2731 // Enable again, this should cause a state change for a new instance to
2732 // its initial state STOPPED.
2733 trace_config.set_deferred_start(true);
2734 consumer->EnableTracing(trace_config);
2735
2736 {
2737 auto events = consumer->WaitForObservableEvents();
2738
2739 ObservableEvents::DataSourceInstanceStateChange change;
2740 change.set_producer_name("mock_producer");
2741 change.set_data_source_name("data_source");
2742 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2743 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2744 EXPECT_EQ(events.instance_state_changes_size(), 1);
2745 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2746 }
2747
2748 producer->WaitForDataSourceSetup("data_source");
2749
2750 // Should move the instance into STARTED state and thus cause an event.
2751 consumer->StartTracing();
2752
2753 {
2754 auto events = consumer->WaitForObservableEvents();
2755
2756 ObservableEvents::DataSourceInstanceStateChange change;
2757 change.set_producer_name("mock_producer");
2758 change.set_data_source_name("data_source");
2759 change.set_state(ObservableEvents::DataSourceInstanceStateChange::
2760 DATA_SOURCE_INSTANCE_STATE_STARTED);
2761 EXPECT_EQ(events.instance_state_changes_size(), 1);
2762 EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
2763 }
2764
2765 producer->WaitForDataSourceStart("data_source");
2766
2767 // Stop observing events.
2768 consumer->ObserveEvents(
2769 TracingService::ConsumerEndpoint::ObservableEventType::kNone);
2770
2771 // Disabling should now no longer cause events to be sent to the consumer.
2772 consumer->DisableTracing();
2773 producer->WaitForDataSourceStop("data_source");
2774 consumer->WaitForTracingDisabled();
2775}
2776
Stephen Nusko6d4d5922019-08-06 15:38:25 +01002777TEST_F(TracingServiceImplTest, ObserveEventsDataSourceInstancesUnregister) {
2778 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2779 consumer->Connect(svc.get());
2780
2781 std::unique_ptr<MockProducer> producer = CreateMockProducer();
2782 producer->Connect(svc.get(), "mock_producer");
2783 producer->RegisterDataSource("data_source");
2784
2785 TraceConfig trace_config;
2786 trace_config.add_buffers()->set_size_kb(128);
2787 auto* ds_config = trace_config.add_data_sources()->mutable_config();
2788 ds_config->set_name("data_source");
2789
2790 // Start tracing before the consumer is interested in events. The consumer's
2791 // OnObservableEvents() should not be called yet.
2792 consumer->EnableTracing(trace_config);
2793 producer->WaitForTracingSetup();
2794 producer->WaitForDataSourceSetup("data_source");
2795 producer->WaitForDataSourceStart("data_source");
2796
2797 // Calling ObserveEvents should cause an event for the initial instance state.
2798 consumer->ObserveEvents(TracingService::ConsumerEndpoint::
2799 ObservableEventType::kDataSourceInstances);
2800 {
2801 ObservableEvents event;
2802 ObservableEvents::DataSourceInstanceStateChange* change =
2803 event.add_instance_state_changes();
2804 change->set_producer_name("mock_producer");
2805 change->set_data_source_name("data_source");
2806 change->set_state(ObservableEvents::DataSourceInstanceStateChange::
2807 DATA_SOURCE_INSTANCE_STATE_STARTED);
2808 EXPECT_CALL(*consumer, OnObservableEvents(Eq(event)))
2809 .WillOnce(InvokeWithoutArgs(
2810 task_runner.CreateCheckpoint("data_source_started")));
2811
2812 task_runner.RunUntilCheckpoint("data_source_started");
2813 }
2814 {
2815 ObservableEvents event;
2816 ObservableEvents::DataSourceInstanceStateChange* change =
2817 event.add_instance_state_changes();
2818 change->set_producer_name("mock_producer");
2819 change->set_data_source_name("data_source");
2820 change->set_state(ObservableEvents::DataSourceInstanceStateChange::
2821 DATA_SOURCE_INSTANCE_STATE_STOPPED);
2822 EXPECT_CALL(*consumer, OnObservableEvents(Eq(event)))
2823 .WillOnce(InvokeWithoutArgs(
2824 task_runner.CreateCheckpoint("data_source_stopped")));
2825 }
2826 producer->UnregisterDataSource("data_source");
2827 producer->WaitForDataSourceStop("data_source");
2828 task_runner.RunUntilCheckpoint("data_source_stopped");
2829
2830 consumer->DisableTracing();
2831 consumer->WaitForTracingDisabled();
2832}
2833
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002834TEST_F(TracingServiceImplTest, QueryServiceState) {
2835 std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2836 consumer->Connect(svc.get());
2837
2838 std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2839 producer1->Connect(svc.get(), "producer1");
2840
2841 std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2842 producer2->Connect(svc.get(), "producer2");
2843
2844 producer1->RegisterDataSource("common_ds");
2845 producer2->RegisterDataSource("common_ds");
2846
2847 producer1->RegisterDataSource("p1_ds");
2848 producer2->RegisterDataSource("p2_ds");
2849
2850 TracingServiceState svc_state = consumer->QueryServiceState();
2851
Eric Seckler4ffe6c22019-06-05 09:07:16 +01002852 EXPECT_EQ(svc_state.producers_size(), 2);
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002853 EXPECT_EQ(svc_state.producers().at(0).id(), 1);
2854 EXPECT_EQ(svc_state.producers().at(0).name(), "producer1");
2855 EXPECT_EQ(svc_state.producers().at(1).id(), 2);
2856 EXPECT_EQ(svc_state.producers().at(1).name(), "producer2");
2857
Eric Seckler4ffe6c22019-06-05 09:07:16 +01002858 EXPECT_EQ(svc_state.data_sources_size(), 4);
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002859
2860 EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 1);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002861 EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().name(), "common_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002862
2863 EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002864 EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().name(), "common_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002865
2866 EXPECT_EQ(svc_state.data_sources().at(2).producer_id(), 1);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002867 EXPECT_EQ(svc_state.data_sources().at(2).ds_descriptor().name(), "p1_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002868
2869 EXPECT_EQ(svc_state.data_sources().at(3).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002870 EXPECT_EQ(svc_state.data_sources().at(3).ds_descriptor().name(), "p2_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002871
2872 // Test that descriptors are cleared when a producer disconnects.
2873 producer1.reset();
2874 svc_state = consumer->QueryServiceState();
2875
Eric Seckler4ffe6c22019-06-05 09:07:16 +01002876 EXPECT_EQ(svc_state.producers_size(), 1);
2877 EXPECT_EQ(svc_state.data_sources_size(), 2);
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002878
2879 EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002880 EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().name(), "common_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002881 EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
Lalit Magantidcc359d2019-06-17 16:28:40 +01002882 EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().name(), "p2_ds");
Primiano Tucci2854a0a2019-06-03 14:51:18 +01002883}
2884
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00002885} // namespace perfetto