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