xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/ftrace/binder_tracker_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2022 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/ftrace/binder_tracker.h"
18 
19 #include <cstdint>
20 
21 #include "src/trace_processor/importers/common/args_tracker.h"
22 #include "src/trace_processor/importers/common/args_translation_table.h"
23 #include "src/trace_processor/importers/common/event_tracker.h"
24 #include "src/trace_processor/importers/common/flow_tracker.h"
25 #include "src/trace_processor/importers/common/global_args_tracker.h"
26 #include "src/trace_processor/importers/common/process_tracker.h"
27 #include "src/trace_processor/importers/common/slice_tracker.h"
28 #include "src/trace_processor/importers/common/slice_translation_table.h"
29 #include "src/trace_processor/importers/common/track_tracker.h"
30 #include "src/trace_processor/storage/trace_storage.h"
31 #include "test/gtest_and_gmock.h"
32 
33 namespace perfetto::trace_processor {
34 namespace {
35 constexpr int kOneWay = 0x01;
36 
37 class BinderTrackerTest : public ::testing::Test {
38  public:
BinderTrackerTest()39   BinderTrackerTest() {
40     context.storage.reset(new TraceStorage());
41     context.global_args_tracker.reset(
42         new GlobalArgsTracker(context.storage.get()));
43     context.args_tracker.reset(new ArgsTracker(&context));
44     context.args_translation_table.reset(
45         new ArgsTranslationTable(context.storage.get()));
46     context.slice_tracker.reset(new SliceTracker(&context));
47     context.slice_translation_table.reset(
48         new SliceTranslationTable(context.storage.get()));
49     context.process_tracker.reset(new ProcessTracker(&context));
50     context.track_tracker.reset(new TrackTracker(&context));
51     context.flow_tracker.reset(new FlowTracker(&context));
52     binder_tracker = BinderTracker::GetOrCreate(&context);
53   }
54 
55  protected:
56   TraceProcessorContext context;
57   BinderTracker* binder_tracker;
58 };
59 
TEST_F(BinderTrackerTest,RequestReply)60 TEST_F(BinderTrackerTest, RequestReply) {
61   int64_t req_ts = 100;
62   int64_t req_recv_ts = 105;
63   int64_t rep_ts = 150;
64   int64_t rep_recv_ts = 155;
65 
66   uint32_t req_tid = 5;
67   uint32_t rep_tid = 10;
68 
69   int32_t req_transaction_id = 1234;
70   int32_t rep_transaction_id = 5678;
71 
72   binder_tracker->Transaction(req_ts, req_tid, req_transaction_id, 9, rep_tid,
73                               rep_tid, false, 0, kNullStringId);
74   binder_tracker->TransactionReceived(req_recv_ts, rep_tid, req_transaction_id);
75 
76   binder_tracker->Transaction(rep_ts, rep_tid, rep_transaction_id, 99, req_tid,
77                               req_tid, true, 0, kNullStringId);
78   binder_tracker->TransactionReceived(rep_recv_ts, req_tid, rep_transaction_id);
79 
80   const auto& thread = context.storage->thread_table();
81   const auto& track = context.storage->thread_track_table();
82   const auto& slice = context.storage->slice_table();
83   const auto& flow = context.storage->flow_table();
84   ASSERT_EQ(slice.row_count(), 2u);
85 
86   auto tid_for_slice = [&](uint32_t row) {
87     auto rr = track.FindById(slice[row].track_id());
88     return thread[rr->utid()].tid();
89   };
90 
91   ASSERT_EQ(slice[0].ts(), req_ts);
92   ASSERT_EQ(slice[0].dur(), rep_recv_ts - req_ts);
93   ASSERT_EQ(tid_for_slice(0), req_tid);
94 
95   ASSERT_EQ(slice[1].ts(), req_recv_ts);
96   ASSERT_EQ(slice[1].dur(), rep_ts - req_recv_ts);
97   ASSERT_EQ(tid_for_slice(1), rep_tid);
98 
99   ASSERT_EQ(flow.row_count(), 1u);
100   ASSERT_EQ(flow[0].slice_out(), slice[0].id());
101   ASSERT_EQ(flow[0].slice_in(), slice[1].id());
102 
103   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
104 }
105 
TEST_F(BinderTrackerTest,Oneway)106 TEST_F(BinderTrackerTest, Oneway) {
107   int64_t sen_ts = 100;
108   int64_t rec_ts = 150;
109 
110   uint32_t sen_tid = 5;
111   uint32_t rec_tid = 10;
112 
113   int32_t transaction_id = 1234;
114 
115   binder_tracker->Transaction(sen_ts, sen_tid, transaction_id, 9, rec_tid,
116                               rec_tid, false, kOneWay, kNullStringId);
117   binder_tracker->TransactionReceived(rec_ts, rec_tid, transaction_id);
118 
119   const auto& thread = context.storage->thread_table();
120   const auto& track = context.storage->thread_track_table();
121   const auto& slice = context.storage->slice_table();
122   const auto& flow = context.storage->flow_table();
123   ASSERT_EQ(slice.row_count(), 2u);
124 
125   auto tid_for_slice = [&](uint32_t row) {
126     TrackId track_id = slice[row].track_id();
127     auto rr = track.FindById(track_id);
128     return thread[rr->utid()].tid();
129   };
130 
131   ASSERT_EQ(slice[0].ts(), sen_ts);
132   ASSERT_EQ(slice[0].dur(), 0);
133   ASSERT_EQ(tid_for_slice(0), sen_tid);
134 
135   ASSERT_EQ(slice[1].ts(), rec_ts);
136   ASSERT_EQ(slice[1].dur(), 0);
137   ASSERT_EQ(tid_for_slice(1), rec_tid);
138 
139   ASSERT_EQ(flow.row_count(), 1u);
140   ASSERT_EQ(flow[0].slice_out(), slice[0].id());
141   ASSERT_EQ(flow[0].slice_in(), slice[1].id());
142 
143   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
144 }
145 
TEST_F(BinderTrackerTest,RequestReplyWithCommands)146 TEST_F(BinderTrackerTest, RequestReplyWithCommands) {
147   constexpr uint32_t kSndTid = 5;
148   constexpr uint32_t kRcvTid = 10;
149 
150   constexpr int32_t kTransactionId = 1234;
151   constexpr int32_t kReplyTransactionId = 5678;
152 
153   int64_t ts = 1;
154   binder_tracker->CommandToKernel(ts++, kSndTid,
155                                   BinderTracker::kBC_TRANSACTION);
156   binder_tracker->Transaction(ts++, kSndTid, kTransactionId, 9, kRcvTid,
157                               kRcvTid, false, 0, kNullStringId);
158   binder_tracker->TransactionReceived(ts++, kRcvTid, kTransactionId);
159   binder_tracker->ReturnFromKernel(ts++, kRcvTid,
160                                    BinderTracker::kBR_TRANSACTION);
161   binder_tracker->CommandToKernel(ts++, kRcvTid, BinderTracker::kBC_REPLY);
162   binder_tracker->Transaction(ts++, kRcvTid, kReplyTransactionId, 99, kSndTid,
163                               kSndTid, true, 0, kNullStringId);
164   binder_tracker->ReturnFromKernel(ts++, kRcvTid,
165                                    BinderTracker::kBR_TRANSACTION_COMPLETE);
166   binder_tracker->ReturnFromKernel(ts++, kSndTid,
167                                    BinderTracker::kBR_TRANSACTION_COMPLETE);
168   binder_tracker->TransactionReceived(ts++, kSndTid, kReplyTransactionId);
169   binder_tracker->ReturnFromKernel(ts++, kSndTid, BinderTracker::kBR_REPLY);
170 
171   const auto& slice = context.storage->slice_table();
172   ASSERT_EQ(slice.row_count(), 2u);
173   EXPECT_NE(slice[0].dur(), -1);
174   EXPECT_NE(slice[1].dur(), -1);
175 
176   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
177 }
178 
TEST_F(BinderTrackerTest,RequestReplyWithCommandsFailAfterBcTransaction)179 TEST_F(BinderTrackerTest, RequestReplyWithCommandsFailAfterBcTransaction) {
180   constexpr uint32_t kSndTid = 5;
181 
182   int64_t ts = 1;
183   binder_tracker->CommandToKernel(ts++, kSndTid,
184                                   BinderTracker::kBC_TRANSACTION);
185   binder_tracker->ReturnFromKernel(ts++, kSndTid,
186                                    BinderTracker::kBR_DEAD_REPLY);
187 
188   const auto& slice = context.storage->slice_table();
189   EXPECT_EQ(slice.row_count(), 0u);
190 
191   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
192 }
193 
TEST_F(BinderTrackerTest,RequestReplyWithCommandsFailAfterSendTxn)194 TEST_F(BinderTrackerTest, RequestReplyWithCommandsFailAfterSendTxn) {
195   constexpr uint32_t kSndTid = 5;
196   constexpr uint32_t kRcvTid = 10;
197 
198   constexpr int32_t kTransactionId = 1234;
199 
200   int64_t ts = 1;
201   binder_tracker->CommandToKernel(ts++, kSndTid,
202                                   BinderTracker::kBC_TRANSACTION);
203   binder_tracker->Transaction(ts++, kSndTid, kTransactionId, 9, kRcvTid,
204                               kRcvTid, false, 0, kNullStringId);
205   binder_tracker->ReturnFromKernel(ts++, kSndTid,
206                                    BinderTracker::kBR_FAILED_REPLY);
207 
208   const auto& slice = context.storage->slice_table();
209   ASSERT_EQ(slice.row_count(), 1u);
210   EXPECT_NE(slice[0].dur(), -1);
211 
212   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
213 }
214 
TEST_F(BinderTrackerTest,RequestReplyWithCommandsFailBeforeReplyTxn)215 TEST_F(BinderTrackerTest, RequestReplyWithCommandsFailBeforeReplyTxn) {
216   constexpr uint32_t kSndTid = 5;
217   constexpr uint32_t kRcvTid = 10;
218 
219   constexpr int32_t kTransactionId = 1234;
220 
221   int64_t ts = 1;
222   binder_tracker->CommandToKernel(ts++, kSndTid,
223                                   BinderTracker::kBC_TRANSACTION);
224   binder_tracker->Transaction(ts++, kSndTid, kTransactionId, 9, kRcvTid,
225                               kRcvTid, false, 0, kNullStringId);
226   binder_tracker->TransactionReceived(ts++, kRcvTid, kTransactionId);
227   binder_tracker->ReturnFromKernel(ts++, kRcvTid,
228                                    BinderTracker::kBR_TRANSACTION);
229   binder_tracker->CommandToKernel(ts++, kRcvTid, BinderTracker::kBC_REPLY);
230   binder_tracker->ReturnFromKernel(ts++, kRcvTid,
231                                    BinderTracker::kBR_FAILED_REPLY);
232   binder_tracker->ReturnFromKernel(ts++, kSndTid,
233                                    BinderTracker::kBR_TRANSACTION_COMPLETE);
234   binder_tracker->ReturnFromKernel(ts++, kSndTid,
235                                    BinderTracker::kBR_FAILED_REPLY);
236 
237   const auto& slice = context.storage->slice_table();
238   ASSERT_EQ(slice.row_count(), 2u);
239   EXPECT_NE(slice[0].dur(), -1);
240   EXPECT_NE(slice[1].dur(), -1);
241 
242   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
243 }
244 
TEST_F(BinderTrackerTest,RequestReplyWithCommandsFailAfterReplyTxn)245 TEST_F(BinderTrackerTest, RequestReplyWithCommandsFailAfterReplyTxn) {
246   constexpr uint32_t kSndTid = 5;
247   constexpr uint32_t kRcvTid = 10;
248 
249   constexpr int32_t kTransactionId = 1234;
250   constexpr int32_t kReplyTransactionId = 5678;
251 
252   int64_t ts = 1;
253   binder_tracker->CommandToKernel(ts++, kSndTid,
254                                   BinderTracker::kBC_TRANSACTION);
255   binder_tracker->Transaction(ts++, kSndTid, kTransactionId, 9, kRcvTid,
256                               kRcvTid, false, 0, kNullStringId);
257   binder_tracker->TransactionReceived(ts++, kRcvTid, kTransactionId);
258   binder_tracker->ReturnFromKernel(ts++, kRcvTid,
259                                    BinderTracker::kBR_TRANSACTION);
260   binder_tracker->CommandToKernel(ts++, kRcvTid, BinderTracker::kBC_REPLY);
261   binder_tracker->Transaction(ts++, kRcvTid, kReplyTransactionId, 99, kSndTid,
262                               kSndTid, true, 0, kNullStringId);
263   binder_tracker->ReturnFromKernel(ts++, kRcvTid,
264                                    BinderTracker::kBR_TRANSACTION_COMPLETE);
265   binder_tracker->ReturnFromKernel(ts++, kSndTid,
266                                    BinderTracker::kBR_TRANSACTION_COMPLETE);
267   binder_tracker->ReturnFromKernel(ts++, kSndTid,
268                                    BinderTracker::kBR_FAILED_REPLY);
269 
270   const auto& slice = context.storage->slice_table();
271   ASSERT_EQ(slice.row_count(), 2u);
272   EXPECT_NE(slice[0].dur(), -1);
273   EXPECT_NE(slice[1].dur(), -1);
274 
275   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
276 }
277 
TEST_F(BinderTrackerTest,OneWayWithCommands)278 TEST_F(BinderTrackerTest, OneWayWithCommands) {
279   constexpr uint32_t kSndTid = 5;
280   constexpr uint32_t kRcvTid = 10;
281 
282   constexpr int32_t kTransactionId = 1234;
283 
284   int64_t ts = 1;
285   binder_tracker->CommandToKernel(ts++, kSndTid,
286                                   BinderTracker::kBC_TRANSACTION);
287   binder_tracker->Transaction(ts++, kSndTid, kTransactionId, 9, kRcvTid,
288                               kRcvTid, false, kOneWay, kNullStringId);
289   binder_tracker->ReturnFromKernel(ts++, kSndTid,
290                                    BinderTracker::kBR_TRANSACTION_COMPLETE);
291   binder_tracker->TransactionReceived(ts++, kRcvTid, kTransactionId);
292   binder_tracker->ReturnFromKernel(ts++, kRcvTid,
293                                    BinderTracker::kBR_TRANSACTION);
294 
295   const auto& slice = context.storage->slice_table();
296   ASSERT_EQ(slice.row_count(), 2u);
297   EXPECT_EQ(slice[0].dur(), 0);
298   EXPECT_EQ(slice[1].dur(), 0);
299 
300   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
301 }
302 
TEST_F(BinderTrackerTest,OneWayWithCommandsFailBeforeTxn)303 TEST_F(BinderTrackerTest, OneWayWithCommandsFailBeforeTxn) {
304   constexpr uint32_t kSndTid = 5;
305 
306   int64_t ts = 1;
307   binder_tracker->CommandToKernel(ts++, kSndTid,
308                                   BinderTracker::kBC_TRANSACTION);
309   binder_tracker->ReturnFromKernel(ts++, kSndTid,
310                                    BinderTracker::kBR_FAILED_REPLY);
311 
312   const auto& slice = context.storage->slice_table();
313   EXPECT_EQ(slice.row_count(), 0u);
314 
315   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
316 }
317 
TEST_F(BinderTrackerTest,OneWayWithCommandsFailAfterTxn)318 TEST_F(BinderTrackerTest, OneWayWithCommandsFailAfterTxn) {
319   constexpr uint32_t kSndTid = 5;
320   constexpr uint32_t kRcvTid = 10;
321 
322   constexpr int32_t kTransactionId = 1234;
323 
324   int64_t ts = 1;
325   binder_tracker->CommandToKernel(ts++, kSndTid,
326                                   BinderTracker::kBC_TRANSACTION);
327   binder_tracker->Transaction(ts++, kSndTid, kTransactionId, 9, kRcvTid,
328                               kRcvTid, false, kOneWay, kNullStringId);
329   binder_tracker->ReturnFromKernel(ts++, kSndTid,
330                                    BinderTracker::kBR_FAILED_REPLY);
331 
332   const auto& slice = context.storage->slice_table();
333   ASSERT_EQ(slice.row_count(), 1u);
334   EXPECT_EQ(slice[0].dur(), 0);
335 
336   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
337 }
338 
339 }  // namespace
340 }  // namespace perfetto::trace_processor
341