1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker *
4*6dbdd20aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker *
8*6dbdd20aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker *
10*6dbdd20aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker */
16*6dbdd20aSAndroid Build Coastguard Worker
17*6dbdd20aSAndroid Build Coastguard Worker #ifndef SRC_SHARED_LIB_TEST_UTILS_H_
18*6dbdd20aSAndroid Build Coastguard Worker #define SRC_SHARED_LIB_TEST_UTILS_H_
19*6dbdd20aSAndroid Build Coastguard Worker
20*6dbdd20aSAndroid Build Coastguard Worker #include <cassert>
21*6dbdd20aSAndroid Build Coastguard Worker #include <condition_variable>
22*6dbdd20aSAndroid Build Coastguard Worker #include <cstdint>
23*6dbdd20aSAndroid Build Coastguard Worker #include <functional>
24*6dbdd20aSAndroid Build Coastguard Worker #include <iterator>
25*6dbdd20aSAndroid Build Coastguard Worker #include <memory>
26*6dbdd20aSAndroid Build Coastguard Worker #include <mutex>
27*6dbdd20aSAndroid Build Coastguard Worker #include <ostream>
28*6dbdd20aSAndroid Build Coastguard Worker #include <string>
29*6dbdd20aSAndroid Build Coastguard Worker #include <vector>
30*6dbdd20aSAndroid Build Coastguard Worker
31*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/public/abi/pb_decoder_abi.h"
32*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/public/pb_utils.h"
33*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/public/tracing_session.h"
34*6dbdd20aSAndroid Build Coastguard Worker
35*6dbdd20aSAndroid Build Coastguard Worker #include "test/gtest_and_gmock.h"
36*6dbdd20aSAndroid Build Coastguard Worker
37*6dbdd20aSAndroid Build Coastguard Worker // Pretty printer for gtest
38*6dbdd20aSAndroid Build Coastguard Worker void PrintTo(const PerfettoPbDecoderField& field, std::ostream*);
39*6dbdd20aSAndroid Build Coastguard Worker
40*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
41*6dbdd20aSAndroid Build Coastguard Worker namespace shlib {
42*6dbdd20aSAndroid Build Coastguard Worker namespace test_utils {
43*6dbdd20aSAndroid Build Coastguard Worker
44*6dbdd20aSAndroid Build Coastguard Worker class WaitableEvent {
45*6dbdd20aSAndroid Build Coastguard Worker public:
46*6dbdd20aSAndroid Build Coastguard Worker WaitableEvent() = default;
Notify()47*6dbdd20aSAndroid Build Coastguard Worker void Notify() {
48*6dbdd20aSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(m_);
49*6dbdd20aSAndroid Build Coastguard Worker notified_ = true;
50*6dbdd20aSAndroid Build Coastguard Worker cv_.notify_one();
51*6dbdd20aSAndroid Build Coastguard Worker }
WaitForNotification()52*6dbdd20aSAndroid Build Coastguard Worker bool WaitForNotification() {
53*6dbdd20aSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(m_);
54*6dbdd20aSAndroid Build Coastguard Worker cv_.wait(lock, [this] { return notified_; });
55*6dbdd20aSAndroid Build Coastguard Worker return notified_;
56*6dbdd20aSAndroid Build Coastguard Worker }
IsNotified()57*6dbdd20aSAndroid Build Coastguard Worker bool IsNotified() {
58*6dbdd20aSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(m_);
59*6dbdd20aSAndroid Build Coastguard Worker return notified_;
60*6dbdd20aSAndroid Build Coastguard Worker }
61*6dbdd20aSAndroid Build Coastguard Worker
62*6dbdd20aSAndroid Build Coastguard Worker private:
63*6dbdd20aSAndroid Build Coastguard Worker std::mutex m_;
64*6dbdd20aSAndroid Build Coastguard Worker std::condition_variable cv_;
65*6dbdd20aSAndroid Build Coastguard Worker bool notified_ = false;
66*6dbdd20aSAndroid Build Coastguard Worker };
67*6dbdd20aSAndroid Build Coastguard Worker
68*6dbdd20aSAndroid Build Coastguard Worker class TracingSession {
69*6dbdd20aSAndroid Build Coastguard Worker public:
70*6dbdd20aSAndroid Build Coastguard Worker class Builder {
71*6dbdd20aSAndroid Build Coastguard Worker public:
72*6dbdd20aSAndroid Build Coastguard Worker Builder() = default;
set_data_source_name(std::string data_source_name)73*6dbdd20aSAndroid Build Coastguard Worker Builder& set_data_source_name(std::string data_source_name) {
74*6dbdd20aSAndroid Build Coastguard Worker data_source_name_ = std::move(data_source_name);
75*6dbdd20aSAndroid Build Coastguard Worker return *this;
76*6dbdd20aSAndroid Build Coastguard Worker }
add_enabled_category(std::string category)77*6dbdd20aSAndroid Build Coastguard Worker Builder& add_enabled_category(std::string category) {
78*6dbdd20aSAndroid Build Coastguard Worker enabled_categories_.push_back(std::move(category));
79*6dbdd20aSAndroid Build Coastguard Worker return *this;
80*6dbdd20aSAndroid Build Coastguard Worker }
add_disabled_category(std::string category)81*6dbdd20aSAndroid Build Coastguard Worker Builder& add_disabled_category(std::string category) {
82*6dbdd20aSAndroid Build Coastguard Worker disabled_categories_.push_back(std::move(category));
83*6dbdd20aSAndroid Build Coastguard Worker return *this;
84*6dbdd20aSAndroid Build Coastguard Worker }
85*6dbdd20aSAndroid Build Coastguard Worker TracingSession Build();
86*6dbdd20aSAndroid Build Coastguard Worker
87*6dbdd20aSAndroid Build Coastguard Worker private:
88*6dbdd20aSAndroid Build Coastguard Worker std::string data_source_name_;
89*6dbdd20aSAndroid Build Coastguard Worker std::vector<std::string> enabled_categories_;
90*6dbdd20aSAndroid Build Coastguard Worker std::vector<std::string> disabled_categories_;
91*6dbdd20aSAndroid Build Coastguard Worker };
92*6dbdd20aSAndroid Build Coastguard Worker
93*6dbdd20aSAndroid Build Coastguard Worker static TracingSession Adopt(struct PerfettoTracingSessionImpl*);
94*6dbdd20aSAndroid Build Coastguard Worker
95*6dbdd20aSAndroid Build Coastguard Worker TracingSession(TracingSession&&) noexcept;
96*6dbdd20aSAndroid Build Coastguard Worker
97*6dbdd20aSAndroid Build Coastguard Worker ~TracingSession();
98*6dbdd20aSAndroid Build Coastguard Worker
session()99*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTracingSessionImpl* session() const { return session_; }
100*6dbdd20aSAndroid Build Coastguard Worker
101*6dbdd20aSAndroid Build Coastguard Worker bool FlushBlocking(uint32_t timeout_ms);
102*6dbdd20aSAndroid Build Coastguard Worker // Waits for the tracing session to be stopped.
103*6dbdd20aSAndroid Build Coastguard Worker void WaitForStopped();
104*6dbdd20aSAndroid Build Coastguard Worker // Asks the tracing session to stop. Doesn't wait for it to be stopped.
105*6dbdd20aSAndroid Build Coastguard Worker void StopAsync();
106*6dbdd20aSAndroid Build Coastguard Worker // Equivalent to StopAsync() + WaitForStopped().
107*6dbdd20aSAndroid Build Coastguard Worker void StopBlocking();
108*6dbdd20aSAndroid Build Coastguard Worker std::vector<uint8_t> ReadBlocking();
109*6dbdd20aSAndroid Build Coastguard Worker
110*6dbdd20aSAndroid Build Coastguard Worker private:
111*6dbdd20aSAndroid Build Coastguard Worker TracingSession() = default;
112*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTracingSessionImpl* session_;
113*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<WaitableEvent> stopped_;
114*6dbdd20aSAndroid Build Coastguard Worker };
115*6dbdd20aSAndroid Build Coastguard Worker
116*6dbdd20aSAndroid Build Coastguard Worker template <typename FieldSkipper>
117*6dbdd20aSAndroid Build Coastguard Worker class FieldViewBase {
118*6dbdd20aSAndroid Build Coastguard Worker public:
119*6dbdd20aSAndroid Build Coastguard Worker class Iterator {
120*6dbdd20aSAndroid Build Coastguard Worker public:
121*6dbdd20aSAndroid Build Coastguard Worker using iterator_category = std::input_iterator_tag;
122*6dbdd20aSAndroid Build Coastguard Worker using value_type = const PerfettoPbDecoderField;
123*6dbdd20aSAndroid Build Coastguard Worker using pointer = value_type;
124*6dbdd20aSAndroid Build Coastguard Worker using reference = value_type;
125*6dbdd20aSAndroid Build Coastguard Worker reference operator*() const {
126*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoPbDecoder decoder;
127*6dbdd20aSAndroid Build Coastguard Worker decoder.read_ptr = read_ptr_;
128*6dbdd20aSAndroid Build Coastguard Worker decoder.end_ptr = end_ptr_;
129*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoPbDecoderField field;
130*6dbdd20aSAndroid Build Coastguard Worker do {
131*6dbdd20aSAndroid Build Coastguard Worker field = PerfettoPbDecoderParseField(&decoder);
132*6dbdd20aSAndroid Build Coastguard Worker } while (field.status == PERFETTO_PB_DECODER_OK &&
133*6dbdd20aSAndroid Build Coastguard Worker skipper_.ShouldSkip(field));
134*6dbdd20aSAndroid Build Coastguard Worker return field;
135*6dbdd20aSAndroid Build Coastguard Worker }
136*6dbdd20aSAndroid Build Coastguard Worker Iterator& operator++() {
137*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoPbDecoder decoder;
138*6dbdd20aSAndroid Build Coastguard Worker decoder.read_ptr = read_ptr_;
139*6dbdd20aSAndroid Build Coastguard Worker decoder.end_ptr = end_ptr_;
140*6dbdd20aSAndroid Build Coastguard Worker PerfettoPbDecoderSkipField(&decoder);
141*6dbdd20aSAndroid Build Coastguard Worker read_ptr_ = decoder.read_ptr;
142*6dbdd20aSAndroid Build Coastguard Worker AdvanceToFirstInterestingField();
143*6dbdd20aSAndroid Build Coastguard Worker return *this;
144*6dbdd20aSAndroid Build Coastguard Worker }
145*6dbdd20aSAndroid Build Coastguard Worker Iterator operator++(int) {
146*6dbdd20aSAndroid Build Coastguard Worker Iterator tmp = *this;
147*6dbdd20aSAndroid Build Coastguard Worker ++(*this);
148*6dbdd20aSAndroid Build Coastguard Worker return tmp;
149*6dbdd20aSAndroid Build Coastguard Worker }
150*6dbdd20aSAndroid Build Coastguard Worker
151*6dbdd20aSAndroid Build Coastguard Worker friend bool operator==(const Iterator& a, const Iterator& b) {
152*6dbdd20aSAndroid Build Coastguard Worker return a.read_ptr_ == b.read_ptr_;
153*6dbdd20aSAndroid Build Coastguard Worker }
154*6dbdd20aSAndroid Build Coastguard Worker friend bool operator!=(const Iterator& a, const Iterator& b) {
155*6dbdd20aSAndroid Build Coastguard Worker return a.read_ptr_ != b.read_ptr_;
156*6dbdd20aSAndroid Build Coastguard Worker }
157*6dbdd20aSAndroid Build Coastguard Worker
158*6dbdd20aSAndroid Build Coastguard Worker private:
Iterator(const uint8_t * read_ptr,const uint8_t * end_ptr,const FieldSkipper & skipper)159*6dbdd20aSAndroid Build Coastguard Worker Iterator(const uint8_t* read_ptr,
160*6dbdd20aSAndroid Build Coastguard Worker const uint8_t* end_ptr,
161*6dbdd20aSAndroid Build Coastguard Worker const FieldSkipper& skipper)
162*6dbdd20aSAndroid Build Coastguard Worker : read_ptr_(read_ptr), end_ptr_(end_ptr), skipper_(skipper) {
163*6dbdd20aSAndroid Build Coastguard Worker AdvanceToFirstInterestingField();
164*6dbdd20aSAndroid Build Coastguard Worker }
AdvanceToFirstInterestingField()165*6dbdd20aSAndroid Build Coastguard Worker void AdvanceToFirstInterestingField() {
166*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoPbDecoder decoder;
167*6dbdd20aSAndroid Build Coastguard Worker decoder.read_ptr = read_ptr_;
168*6dbdd20aSAndroid Build Coastguard Worker decoder.end_ptr = end_ptr_;
169*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoPbDecoderField field;
170*6dbdd20aSAndroid Build Coastguard Worker const uint8_t* prev_read_ptr;
171*6dbdd20aSAndroid Build Coastguard Worker do {
172*6dbdd20aSAndroid Build Coastguard Worker prev_read_ptr = decoder.read_ptr;
173*6dbdd20aSAndroid Build Coastguard Worker field = PerfettoPbDecoderParseField(&decoder);
174*6dbdd20aSAndroid Build Coastguard Worker } while (field.status == PERFETTO_PB_DECODER_OK &&
175*6dbdd20aSAndroid Build Coastguard Worker skipper_.ShouldSkip(field));
176*6dbdd20aSAndroid Build Coastguard Worker if (field.status == PERFETTO_PB_DECODER_OK) {
177*6dbdd20aSAndroid Build Coastguard Worker read_ptr_ = prev_read_ptr;
178*6dbdd20aSAndroid Build Coastguard Worker } else {
179*6dbdd20aSAndroid Build Coastguard Worker read_ptr_ = decoder.read_ptr;
180*6dbdd20aSAndroid Build Coastguard Worker }
181*6dbdd20aSAndroid Build Coastguard Worker }
182*6dbdd20aSAndroid Build Coastguard Worker friend class FieldViewBase<FieldSkipper>;
183*6dbdd20aSAndroid Build Coastguard Worker const uint8_t* read_ptr_;
184*6dbdd20aSAndroid Build Coastguard Worker const uint8_t* end_ptr_;
185*6dbdd20aSAndroid Build Coastguard Worker const FieldSkipper& skipper_;
186*6dbdd20aSAndroid Build Coastguard Worker };
187*6dbdd20aSAndroid Build Coastguard Worker using value_type = const PerfettoPbDecoderField;
188*6dbdd20aSAndroid Build Coastguard Worker using const_iterator = Iterator;
189*6dbdd20aSAndroid Build Coastguard Worker template <typename... Args>
FieldViewBase(const uint8_t * begin,const uint8_t * end,Args...args)190*6dbdd20aSAndroid Build Coastguard Worker explicit FieldViewBase(const uint8_t* begin, const uint8_t* end, Args... args)
191*6dbdd20aSAndroid Build Coastguard Worker : begin_(begin), end_(end), s_(args...) {}
192*6dbdd20aSAndroid Build Coastguard Worker template <typename... Args>
FieldViewBase(const std::vector<uint8_t> & data,Args...args)193*6dbdd20aSAndroid Build Coastguard Worker explicit FieldViewBase(const std::vector<uint8_t>& data, Args... args)
194*6dbdd20aSAndroid Build Coastguard Worker : FieldViewBase(data.data(), data.data() + data.size(), args...) {}
195*6dbdd20aSAndroid Build Coastguard Worker template <typename... Args>
FieldViewBase(const struct PerfettoPbDecoderField & field,Args...args)196*6dbdd20aSAndroid Build Coastguard Worker explicit FieldViewBase(const struct PerfettoPbDecoderField& field,
197*6dbdd20aSAndroid Build Coastguard Worker Args... args)
198*6dbdd20aSAndroid Build Coastguard Worker : s_(args...) {
199*6dbdd20aSAndroid Build Coastguard Worker if (field.wire_type != PERFETTO_PB_WIRE_TYPE_DELIMITED) {
200*6dbdd20aSAndroid Build Coastguard Worker abort();
201*6dbdd20aSAndroid Build Coastguard Worker }
202*6dbdd20aSAndroid Build Coastguard Worker begin_ = field.value.delimited.start;
203*6dbdd20aSAndroid Build Coastguard Worker end_ = begin_ + field.value.delimited.len;
204*6dbdd20aSAndroid Build Coastguard Worker }
begin()205*6dbdd20aSAndroid Build Coastguard Worker Iterator begin() const { return Iterator(begin_, end_, s_); }
end()206*6dbdd20aSAndroid Build Coastguard Worker Iterator end() const { return Iterator(end_, end_, s_); }
front()207*6dbdd20aSAndroid Build Coastguard Worker PerfettoPbDecoderField front() const { return *begin(); }
208*6dbdd20aSAndroid Build Coastguard Worker
size()209*6dbdd20aSAndroid Build Coastguard Worker size_t size() const {
210*6dbdd20aSAndroid Build Coastguard Worker size_t count = 0;
211*6dbdd20aSAndroid Build Coastguard Worker for (auto field : *this) {
212*6dbdd20aSAndroid Build Coastguard Worker (void)field;
213*6dbdd20aSAndroid Build Coastguard Worker count++;
214*6dbdd20aSAndroid Build Coastguard Worker }
215*6dbdd20aSAndroid Build Coastguard Worker return count;
216*6dbdd20aSAndroid Build Coastguard Worker }
217*6dbdd20aSAndroid Build Coastguard Worker
ok()218*6dbdd20aSAndroid Build Coastguard Worker bool ok() const {
219*6dbdd20aSAndroid Build Coastguard Worker for (auto field : *this) {
220*6dbdd20aSAndroid Build Coastguard Worker if (field.status != PERFETTO_PB_DECODER_OK) {
221*6dbdd20aSAndroid Build Coastguard Worker return false;
222*6dbdd20aSAndroid Build Coastguard Worker }
223*6dbdd20aSAndroid Build Coastguard Worker }
224*6dbdd20aSAndroid Build Coastguard Worker return true;
225*6dbdd20aSAndroid Build Coastguard Worker }
226*6dbdd20aSAndroid Build Coastguard Worker
227*6dbdd20aSAndroid Build Coastguard Worker private:
228*6dbdd20aSAndroid Build Coastguard Worker const uint8_t* begin_;
229*6dbdd20aSAndroid Build Coastguard Worker const uint8_t* end_;
230*6dbdd20aSAndroid Build Coastguard Worker FieldSkipper s_;
231*6dbdd20aSAndroid Build Coastguard Worker };
232*6dbdd20aSAndroid Build Coastguard Worker
233*6dbdd20aSAndroid Build Coastguard Worker // Pretty printer for gtest
234*6dbdd20aSAndroid Build Coastguard Worker template <typename FieldSkipper>
PrintTo(const FieldViewBase<FieldSkipper> & field_view,std::ostream * pos)235*6dbdd20aSAndroid Build Coastguard Worker void PrintTo(const FieldViewBase<FieldSkipper>& field_view, std::ostream* pos) {
236*6dbdd20aSAndroid Build Coastguard Worker std::ostream& os = *pos;
237*6dbdd20aSAndroid Build Coastguard Worker os << "{";
238*6dbdd20aSAndroid Build Coastguard Worker for (PerfettoPbDecoderField f : field_view) {
239*6dbdd20aSAndroid Build Coastguard Worker PrintTo(f, pos);
240*6dbdd20aSAndroid Build Coastguard Worker os << ", ";
241*6dbdd20aSAndroid Build Coastguard Worker }
242*6dbdd20aSAndroid Build Coastguard Worker os << "}";
243*6dbdd20aSAndroid Build Coastguard Worker }
244*6dbdd20aSAndroid Build Coastguard Worker
245*6dbdd20aSAndroid Build Coastguard Worker class IdFieldSkipper {
246*6dbdd20aSAndroid Build Coastguard Worker public:
IdFieldSkipper(uint32_t id)247*6dbdd20aSAndroid Build Coastguard Worker explicit IdFieldSkipper(uint32_t id) : id_(id) {}
IdFieldSkipper(int32_t id)248*6dbdd20aSAndroid Build Coastguard Worker explicit IdFieldSkipper(int32_t id) : id_(static_cast<uint32_t>(id)) {}
ShouldSkip(const struct PerfettoPbDecoderField & field)249*6dbdd20aSAndroid Build Coastguard Worker bool ShouldSkip(const struct PerfettoPbDecoderField& field) const {
250*6dbdd20aSAndroid Build Coastguard Worker return field.id != id_;
251*6dbdd20aSAndroid Build Coastguard Worker }
252*6dbdd20aSAndroid Build Coastguard Worker
253*6dbdd20aSAndroid Build Coastguard Worker private:
254*6dbdd20aSAndroid Build Coastguard Worker uint32_t id_;
255*6dbdd20aSAndroid Build Coastguard Worker };
256*6dbdd20aSAndroid Build Coastguard Worker
257*6dbdd20aSAndroid Build Coastguard Worker class NoFieldSkipper {
258*6dbdd20aSAndroid Build Coastguard Worker public:
259*6dbdd20aSAndroid Build Coastguard Worker NoFieldSkipper() = default;
ShouldSkip(const struct PerfettoPbDecoderField &)260*6dbdd20aSAndroid Build Coastguard Worker bool ShouldSkip(const struct PerfettoPbDecoderField&) const { return false; }
261*6dbdd20aSAndroid Build Coastguard Worker };
262*6dbdd20aSAndroid Build Coastguard Worker
263*6dbdd20aSAndroid Build Coastguard Worker // View over all the fields of a contiguous serialized protobuf message.
264*6dbdd20aSAndroid Build Coastguard Worker //
265*6dbdd20aSAndroid Build Coastguard Worker // Examples:
266*6dbdd20aSAndroid Build Coastguard Worker //
267*6dbdd20aSAndroid Build Coastguard Worker // for (struct PerfettoPbDecoderField field : FieldView(msg_begin, msg_end)) {
268*6dbdd20aSAndroid Build Coastguard Worker // //...
269*6dbdd20aSAndroid Build Coastguard Worker // }
270*6dbdd20aSAndroid Build Coastguard Worker // FieldView fields2(/*PerfettoPbDecoderField*/ nested_field);
271*6dbdd20aSAndroid Build Coastguard Worker // FieldView fields3(/*std::vector<uint8_t>*/ data);
272*6dbdd20aSAndroid Build Coastguard Worker // size_t num = fields1.size(); // The number of fields.
273*6dbdd20aSAndroid Build Coastguard Worker // bool ok = fields1.ok(); // Checks that the message is not malformed.
274*6dbdd20aSAndroid Build Coastguard Worker using FieldView = FieldViewBase<NoFieldSkipper>;
275*6dbdd20aSAndroid Build Coastguard Worker
276*6dbdd20aSAndroid Build Coastguard Worker // Like `FieldView`, but only considers fields with a specific id.
277*6dbdd20aSAndroid Build Coastguard Worker //
278*6dbdd20aSAndroid Build Coastguard Worker // Examples:
279*6dbdd20aSAndroid Build Coastguard Worker //
280*6dbdd20aSAndroid Build Coastguard Worker // IdFieldView fields(msg_begin, msg_end, id)
281*6dbdd20aSAndroid Build Coastguard Worker using IdFieldView = FieldViewBase<IdFieldSkipper>;
282*6dbdd20aSAndroid Build Coastguard Worker
283*6dbdd20aSAndroid Build Coastguard Worker // Matches a PerfettoPbDecoderField with the specified id. Accepts another
284*6dbdd20aSAndroid Build Coastguard Worker // matcher to match the contents of the field.
285*6dbdd20aSAndroid Build Coastguard Worker //
286*6dbdd20aSAndroid Build Coastguard Worker // Example:
287*6dbdd20aSAndroid Build Coastguard Worker // PerfettoPbDecoderField field = ...
288*6dbdd20aSAndroid Build Coastguard Worker // EXPECT_THAT(field, PbField(900, VarIntField(5)));
289*6dbdd20aSAndroid Build Coastguard Worker template <typename M>
PbField(int32_t id,M m)290*6dbdd20aSAndroid Build Coastguard Worker auto PbField(int32_t id, M m) {
291*6dbdd20aSAndroid Build Coastguard Worker return testing::AllOf(
292*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK),
293*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::id, id), m);
294*6dbdd20aSAndroid Build Coastguard Worker }
295*6dbdd20aSAndroid Build Coastguard Worker
296*6dbdd20aSAndroid Build Coastguard Worker // Matches a PerfettoPbDecoderField submessage field. Accepts a container
297*6dbdd20aSAndroid Build Coastguard Worker // matcher for the subfields.
298*6dbdd20aSAndroid Build Coastguard Worker //
299*6dbdd20aSAndroid Build Coastguard Worker // Example:
300*6dbdd20aSAndroid Build Coastguard Worker // PerfettoPbDecoderField field = ...
301*6dbdd20aSAndroid Build Coastguard Worker // EXPECT_THAT(field, MsgField(ElementsAre(...)));
302*6dbdd20aSAndroid Build Coastguard Worker template <typename M>
MsgField(M m)303*6dbdd20aSAndroid Build Coastguard Worker auto MsgField(M m) {
304*6dbdd20aSAndroid Build Coastguard Worker auto f = [](const PerfettoPbDecoderField& field) { return FieldView(field); };
305*6dbdd20aSAndroid Build Coastguard Worker return testing::AllOf(
306*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK),
307*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::wire_type,
308*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_PB_WIRE_TYPE_DELIMITED),
309*6dbdd20aSAndroid Build Coastguard Worker testing::ResultOf(f, m));
310*6dbdd20aSAndroid Build Coastguard Worker }
311*6dbdd20aSAndroid Build Coastguard Worker
312*6dbdd20aSAndroid Build Coastguard Worker // Matches a PerfettoPbDecoderField length delimited field. Accepts a string
313*6dbdd20aSAndroid Build Coastguard Worker // matcher.
314*6dbdd20aSAndroid Build Coastguard Worker //
315*6dbdd20aSAndroid Build Coastguard Worker // Example:
316*6dbdd20aSAndroid Build Coastguard Worker // PerfettoPbDecoderField field = ...
317*6dbdd20aSAndroid Build Coastguard Worker // EXPECT_THAT(field, StringField("string"));
318*6dbdd20aSAndroid Build Coastguard Worker template <typename M>
StringField(M m)319*6dbdd20aSAndroid Build Coastguard Worker auto StringField(M m) {
320*6dbdd20aSAndroid Build Coastguard Worker auto f = [](const PerfettoPbDecoderField& field) {
321*6dbdd20aSAndroid Build Coastguard Worker return std::string(
322*6dbdd20aSAndroid Build Coastguard Worker reinterpret_cast<const char*>(field.value.delimited.start),
323*6dbdd20aSAndroid Build Coastguard Worker field.value.delimited.len);
324*6dbdd20aSAndroid Build Coastguard Worker };
325*6dbdd20aSAndroid Build Coastguard Worker return testing::AllOf(
326*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK),
327*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::wire_type,
328*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_PB_WIRE_TYPE_DELIMITED),
329*6dbdd20aSAndroid Build Coastguard Worker testing::ResultOf(f, m));
330*6dbdd20aSAndroid Build Coastguard Worker }
331*6dbdd20aSAndroid Build Coastguard Worker
332*6dbdd20aSAndroid Build Coastguard Worker // Matches a PerfettoPbDecoderField VarInt field. Accepts an integer matcher
333*6dbdd20aSAndroid Build Coastguard Worker //
334*6dbdd20aSAndroid Build Coastguard Worker // Example:
335*6dbdd20aSAndroid Build Coastguard Worker // PerfettoPbDecoderField field = ...
336*6dbdd20aSAndroid Build Coastguard Worker // EXPECT_THAT(field, VarIntField(1)));
337*6dbdd20aSAndroid Build Coastguard Worker template <typename M>
VarIntField(M m)338*6dbdd20aSAndroid Build Coastguard Worker auto VarIntField(M m) {
339*6dbdd20aSAndroid Build Coastguard Worker auto f = [](const PerfettoPbDecoderField& field) {
340*6dbdd20aSAndroid Build Coastguard Worker return field.value.integer64;
341*6dbdd20aSAndroid Build Coastguard Worker };
342*6dbdd20aSAndroid Build Coastguard Worker return testing::AllOf(
343*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK),
344*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::wire_type,
345*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_PB_WIRE_TYPE_VARINT),
346*6dbdd20aSAndroid Build Coastguard Worker testing::ResultOf(f, m));
347*6dbdd20aSAndroid Build Coastguard Worker }
348*6dbdd20aSAndroid Build Coastguard Worker
349*6dbdd20aSAndroid Build Coastguard Worker // Matches a PerfettoPbDecoderField fixed64 field. Accepts an integer matcher
350*6dbdd20aSAndroid Build Coastguard Worker //
351*6dbdd20aSAndroid Build Coastguard Worker // Example:
352*6dbdd20aSAndroid Build Coastguard Worker // PerfettoPbDecoderField field = ...
353*6dbdd20aSAndroid Build Coastguard Worker // EXPECT_THAT(field, Fixed64Field(1)));
354*6dbdd20aSAndroid Build Coastguard Worker template <typename M>
Fixed64Field(M m)355*6dbdd20aSAndroid Build Coastguard Worker auto Fixed64Field(M m) {
356*6dbdd20aSAndroid Build Coastguard Worker auto f = [](const PerfettoPbDecoderField& field) {
357*6dbdd20aSAndroid Build Coastguard Worker return field.value.integer64;
358*6dbdd20aSAndroid Build Coastguard Worker };
359*6dbdd20aSAndroid Build Coastguard Worker return testing::AllOf(
360*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK),
361*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::wire_type,
362*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_PB_WIRE_TYPE_FIXED64),
363*6dbdd20aSAndroid Build Coastguard Worker testing::ResultOf(f, m));
364*6dbdd20aSAndroid Build Coastguard Worker }
365*6dbdd20aSAndroid Build Coastguard Worker
366*6dbdd20aSAndroid Build Coastguard Worker // Matches a PerfettoPbDecoderField fixed32 field. Accepts an integer matcher
367*6dbdd20aSAndroid Build Coastguard Worker //
368*6dbdd20aSAndroid Build Coastguard Worker // Example:
369*6dbdd20aSAndroid Build Coastguard Worker // PerfettoPbDecoderField field = ...
370*6dbdd20aSAndroid Build Coastguard Worker // EXPECT_THAT(field, Fixed32Field(1)));
371*6dbdd20aSAndroid Build Coastguard Worker template <typename M>
Fixed32Field(M m)372*6dbdd20aSAndroid Build Coastguard Worker auto Fixed32Field(M m) {
373*6dbdd20aSAndroid Build Coastguard Worker auto f = [](const PerfettoPbDecoderField& field) {
374*6dbdd20aSAndroid Build Coastguard Worker return field.value.integer32;
375*6dbdd20aSAndroid Build Coastguard Worker };
376*6dbdd20aSAndroid Build Coastguard Worker return testing::AllOf(
377*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK),
378*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::wire_type,
379*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_PB_WIRE_TYPE_FIXED32),
380*6dbdd20aSAndroid Build Coastguard Worker testing::ResultOf(f, m));
381*6dbdd20aSAndroid Build Coastguard Worker }
382*6dbdd20aSAndroid Build Coastguard Worker
383*6dbdd20aSAndroid Build Coastguard Worker // Matches a PerfettoPbDecoderField double field. Accepts an double matcher
384*6dbdd20aSAndroid Build Coastguard Worker //
385*6dbdd20aSAndroid Build Coastguard Worker // Example:
386*6dbdd20aSAndroid Build Coastguard Worker // PerfettoPbDecoderField field = ...
387*6dbdd20aSAndroid Build Coastguard Worker // EXPECT_THAT(field, DoubleField(1.0)));
388*6dbdd20aSAndroid Build Coastguard Worker template <typename M>
DoubleField(M m)389*6dbdd20aSAndroid Build Coastguard Worker auto DoubleField(M m) {
390*6dbdd20aSAndroid Build Coastguard Worker auto f = [](const PerfettoPbDecoderField& field) {
391*6dbdd20aSAndroid Build Coastguard Worker return field.value.double_val;
392*6dbdd20aSAndroid Build Coastguard Worker };
393*6dbdd20aSAndroid Build Coastguard Worker return testing::AllOf(
394*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK),
395*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::wire_type,
396*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_PB_WIRE_TYPE_FIXED64),
397*6dbdd20aSAndroid Build Coastguard Worker testing::ResultOf(f, m));
398*6dbdd20aSAndroid Build Coastguard Worker }
399*6dbdd20aSAndroid Build Coastguard Worker
400*6dbdd20aSAndroid Build Coastguard Worker // Matches a PerfettoPbDecoderField float field. Accepts a float matcher
401*6dbdd20aSAndroid Build Coastguard Worker //
402*6dbdd20aSAndroid Build Coastguard Worker // Example:
403*6dbdd20aSAndroid Build Coastguard Worker // PerfettoPbDecoderField field = ...
404*6dbdd20aSAndroid Build Coastguard Worker // EXPECT_THAT(field, FloatField(1.0)));
405*6dbdd20aSAndroid Build Coastguard Worker template <typename M>
FloatField(M m)406*6dbdd20aSAndroid Build Coastguard Worker auto FloatField(M m) {
407*6dbdd20aSAndroid Build Coastguard Worker auto f = [](const PerfettoPbDecoderField& field) {
408*6dbdd20aSAndroid Build Coastguard Worker return field.value.float_val;
409*6dbdd20aSAndroid Build Coastguard Worker };
410*6dbdd20aSAndroid Build Coastguard Worker return testing::AllOf(
411*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK),
412*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::wire_type,
413*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_PB_WIRE_TYPE_FIXED32),
414*6dbdd20aSAndroid Build Coastguard Worker testing::ResultOf(f, m));
415*6dbdd20aSAndroid Build Coastguard Worker }
416*6dbdd20aSAndroid Build Coastguard Worker
417*6dbdd20aSAndroid Build Coastguard Worker // Matches a PerfettoPbDecoderField submessage field. Accepts a container
418*6dbdd20aSAndroid Build Coastguard Worker // matcher for the subfields.
419*6dbdd20aSAndroid Build Coastguard Worker //
420*6dbdd20aSAndroid Build Coastguard Worker // Example:
421*6dbdd20aSAndroid Build Coastguard Worker // PerfettoPbDecoderField field = ...
422*6dbdd20aSAndroid Build Coastguard Worker // EXPECT_THAT(field, AllFieldsWithId(900, ElementsAre(...)));
423*6dbdd20aSAndroid Build Coastguard Worker template <typename M>
AllFieldsWithId(int32_t id,M m)424*6dbdd20aSAndroid Build Coastguard Worker auto AllFieldsWithId(int32_t id, M m) {
425*6dbdd20aSAndroid Build Coastguard Worker auto f = [id](const PerfettoPbDecoderField& field) {
426*6dbdd20aSAndroid Build Coastguard Worker return IdFieldView(field, id);
427*6dbdd20aSAndroid Build Coastguard Worker };
428*6dbdd20aSAndroid Build Coastguard Worker return testing::AllOf(
429*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK),
430*6dbdd20aSAndroid Build Coastguard Worker testing::Field(&PerfettoPbDecoderField::wire_type,
431*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_PB_WIRE_TYPE_DELIMITED),
432*6dbdd20aSAndroid Build Coastguard Worker testing::ResultOf(f, m));
433*6dbdd20aSAndroid Build Coastguard Worker }
434*6dbdd20aSAndroid Build Coastguard Worker
435*6dbdd20aSAndroid Build Coastguard Worker } // namespace test_utils
436*6dbdd20aSAndroid Build Coastguard Worker } // namespace shlib
437*6dbdd20aSAndroid Build Coastguard Worker } // namespace perfetto
438*6dbdd20aSAndroid Build Coastguard Worker
439*6dbdd20aSAndroid Build Coastguard Worker #endif // SRC_SHARED_LIB_TEST_UTILS_H_
440