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 value has been bumped to 10s in Oct 2020 because the x86 cuttlefish 38 // emulator is sensibly slower (up to 10x) than real hw and caused flakes. 39 // See bugs duped against b/171771440. 40 constexpr uint32_t kDefaultTestTimeoutMs = 10000; 41 42 // This is used only in daemon starting integrations tests. 43 class ServiceThread { 44 public: ServiceThread(const std::string & producer_socket,const std::string & consumer_socket)45 ServiceThread(const std::string& producer_socket, 46 const std::string& consumer_socket) 47 : producer_socket_(producer_socket), consumer_socket_(consumer_socket) {} 48 ~ServiceThread()49 ~ServiceThread() { 50 if (!runner_) 51 return; 52 runner_->PostTaskAndWaitForTesting([this]() { svc_.reset(); }); 53 } 54 Start()55 void Start() { 56 runner_ = base::ThreadTaskRunner::CreateAndStart("perfetto.svc"); 57 runner_->PostTaskAndWaitForTesting([this]() { 58 svc_ = ServiceIPCHost::CreateInstance(runner_->get()); 59 unlink(producer_socket_.c_str()); 60 unlink(consumer_socket_.c_str()); 61 setenv("PERFETTO_PRODUCER_SOCK_NAME", producer_socket_.c_str(), 62 /*overwrite=*/true); 63 setenv("PERFETTO_CONSUMER_SOCK_NAME", consumer_socket_.c_str(), 64 /*overwrite=*/true); 65 bool res = 66 svc_->Start(producer_socket_.c_str(), consumer_socket_.c_str()); 67 PERFETTO_CHECK(res); 68 }); 69 } 70 runner()71 base::ThreadTaskRunner* runner() { return runner_ ? &*runner_ : nullptr; } 72 73 private: 74 base::Optional<base::ThreadTaskRunner> runner_; // Keep first. 75 76 std::string producer_socket_; 77 std::string consumer_socket_; 78 std::unique_ptr<ServiceIPCHost> svc_; 79 }; 80 81 // This is used only in daemon starting integrations tests. 82 class ProbesProducerThread { 83 public: ProbesProducerThread(const std::string & producer_socket)84 ProbesProducerThread(const std::string& producer_socket) 85 : producer_socket_(producer_socket) {} 86 ~ProbesProducerThread()87 ~ProbesProducerThread() { 88 if (!runner_) 89 return; 90 runner_->PostTaskAndWaitForTesting([this]() { producer_.reset(); }); 91 } 92 Connect()93 void Connect() { 94 runner_ = base::ThreadTaskRunner::CreateAndStart("perfetto.prd.probes"); 95 runner_->PostTaskAndWaitForTesting([this]() { 96 producer_.reset(new ProbesProducer()); 97 producer_->ConnectWithRetries(producer_socket_.c_str(), runner_->get()); 98 }); 99 } 100 101 private: 102 base::Optional<base::ThreadTaskRunner> runner_; // Keep first. 103 104 std::string producer_socket_; 105 std::unique_ptr<ProbesProducer> producer_; 106 }; 107 108 class FakeProducerThread { 109 public: FakeProducerThread(const std::string & producer_socket,std::function<void ()> connect_callback,std::function<void ()> setup_callback,std::function<void ()> start_callback)110 FakeProducerThread(const std::string& producer_socket, 111 std::function<void()> connect_callback, 112 std::function<void()> setup_callback, 113 std::function<void()> start_callback) 114 : producer_socket_(producer_socket), 115 connect_callback_(std::move(connect_callback)), 116 setup_callback_(std::move(setup_callback)), 117 start_callback_(std::move(start_callback)) { 118 runner_ = base::ThreadTaskRunner::CreateAndStart("perfetto.prd.fake"); 119 runner_->PostTaskAndWaitForTesting([this]() { 120 producer_.reset( 121 new FakeProducer("android.perfetto.FakeProducer", runner_->get())); 122 }); 123 } 124 ~FakeProducerThread()125 ~FakeProducerThread() { 126 runner_->PostTaskAndWaitForTesting([this]() { producer_.reset(); }); 127 } 128 Connect()129 void Connect() { 130 runner_->PostTaskAndWaitForTesting([this]() { 131 producer_->Connect(producer_socket_.c_str(), std::move(connect_callback_), 132 std::move(setup_callback_), std::move(start_callback_), 133 std::move(shm_), std::move(shm_arbiter_)); 134 }); 135 } 136 runner()137 base::ThreadTaskRunner* runner() { return runner_ ? &*runner_ : nullptr; } 138 producer()139 FakeProducer* producer() { return producer_.get(); } 140 CreateProducerProvidedSmb()141 void CreateProducerProvidedSmb() { 142 PosixSharedMemory::Factory factory; 143 shm_ = factory.CreateSharedMemory(1024 * 1024); 144 shm_arbiter_ = SharedMemoryArbiter::CreateUnboundInstance(shm_.get(), 4096); 145 } 146 ProduceStartupEventBatch(const protos::gen::TestConfig & config,std::function<void ()> callback)147 void ProduceStartupEventBatch(const protos::gen::TestConfig& config, 148 std::function<void()> callback) { 149 PERFETTO_CHECK(shm_arbiter_); 150 producer_->ProduceStartupEventBatch(config, shm_arbiter_.get(), callback); 151 } 152 153 private: 154 base::Optional<base::ThreadTaskRunner> runner_; // Keep first. 155 156 std::string producer_socket_; 157 std::unique_ptr<FakeProducer> producer_; 158 std::function<void()> connect_callback_; 159 std::function<void()> setup_callback_; 160 std::function<void()> start_callback_; 161 std::unique_ptr<SharedMemory> shm_; 162 std::unique_ptr<SharedMemoryArbiter> shm_arbiter_; 163 }; 164 165 class TestHelper : public Consumer { 166 public: 167 static const char* GetConsumerSocketName(); 168 static const char* GetProducerSocketName(); 169 170 explicit TestHelper(base::TestTaskRunner* task_runner); 171 172 // Consumer implementation. 173 void OnConnect() override; 174 void OnDisconnect() override; 175 void OnTracingDisabled(const std::string& error) override; 176 void OnTraceData(std::vector<TracePacket> packets, bool has_more) override; 177 void OnDetach(bool) override; 178 void OnAttach(bool, const TraceConfig&) override; 179 void OnTraceStats(bool, const TraceStats&) override; 180 void OnObservableEvents(const ObservableEvents&) override; 181 182 // Starts the tracing service unconditionally. 183 void StartService(); 184 185 // Starts the tracing service unless the build was configured to use an 186 // existing one running on the system. 187 void StartServiceIfRequired(); 188 189 // Connects the producer and waits that the service has seen the 190 // RegisterDataSource() call. 191 FakeProducer* ConnectFakeProducer(); 192 193 void ConnectConsumer(); 194 void StartTracing(const TraceConfig& config, 195 base::ScopedFile = base::ScopedFile()); 196 void DisableTracing(); 197 void FlushAndWait(uint32_t timeout_ms); 198 void ReadData(uint32_t read_count = 0); 199 void DetachConsumer(const std::string& key); 200 bool AttachConsumer(const std::string& key); 201 void CreateProducerProvidedSmb(); 202 bool IsShmemProvidedByProducer(); 203 void ProduceStartupEventBatch(const protos::gen::TestConfig& config); 204 205 void WaitForConsumerConnect(); 206 void WaitForProducerSetup(); 207 void WaitForProducerEnabled(); 208 void WaitForTracingDisabled(uint32_t timeout_ms = kDefaultTestTimeoutMs); 209 void WaitForReadData(uint32_t read_count = 0, 210 uint32_t timeout_ms = kDefaultTestTimeoutMs); 211 void SyncAndWaitProducer(); 212 TracingServiceState QueryServiceStateAndWait(); 213 AddID(const std::string & checkpoint)214 std::string AddID(const std::string& checkpoint) { 215 return checkpoint + "." + std::to_string(instance_num_); 216 } 217 CreateCheckpoint(const std::string & checkpoint)218 std::function<void()> CreateCheckpoint(const std::string& checkpoint) { 219 return task_runner_->CreateCheckpoint(AddID(checkpoint)); 220 } 221 222 void RunUntilCheckpoint(const std::string& checkpoint, 223 uint32_t timeout_ms = kDefaultTestTimeoutMs) { 224 return task_runner_->RunUntilCheckpoint(AddID(checkpoint), timeout_ms); 225 } 226 227 std::function<void()> WrapTask(const std::function<void()>& function); 228 service_thread()229 base::ThreadTaskRunner* service_thread() { return service_thread_.runner(); } producer_thread()230 base::ThreadTaskRunner* producer_thread() { 231 return fake_producer_thread_.runner(); 232 } full_trace()233 const std::vector<protos::gen::TracePacket>& full_trace() { 234 return full_trace_; 235 } trace()236 const std::vector<protos::gen::TracePacket>& trace() { return trace_; } 237 238 private: 239 static uint64_t next_instance_num_; 240 uint64_t instance_num_; 241 base::TestTaskRunner* task_runner_ = nullptr; 242 int cur_consumer_num_ = 0; 243 244 std::function<void()> on_connect_callback_; 245 std::function<void()> on_packets_finished_callback_; 246 std::function<void()> on_stop_tracing_callback_; 247 std::function<void()> on_detach_callback_; 248 std::function<void(bool)> on_attach_callback_; 249 250 std::vector<protos::gen::TracePacket> full_trace_; 251 std::vector<protos::gen::TracePacket> trace_; 252 253 ServiceThread service_thread_; 254 FakeProducerThread fake_producer_thread_; 255 256 std::unique_ptr<TracingService::ConsumerEndpoint> endpoint_; // Keep last. 257 }; 258 259 } // namespace perfetto 260 261 #endif // TEST_TEST_HELPER_H_ 262