1 /*
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
20 #include <stdio.h>
21 #include <stdlib.h>
22
23 #include "perfetto/base/build_config.h"
24 #include "perfetto/ext/base/file_utils.h"
25 #include "perfetto/ext/base/optional.h"
26 #include "perfetto/ext/base/scoped_file.h"
27 #include "perfetto/ext/base/subprocess.h"
28 #include "perfetto/ext/base/thread_task_runner.h"
29 #include "perfetto/ext/base/utils.h"
30 #include "perfetto/ext/tracing/core/consumer.h"
31 #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
32 #include "perfetto/ext/tracing/core/trace_packet.h"
33 #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
34 #include "perfetto/ext/tracing/ipc/default_socket.h"
35 #include "perfetto/ext/tracing/ipc/service_ipc_host.h"
36 #include "perfetto/tracing/core/trace_config.h"
37 #include "src/base/test/test_task_runner.h"
38 #include "test/fake_producer.h"
39
40 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
41 #include "src/tracing/ipc/shared_memory_windows.h"
42 #else
43 #include "src/traced/probes/probes_producer.h"
44 #include "src/tracing/ipc/posix_shared_memory.h"
45 #endif
46
47 #include "protos/perfetto/trace/trace_packet.gen.h"
48
49 namespace perfetto {
50
51 // This value has been bumped to 10s in Oct 2020 because the GCE-based emulator
52 // can be sensibly slower than real hw (more than 10x) and caused flakes.
53 // See bugs duped against b/171771440.
54 constexpr uint32_t kDefaultTestTimeoutMs = 30000;
55
GetTestProducerSockName()56 inline const char* GetTestProducerSockName() {
57 // If we're building on Android and starting the daemons ourselves,
58 // create the sockets in a world-writable location.
59 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
60 PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
61 return "/data/local/tmp/traced_producer";
62 #else
63 return ::perfetto::GetProducerSocket();
64 #endif
65 }
66
67 // This is used only in daemon starting integrations tests.
68 class ServiceThread {
69 public:
ServiceThread(const std::string & producer_socket,const std::string & consumer_socket)70 ServiceThread(const std::string& producer_socket,
71 const std::string& consumer_socket)
72 : producer_socket_(producer_socket), consumer_socket_(consumer_socket) {}
73
~ServiceThread()74 ~ServiceThread() {
75 if (!runner_)
76 return;
77 runner_->PostTaskAndWaitForTesting([this]() { svc_.reset(); });
78 }
79
Start()80 void Start() {
81 runner_ = base::ThreadTaskRunner::CreateAndStart("perfetto.svc");
82 runner_->PostTaskAndWaitForTesting([this]() {
83 svc_ = ServiceIPCHost::CreateInstance(runner_->get());
84 if (remove(producer_socket_.c_str()) == -1) {
85 if (errno != ENOENT)
86 PERFETTO_FATAL("Failed to remove %s", producer_socket_.c_str());
87 }
88 if (remove(consumer_socket_.c_str()) == -1) {
89 if (errno != ENOENT)
90 PERFETTO_FATAL("Failed to remove %s", consumer_socket_.c_str());
91 }
92 base::SetEnv("PERFETTO_PRODUCER_SOCK_NAME", producer_socket_);
93 base::SetEnv("PERFETTO_CONSUMER_SOCK_NAME", consumer_socket_);
94 bool res =
95 svc_->Start(producer_socket_.c_str(), consumer_socket_.c_str());
96 if (!res) {
97 PERFETTO_FATAL("Failed to start service listening on %s and %s",
98 producer_socket_.c_str(), consumer_socket_.c_str());
99 }
100 });
101 }
102
runner()103 base::ThreadTaskRunner* runner() { return runner_ ? &*runner_ : nullptr; }
104
105 private:
106 base::Optional<base::ThreadTaskRunner> runner_; // Keep first.
107
108 std::string producer_socket_;
109 std::string consumer_socket_;
110 std::unique_ptr<ServiceIPCHost> svc_;
111 };
112
113 // This is used only in daemon starting integrations tests.
114 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
115 // On Windows we don't have any traced_probes, make this a no-op to avoid
116 // propagating #ifdefs to the outer test.
117 class ProbesProducerThread {
118 public:
ProbesProducerThread(const std::string &)119 ProbesProducerThread(const std::string& /*producer_socket*/) {}
Connect()120 void Connect() {}
121 };
122 #else
123 class ProbesProducerThread {
124 public:
ProbesProducerThread(const std::string & producer_socket)125 ProbesProducerThread(const std::string& producer_socket)
126 : producer_socket_(producer_socket) {}
127
~ProbesProducerThread()128 ~ProbesProducerThread() {
129 if (!runner_)
130 return;
131 runner_->PostTaskAndWaitForTesting([this]() { producer_.reset(); });
132 }
133
Connect()134 void Connect() {
135 runner_ = base::ThreadTaskRunner::CreateAndStart("perfetto.prd.probes");
136 runner_->PostTaskAndWaitForTesting([this]() {
137 producer_.reset(new ProbesProducer());
138 producer_->ConnectWithRetries(producer_socket_.c_str(), runner_->get());
139 });
140 }
141
142 private:
143 base::Optional<base::ThreadTaskRunner> runner_; // Keep first.
144
145 std::string producer_socket_;
146 std::unique_ptr<ProbesProducer> producer_;
147 };
148 #endif // !OS_WIN
149
150 class FakeProducerThread {
151 public:
FakeProducerThread(const std::string & producer_socket,std::function<void ()> connect_callback,std::function<void ()> setup_callback,std::function<void ()> start_callback)152 FakeProducerThread(const std::string& producer_socket,
153 std::function<void()> connect_callback,
154 std::function<void()> setup_callback,
155 std::function<void()> start_callback)
156 : producer_socket_(producer_socket),
157 connect_callback_(std::move(connect_callback)),
158 setup_callback_(std::move(setup_callback)),
159 start_callback_(std::move(start_callback)) {
160 runner_ = base::ThreadTaskRunner::CreateAndStart("perfetto.prd.fake");
161 runner_->PostTaskAndWaitForTesting([this]() {
162 producer_.reset(
163 new FakeProducer("android.perfetto.FakeProducer", runner_->get()));
164 });
165 }
166
~FakeProducerThread()167 ~FakeProducerThread() {
168 runner_->PostTaskAndWaitForTesting([this]() { producer_.reset(); });
169 }
170
Connect()171 void Connect() {
172 runner_->PostTaskAndWaitForTesting([this]() {
173 producer_->Connect(producer_socket_.c_str(), std::move(connect_callback_),
174 std::move(setup_callback_), std::move(start_callback_),
175 std::move(shm_), std::move(shm_arbiter_));
176 });
177 }
178
runner()179 base::ThreadTaskRunner* runner() { return runner_ ? &*runner_ : nullptr; }
180
producer()181 FakeProducer* producer() { return producer_.get(); }
182
CreateProducerProvidedSmb()183 void CreateProducerProvidedSmb() {
184 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
185 SharedMemoryWindows::Factory factory;
186 #else
187 PosixSharedMemory::Factory factory;
188 #endif
189 shm_ = factory.CreateSharedMemory(1024 * 1024);
190 shm_arbiter_ = SharedMemoryArbiter::CreateUnboundInstance(shm_.get(), 4096);
191 }
192
ProduceStartupEventBatch(const protos::gen::TestConfig & config,std::function<void ()> callback)193 void ProduceStartupEventBatch(const protos::gen::TestConfig& config,
194 std::function<void()> callback) {
195 PERFETTO_CHECK(shm_arbiter_);
196 producer_->ProduceStartupEventBatch(config, shm_arbiter_.get(), callback);
197 }
198
199 private:
200 base::Optional<base::ThreadTaskRunner> runner_; // Keep first.
201
202 std::string producer_socket_;
203 std::unique_ptr<FakeProducer> producer_;
204 std::function<void()> connect_callback_;
205 std::function<void()> setup_callback_;
206 std::function<void()> start_callback_;
207 std::unique_ptr<SharedMemory> shm_;
208 std::unique_ptr<SharedMemoryArbiter> shm_arbiter_;
209 };
210
211 class TestHelper : public Consumer {
212 public:
213 enum class Mode {
214 kStartDaemons,
215 kUseSystemService,
216 };
217 static Mode kDefaultMode;
218
219 static const char* GetDefaultModeConsumerSocketName();
220 static const char* GetDefaultModeProducerSocketName();
221
TestHelper(base::TestTaskRunner * task_runner)222 explicit TestHelper(base::TestTaskRunner* task_runner)
223 : TestHelper(task_runner, kDefaultMode) {}
224
225 explicit TestHelper(base::TestTaskRunner* task_runner, Mode mode);
226
227 // Consumer implementation.
228 void OnConnect() override;
229 void OnDisconnect() override;
230 void OnTracingDisabled(const std::string& error) override;
231 virtual void ReadTraceData(std::vector<TracePacket> packets);
232 void OnTraceData(std::vector<TracePacket> packets, bool has_more) override;
233 void OnDetach(bool) override;
234 void OnAttach(bool, const TraceConfig&) override;
235 void OnTraceStats(bool, const TraceStats&) override;
236 void OnObservableEvents(const ObservableEvents&) override;
237
238 // Starts the tracing service if in kStartDaemons mode.
239 void StartServiceIfRequired();
240
241 // Connects the producer and waits that the service has seen the
242 // RegisterDataSource() call.
243 FakeProducer* ConnectFakeProducer();
244
245 void ConnectConsumer();
246 void StartTracing(const TraceConfig& config,
247 base::ScopedFile = base::ScopedFile());
248 void DisableTracing();
249 void FlushAndWait(uint32_t timeout_ms);
250 void ReadData(uint32_t read_count = 0);
251 void FreeBuffers();
252 void DetachConsumer(const std::string& key);
253 bool AttachConsumer(const std::string& key);
254 bool SaveTraceForBugreportAndWait();
255 void CreateProducerProvidedSmb();
256 bool IsShmemProvidedByProducer();
257 void ProduceStartupEventBatch(const protos::gen::TestConfig& config);
258
259 void WaitFor(std::function<bool()> predicate,
260 const std::string& error_msg,
261 uint32_t timeout_ms = kDefaultTestTimeoutMs);
262 void WaitForConsumerConnect();
263 void WaitForProducerSetup();
264 void WaitForProducerEnabled();
265 void WaitForDataSourceConnected(const std::string& ds_name);
266 void WaitForTracingDisabled(uint32_t timeout_ms = kDefaultTestTimeoutMs);
267 void WaitForReadData(uint32_t read_count = 0,
268 uint32_t timeout_ms = kDefaultTestTimeoutMs);
269 void SyncAndWaitProducer();
270 TracingServiceState QueryServiceStateAndWait();
271
AddID(const std::string & checkpoint)272 std::string AddID(const std::string& checkpoint) {
273 return checkpoint + "." + std::to_string(instance_num_);
274 }
275
CreateCheckpoint(const std::string & checkpoint)276 std::function<void()> CreateCheckpoint(const std::string& checkpoint) {
277 return task_runner_->CreateCheckpoint(AddID(checkpoint));
278 }
279
280 void RunUntilCheckpoint(const std::string& checkpoint,
281 uint32_t timeout_ms = kDefaultTestTimeoutMs) {
282 return task_runner_->RunUntilCheckpoint(AddID(checkpoint), timeout_ms);
283 }
284
285 std::function<void()> WrapTask(const std::function<void()>& function);
286
service_thread()287 base::ThreadTaskRunner* service_thread() { return service_thread_.runner(); }
producer_thread()288 base::ThreadTaskRunner* producer_thread() {
289 return fake_producer_thread_.runner();
290 }
full_trace()291 const std::vector<protos::gen::TracePacket>& full_trace() {
292 return full_trace_;
293 }
trace()294 const std::vector<protos::gen::TracePacket>& trace() { return trace_; }
295
296 private:
297 static uint64_t next_instance_num_;
298 uint64_t instance_num_;
299 base::TestTaskRunner* task_runner_ = nullptr;
300 int cur_consumer_num_ = 0;
301 uint64_t trace_count_ = 0;
302
303 std::function<void()> on_connect_callback_;
304 std::function<void()> on_packets_finished_callback_;
305 std::function<void()> on_stop_tracing_callback_;
306 std::function<void()> on_detach_callback_;
307 std::function<void(bool)> on_attach_callback_;
308
309 std::vector<protos::gen::TracePacket> full_trace_;
310 std::vector<protos::gen::TracePacket> trace_;
311
312 Mode mode_;
313 const char* producer_socket_;
314 const char* consumer_socket_;
315 ServiceThread service_thread_;
316 FakeProducerThread fake_producer_thread_;
317
318 std::unique_ptr<TracingService::ConsumerEndpoint> endpoint_; // Keep last.
319 };
320
321 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
322
323 // This class is a reference to a child process that has in essence been execv
324 // to the requested binary. The process will start and then wait for Run()
325 // before proceeding. We use this to fork new processes before starting any
326 // additional threads in the parent process (otherwise you would risk
327 // deadlocks), but pause the forked processes until remaining setup (including
328 // any necessary threads) in the parent process is complete.
329 class Exec {
330 public:
331 // Starts the forked process that was created. If not null then |stderr_out|
332 // will contain the stderr of the process.
333 int Run(std::string* stderr_out = nullptr) {
334 // We can't be the child process.
335 PERFETTO_CHECK(getpid() != subprocess_.pid());
336 // Will cause the entrypoint to continue.
337 PERFETTO_CHECK(write(*sync_pipe_.wr, "1", 1) == 1);
338 sync_pipe_.wr.reset();
339 subprocess_.Wait();
340
341 if (stderr_out) {
342 *stderr_out = std::move(subprocess_.output());
343 } else {
344 PERFETTO_LOG("Child proc %d exited with stderr: \"%s\"",
345 subprocess_.pid(), subprocess_.output().c_str());
346 }
347 return subprocess_.returncode();
348 }
349
350 Exec(const std::string& argv0,
351 std::initializer_list<std::string> args,
352 std::string input = "") {
353 subprocess_.args.stderr_mode = base::Subprocess::OutputMode::kBuffer;
354 subprocess_.args.stdout_mode = base::Subprocess::OutputMode::kDevNull;
355 subprocess_.args.input = input;
356
357 #if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
358 constexpr bool kUseSystemBinaries = false;
359 #else
360 constexpr bool kUseSystemBinaries = true;
361 #endif
362
363 std::vector<std::string>& cmd = subprocess_.args.exec_cmd;
364 if (kUseSystemBinaries) {
365 PERFETTO_CHECK(TestHelper::kDefaultMode ==
366 TestHelper::Mode::kUseSystemService);
367 cmd.push_back("/system/bin/" + argv0);
368 cmd.insert(cmd.end(), args.begin(), args.end());
369 } else {
370 PERFETTO_CHECK(TestHelper::kDefaultMode ==
371 TestHelper::Mode::kStartDaemons);
372 subprocess_.args.env.push_back(
373 std::string("PERFETTO_PRODUCER_SOCK_NAME=") +
374 TestHelper::GetDefaultModeProducerSocketName());
375 subprocess_.args.env.push_back(
376 std::string("PERFETTO_CONSUMER_SOCK_NAME=") +
377 TestHelper::GetDefaultModeConsumerSocketName());
378 cmd.push_back(base::GetCurExecutableDir() + "/" + argv0);
379 cmd.insert(cmd.end(), args.begin(), args.end());
380 }
381
382 if (!base::FileExists(cmd[0])) {
383 PERFETTO_FATAL(
384 "Cannot find %s. Make sure that the target has been built and, on "
385 "Android, pushed to the device.",
386 cmd[0].c_str());
387 }
388
389 // This pipe blocks the execution of the child process until the main test
390 // process calls Run(). There are two conflicting problems here:
391 // 1) We can't fork() subprocesses too late, because the test spawns threads
392 // for hosting the service. fork+threads = bad (see aosp/1089744).
393 // 2) We can't run the subprocess too early, because we need to wait that
394 // the service threads are ready before trying to connect from the child
395 // process.
396 sync_pipe_ = base::Pipe::Create();
397 int sync_pipe_rd = *sync_pipe_.rd;
398 subprocess_.args.preserve_fds.push_back(sync_pipe_rd);
399
400 // This lambda will be called on the forked child process after having
401 // setup pipe redirection and closed all FDs, right before the exec().
402 // The Subprocesss harness will take care of closing also |sync_pipe_.wr|.
403 subprocess_.args.posix_entrypoint_for_testing = [sync_pipe_rd] {
404 // Don't add any logging here, all file descriptors are closed and trying
405 // to log will likely cause undefined behaviors.
406 char ignored = 0;
407 PERFETTO_CHECK(PERFETTO_EINTR(read(sync_pipe_rd, &ignored, 1)) > 0);
408 PERFETTO_CHECK(close(sync_pipe_rd) == 0 || errno == EINTR);
409 };
410
411 subprocess_.Start();
412 sync_pipe_.rd.reset();
413 }
414
415 private:
416 base::Subprocess subprocess_;
417 base::Pipe sync_pipe_;
418 };
419
420 #endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
421
422 } // namespace perfetto
423
424 #endif // TEST_TEST_HELPER_H_
425