blob: d9a99b95f31454eb65244bbf8c8d0cdb1d246dd0 [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#ifndef TEST_TEST_HELPER_H_
18#define TEST_TEST_HELPER_H_
19
Primiano Tucci10c9e9e2021-01-08 13:04:40 +010020#include <stdio.h>
21#include <stdlib.h>
22
23#include "perfetto/ext/base/optional.h"
Primiano Tucci2c5488f2019-06-01 03:27:28 +010024#include "perfetto/ext/base/scoped_file.h"
Lalit Maganti9782f492020-01-10 18:13:13 +000025#include "perfetto/ext/base/thread_task_runner.h"
Primiano Tucci10c9e9e2021-01-08 13:04:40 +010026#include "perfetto/ext/base/utils.h"
Primiano Tucci2c5488f2019-06-01 03:27:28 +010027#include "perfetto/ext/tracing/core/consumer.h"
Eric Seckler526921b2020-02-18 11:44:30 +000028#include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
Primiano Tucci2c5488f2019-06-01 03:27:28 +010029#include "perfetto/ext/tracing/core/trace_packet.h"
30#include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
Lalit Maganti9782f492020-01-10 18:13:13 +000031#include "perfetto/ext/tracing/ipc/service_ipc_host.h"
Primiano Tucci0f9e0222019-06-05 09:36:41 +010032#include "perfetto/tracing/core/trace_config.h"
Lalit Magantic4c3ceb2018-03-29 20:38:13 +010033#include "src/base/test/test_task_runner.h"
Primiano Tucci10c9e9e2021-01-08 13:04:40 +010034#include "test/fake_producer.h"
35
36#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
Primiano Tucci5f3008e2021-05-19 21:34:45 +010037#include "src/tracing/ipc/shared_memory_windows.h"
Primiano Tucci10c9e9e2021-01-08 13:04:40 +010038#else
Lalit Maganti9782f492020-01-10 18:13:13 +000039#include "src/traced/probes/probes_producer.h"
Eric Seckler326a3d32020-02-04 11:24:56 +000040#include "src/tracing/ipc/posix_shared_memory.h"
Primiano Tucci10c9e9e2021-01-08 13:04:40 +010041#endif
Lalit Magantic4c3ceb2018-03-29 20:38:13 +010042
Primiano Tuccife502c42019-12-11 01:00:27 +000043#include "protos/perfetto/trace/trace_packet.gen.h"
Primiano Tucci07e104d2018-04-03 20:45:35 +020044
Lalit Magantic4c3ceb2018-03-29 20:38:13 +010045namespace perfetto {
46
Primiano Tucci5d6f1b52020-10-27 10:29:21 +010047// This value has been bumped to 10s in Oct 2020 because the x86 cuttlefish
48// emulator is sensibly slower (up to 10x) than real hw and caused flakes.
49// See bugs duped against b/171771440.
50constexpr uint32_t kDefaultTestTimeoutMs = 10000;
51
Lalit Maganti9782f492020-01-10 18:13:13 +000052// This is used only in daemon starting integrations tests.
53class ServiceThread {
54 public:
55 ServiceThread(const std::string& producer_socket,
56 const std::string& consumer_socket)
57 : producer_socket_(producer_socket), consumer_socket_(consumer_socket) {}
58
59 ~ServiceThread() {
60 if (!runner_)
61 return;
62 runner_->PostTaskAndWaitForTesting([this]() { svc_.reset(); });
63 }
64
65 void Start() {
66 runner_ = base::ThreadTaskRunner::CreateAndStart("perfetto.svc");
67 runner_->PostTaskAndWaitForTesting([this]() {
68 svc_ = ServiceIPCHost::CreateInstance(runner_->get());
Florian Mayer67b26852021-02-04 19:13:01 +000069 if (remove(producer_socket_.c_str()) == -1) {
70 if (errno != ENOENT)
71 PERFETTO_FATAL("Failed to remove %s", producer_socket_.c_str());
72 }
73 if (remove(consumer_socket_.c_str()) == -1) {
74 if (errno != ENOENT)
75 PERFETTO_FATAL("Failed to remove %s", consumer_socket_.c_str());
76 }
Primiano Tucci10c9e9e2021-01-08 13:04:40 +010077 base::SetEnv("PERFETTO_PRODUCER_SOCK_NAME", producer_socket_);
78 base::SetEnv("PERFETTO_CONSUMER_SOCK_NAME", consumer_socket_);
Lalit Maganti9782f492020-01-10 18:13:13 +000079 bool res =
80 svc_->Start(producer_socket_.c_str(), consumer_socket_.c_str());
Florian Mayer67b26852021-02-04 19:13:01 +000081 if (!res) {
82 PERFETTO_FATAL("Failed to start service listening on %s and %s",
83 producer_socket_.c_str(), consumer_socket_.c_str());
84 }
Lalit Maganti9782f492020-01-10 18:13:13 +000085 });
86 }
87
88 base::ThreadTaskRunner* runner() { return runner_ ? &*runner_ : nullptr; }
89
90 private:
91 base::Optional<base::ThreadTaskRunner> runner_; // Keep first.
92
93 std::string producer_socket_;
94 std::string consumer_socket_;
95 std::unique_ptr<ServiceIPCHost> svc_;
96};
97
98// This is used only in daemon starting integrations tests.
Primiano Tucci10c9e9e2021-01-08 13:04:40 +010099#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
100// On Windows we don't have any traced_probes, make this a no-op to avoid
101// propagating #ifdefs to the outer test.
102class ProbesProducerThread {
103 public:
104 ProbesProducerThread(const std::string& /*producer_socket*/) {}
105 void Connect() {}
106};
107#else
Lalit Maganti9782f492020-01-10 18:13:13 +0000108class ProbesProducerThread {
109 public:
110 ProbesProducerThread(const std::string& producer_socket)
111 : producer_socket_(producer_socket) {}
112
113 ~ProbesProducerThread() {
114 if (!runner_)
115 return;
116 runner_->PostTaskAndWaitForTesting([this]() { producer_.reset(); });
117 }
118
119 void Connect() {
120 runner_ = base::ThreadTaskRunner::CreateAndStart("perfetto.prd.probes");
121 runner_->PostTaskAndWaitForTesting([this]() {
122 producer_.reset(new ProbesProducer());
123 producer_->ConnectWithRetries(producer_socket_.c_str(), runner_->get());
124 });
125 }
126
127 private:
128 base::Optional<base::ThreadTaskRunner> runner_; // Keep first.
129
130 std::string producer_socket_;
131 std::unique_ptr<ProbesProducer> producer_;
132};
Primiano Tucci10c9e9e2021-01-08 13:04:40 +0100133#endif // !OS_WIN
Lalit Maganti9782f492020-01-10 18:13:13 +0000134
135class FakeProducerThread {
136 public:
137 FakeProducerThread(const std::string& producer_socket,
Primiano Tuccibbe68be2020-04-16 22:17:12 +0100138 std::function<void()> connect_callback,
Lalit Maganti9782f492020-01-10 18:13:13 +0000139 std::function<void()> setup_callback,
Eric Seckler326a3d32020-02-04 11:24:56 +0000140 std::function<void()> start_callback)
Lalit Maganti9782f492020-01-10 18:13:13 +0000141 : producer_socket_(producer_socket),
Primiano Tuccibbe68be2020-04-16 22:17:12 +0100142 connect_callback_(std::move(connect_callback)),
Lalit Maganti9782f492020-01-10 18:13:13 +0000143 setup_callback_(std::move(setup_callback)),
Eric Seckler526921b2020-02-18 11:44:30 +0000144 start_callback_(std::move(start_callback)) {
145 runner_ = base::ThreadTaskRunner::CreateAndStart("perfetto.prd.fake");
146 runner_->PostTaskAndWaitForTesting([this]() {
147 producer_.reset(
148 new FakeProducer("android.perfetto.FakeProducer", runner_->get()));
149 });
150 }
Lalit Maganti9782f492020-01-10 18:13:13 +0000151
152 ~FakeProducerThread() {
Lalit Maganti9782f492020-01-10 18:13:13 +0000153 runner_->PostTaskAndWaitForTesting([this]() { producer_.reset(); });
154 }
155
156 void Connect() {
Lalit Maganti9782f492020-01-10 18:13:13 +0000157 runner_->PostTaskAndWaitForTesting([this]() {
Primiano Tuccibbe68be2020-04-16 22:17:12 +0100158 producer_->Connect(producer_socket_.c_str(), std::move(connect_callback_),
159 std::move(setup_callback_), std::move(start_callback_),
160 std::move(shm_), std::move(shm_arbiter_));
Lalit Maganti9782f492020-01-10 18:13:13 +0000161 });
162 }
163
164 base::ThreadTaskRunner* runner() { return runner_ ? &*runner_ : nullptr; }
165
166 FakeProducer* producer() { return producer_.get(); }
167
Eric Seckler326a3d32020-02-04 11:24:56 +0000168 void CreateProducerProvidedSmb() {
Primiano Tucci10c9e9e2021-01-08 13:04:40 +0100169#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
Primiano Tucci5f3008e2021-05-19 21:34:45 +0100170 SharedMemoryWindows::Factory factory;
Primiano Tucci10c9e9e2021-01-08 13:04:40 +0100171#else
Eric Seckler326a3d32020-02-04 11:24:56 +0000172 PosixSharedMemory::Factory factory;
Primiano Tucci5f3008e2021-05-19 21:34:45 +0100173#endif
Eric Seckler326a3d32020-02-04 11:24:56 +0000174 shm_ = factory.CreateSharedMemory(1024 * 1024);
Primiano Tucci90d69302020-08-20 17:22:12 +0200175 shm_arbiter_ = SharedMemoryArbiter::CreateUnboundInstance(shm_.get(), 4096);
Eric Seckler526921b2020-02-18 11:44:30 +0000176 }
177
178 void ProduceStartupEventBatch(const protos::gen::TestConfig& config,
179 std::function<void()> callback) {
180 PERFETTO_CHECK(shm_arbiter_);
181 producer_->ProduceStartupEventBatch(config, shm_arbiter_.get(), callback);
Eric Seckler326a3d32020-02-04 11:24:56 +0000182 }
183
Lalit Maganti9782f492020-01-10 18:13:13 +0000184 private:
185 base::Optional<base::ThreadTaskRunner> runner_; // Keep first.
186
187 std::string producer_socket_;
188 std::unique_ptr<FakeProducer> producer_;
Primiano Tuccibbe68be2020-04-16 22:17:12 +0100189 std::function<void()> connect_callback_;
Lalit Maganti9782f492020-01-10 18:13:13 +0000190 std::function<void()> setup_callback_;
Eric Seckler326a3d32020-02-04 11:24:56 +0000191 std::function<void()> start_callback_;
192 std::unique_ptr<SharedMemory> shm_;
Eric Seckler526921b2020-02-18 11:44:30 +0000193 std::unique_ptr<SharedMemoryArbiter> shm_arbiter_;
Lalit Maganti9782f492020-01-10 18:13:13 +0000194};
195
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100196class TestHelper : public Consumer {
197 public:
Florian Mayer67b26852021-02-04 19:13:01 +0000198 enum class Mode {
199 kStartDaemons,
200 kUseSystemService,
201 };
202 static Mode kDefaultMode;
Primiano Tucci106605c2019-01-08 21:12:58 +0000203
Florian Mayer67b26852021-02-04 19:13:01 +0000204 static const char* GetDefaultModeConsumerSocketName();
205 static const char* GetDefaultModeProducerSocketName();
206
207 explicit TestHelper(base::TestTaskRunner* task_runner)
208 : TestHelper(task_runner, kDefaultMode) {}
209
210 explicit TestHelper(base::TestTaskRunner* task_runner, Mode mode);
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100211
212 // Consumer implementation.
213 void OnConnect() override;
214 void OnDisconnect() override;
Primiano Tuccidf440312020-10-30 16:43:58 +0100215 void OnTracingDisabled(const std::string& error) override;
Florian Mayer709de7f2021-01-28 21:41:14 +0000216 virtual void ReadTraceData(std::vector<TracePacket> packets);
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100217 void OnTraceData(std::vector<TracePacket> packets, bool has_more) override;
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100218 void OnDetach(bool) override;
219 void OnAttach(bool, const TraceConfig&) override;
Eric Secklereaf29ed2019-01-23 09:53:55 +0000220 void OnTraceStats(bool, const TraceStats&) override;
Eric Seckler7b0c9452019-03-18 13:14:36 +0000221 void OnObservableEvents(const ObservableEvents&) override;
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100222
Florian Mayer67b26852021-02-04 19:13:01 +0000223 // Starts the tracing service if in kStartDaemons mode.
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100224 void StartServiceIfRequired();
Primiano Tuccibbe68be2020-04-16 22:17:12 +0100225
226 // Connects the producer and waits that the service has seen the
227 // RegisterDataSource() call.
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100228 FakeProducer* ConnectFakeProducer();
Primiano Tuccibbe68be2020-04-16 22:17:12 +0100229
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100230 void ConnectConsumer();
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100231 void StartTracing(const TraceConfig& config,
232 base::ScopedFile = base::ScopedFile());
Primiano Tuccic1855302018-12-06 10:36:55 +0000233 void DisableTracing();
234 void FlushAndWait(uint32_t timeout_ms);
Lalit Maganti3f0b7c62018-04-18 19:10:09 +0100235 void ReadData(uint32_t read_count = 0);
Stephen Nusko1af720e2020-11-18 14:04:16 -0500236 void FreeBuffers();
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100237 void DetachConsumer(const std::string& key);
238 bool AttachConsumer(const std::string& key);
Primiano Tucci40207fe2020-12-03 18:27:55 +0100239 bool SaveTraceForBugreportAndWait();
Eric Seckler326a3d32020-02-04 11:24:56 +0000240 void CreateProducerProvidedSmb();
241 bool IsShmemProvidedByProducer();
Eric Seckler526921b2020-02-18 11:44:30 +0000242 void ProduceStartupEventBatch(const protos::gen::TestConfig& config);
Lalit Maganti36557d82018-04-11 14:36:17 +0100243
244 void WaitForConsumerConnect();
Stephen Nuskoe8238112019-04-09 18:37:00 +0100245 void WaitForProducerSetup();
Lalit Maganti36557d82018-04-11 14:36:17 +0100246 void WaitForProducerEnabled();
Primiano Tucci5d6f1b52020-10-27 10:29:21 +0100247 void WaitForTracingDisabled(uint32_t timeout_ms = kDefaultTestTimeoutMs);
248 void WaitForReadData(uint32_t read_count = 0,
249 uint32_t timeout_ms = kDefaultTestTimeoutMs);
Primiano Tuccibbe68be2020-04-16 22:17:12 +0100250 void SyncAndWaitProducer();
Primiano Tucci9c41ceb2020-04-14 13:23:01 +0100251 TracingServiceState QueryServiceStateAndWait();
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100252
Florian Mayer05a87c92019-01-30 13:17:51 +0000253 std::string AddID(const std::string& checkpoint) {
254 return checkpoint + "." + std::to_string(instance_num_);
255 }
256
257 std::function<void()> CreateCheckpoint(const std::string& checkpoint) {
258 return task_runner_->CreateCheckpoint(AddID(checkpoint));
259 }
260
261 void RunUntilCheckpoint(const std::string& checkpoint,
Primiano Tucci5d6f1b52020-10-27 10:29:21 +0100262 uint32_t timeout_ms = kDefaultTestTimeoutMs) {
Florian Mayer05a87c92019-01-30 13:17:51 +0000263 return task_runner_->RunUntilCheckpoint(AddID(checkpoint), timeout_ms);
264 }
265
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100266 std::function<void()> WrapTask(const std::function<void()>& function);
267
Lalit Maganti9782f492020-01-10 18:13:13 +0000268 base::ThreadTaskRunner* service_thread() { return service_thread_.runner(); }
269 base::ThreadTaskRunner* producer_thread() {
270 return fake_producer_thread_.runner();
271 }
Florian Mayer51016d32020-09-17 11:34:44 +0100272 const std::vector<protos::gen::TracePacket>& full_trace() {
273 return full_trace_;
274 }
Primiano Tuccife502c42019-12-11 01:00:27 +0000275 const std::vector<protos::gen::TracePacket>& trace() { return trace_; }
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100276
277 private:
Florian Mayer05a87c92019-01-30 13:17:51 +0000278 static uint64_t next_instance_num_;
279 uint64_t instance_num_;
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100280 base::TestTaskRunner* task_runner_ = nullptr;
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100281 int cur_consumer_num_ = 0;
Stephen Nusko1af720e2020-11-18 14:04:16 -0500282 uint64_t trace_count_ = 0;
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100283
Lalit Maganti36557d82018-04-11 14:36:17 +0100284 std::function<void()> on_connect_callback_;
285 std::function<void()> on_packets_finished_callback_;
286 std::function<void()> on_stop_tracing_callback_;
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100287 std::function<void()> on_detach_callback_;
288 std::function<void(bool)> on_attach_callback_;
Lalit Maganti36557d82018-04-11 14:36:17 +0100289
Florian Mayer51016d32020-09-17 11:34:44 +0100290 std::vector<protos::gen::TracePacket> full_trace_;
Primiano Tuccife502c42019-12-11 01:00:27 +0000291 std::vector<protos::gen::TracePacket> trace_;
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100292
Florian Mayer67b26852021-02-04 19:13:01 +0000293 Mode mode_;
294 const char* producer_socket_;
295 const char* consumer_socket_;
Lalit Maganti9782f492020-01-10 18:13:13 +0000296 ServiceThread service_thread_;
297 FakeProducerThread fake_producer_thread_;
298
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100299 std::unique_ptr<TracingService::ConsumerEndpoint> endpoint_; // Keep last.
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100300};
301
302} // namespace perfetto
303
304#endif // TEST_TEST_HELPER_H_