• 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 #include "test/test_helper.h"
18 
19 #include "perfetto/ext/traced/traced.h"
20 #include "perfetto/ext/tracing/core/trace_packet.h"
21 #include "perfetto/ext/tracing/ipc/default_socket.h"
22 #include "perfetto/tracing/core/tracing_service_state.h"
23 
24 #include "protos/perfetto/trace/trace_packet.pbzero.h"
25 
26 namespace perfetto {
27 
28 uint64_t TestHelper::next_instance_num_ = 0;
29 
30 // If we're building on Android and starting the daemons ourselves,
31 // create the sockets in a world-writable location.
32 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
33     PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
34 #define TEST_PRODUCER_SOCK_NAME "/data/local/tmp/traced_producer"
35 #define TEST_CONSUMER_SOCK_NAME "/data/local/tmp/traced_consumer"
36 #else
37 #define TEST_PRODUCER_SOCK_NAME ::perfetto::GetProducerSocket()
38 #define TEST_CONSUMER_SOCK_NAME ::perfetto::GetConsumerSocket()
39 #endif
40 
TestHelper(base::TestTaskRunner * task_runner)41 TestHelper::TestHelper(base::TestTaskRunner* task_runner)
42     : instance_num_(next_instance_num_++),
43       task_runner_(task_runner),
44       service_thread_(TEST_PRODUCER_SOCK_NAME, TEST_CONSUMER_SOCK_NAME),
45       fake_producer_thread_(TEST_PRODUCER_SOCK_NAME,
46                             WrapTask(CreateCheckpoint("producer.connect")),
47                             WrapTask(CreateCheckpoint("producer.setup")),
48                             WrapTask(CreateCheckpoint("producer.enabled"))) {}
49 
OnConnect()50 void TestHelper::OnConnect() {
51   std::move(on_connect_callback_)();
52 }
53 
OnDisconnect()54 void TestHelper::OnDisconnect() {
55   PERFETTO_FATAL("Consumer unexpectedly disconnected from the service");
56 }
57 
OnTracingDisabled()58 void TestHelper::OnTracingDisabled() {
59   std::move(on_stop_tracing_callback_)();
60 }
61 
OnTraceData(std::vector<TracePacket> packets,bool has_more)62 void TestHelper::OnTraceData(std::vector<TracePacket> packets, bool has_more) {
63   for (auto& encoded_packet : packets) {
64     protos::gen::TracePacket packet;
65     PERFETTO_CHECK(
66         packet.ParseFromString(encoded_packet.GetRawBytesForTesting()));
67     if (packet.has_clock_snapshot() || packet.has_trace_config() ||
68         packet.has_trace_stats() || !packet.synchronization_marker().empty() ||
69         packet.has_system_info() || packet.has_service_event()) {
70       continue;
71     }
72     PERFETTO_CHECK(packet.has_trusted_uid());
73     trace_.push_back(std::move(packet));
74   }
75 
76   if (!has_more) {
77     std::move(on_packets_finished_callback_)();
78   }
79 }
80 
StartServiceIfRequired()81 void TestHelper::StartServiceIfRequired() {
82 #if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
83   service_thread_.Start();
84 #endif
85 }
86 
ConnectFakeProducer()87 FakeProducer* TestHelper::ConnectFakeProducer() {
88   fake_producer_thread_.Connect();
89   // This will wait until the service has seen the RegisterDataSource() call
90   // (because of the Sync() in FakeProducer::OnConnect()).
91   RunUntilCheckpoint("producer.connect");
92   return fake_producer_thread_.producer();
93 }
94 
ConnectConsumer()95 void TestHelper::ConnectConsumer() {
96   cur_consumer_num_++;
97   on_connect_callback_ = CreateCheckpoint("consumer.connected." +
98                                           std::to_string(cur_consumer_num_));
99   endpoint_ =
100       ConsumerIPCClient::Connect(TEST_CONSUMER_SOCK_NAME, this, task_runner_);
101 }
102 
DetachConsumer(const std::string & key)103 void TestHelper::DetachConsumer(const std::string& key) {
104   on_detach_callback_ = CreateCheckpoint("detach." + key);
105   endpoint_->Detach(key);
106   RunUntilCheckpoint("detach." + key);
107   endpoint_.reset();
108 }
109 
AttachConsumer(const std::string & key)110 bool TestHelper::AttachConsumer(const std::string& key) {
111   bool success = false;
112   auto checkpoint = CreateCheckpoint("attach." + key);
113   on_attach_callback_ = [&success, checkpoint](bool s) {
114     success = s;
115     checkpoint();
116   };
117   endpoint_->Attach(key);
118   RunUntilCheckpoint("attach." + key);
119   return success;
120 }
121 
CreateProducerProvidedSmb()122 void TestHelper::CreateProducerProvidedSmb() {
123   fake_producer_thread_.CreateProducerProvidedSmb();
124 }
125 
IsShmemProvidedByProducer()126 bool TestHelper::IsShmemProvidedByProducer() {
127   return fake_producer_thread_.producer()->IsShmemProvidedByProducer();
128 }
129 
ProduceStartupEventBatch(const protos::gen::TestConfig & config)130 void TestHelper::ProduceStartupEventBatch(
131     const protos::gen::TestConfig& config) {
132   auto on_data_written = CreateCheckpoint("startup_data_written");
133   fake_producer_thread_.ProduceStartupEventBatch(config,
134                                                  WrapTask(on_data_written));
135   RunUntilCheckpoint("startup_data_written");
136 }
137 
StartTracing(const TraceConfig & config,base::ScopedFile file)138 void TestHelper::StartTracing(const TraceConfig& config,
139                               base::ScopedFile file) {
140   trace_.clear();
141   on_stop_tracing_callback_ = CreateCheckpoint("stop.tracing");
142   endpoint_->EnableTracing(config, std::move(file));
143 }
144 
DisableTracing()145 void TestHelper::DisableTracing() {
146   endpoint_->DisableTracing();
147 }
148 
FlushAndWait(uint32_t timeout_ms)149 void TestHelper::FlushAndWait(uint32_t timeout_ms) {
150   static int flush_num = 0;
151   std::string checkpoint_name = "flush." + std::to_string(flush_num++);
152   auto checkpoint = CreateCheckpoint(checkpoint_name);
153   endpoint_->Flush(timeout_ms, [checkpoint](bool) { checkpoint(); });
154   RunUntilCheckpoint(checkpoint_name, timeout_ms + 1000);
155 }
156 
ReadData(uint32_t read_count)157 void TestHelper::ReadData(uint32_t read_count) {
158   on_packets_finished_callback_ =
159       CreateCheckpoint("readback.complete." + std::to_string(read_count));
160   endpoint_->ReadBuffers();
161 }
162 
WaitForConsumerConnect()163 void TestHelper::WaitForConsumerConnect() {
164   RunUntilCheckpoint("consumer.connected." + std::to_string(cur_consumer_num_));
165 }
166 
WaitForProducerSetup()167 void TestHelper::WaitForProducerSetup() {
168   RunUntilCheckpoint("producer.setup");
169 }
170 
WaitForProducerEnabled()171 void TestHelper::WaitForProducerEnabled() {
172   RunUntilCheckpoint("producer.enabled");
173 }
174 
WaitForTracingDisabled(uint32_t timeout_ms)175 void TestHelper::WaitForTracingDisabled(uint32_t timeout_ms) {
176   RunUntilCheckpoint("stop.tracing", timeout_ms);
177 }
178 
WaitForReadData(uint32_t read_count,uint32_t timeout_ms)179 void TestHelper::WaitForReadData(uint32_t read_count, uint32_t timeout_ms) {
180   RunUntilCheckpoint("readback.complete." + std::to_string(read_count),
181                      timeout_ms);
182 }
183 
SyncAndWaitProducer()184 void TestHelper::SyncAndWaitProducer() {
185   static int sync_id = 0;
186   std::string checkpoint_name = "producer_sync_" + std::to_string(++sync_id);
187   auto checkpoint = CreateCheckpoint(checkpoint_name);
188   fake_producer_thread_.producer()->Sync(
189       [this, &checkpoint] { task_runner_->PostTask(checkpoint); });
190   RunUntilCheckpoint(checkpoint_name);
191 }
192 
QueryServiceStateAndWait()193 TracingServiceState TestHelper::QueryServiceStateAndWait() {
194   TracingServiceState res;
195   auto checkpoint = CreateCheckpoint("query_svc_state");
196   auto callback = [&checkpoint, &res](bool, const TracingServiceState& tss) {
197     res = tss;
198     checkpoint();
199   };
200   endpoint_->QueryServiceState(callback);
201   RunUntilCheckpoint("query_svc_state");
202   return res;
203 }
204 
WrapTask(const std::function<void ()> & function)205 std::function<void()> TestHelper::WrapTask(
206     const std::function<void()>& function) {
207   return [this, function] { task_runner_->PostTask(function); };
208 }
209 
OnDetach(bool)210 void TestHelper::OnDetach(bool) {
211   if (on_detach_callback_)
212     std::move(on_detach_callback_)();
213 }
214 
OnAttach(bool success,const TraceConfig &)215 void TestHelper::OnAttach(bool success, const TraceConfig&) {
216   if (on_attach_callback_)
217     std::move(on_attach_callback_)(success);
218 }
219 
OnTraceStats(bool,const TraceStats &)220 void TestHelper::OnTraceStats(bool, const TraceStats&) {}
221 
OnObservableEvents(const ObservableEvents &)222 void TestHelper::OnObservableEvents(const ObservableEvents&) {}
223 
224 // static
GetConsumerSocketName()225 const char* TestHelper::GetConsumerSocketName() {
226   return TEST_CONSUMER_SOCK_NAME;
227 }
228 
229 // static
GetProducerSocketName()230 const char* TestHelper::GetProducerSocketName() {
231   return TEST_PRODUCER_SOCK_NAME;
232 }
233 
234 }  // namespace perfetto
235