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