xref: /aosp_15_r20/external/perfetto/src/trace_processor/sorter/trace_token_buffer_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2023 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/sorter/trace_token_buffer.h"
18 
19 #include <optional>
20 
21 #include "perfetto/base/compiler.h"
22 #include "perfetto/trace_processor/ref_counted.h"
23 #include "perfetto/trace_processor/trace_blob.h"
24 #include "perfetto/trace_processor/trace_blob_view.h"
25 #include "src/trace_processor/importers/common/parser_types.h"
26 #include "src/trace_processor/importers/proto/packet_sequence_state_generation.h"
27 #include "src/trace_processor/types/trace_processor_context.h"
28 #include "test/gtest_and_gmock.h"
29 
30 namespace perfetto {
31 namespace trace_processor {
32 namespace {
33 
34 class TraceTokenBufferUnittest : public testing::Test {
35  protected:
36   TraceTokenBuffer store;
37   TraceProcessorContext context;
38   RefPtr<PacketSequenceStateGeneration> state =
39       PacketSequenceStateGeneration::CreateFirst(&context);
40 };
41 
TEST_F(TraceTokenBufferUnittest,TracePacketDataInOut)42 TEST_F(TraceTokenBufferUnittest, TracePacketDataInOut) {
43   TraceBlobView tbv(TraceBlob::Allocate(1024));
44   TracePacketData tpd{tbv.copy(), state};
45 
46   TraceTokenBuffer::Id id = store.Append(std::move(tpd));
47   TracePacketData extracted = store.Extract<TracePacketData>(id);
48   ASSERT_EQ(extracted.packet, tbv);
49   ASSERT_EQ(extracted.sequence_state, state);
50 }
51 
TEST_F(TraceTokenBufferUnittest,PacketAppendMultipleBlobs)52 TEST_F(TraceTokenBufferUnittest, PacketAppendMultipleBlobs) {
53   TraceBlobView tbv_1(TraceBlob::Allocate(1024));
54   TraceBlobView tbv_2(TraceBlob::Allocate(2048));
55   TraceBlobView tbv_3(TraceBlob::Allocate(4096));
56 
57   TraceTokenBuffer::Id id_1 =
58       store.Append(TracePacketData{tbv_1.copy(), state});
59   TraceTokenBuffer::Id id_2 =
60       store.Append(TracePacketData{tbv_2.copy(), state});
61   ASSERT_EQ(store.Extract<TracePacketData>(id_1).packet, tbv_1);
62   ASSERT_EQ(store.Extract<TracePacketData>(id_2).packet, tbv_2);
63 
64   TraceTokenBuffer::Id id_3 =
65       store.Append(TracePacketData{tbv_3.copy(), state});
66   ASSERT_EQ(store.Extract<TracePacketData>(id_3).packet, tbv_3);
67 }
68 
TEST_F(TraceTokenBufferUnittest,BlobSharing)69 TEST_F(TraceTokenBufferUnittest, BlobSharing) {
70   TraceBlobView root(TraceBlob::Allocate(2048));
71   TraceBlobView tbv_1 = root.slice_off(0, 1024);
72   TraceBlobView tbv_2 = root.slice_off(1024, 512);
73   TraceBlobView tbv_3 = root.slice_off(1536, 512);
74 
75   TraceTokenBuffer::Id id_1 =
76       store.Append(TracePacketData{tbv_1.copy(), state});
77   TraceTokenBuffer::Id id_2 =
78       store.Append(TracePacketData{tbv_2.copy(), state});
79   ASSERT_EQ(store.Extract<TracePacketData>(id_1).packet, tbv_1);
80   ASSERT_EQ(store.Extract<TracePacketData>(id_2).packet, tbv_2);
81 
82   TraceTokenBuffer::Id id_3 =
83       store.Append(TracePacketData{tbv_3.copy(), state});
84   ASSERT_EQ(store.Extract<TracePacketData>(id_3).packet, tbv_3);
85 }
86 
TEST_F(TraceTokenBufferUnittest,SequenceStateSharing)87 TEST_F(TraceTokenBufferUnittest, SequenceStateSharing) {
88   TraceBlobView root(TraceBlob::Allocate(2048));
89   TraceBlobView tbv_1 = root.slice_off(0, 1024);
90   TraceBlobView tbv_2 = root.slice_off(1024, 512);
91 
92   TraceTokenBuffer::Id id_1 =
93       store.Append(TracePacketData{tbv_1.copy(), state});
94   TraceTokenBuffer::Id id_2 =
95       store.Append(TracePacketData{tbv_2.copy(), state});
96   ASSERT_EQ(store.Extract<TracePacketData>(id_1).sequence_state, state);
97   ASSERT_EQ(store.Extract<TracePacketData>(id_2).sequence_state, state);
98 }
99 
TEST_F(TraceTokenBufferUnittest,ManySequenceState)100 TEST_F(TraceTokenBufferUnittest, ManySequenceState) {
101   TraceBlobView root(TraceBlob::Allocate(1024));
102 
103   std::array<TraceTokenBuffer::Id, 1024> ids;
104   std::array<PacketSequenceStateGeneration*, 1024> refs;
105   for (uint32_t i = 0; i < 1024; ++i) {
106     refs[i] = state.get();
107     ids[i] = store.Append(TracePacketData{root.slice_off(i, 1), state});
108     state = state->OnNewTracePacketDefaults(TraceBlobView());
109   }
110 
111   for (uint32_t i = 0; i < 1024; ++i) {
112     ASSERT_EQ(refs[i],
113               store.Extract<TracePacketData>(ids[i]).sequence_state.get());
114   }
115 }
116 
TEST_F(TraceTokenBufferUnittest,PacketLargeOffset)117 TEST_F(TraceTokenBufferUnittest, PacketLargeOffset) {
118   TraceBlobView tbv(TraceBlob::Allocate(256ul * 1024));
119 
120   TraceBlobView slice_1 = tbv.slice_off(0, 1024ul);
121   TraceTokenBuffer::Id id_1 =
122       store.Append(TracePacketData{slice_1.copy(), state});
123   TracePacketData out_1 = store.Extract<TracePacketData>(id_1);
124   ASSERT_EQ(out_1.packet, slice_1);
125   ASSERT_EQ(out_1.sequence_state, state);
126 
127   TraceBlobView slice_2 = tbv.slice_off(128ul * 1024, 1024ul);
128   TraceTokenBuffer::Id id_2 =
129       store.Append(TracePacketData{slice_2.copy(), state});
130   TracePacketData out_2 = store.Extract<TracePacketData>(id_2);
131   ASSERT_EQ(out_2.packet, slice_2);
132   ASSERT_EQ(out_2.sequence_state, state);
133 }
134 
TEST_F(TraceTokenBufferUnittest,TrackEventDataInOut)135 TEST_F(TraceTokenBufferUnittest, TrackEventDataInOut) {
136   TraceBlobView tbv(TraceBlob::Allocate(1234));
137   TrackEventData ted(tbv.copy(), state);
138   ted.thread_instruction_count = 123;
139   ted.extra_counter_values = {10, 2, 0, 0, 0, 0, 0, 0};
140   auto counter_array = ted.extra_counter_values;
141 
142   TraceTokenBuffer::Id id = store.Append(std::move(ted));
143   TrackEventData extracted = store.Extract<TrackEventData>(id);
144   ASSERT_EQ(extracted.trace_packet_data.packet, tbv);
145   ASSERT_EQ(extracted.trace_packet_data.sequence_state, state);
146   ASSERT_EQ(extracted.thread_instruction_count, 123);
147   ASSERT_EQ(extracted.thread_timestamp, std::nullopt);
148   ASSERT_DOUBLE_EQ(extracted.counter_value, 0.0);
149   ASSERT_EQ(extracted.extra_counter_values, counter_array);
150 }
151 
TEST_F(TraceTokenBufferUnittest,ExtractOrAppendAfterFreeMemory)152 TEST_F(TraceTokenBufferUnittest, ExtractOrAppendAfterFreeMemory) {
153   auto unused_res = store.Extract<TraceBlobView>(
154       store.Append(TraceBlobView(TraceBlob::Allocate(1234))));
155   base::ignore_result(unused_res);
156 
157   store.FreeMemory();
158 
159   TraceTokenBuffer::Id id =
160       store.Append(TraceBlobView(TraceBlob::Allocate(4567)));
161   TraceBlobView tbv = store.Extract<TraceBlobView>(id);
162   ASSERT_EQ(tbv.size(), 4567u);
163 }
164 
165 }  // namespace
166 }  // namespace trace_processor
167 }  // namespace perfetto
168