xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/proto/proto_trace_tokenizer_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2024 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 "src/trace_processor/importers/proto/proto_trace_tokenizer.h"
18 
19 #include "perfetto/protozero/scattered_heap_buffer.h"
20 #include "test/gtest_and_gmock.h"
21 
22 namespace perfetto::trace_processor {
23 namespace {
24 
25 using testing::Invoke;
26 using testing::MockFunction;
27 
ToStringView(const TraceBlobView & tbv)28 std::string_view ToStringView(const TraceBlobView& tbv) {
29   return std::string_view(reinterpret_cast<const char*>(tbv.data()),
30                           tbv.size());
31 }
32 
TEST(ProtoTraceTokenizerTest,TwoPacketsSingleBlob)33 TEST(ProtoTraceTokenizerTest, TwoPacketsSingleBlob) {
34   protozero::HeapBuffered<protozero::Message> message;
35   message->AppendString(/*field_id=*/1, "payload1");
36   message->AppendString(/*field_id=*/1, "payload2");
37   std::vector<uint8_t> data = message.SerializeAsArray();
38 
39   MockFunction<base::Status(TraceBlobView)> cb;
40 
41   ProtoTraceTokenizer tokenizer;
42 
43   EXPECT_CALL(cb, Call)
44       .WillOnce(Invoke([](TraceBlobView out) {
45         EXPECT_EQ(ToStringView(out), "payload1");
46         return base::OkStatus();
47       }))
48       .WillOnce(Invoke([](TraceBlobView out) {
49         EXPECT_EQ(ToStringView(out), "payload2");
50         return base::OkStatus();
51       }));
52 
53   auto bv = TraceBlobView(TraceBlob::CopyFrom(data.data(), data.size()));
54   EXPECT_TRUE(tokenizer.Tokenize(std::move(bv), cb.AsStdFunction()).ok());
55 }
56 
TEST(ProtoTraceTokenizerTest,TwoPacketsByteByByte)57 TEST(ProtoTraceTokenizerTest, TwoPacketsByteByByte) {
58   protozero::HeapBuffered<protozero::Message> message;
59   message->AppendString(/*field_id=*/1, "payload1");
60   message->AppendString(/*field_id=*/1, "payload2");
61   std::vector<uint8_t> data = message.SerializeAsArray();
62 
63   ProtoTraceTokenizer tokenizer;
64 
65   MockFunction<base::Status(TraceBlobView)> cb;
66   EXPECT_CALL(cb, Call)
67       .WillOnce(Invoke([](TraceBlobView out) {
68         EXPECT_EQ(ToStringView(out), "payload1");
69         return base::OkStatus();
70       }))
71       .WillOnce(Invoke([](TraceBlobView out) {
72         EXPECT_EQ(ToStringView(out), "payload2");
73         return base::OkStatus();
74       }));
75 
76   for (uint8_t c : data) {
77     auto bv = TraceBlobView(TraceBlob::CopyFrom(&c, sizeof(c)));
78     EXPECT_TRUE(tokenizer.Tokenize(std::move(bv), cb.AsStdFunction()).ok());
79   }
80 }
81 
TEST(ProtoTraceTokenizerTest,SkipFieldsSingleBlob)82 TEST(ProtoTraceTokenizerTest, SkipFieldsSingleBlob) {
83   protozero::HeapBuffered<protozero::Message> message;
84   message->AppendVarInt(/*field_id=*/2, 42);
85   message->AppendString(/*field_id=*/1, "payload1");
86   message->AppendString(/*field_id=*/3, "ignored");
87   message->AppendFixed<uint32_t>(/*field_id=*/3, 42);
88   message->AppendString(/*field_id=*/1, "payload2");
89   message->AppendFixed<uint64_t>(/*field_id=*/3, 42);
90   message->AppendString(/*field_id=*/1, "payload3");
91   std::vector<uint8_t> data = message.SerializeAsArray();
92 
93   ProtoTraceTokenizer tokenizer;
94 
95   MockFunction<base::Status(TraceBlobView)> cb;
96   EXPECT_CALL(cb, Call)
97       .WillOnce(Invoke([](TraceBlobView out) {
98         EXPECT_EQ(ToStringView(out), "payload1");
99         return base::OkStatus();
100       }))
101       .WillOnce(Invoke([](TraceBlobView out) {
102         EXPECT_EQ(ToStringView(out), "payload2");
103         return base::OkStatus();
104       }))
105       .WillOnce(Invoke([](TraceBlobView out) {
106         EXPECT_EQ(ToStringView(out), "payload3");
107         return base::OkStatus();
108       }));
109 
110   auto bv = TraceBlobView(TraceBlob::CopyFrom(data.data(), data.size()));
111   EXPECT_TRUE(tokenizer.Tokenize(std::move(bv), cb.AsStdFunction()).ok());
112 }
113 
TEST(ProtoTraceTokenizerTest,SkipFieldsSingleByteByByte)114 TEST(ProtoTraceTokenizerTest, SkipFieldsSingleByteByByte) {
115   protozero::HeapBuffered<protozero::Message> message;
116   message->AppendVarInt(/*field_id=*/2, 42);
117   message->AppendString(/*field_id=*/1, "payload1");
118   message->AppendString(/*field_id=*/3, "ignored");
119   message->AppendFixed<uint32_t>(/*field_id=*/3, 42);
120   message->AppendString(/*field_id=*/1, "payload2");
121   message->AppendFixed<uint64_t>(/*field_id=*/3, 42);
122   message->AppendString(/*field_id=*/1, "payload3");
123   std::vector<uint8_t> data = message.SerializeAsArray();
124 
125   ProtoTraceTokenizer tokenizer;
126 
127   MockFunction<base::Status(TraceBlobView)> cb;
128   EXPECT_CALL(cb, Call)
129       .WillOnce(Invoke([](TraceBlobView out) {
130         EXPECT_EQ(ToStringView(out), "payload1");
131         return base::OkStatus();
132       }))
133       .WillOnce(Invoke([](TraceBlobView out) {
134         EXPECT_EQ(ToStringView(out), "payload2");
135         return base::OkStatus();
136       }))
137       .WillOnce(Invoke([](TraceBlobView out) {
138         EXPECT_EQ(ToStringView(out), "payload3");
139         return base::OkStatus();
140       }));
141 
142   for (uint8_t c : data) {
143     auto bv = TraceBlobView(TraceBlob::CopyFrom(&c, sizeof(c)));
144     EXPECT_TRUE(tokenizer.Tokenize(std::move(bv), cb.AsStdFunction()).ok());
145   }
146 }
147 
148 }  // namespace
149 }  // namespace perfetto::trace_processor
150