xref: /aosp_15_r20/external/perfetto/src/shared_lib/test/utils.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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