1 /*
2 * Copyright (C) 2019 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/util/protozero_to_text.h"
18
19 #include "perfetto/protozero/scattered_heap_buffer.h"
20 #include "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.h"
21 #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
22 #include "src/trace_processor/importers/track_event.descriptor.h"
23 #include "src/trace_processor/util/descriptors.h"
24 #include "test/gtest_and_gmock.h"
25
26 namespace perfetto {
27 namespace trace_processor {
28 namespace protozero_to_text {
29
30 namespace {
31
32 constexpr size_t kChunkSize = 42;
33
34 using ::testing::_;
35 using ::testing::Eq;
36
TEST(ProtozeroToTextTest,TrackEventBasic)37 TEST(ProtozeroToTextTest, TrackEventBasic) {
38 using perfetto::protos::pbzero::TrackEvent;
39 protozero::HeapBuffered<TrackEvent> msg{kChunkSize, kChunkSize};
40 msg->set_track_uuid(4);
41 msg->set_timestamp_delta_us(3);
42 auto binary_proto = msg.SerializeAsArray();
43 EXPECT_EQ(
44 "track_uuid: 4\ntimestamp_delta_us: 3",
45 DebugTrackEventProtozeroToText(
46 ".perfetto.protos.TrackEvent",
47 protozero::ConstBytes{binary_proto.data(), binary_proto.size()}));
48 EXPECT_EQ(
49 "track_uuid: 4 timestamp_delta_us: 3",
50 ShortDebugTrackEventProtozeroToText(
51 ".perfetto.protos.TrackEvent",
52 protozero::ConstBytes{binary_proto.data(), binary_proto.size()}));
53 }
54
TEST(ProtozeroToTextTest,TrackEventNestedMsg)55 TEST(ProtozeroToTextTest, TrackEventNestedMsg) {
56 using perfetto::protos::pbzero::TrackEvent;
57 protozero::HeapBuffered<TrackEvent> msg{kChunkSize, kChunkSize};
58 msg->set_track_uuid(4);
59 auto* state = msg->set_cc_scheduler_state();
60 state->set_deadline_us(7);
61 auto* machine = state->set_state_machine();
62 auto* minor_state = machine->set_minor_state();
63 minor_state->set_commit_count(8);
64 state->set_observing_begin_frame_source(true);
65 msg->set_timestamp_delta_us(3);
66 auto binary_proto = msg.SerializeAsArray();
67
68 EXPECT_EQ(
69 R"(track_uuid: 4
70 cc_scheduler_state: {
71 deadline_us: 7
72 state_machine: {
73 minor_state: {
74 commit_count: 8
75 }
76 }
77 observing_begin_frame_source: true
78 }
79 timestamp_delta_us: 3)",
80 DebugTrackEventProtozeroToText(
81 ".perfetto.protos.TrackEvent",
82 protozero::ConstBytes{binary_proto.data(), binary_proto.size()}));
83
84 EXPECT_EQ(
85 "track_uuid: 4 cc_scheduler_state: { deadline_us: 7 state_machine: { "
86 "minor_state: { commit_count: 8 } } observing_begin_frame_source: true } "
87 "timestamp_delta_us: 3",
88 ShortDebugTrackEventProtozeroToText(
89 ".perfetto.protos.TrackEvent",
90 protozero::ConstBytes{binary_proto.data(), binary_proto.size()}));
91 }
92
TEST(ProtozeroToTextTest,TrackEventEnumNames)93 TEST(ProtozeroToTextTest, TrackEventEnumNames) {
94 using perfetto::protos::pbzero::TrackEvent;
95 protozero::HeapBuffered<TrackEvent> msg{kChunkSize, kChunkSize};
96 msg->set_type(TrackEvent::TYPE_SLICE_BEGIN);
97 auto binary_proto = msg.SerializeAsArray();
98 EXPECT_EQ(
99 "type: TYPE_SLICE_BEGIN",
100 DebugTrackEventProtozeroToText(
101 ".perfetto.protos.TrackEvent",
102 protozero::ConstBytes{binary_proto.data(), binary_proto.size()}));
103 EXPECT_EQ(
104 "type: TYPE_SLICE_BEGIN",
105 DebugTrackEventProtozeroToText(
106 ".perfetto.protos.TrackEvent",
107 protozero::ConstBytes{binary_proto.data(), binary_proto.size()}));
108 }
109
TEST(ProtozeroToTextTest,CustomDescriptorPoolBasic)110 TEST(ProtozeroToTextTest, CustomDescriptorPoolBasic) {
111 using perfetto::protos::pbzero::TrackEvent;
112 protozero::HeapBuffered<TrackEvent> msg{kChunkSize, kChunkSize};
113 msg->set_track_uuid(4);
114 msg->set_timestamp_delta_us(3);
115 auto binary_proto = msg.SerializeAsArray();
116 DescriptorPool pool;
117 auto status = pool.AddFromFileDescriptorSet(kTrackEventDescriptor.data(),
118 kTrackEventDescriptor.size());
119 ASSERT_TRUE(status.ok());
120 EXPECT_EQ("track_uuid: 4\ntimestamp_delta_us: 3",
121 ProtozeroToText(pool, ".perfetto.protos.TrackEvent", binary_proto,
122 kIncludeNewLines));
123 EXPECT_EQ("track_uuid: 4 timestamp_delta_us: 3",
124 ProtozeroToText(pool, ".perfetto.protos.TrackEvent", binary_proto,
125 kSkipNewLines));
126 }
127
TEST(ProtozeroToTextTest,CustomDescriptorPoolNestedMsg)128 TEST(ProtozeroToTextTest, CustomDescriptorPoolNestedMsg) {
129 using perfetto::protos::pbzero::TrackEvent;
130 protozero::HeapBuffered<TrackEvent> msg{kChunkSize, kChunkSize};
131 msg->set_track_uuid(4);
132 auto* state = msg->set_cc_scheduler_state();
133 state->set_deadline_us(7);
134 auto* machine = state->set_state_machine();
135 auto* minor_state = machine->set_minor_state();
136 minor_state->set_commit_count(8);
137 state->set_observing_begin_frame_source(true);
138 msg->set_timestamp_delta_us(3);
139 auto binary_proto = msg.SerializeAsArray();
140
141 DescriptorPool pool;
142 auto status = pool.AddFromFileDescriptorSet(kTrackEventDescriptor.data(),
143 kTrackEventDescriptor.size());
144 ASSERT_TRUE(status.ok());
145
146 EXPECT_EQ(
147 R"(track_uuid: 4
148 cc_scheduler_state: {
149 deadline_us: 7
150 state_machine: {
151 minor_state: {
152 commit_count: 8
153 }
154 }
155 observing_begin_frame_source: true
156 }
157 timestamp_delta_us: 3)",
158 ProtozeroToText(pool, ".perfetto.protos.TrackEvent", binary_proto,
159 kIncludeNewLines));
160
161 EXPECT_EQ(
162 "track_uuid: 4 cc_scheduler_state: { deadline_us: 7 state_machine: { "
163 "minor_state: { commit_count: 8 } } observing_begin_frame_source: true } "
164 "timestamp_delta_us: 3",
165 ProtozeroToText(pool, ".perfetto.protos.TrackEvent", binary_proto,
166 kSkipNewLines));
167 }
168
TEST(ProtozeroToTextTest,EnumToString)169 TEST(ProtozeroToTextTest, EnumToString) {
170 using perfetto::protos::pbzero::TrackEvent;
171 EXPECT_EQ("TYPE_SLICE_END",
172 ProtozeroEnumToText(".perfetto.protos.TrackEvent.Type",
173 TrackEvent::TYPE_SLICE_END));
174 }
175
TEST(ProtozeroToTextTest,UnknownField)176 TEST(ProtozeroToTextTest, UnknownField) {
177 using perfetto::protos::pbzero::TrackEvent;
178 // Wrong type to force unknown field:
179 const auto type = ".perfetto.protos.ChromeCompositorSchedulerState";
180 protozero::HeapBuffered<TrackEvent> msg{kChunkSize, kChunkSize};
181 auto* state = msg->set_cc_scheduler_state();
182 state->set_deadline_us(7);
183 auto* machine = state->set_state_machine();
184 auto* minor_state = machine->set_minor_state();
185 minor_state->set_commit_count(8);
186 auto bytes = msg.SerializeAsArray();
187
188 DescriptorPool pool;
189 auto status = pool.AddFromFileDescriptorSet(kTrackEventDescriptor.data(),
190 kTrackEventDescriptor.size());
191 ASSERT_TRUE(status.ok());
192 ASSERT_EQ(ProtozeroToText(pool, type, bytes, kIncludeNewLines),
193 "# Ignoring unknown field with id: 24");
194 }
195
TEST(ProtozeroToTextTest,StringField)196 TEST(ProtozeroToTextTest, StringField) {
197 using perfetto::protos::pbzero::TrackEvent;
198 // Wrong type to force unknown field:
199 const auto type = ".perfetto.protos.TrackEvent";
200 protozero::HeapBuffered<TrackEvent> msg{kChunkSize, kChunkSize};
201 msg->add_categories(R"(Hello, "World")");
202 auto bytes = msg.SerializeAsArray();
203
204 DescriptorPool pool;
205 auto status = pool.AddFromFileDescriptorSet(kTrackEventDescriptor.data(),
206 kTrackEventDescriptor.size());
207 ASSERT_TRUE(status.ok());
208 ASSERT_EQ(ProtozeroToText(pool, type, bytes, kIncludeNewLines),
209 "categories: \"Hello, \\\"World\\\"\"");
210 }
211
TEST(ProtozeroToTextTest,BytesField)212 TEST(ProtozeroToTextTest, BytesField) {
213 EXPECT_EQ(BytesToHexEncodedStringForTesting("abc"), R"(\x61\x62\x63)");
214 }
215
216 } // namespace
217 } // namespace protozero_to_text
218 } // namespace trace_processor
219 } // namespace perfetto
220