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