• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "perfetto/ext/base/scoped_file.h"
21 #include "perfetto/ext/base/thread_task_runner.h"
22 #include "perfetto/ext/tracing/core/consumer.h"
23 #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
24 #include "perfetto/ext/tracing/core/trace_packet.h"
25 #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
26 #include "perfetto/ext/tracing/ipc/service_ipc_host.h"
27 #include "perfetto/tracing/core/trace_config.h"
28 #include "src/base/test/test_task_runner.h"
29 #include "src/traced/probes/probes_producer.h"
30 #include "src/tracing/ipc/posix_shared_memory.h"
31 #include "test/fake_producer.h"
32 
33 #include "protos/perfetto/trace/trace_packet.gen.h"
34 
35 namespace perfetto {
36 
37 // This is used only in daemon starting integrations tests.
38 class ServiceThread {
39  public:
ServiceThread(const std::string & producer_socket,const std::string & consumer_socket)40   ServiceThread(const std::string& producer_socket,
41                 const std::string& consumer_socket)
42       : producer_socket_(producer_socket), consumer_socket_(consumer_socket) {}
43 
~ServiceThread()44   ~ServiceThread() {
45     if (!runner_)
46       return;
47     runner_->PostTaskAndWaitForTesting([this]() { svc_.reset(); });
48   }
49 
Start()50   void Start() {
51     runner_ = base::ThreadTaskRunner::CreateAndStart("perfetto.svc");
52     runner_->PostTaskAndWaitForTesting([this]() {
53       svc_ = ServiceIPCHost::CreateInstance(runner_->get());
54       unlink(producer_socket_.c_str());
55       unlink(consumer_socket_.c_str());
56 
57       bool res =
58           svc_->Start(producer_socket_.c_str(), consumer_socket_.c_str());
59       PERFETTO_CHECK(res);
60     });
61   }
62 
runner()63   base::ThreadTaskRunner* runner() { return runner_ ? &*runner_ : nullptr; }
64 
65  private:
66   base::Optional<base::ThreadTaskRunner> runner_;  // Keep first.
67 
68   std::string producer_socket_;
69   std::string consumer_socket_;
70   std::unique_ptr<ServiceIPCHost> svc_;
71 };
72 
73 // This is used only in daemon starting integrations tests.
74 class ProbesProducerThread {
75  public:
ProbesProducerThread(const std::string & producer_socket)76   ProbesProducerThread(const std::string& producer_socket)
77       : producer_socket_(producer_socket) {}
78 
~ProbesProducerThread()79   ~ProbesProducerThread() {
80     if (!runner_)
81       return;
82     runner_->PostTaskAndWaitForTesting([this]() { producer_.reset(); });
83   }
84 
Connect()85   void Connect() {
86     runner_ = base::ThreadTaskRunner::CreateAndStart("perfetto.prd.probes");
87     runner_->PostTaskAndWaitForTesting([this]() {
88       producer_.reset(new ProbesProducer());
89       producer_->ConnectWithRetries(producer_socket_.c_str(), runner_->get());
90     });
91   }
92 
93  private:
94   base::Optional<base::ThreadTaskRunner> runner_;  // Keep first.
95 
96   std::string producer_socket_;
97   std::unique_ptr<ProbesProducer> producer_;
98 };
99 
100 class FakeProducerThread {
101  public:
FakeProducerThread(const std::string & producer_socket,std::function<void ()> connect_callback,std::function<void ()> setup_callback,std::function<void ()> start_callback)102   FakeProducerThread(const std::string& producer_socket,
103                      std::function<void()> connect_callback,
104                      std::function<void()> setup_callback,
105                      std::function<void()> start_callback)
106       : producer_socket_(producer_socket),
107         connect_callback_(std::move(connect_callback)),
108         setup_callback_(std::move(setup_callback)),
109         start_callback_(std::move(start_callback)) {
110     runner_ = base::ThreadTaskRunner::CreateAndStart("perfetto.prd.fake");
111     runner_->PostTaskAndWaitForTesting([this]() {
112       producer_.reset(
113           new FakeProducer("android.perfetto.FakeProducer", runner_->get()));
114     });
115   }
116 
~FakeProducerThread()117   ~FakeProducerThread() {
118     runner_->PostTaskAndWaitForTesting([this]() { producer_.reset(); });
119   }
120 
Connect()121   void Connect() {
122     runner_->PostTaskAndWaitForTesting([this]() {
123       producer_->Connect(producer_socket_.c_str(), std::move(connect_callback_),
124                          std::move(setup_callback_), std::move(start_callback_),
125                          std::move(shm_), std::move(shm_arbiter_));
126     });
127   }
128 
runner()129   base::ThreadTaskRunner* runner() { return runner_ ? &*runner_ : nullptr; }
130 
producer()131   FakeProducer* producer() { return producer_.get(); }
132 
CreateProducerProvidedSmb()133   void CreateProducerProvidedSmb() {
134     PosixSharedMemory::Factory factory;
135     shm_ = factory.CreateSharedMemory(1024 * 1024);
136     shm_arbiter_ =
137         SharedMemoryArbiter::CreateUnboundInstance(shm_.get(), base::kPageSize);
138   }
139 
ProduceStartupEventBatch(const protos::gen::TestConfig & config,std::function<void ()> callback)140   void ProduceStartupEventBatch(const protos::gen::TestConfig& config,
141                                 std::function<void()> callback) {
142     PERFETTO_CHECK(shm_arbiter_);
143     producer_->ProduceStartupEventBatch(config, shm_arbiter_.get(), callback);
144   }
145 
146  private:
147   base::Optional<base::ThreadTaskRunner> runner_;  // Keep first.
148 
149   std::string producer_socket_;
150   std::unique_ptr<FakeProducer> producer_;
151   std::function<void()> connect_callback_;
152   std::function<void()> setup_callback_;
153   std::function<void()> start_callback_;
154   std::unique_ptr<SharedMemory> shm_;
155   std::unique_ptr<SharedMemoryArbiter> shm_arbiter_;
156 };
157 
158 class TestHelper : public Consumer {
159  public:
160   static const char* GetConsumerSocketName();
161   static const char* GetProducerSocketName();
162 
163   explicit TestHelper(base::TestTaskRunner* task_runner);
164 
165   // Consumer implementation.
166   void OnConnect() override;
167   void OnDisconnect() override;
168   void OnTracingDisabled() override;
169   void OnTraceData(std::vector<TracePacket> packets, bool has_more) override;
170   void OnDetach(bool) override;
171   void OnAttach(bool, const TraceConfig&) override;
172   void OnTraceStats(bool, const TraceStats&) override;
173   void OnObservableEvents(const ObservableEvents&) override;
174 
175   void StartServiceIfRequired();
176 
177   // Connects the producer and waits that the service has seen the
178   // RegisterDataSource() call.
179   FakeProducer* ConnectFakeProducer();
180 
181   void ConnectConsumer();
182   void StartTracing(const TraceConfig& config,
183                     base::ScopedFile = base::ScopedFile());
184   void DisableTracing();
185   void FlushAndWait(uint32_t timeout_ms);
186   void ReadData(uint32_t read_count = 0);
187   void DetachConsumer(const std::string& key);
188   bool AttachConsumer(const std::string& key);
189   void CreateProducerProvidedSmb();
190   bool IsShmemProvidedByProducer();
191   void ProduceStartupEventBatch(const protos::gen::TestConfig& config);
192 
193   void WaitForConsumerConnect();
194   void WaitForProducerSetup();
195   void WaitForProducerEnabled();
196   void WaitForTracingDisabled(uint32_t timeout_ms = 5000);
197   void WaitForReadData(uint32_t read_count = 0, uint32_t timeout_ms = 5000);
198   void SyncAndWaitProducer();
199   TracingServiceState QueryServiceStateAndWait();
200 
AddID(const std::string & checkpoint)201   std::string AddID(const std::string& checkpoint) {
202     return checkpoint + "." + std::to_string(instance_num_);
203   }
204 
CreateCheckpoint(const std::string & checkpoint)205   std::function<void()> CreateCheckpoint(const std::string& checkpoint) {
206     return task_runner_->CreateCheckpoint(AddID(checkpoint));
207   }
208 
209   void RunUntilCheckpoint(const std::string& checkpoint,
210                           uint32_t timeout_ms = 5000) {
211     return task_runner_->RunUntilCheckpoint(AddID(checkpoint), timeout_ms);
212   }
213 
214   std::function<void()> WrapTask(const std::function<void()>& function);
215 
service_thread()216   base::ThreadTaskRunner* service_thread() { return service_thread_.runner(); }
producer_thread()217   base::ThreadTaskRunner* producer_thread() {
218     return fake_producer_thread_.runner();
219   }
trace()220   const std::vector<protos::gen::TracePacket>& trace() { return trace_; }
221 
222  private:
223   static uint64_t next_instance_num_;
224   uint64_t instance_num_;
225   base::TestTaskRunner* task_runner_ = nullptr;
226   int cur_consumer_num_ = 0;
227 
228   std::function<void()> on_connect_callback_;
229   std::function<void()> on_packets_finished_callback_;
230   std::function<void()> on_stop_tracing_callback_;
231   std::function<void()> on_detach_callback_;
232   std::function<void(bool)> on_attach_callback_;
233 
234   std::vector<protos::gen::TracePacket> trace_;
235 
236   ServiceThread service_thread_;
237   FakeProducerThread fake_producer_thread_;
238 
239   std::unique_ptr<TracingService::ConsumerEndpoint> endpoint_;  // Keep last.
240 };
241 
242 }  // namespace perfetto
243 
244 #endif  // TEST_TEST_HELPER_H_
245