xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/syscalls/syscall_tracker_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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/importers/syscalls/syscall_tracker.h"
18 
19 #include "src/trace_processor/importers/common/global_args_tracker.h"
20 #include "src/trace_processor/importers/common/slice_tracker.h"
21 #include "test/gtest_and_gmock.h"
22 
23 namespace perfetto {
24 namespace trace_processor {
25 namespace {
26 
27 using ::testing::_;
28 using ::testing::DoAll;
29 using ::testing::Return;
30 using ::testing::SaveArg;
31 
32 class MockSliceTracker : public SliceTracker {
33  public:
MockSliceTracker(TraceProcessorContext * context)34   MockSliceTracker(TraceProcessorContext* context) : SliceTracker(context) {}
35   ~MockSliceTracker() override = default;
36 
37   MOCK_METHOD(std::optional<SliceId>,
38               Begin,
39               (int64_t timestamp,
40                TrackId track_id,
41                StringId cat,
42                StringId name,
43                SetArgsCallback args_callback),
44               (override));
45   MOCK_METHOD(std::optional<SliceId>,
46               End,
47               (int64_t timestamp,
48                TrackId track_id,
49                StringId cat,
50                StringId name,
51                SetArgsCallback args_callback),
52               (override));
53   MOCK_METHOD(std::optional<SliceId>,
54               Scoped,
55               (int64_t timestamp,
56                TrackId track_id,
57                StringId cat,
58                StringId name,
59                int64_t duration,
60                SetArgsCallback args_callback),
61               (override));
62 };
63 
64 class SyscallTrackerTest : public ::testing::Test {
65  public:
SyscallTrackerTest()66   SyscallTrackerTest() {
67     context.storage.reset(new TraceStorage());
68     context.global_args_tracker.reset(
69         new GlobalArgsTracker(context.storage.get()));
70     track_tracker = new TrackTracker(&context);
71     context.track_tracker.reset(track_tracker);
72     slice_tracker = new MockSliceTracker(&context);
73     context.slice_tracker.reset(slice_tracker);
74   }
75 
76  protected:
77   TraceProcessorContext context;
78   MockSliceTracker* slice_tracker;
79   TrackTracker* track_tracker;
80 };
81 
TEST_F(SyscallTrackerTest,ReportUnknownSyscalls)82 TEST_F(SyscallTrackerTest, ReportUnknownSyscalls) {
83   constexpr TrackId track{0u};
84   StringId begin_name = kNullStringId;
85   StringId end_name = kNullStringId;
86   EXPECT_CALL(*slice_tracker, Begin(100, track, kNullStringId, _, _))
87       .WillOnce(DoAll(SaveArg<3>(&begin_name), Return(std::nullopt)));
88   EXPECT_CALL(*slice_tracker, End(110, track, kNullStringId, _, _))
89       .WillOnce(DoAll(SaveArg<3>(&end_name), Return(std::nullopt)));
90 
91   SyscallTracker* syscall_tracker = SyscallTracker::GetOrCreate(&context);
92   syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 57 /*sys_read*/);
93   syscall_tracker->Exit(110 /*ts*/, 42 /*utid*/, 57 /*sys_read*/);
94   EXPECT_EQ(context.storage->GetString(begin_name), "sys_57");
95   EXPECT_EQ(context.storage->GetString(end_name), "sys_57");
96 }
97 
TEST_F(SyscallTrackerTest,ReportSysreturn)98 TEST_F(SyscallTrackerTest, ReportSysreturn) {
99   EXPECT_CALL(*slice_tracker, Scoped(_, _, _, _, _, _)).Times(1);
100 
101   SyscallTracker* syscall_tracker = SyscallTracker::GetOrCreate(&context);
102   syscall_tracker->SetArchitecture(Architecture::kArm64);
103   syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 139);
104 }
105 
TEST_F(SyscallTrackerTest,Arm64)106 TEST_F(SyscallTrackerTest, Arm64) {
107   constexpr TrackId track{0u};
108   StringId begin_name = kNullStringId;
109   StringId end_name = kNullStringId;
110   EXPECT_CALL(*slice_tracker, Begin(100, track, kNullStringId, _, _))
111       .WillOnce(DoAll(SaveArg<3>(&begin_name), Return(std::nullopt)));
112   EXPECT_CALL(*slice_tracker, End(110, track, kNullStringId, _, _))
113       .WillOnce(DoAll(SaveArg<3>(&end_name), Return(std::nullopt)));
114 
115   SyscallTracker* syscall_tracker = SyscallTracker::GetOrCreate(&context);
116   syscall_tracker->SetArchitecture(Architecture::kArm64);
117   syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 63 /*sys_read*/);
118   syscall_tracker->Exit(110 /*ts*/, 42 /*utid*/, 63 /*sys_read*/);
119   EXPECT_EQ(context.storage->GetString(begin_name), "sys_read");
120   EXPECT_EQ(context.storage->GetString(end_name), "sys_read");
121 }
122 
TEST_F(SyscallTrackerTest,x8664)123 TEST_F(SyscallTrackerTest, x8664) {
124   constexpr TrackId track{0u};
125   StringId begin_name = kNullStringId;
126   StringId end_name = kNullStringId;
127   EXPECT_CALL(*slice_tracker, Begin(100, track, kNullStringId, _, _))
128       .WillOnce(DoAll(SaveArg<3>(&begin_name), Return(std::nullopt)));
129   EXPECT_CALL(*slice_tracker, End(110, track, kNullStringId, _, _))
130       .WillOnce(DoAll(SaveArg<3>(&end_name), Return(std::nullopt)));
131 
132   SyscallTracker* syscall_tracker = SyscallTracker::GetOrCreate(&context);
133   syscall_tracker->SetArchitecture(Architecture::kX86_64);
134   syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 0 /*sys_read*/);
135   syscall_tracker->Exit(110 /*ts*/, 42 /*utid*/, 0 /*sys_read*/);
136   EXPECT_EQ(context.storage->GetString(begin_name), "sys_read");
137   EXPECT_EQ(context.storage->GetString(end_name), "sys_read");
138 }
139 
TEST_F(SyscallTrackerTest,SyscallNumberTooLarge)140 TEST_F(SyscallTrackerTest, SyscallNumberTooLarge) {
141   EXPECT_CALL(*slice_tracker, Begin(_, _, _, _, _)).Times(0);
142   EXPECT_CALL(*slice_tracker, End(_, _, _, _, _)).Times(0);
143 
144   SyscallTracker* syscall_tracker = SyscallTracker::GetOrCreate(&context);
145   syscall_tracker->SetArchitecture(Architecture::kArm64);
146   syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 9999);
147   syscall_tracker->Exit(110 /*ts*/, 42 /*utid*/, 9999);
148 }
149 
150 }  // namespace
151 }  // namespace trace_processor
152 }  // namespace perfetto
153