blob: 85e6829ce7f2d9dbbba37e3dec04fbe6b0f04574 [file] [log] [blame]
Lalit Magantic4c3ceb2018-03-29 20:38:13 +01001/*
2 * Copyright (C) 2018 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
17#include "test/test_helper.h"
Chinglin Yue1efd722023-06-08 13:48:47 +000018#include <string>
Lalit Magantic4c3ceb2018-03-29 20:38:13 +010019
Florian Mayer67b26852021-02-04 19:13:01 +000020#include "perfetto/base/compiler.h"
Chinglin Yue1efd722023-06-08 13:48:47 +000021#include "perfetto/ext/base/string_utils.h"
Primiano Tucci2c5488f2019-06-01 03:27:28 +010022#include "perfetto/ext/tracing/core/trace_packet.h"
Primiano Tucci9c41ceb2020-04-14 13:23:01 +010023#include "perfetto/tracing/core/tracing_service_state.h"
Mikhail Khokhlovec273802023-11-29 12:24:02 +000024#include "perfetto/tracing/default_socket.h"
Florian Mayerc29e0d32018-04-04 15:55:46 +010025
Primiano Tucci355b8c82019-08-29 08:37:51 +020026#include "protos/perfetto/trace/trace_packet.pbzero.h"
Primiano Tucci07e104d2018-04-03 20:45:35 +020027
Lalit Magantic4c3ceb2018-03-29 20:38:13 +010028namespace perfetto {
29
Florian Mayer67b26852021-02-04 19:13:01 +000030namespace {
31const char* ProducerSocketForMode(TestHelper::Mode mode) {
32#if !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
33 base::ignore_result(mode);
34 return ::perfetto::GetProducerSocket();
Lalit Magantic4c3ceb2018-03-29 20:38:13 +010035#else
Florian Mayer67b26852021-02-04 19:13:01 +000036 switch (mode) {
37 case TestHelper::Mode::kStartDaemons:
38 return "/data/local/tmp/traced_producer";
39 case TestHelper::Mode::kUseSystemService:
40 return ::perfetto::GetProducerSocket();
41 }
42#endif
43}
44
45const char* ConsumerSocketForMode(TestHelper::Mode mode) {
46#if !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
47 base::ignore_result(mode);
48 return ::perfetto::GetConsumerSocket();
49#else
50 switch (mode) {
51 case TestHelper::Mode::kStartDaemons:
52 return "/data/local/tmp/traced_consumer";
53 case TestHelper::Mode::kUseSystemService:
54 return ::perfetto::GetConsumerSocket();
55 }
56#endif
57}
58} // namespace
59
60uint64_t TestHelper::next_instance_num_ = 0;
61#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
62TestHelper::Mode TestHelper::kDefaultMode = Mode::kStartDaemons;
63#else
64TestHelper::Mode TestHelper::kDefaultMode = Mode::kUseSystemService;
Lalit Magantic4c3ceb2018-03-29 20:38:13 +010065#endif
66
Florian Mayer67b26852021-02-04 19:13:01 +000067TestHelper::TestHelper(base::TestTaskRunner* task_runner, Mode mode)
Chinglin Yue1efd722023-06-08 13:48:47 +000068 : TestHelper(task_runner, mode, ProducerSocketForMode(mode)) {}
69
70TestHelper::TestHelper(base::TestTaskRunner* task_runner,
71 Mode mode,
Chinglin Yu76788d22024-02-21 15:49:43 +080072 const char* producer_socket,
73 bool enable_relay_endpoint)
Florian Mayer05a87c92019-01-30 13:17:51 +000074 : instance_num_(next_instance_num_++),
75 task_runner_(task_runner),
Florian Mayer67b26852021-02-04 19:13:01 +000076 mode_(mode),
Chinglin Yue1efd722023-06-08 13:48:47 +000077 producer_socket_(producer_socket),
Florian Mayer67b26852021-02-04 19:13:01 +000078 consumer_socket_(ConsumerSocketForMode(mode)),
Chinglin Yu76788d22024-02-21 15:49:43 +080079 service_thread_(producer_socket_,
80 consumer_socket_,
81 enable_relay_endpoint) {
Chinglin Yue1efd722023-06-08 13:48:47 +000082 auto producer_sockets = TokenizeProducerSockets(producer_socket_);
83 static constexpr const char* kDefaultFakeProducerName =
84 "android.perfetto.FakeProducer";
85 for (size_t i = 0; i < producer_sockets.size(); i++) {
86 auto cp_connect = "producer." + std::to_string(i) + ".connect";
87 auto cp_setup = "producer." + std::to_string(i) + ".setup";
88 auto cp_enabled = "producer." + std::to_string(i) + ".enabled";
89 std::string producer_name =
90 (!!i) ? +kDefaultFakeProducerName + std::string(".") + std::to_string(i)
91 : kDefaultFakeProducerName;
92 fake_producer_threads_.emplace_back(std::make_unique<FakeProducerThread>(
93 producer_sockets[i], WrapTask(CreateCheckpoint(cp_connect)),
94 WrapTask(CreateCheckpoint(cp_setup)),
95 WrapTask(CreateCheckpoint(cp_enabled)), producer_name));
96 }
97}
Lalit Magantic4c3ceb2018-03-29 20:38:13 +010098
99void TestHelper::OnConnect() {
Primiano Tucci72d2a3f2023-11-03 18:51:12 +0000100 endpoint_->ObserveEvents(ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
Lalit Maganti36557d82018-04-11 14:36:17 +0100101 std::move(on_connect_callback_)();
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100102}
103
104void TestHelper::OnDisconnect() {
Primiano Tucci008cdb92019-07-19 19:52:41 +0100105 PERFETTO_FATAL("Consumer unexpectedly disconnected from the service");
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100106}
107
Primiano Tuccidf440312020-10-30 16:43:58 +0100108void TestHelper::OnTracingDisabled(const std::string& /*error*/) {
Lalit Maganti36557d82018-04-11 14:36:17 +0100109 std::move(on_stop_tracing_callback_)();
Stephen Nusko1af720e2020-11-18 14:04:16 -0500110 on_stop_tracing_callback_ = nullptr;
Lalit Maganti36557d82018-04-11 14:36:17 +0100111}
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100112
Florian Mayer709de7f2021-01-28 21:41:14 +0000113void TestHelper::ReadTraceData(std::vector<TracePacket> packets) {
Primiano Tucci07e104d2018-04-03 20:45:35 +0200114 for (auto& encoded_packet : packets) {
Primiano Tuccife502c42019-12-11 01:00:27 +0000115 protos::gen::TracePacket packet;
Primiano Tuccif7851ee2019-09-09 06:20:30 -0700116 PERFETTO_CHECK(
117 packet.ParseFromString(encoded_packet.GetRawBytesForTesting()));
Florian Mayer51016d32020-09-17 11:34:44 +0100118 full_trace_.push_back(packet);
Primiano Tucci7c327c22022-11-23 12:24:49 +0000119 if (packet.has_clock_snapshot() || packet.has_trace_uuid() ||
120 packet.has_trace_config() || packet.has_trace_stats() ||
121 !packet.synchronization_marker().empty() || packet.has_system_info() ||
122 packet.has_service_event()) {
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100123 continue;
Primiano Tucci5e33cad2018-04-30 14:41:25 +0100124 }
Primiano Tuccife502c42019-12-11 01:00:27 +0000125 PERFETTO_CHECK(packet.has_trusted_uid());
Lalit Maganti36557d82018-04-11 14:36:17 +0100126 trace_.push_back(std::move(packet));
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100127 }
Florian Mayer709de7f2021-01-28 21:41:14 +0000128}
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100129
Florian Mayer709de7f2021-01-28 21:41:14 +0000130void TestHelper::OnTraceData(std::vector<TracePacket> packets, bool has_more) {
131 ReadTraceData(std::move(packets));
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100132 if (!has_more) {
Lalit Maganti36557d82018-04-11 14:36:17 +0100133 std::move(on_packets_finished_callback_)();
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100134 }
135}
136
137void TestHelper::StartServiceIfRequired() {
Florian Mayer67b26852021-02-04 19:13:01 +0000138 if (mode_ == Mode::kStartDaemons)
Daniele Di Proietto65c6a282022-09-22 14:54:26 +0100139 env_cleaner_ = service_thread_.Start();
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100140}
141
Daniele Di Proiettoa92d6582023-01-31 18:40:42 +0000142void TestHelper::RestartService() {
143 PERFETTO_CHECK(mode_ == Mode::kStartDaemons);
144 service_thread_.Stop();
145 service_thread_.Start();
146}
147
Chinglin Yue1efd722023-06-08 13:48:47 +0000148FakeProducer* TestHelper::ConnectFakeProducer(size_t idx) {
149 fake_producer_threads_[idx]->Connect();
Primiano Tuccibbe68be2020-04-16 22:17:12 +0100150 // This will wait until the service has seen the RegisterDataSource() call
151 // (because of the Sync() in FakeProducer::OnConnect()).
Chinglin Yue1efd722023-06-08 13:48:47 +0000152 RunUntilCheckpoint("producer." + std::to_string(idx) + ".connect");
153 return fake_producer_threads_[idx]->producer();
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100154}
155
156void TestHelper::ConnectConsumer() {
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100157 cur_consumer_num_++;
Florian Mayer05a87c92019-01-30 13:17:51 +0000158 on_connect_callback_ = CreateCheckpoint("consumer.connected." +
159 std::to_string(cur_consumer_num_));
Florian Mayer67b26852021-02-04 19:13:01 +0000160 endpoint_ = ConsumerIPCClient::Connect(consumer_socket_, this, task_runner_);
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100161}
162
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100163void TestHelper::DetachConsumer(const std::string& key) {
Florian Mayer05a87c92019-01-30 13:17:51 +0000164 on_detach_callback_ = CreateCheckpoint("detach." + key);
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100165 endpoint_->Detach(key);
Florian Mayer05a87c92019-01-30 13:17:51 +0000166 RunUntilCheckpoint("detach." + key);
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100167 endpoint_.reset();
168}
169
170bool TestHelper::AttachConsumer(const std::string& key) {
171 bool success = false;
Florian Mayer05a87c92019-01-30 13:17:51 +0000172 auto checkpoint = CreateCheckpoint("attach." + key);
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100173 on_attach_callback_ = [&success, checkpoint](bool s) {
174 success = s;
175 checkpoint();
176 };
177 endpoint_->Attach(key);
Florian Mayer05a87c92019-01-30 13:17:51 +0000178 RunUntilCheckpoint("attach." + key);
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100179 return success;
180}
181
Eric Seckler326a3d32020-02-04 11:24:56 +0000182void TestHelper::CreateProducerProvidedSmb() {
Chinglin Yue1efd722023-06-08 13:48:47 +0000183 for (auto& thread : fake_producer_threads_)
184 thread->CreateProducerProvidedSmb();
Eric Seckler326a3d32020-02-04 11:24:56 +0000185}
186
Chinglin Yue1efd722023-06-08 13:48:47 +0000187bool TestHelper::IsShmemProvidedByProducer(size_t i) {
188 return fake_producer_threads_[i]->producer()->IsShmemProvidedByProducer();
Eric Seckler326a3d32020-02-04 11:24:56 +0000189}
190
Eric Seckler526921b2020-02-18 11:44:30 +0000191void TestHelper::ProduceStartupEventBatch(
192 const protos::gen::TestConfig& config) {
Chinglin Yue1efd722023-06-08 13:48:47 +0000193 for (size_t i = 0; i < fake_producer_threads_.size(); i++) {
194 auto checkpoint_name =
195 base::StackString<32>("startup_data_written.%zu", i).ToStdString();
196 auto on_data_written = CreateCheckpoint(checkpoint_name);
197 fake_producer_threads_[i]->ProduceStartupEventBatch(
198 config, WrapTask(on_data_written));
199 RunUntilCheckpoint(checkpoint_name);
200 }
Eric Seckler526921b2020-02-18 11:44:30 +0000201}
202
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100203void TestHelper::StartTracing(const TraceConfig& config,
204 base::ScopedFile file) {
Stephen Nusko1af720e2020-11-18 14:04:16 -0500205 PERFETTO_CHECK(!on_stop_tracing_callback_);
Florian Mayer05a87c92019-01-30 13:17:51 +0000206 trace_.clear();
Stephen Nusko1af720e2020-11-18 14:04:16 -0500207 on_stop_tracing_callback_ =
208 CreateCheckpoint("stop.tracing" + std::to_string(++trace_count_));
Primiano Tucci72d2a3f2023-11-03 18:51:12 +0000209 on_all_ds_started_callback_ = CreateCheckpoint("all.datasources.started" +
210 std::to_string(trace_count_));
211
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100212 endpoint_->EnableTracing(config, std::move(file));
Lalit Maganti36557d82018-04-11 14:36:17 +0100213}
214
Primiano Tuccic1855302018-12-06 10:36:55 +0000215void TestHelper::DisableTracing() {
216 endpoint_->DisableTracing();
217}
218
Primiano Tucci7dc76e12023-08-22 16:57:25 +0200219void TestHelper::FlushAndWait(uint32_t timeout_ms, FlushFlags flush_flags) {
Primiano Tuccic1855302018-12-06 10:36:55 +0000220 static int flush_num = 0;
221 std::string checkpoint_name = "flush." + std::to_string(flush_num++);
Florian Mayer05a87c92019-01-30 13:17:51 +0000222 auto checkpoint = CreateCheckpoint(checkpoint_name);
Primiano Tucci7dc76e12023-08-22 16:57:25 +0200223 endpoint_->Flush(
224 timeout_ms, [checkpoint](bool) { checkpoint(); }, flush_flags);
Florian Mayer05a87c92019-01-30 13:17:51 +0000225 RunUntilCheckpoint(checkpoint_name, timeout_ms + 1000);
Primiano Tuccic1855302018-12-06 10:36:55 +0000226}
227
Lalit Maganti3f0b7c62018-04-18 19:10:09 +0100228void TestHelper::ReadData(uint32_t read_count) {
Florian Mayer05a87c92019-01-30 13:17:51 +0000229 on_packets_finished_callback_ =
230 CreateCheckpoint("readback.complete." + std::to_string(read_count));
Lalit Maganti36557d82018-04-11 14:36:17 +0100231 endpoint_->ReadBuffers();
232}
233
Stephen Nusko1af720e2020-11-18 14:04:16 -0500234void TestHelper::FreeBuffers() {
235 endpoint_->FreeBuffers();
236}
237
Lalit Maganti36557d82018-04-11 14:36:17 +0100238void TestHelper::WaitForConsumerConnect() {
Florian Mayer05a87c92019-01-30 13:17:51 +0000239 RunUntilCheckpoint("consumer.connected." + std::to_string(cur_consumer_num_));
Lalit Maganti36557d82018-04-11 14:36:17 +0100240}
241
Chinglin Yue1efd722023-06-08 13:48:47 +0000242void TestHelper::WaitForProducerSetup(size_t idx) {
243 RunUntilCheckpoint("producer." + std::to_string(idx) + ".setup");
Stephen Nuskoe8238112019-04-09 18:37:00 +0100244}
245
Chinglin Yue1efd722023-06-08 13:48:47 +0000246void TestHelper::WaitForProducerEnabled(size_t idx) {
247 RunUntilCheckpoint("producer." + std::to_string(idx) + ".enabled");
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100248}
249
Primiano Tuccic1855302018-12-06 10:36:55 +0000250void TestHelper::WaitForTracingDisabled(uint32_t timeout_ms) {
Primiano Tucci72d2a3f2023-11-03 18:51:12 +0000251 RunUntilCheckpoint("stop.tracing" + std::to_string(trace_count_), timeout_ms);
252}
253
254void TestHelper::WaitForAllDataSourceStarted(uint32_t timeout_ms) {
255 RunUntilCheckpoint("all.datasources.started" + std::to_string(trace_count_),
Stephen Nusko1af720e2020-11-18 14:04:16 -0500256 timeout_ms);
Lalit Maganti36557d82018-04-11 14:36:17 +0100257}
258
Florian Mayer3e6e4b42019-06-05 10:17:36 +0100259void TestHelper::WaitForReadData(uint32_t read_count, uint32_t timeout_ms) {
260 RunUntilCheckpoint("readback.complete." + std::to_string(read_count),
261 timeout_ms);
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100262}
263
Primiano Tuccif26cb9c2022-01-18 23:19:36 +0000264void TestHelper::WaitFor(std::function<bool()> predicate,
265 const std::string& error_msg,
266 uint32_t timeout_ms) {
267 int64_t deadline_ms = base::GetWallTimeMs().count() + timeout_ms;
268 while (base::GetWallTimeMs().count() < deadline_ms) {
269 if (predicate())
270 return;
271 base::SleepMicroseconds(500 * 1000); // 0.5 s.
272 }
273 PERFETTO_FATAL("Test timed out waiting for: %s", error_msg.c_str());
274}
275
276void TestHelper::WaitForDataSourceConnected(const std::string& ds_name) {
277 auto predicate = [&] {
278 auto dss = QueryServiceStateAndWait().data_sources();
279 return std::any_of(dss.begin(), dss.end(),
280 [&](const TracingServiceState::DataSource& ds) {
281 return ds.ds_descriptor().name() == ds_name;
282 });
283 };
284 WaitFor(predicate, "connection of data source " + ds_name);
285}
286
Chinglin Yue1efd722023-06-08 13:48:47 +0000287void TestHelper::SyncAndWaitProducer(size_t idx) {
Primiano Tuccibbe68be2020-04-16 22:17:12 +0100288 static int sync_id = 0;
Chinglin Yue1efd722023-06-08 13:48:47 +0000289 std::string checkpoint_name =
290 "producer_sync_" + std::to_string(idx) + "_" + std::to_string(++sync_id);
Primiano Tuccibbe68be2020-04-16 22:17:12 +0100291 auto checkpoint = CreateCheckpoint(checkpoint_name);
Chinglin Yue1efd722023-06-08 13:48:47 +0000292 fake_producer_threads_[idx]->producer()->Sync(
Primiano Tuccibbe68be2020-04-16 22:17:12 +0100293 [this, &checkpoint] { task_runner_->PostTask(checkpoint); });
294 RunUntilCheckpoint(checkpoint_name);
295}
296
Primiano Tucci9c41ceb2020-04-14 13:23:01 +0100297TracingServiceState TestHelper::QueryServiceStateAndWait() {
298 TracingServiceState res;
Primiano Tuccif26cb9c2022-01-18 23:19:36 +0000299 static int n = 0;
300 std::string checkpoint_name = "query_svc_state_" + std::to_string(n++);
301 auto checkpoint = CreateCheckpoint(checkpoint_name);
Primiano Tucci9c41ceb2020-04-14 13:23:01 +0100302 auto callback = [&checkpoint, &res](bool, const TracingServiceState& tss) {
303 res = tss;
304 checkpoint();
305 };
Primiano Tucci13628322024-01-26 12:59:04 -0800306 endpoint_->QueryServiceState({}, callback);
Primiano Tuccif26cb9c2022-01-18 23:19:36 +0000307 RunUntilCheckpoint(checkpoint_name);
Primiano Tucci9c41ceb2020-04-14 13:23:01 +0100308 return res;
309}
310
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100311std::function<void()> TestHelper::WrapTask(
312 const std::function<void()>& function) {
313 return [this, function] { task_runner_->PostTask(function); };
314}
315
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100316void TestHelper::OnDetach(bool) {
317 if (on_detach_callback_)
318 std::move(on_detach_callback_)();
319}
320
321void TestHelper::OnAttach(bool success, const TraceConfig&) {
322 if (on_attach_callback_)
323 std::move(on_attach_callback_)(success);
324}
325
Eric Secklereaf29ed2019-01-23 09:53:55 +0000326void TestHelper::OnTraceStats(bool, const TraceStats&) {}
327
Primiano Tucci72d2a3f2023-11-03 18:51:12 +0000328void TestHelper::OnObservableEvents(const ObservableEvents& events) {
329 if (events.all_data_sources_started())
330 std::move(on_all_ds_started_callback_)();
331}
Eric Seckler7b0c9452019-03-18 13:14:36 +0000332
Primiano Tuccia7a5cb92023-04-27 19:17:31 +0100333void TestHelper::OnSessionCloned(const OnSessionClonedArgs&) {}
Primiano Tucci3f6a1332022-12-05 11:23:41 +0000334
Primiano Tucci106605c2019-01-08 21:12:58 +0000335// static
Florian Mayer67b26852021-02-04 19:13:01 +0000336const char* TestHelper::GetDefaultModeConsumerSocketName() {
337 return ConsumerSocketForMode(TestHelper::kDefaultMode);
Primiano Tucci106605c2019-01-08 21:12:58 +0000338}
339
Stephen Nuskoe8238112019-04-09 18:37:00 +0100340// static
Florian Mayer67b26852021-02-04 19:13:01 +0000341const char* TestHelper::GetDefaultModeProducerSocketName() {
342 return ProducerSocketForMode(TestHelper::kDefaultMode);
Stephen Nuskoe8238112019-04-09 18:37:00 +0100343}
344
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100345} // namespace perfetto