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/ext/base/optional.h" 24 #include "perfetto/ext/base/scoped_file.h" 25 #include "perfetto/ext/base/thread_task_runner.h" 26 #include "perfetto/ext/base/utils.h" 27 #include "perfetto/ext/tracing/core/consumer.h" 28 #include "perfetto/ext/tracing/core/shared_memory_arbiter.h" 29 #include "perfetto/ext/tracing/core/trace_packet.h" 30 #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h" 31 #include "perfetto/ext/tracing/ipc/service_ipc_host.h" 32 #include "perfetto/tracing/core/trace_config.h" 33 #include "src/base/test/test_task_runner.h" 34 #include "test/fake_producer.h" 35 36 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) 37 // TODO(primiano): uncomment in next CL. 38 // #include "src/tracing/ipc/shared_memory_windows.h" 39 #else 40 #include "src/traced/probes/probes_producer.h" 41 #include "src/tracing/ipc/posix_shared_memory.h" 42 #endif 43 44 #include "protos/perfetto/trace/trace_packet.gen.h" 45 46 namespace perfetto { 47 48 // This value has been bumped to 10s in Oct 2020 because the x86 cuttlefish 49 // emulator is sensibly slower (up to 10x) than real hw and caused flakes. 50 // See bugs duped against b/171771440. 51 constexpr uint32_t kDefaultTestTimeoutMs = 10000; 52 53 // This is used only in daemon starting integrations tests. 54 class ServiceThread { 55 public: ServiceThread(const std::string & producer_socket,const std::string & consumer_socket)56 ServiceThread(const std::string& producer_socket, 57 const std::string& consumer_socket) 58 : producer_socket_(producer_socket), consumer_socket_(consumer_socket) {} 59 ~ServiceThread()60 ~ServiceThread() { 61 if (!runner_) 62 return; 63 runner_->PostTaskAndWaitForTesting([this]() { svc_.reset(); }); 64 } 65 Start()66 void Start() { 67 runner_ = base::ThreadTaskRunner::CreateAndStart("perfetto.svc"); 68 runner_->PostTaskAndWaitForTesting([this]() { 69 svc_ = ServiceIPCHost::CreateInstance(runner_->get()); 70 if (remove(producer_socket_.c_str()) == -1) { 71 if (errno != ENOENT) 72 PERFETTO_FATAL("Failed to remove %s", producer_socket_.c_str()); 73 } 74 if (remove(consumer_socket_.c_str()) == -1) { 75 if (errno != ENOENT) 76 PERFETTO_FATAL("Failed to remove %s", consumer_socket_.c_str()); 77 } 78 base::SetEnv("PERFETTO_PRODUCER_SOCK_NAME", producer_socket_); 79 base::SetEnv("PERFETTO_CONSUMER_SOCK_NAME", consumer_socket_); 80 bool res = 81 svc_->Start(producer_socket_.c_str(), consumer_socket_.c_str()); 82 if (!res) { 83 PERFETTO_FATAL("Failed to start service listening on %s and %s", 84 producer_socket_.c_str(), consumer_socket_.c_str()); 85 } 86 }); 87 } 88 runner()89 base::ThreadTaskRunner* runner() { return runner_ ? &*runner_ : nullptr; } 90 91 private: 92 base::Optional<base::ThreadTaskRunner> runner_; // Keep first. 93 94 std::string producer_socket_; 95 std::string consumer_socket_; 96 std::unique_ptr<ServiceIPCHost> svc_; 97 }; 98 99 // This is used only in daemon starting integrations tests. 100 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) 101 // On Windows we don't have any traced_probes, make this a no-op to avoid 102 // propagating #ifdefs to the outer test. 103 class ProbesProducerThread { 104 public: ProbesProducerThread(const std::string &)105 ProbesProducerThread(const std::string& /*producer_socket*/) {} Connect()106 void Connect() {} 107 }; 108 #else 109 class ProbesProducerThread { 110 public: ProbesProducerThread(const std::string & producer_socket)111 ProbesProducerThread(const std::string& producer_socket) 112 : producer_socket_(producer_socket) {} 113 ~ProbesProducerThread()114 ~ProbesProducerThread() { 115 if (!runner_) 116 return; 117 runner_->PostTaskAndWaitForTesting([this]() { producer_.reset(); }); 118 } 119 Connect()120 void Connect() { 121 runner_ = base::ThreadTaskRunner::CreateAndStart("perfetto.prd.probes"); 122 runner_->PostTaskAndWaitForTesting([this]() { 123 producer_.reset(new ProbesProducer()); 124 producer_->ConnectWithRetries(producer_socket_.c_str(), runner_->get()); 125 }); 126 } 127 128 private: 129 base::Optional<base::ThreadTaskRunner> runner_; // Keep first. 130 131 std::string producer_socket_; 132 std::unique_ptr<ProbesProducer> producer_; 133 }; 134 #endif // !OS_WIN 135 136 class FakeProducerThread { 137 public: FakeProducerThread(const std::string & producer_socket,std::function<void ()> connect_callback,std::function<void ()> setup_callback,std::function<void ()> start_callback)138 FakeProducerThread(const std::string& producer_socket, 139 std::function<void()> connect_callback, 140 std::function<void()> setup_callback, 141 std::function<void()> start_callback) 142 : producer_socket_(producer_socket), 143 connect_callback_(std::move(connect_callback)), 144 setup_callback_(std::move(setup_callback)), 145 start_callback_(std::move(start_callback)) { 146 runner_ = base::ThreadTaskRunner::CreateAndStart("perfetto.prd.fake"); 147 runner_->PostTaskAndWaitForTesting([this]() { 148 producer_.reset( 149 new FakeProducer("android.perfetto.FakeProducer", runner_->get())); 150 }); 151 } 152 ~FakeProducerThread()153 ~FakeProducerThread() { 154 runner_->PostTaskAndWaitForTesting([this]() { producer_.reset(); }); 155 } 156 Connect()157 void Connect() { 158 runner_->PostTaskAndWaitForTesting([this]() { 159 producer_->Connect(producer_socket_.c_str(), std::move(connect_callback_), 160 std::move(setup_callback_), std::move(start_callback_), 161 std::move(shm_), std::move(shm_arbiter_)); 162 }); 163 } 164 runner()165 base::ThreadTaskRunner* runner() { return runner_ ? &*runner_ : nullptr; } 166 producer()167 FakeProducer* producer() { return producer_.get(); } 168 CreateProducerProvidedSmb()169 void CreateProducerProvidedSmb() { 170 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) 171 // TODO(primiano): in next CLs introduce SharedMemoryWindows. 172 #else 173 PosixSharedMemory::Factory factory; 174 shm_ = factory.CreateSharedMemory(1024 * 1024); 175 shm_arbiter_ = SharedMemoryArbiter::CreateUnboundInstance(shm_.get(), 4096); 176 #endif 177 } 178 ProduceStartupEventBatch(const protos::gen::TestConfig & config,std::function<void ()> callback)179 void ProduceStartupEventBatch(const protos::gen::TestConfig& config, 180 std::function<void()> callback) { 181 PERFETTO_CHECK(shm_arbiter_); 182 producer_->ProduceStartupEventBatch(config, shm_arbiter_.get(), callback); 183 } 184 185 private: 186 base::Optional<base::ThreadTaskRunner> runner_; // Keep first. 187 188 std::string producer_socket_; 189 std::unique_ptr<FakeProducer> producer_; 190 std::function<void()> connect_callback_; 191 std::function<void()> setup_callback_; 192 std::function<void()> start_callback_; 193 std::unique_ptr<SharedMemory> shm_; 194 std::unique_ptr<SharedMemoryArbiter> shm_arbiter_; 195 }; 196 197 class TestHelper : public Consumer { 198 public: 199 enum class Mode { 200 kStartDaemons, 201 kUseSystemService, 202 }; 203 static Mode kDefaultMode; 204 205 static const char* GetDefaultModeConsumerSocketName(); 206 static const char* GetDefaultModeProducerSocketName(); 207 TestHelper(base::TestTaskRunner * task_runner)208 explicit TestHelper(base::TestTaskRunner* task_runner) 209 : TestHelper(task_runner, kDefaultMode) {} 210 211 explicit TestHelper(base::TestTaskRunner* task_runner, Mode mode); 212 213 // Consumer implementation. 214 void OnConnect() override; 215 void OnDisconnect() override; 216 void OnTracingDisabled(const std::string& error) override; 217 virtual void ReadTraceData(std::vector<TracePacket> packets); 218 void OnTraceData(std::vector<TracePacket> packets, bool has_more) override; 219 void OnDetach(bool) override; 220 void OnAttach(bool, const TraceConfig&) override; 221 void OnTraceStats(bool, const TraceStats&) override; 222 void OnObservableEvents(const ObservableEvents&) override; 223 224 // Starts the tracing service if in kStartDaemons mode. 225 void StartServiceIfRequired(); 226 227 // Connects the producer and waits that the service has seen the 228 // RegisterDataSource() call. 229 FakeProducer* ConnectFakeProducer(); 230 231 void ConnectConsumer(); 232 void StartTracing(const TraceConfig& config, 233 base::ScopedFile = base::ScopedFile()); 234 void DisableTracing(); 235 void FlushAndWait(uint32_t timeout_ms); 236 void ReadData(uint32_t read_count = 0); 237 void FreeBuffers(); 238 void DetachConsumer(const std::string& key); 239 bool AttachConsumer(const std::string& key); 240 bool SaveTraceForBugreportAndWait(); 241 void CreateProducerProvidedSmb(); 242 bool IsShmemProvidedByProducer(); 243 void ProduceStartupEventBatch(const protos::gen::TestConfig& config); 244 245 void WaitForConsumerConnect(); 246 void WaitForProducerSetup(); 247 void WaitForProducerEnabled(); 248 void WaitForTracingDisabled(uint32_t timeout_ms = kDefaultTestTimeoutMs); 249 void WaitForReadData(uint32_t read_count = 0, 250 uint32_t timeout_ms = kDefaultTestTimeoutMs); 251 void SyncAndWaitProducer(); 252 TracingServiceState QueryServiceStateAndWait(); 253 AddID(const std::string & checkpoint)254 std::string AddID(const std::string& checkpoint) { 255 return checkpoint + "." + std::to_string(instance_num_); 256 } 257 CreateCheckpoint(const std::string & checkpoint)258 std::function<void()> CreateCheckpoint(const std::string& checkpoint) { 259 return task_runner_->CreateCheckpoint(AddID(checkpoint)); 260 } 261 262 void RunUntilCheckpoint(const std::string& checkpoint, 263 uint32_t timeout_ms = kDefaultTestTimeoutMs) { 264 return task_runner_->RunUntilCheckpoint(AddID(checkpoint), timeout_ms); 265 } 266 267 std::function<void()> WrapTask(const std::function<void()>& function); 268 service_thread()269 base::ThreadTaskRunner* service_thread() { return service_thread_.runner(); } producer_thread()270 base::ThreadTaskRunner* producer_thread() { 271 return fake_producer_thread_.runner(); 272 } full_trace()273 const std::vector<protos::gen::TracePacket>& full_trace() { 274 return full_trace_; 275 } trace()276 const std::vector<protos::gen::TracePacket>& trace() { return trace_; } 277 278 private: 279 static uint64_t next_instance_num_; 280 uint64_t instance_num_; 281 base::TestTaskRunner* task_runner_ = nullptr; 282 int cur_consumer_num_ = 0; 283 uint64_t trace_count_ = 0; 284 285 std::function<void()> on_connect_callback_; 286 std::function<void()> on_packets_finished_callback_; 287 std::function<void()> on_stop_tracing_callback_; 288 std::function<void()> on_detach_callback_; 289 std::function<void(bool)> on_attach_callback_; 290 291 std::vector<protos::gen::TracePacket> full_trace_; 292 std::vector<protos::gen::TracePacket> trace_; 293 294 Mode mode_; 295 const char* producer_socket_; 296 const char* consumer_socket_; 297 ServiceThread service_thread_; 298 FakeProducerThread fake_producer_thread_; 299 300 std::unique_ptr<TracingService::ConsumerEndpoint> endpoint_; // Keep last. 301 }; 302 303 } // namespace perfetto 304 305 #endif // TEST_TEST_HELPER_H_ 306