• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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/common/process_tracker.h"
18 
19 #include <optional>
20 
21 #include "perfetto/base/logging.h"
22 #include "src/trace_processor/importers/common/args_tracker.h"
23 #include "src/trace_processor/importers/common/event_tracker.h"
24 #include "test/gtest_and_gmock.h"
25 
26 namespace perfetto {
27 namespace trace_processor {
28 namespace {
29 
30 using ::testing::_;
31 using ::testing::InSequence;
32 using ::testing::Invoke;
33 
34 class ProcessTrackerTest : public ::testing::Test {
35  public:
ProcessTrackerTest()36   ProcessTrackerTest() {
37     context.storage.reset(new TraceStorage());
38     context.global_args_tracker.reset(
39         new GlobalArgsTracker(context.storage.get()));
40     context.args_tracker.reset(new ArgsTracker(&context));
41     context.process_tracker.reset(new ProcessTracker(&context));
42     context.event_tracker.reset(new EventTracker(&context));
43   }
44 
45  protected:
46   TraceProcessorContext context;
47 };
48 
TEST_F(ProcessTrackerTest,PushProcess)49 TEST_F(ProcessTrackerTest, PushProcess) {
50   context.process_tracker->SetProcessMetadata(1, std::nullopt, "test",
51                                               base::StringView());
52   auto opt_upid = context.process_tracker->UpidForPidForTesting(1);
53   ASSERT_EQ(opt_upid.value_or(-1), 1u);
54 }
55 
TEST_F(ProcessTrackerTest,GetOrCreateNewProcess)56 TEST_F(ProcessTrackerTest, GetOrCreateNewProcess) {
57   auto upid = context.process_tracker->GetOrCreateProcess(123);
58   ASSERT_EQ(context.process_tracker->GetOrCreateProcess(123), upid);
59 }
60 
TEST_F(ProcessTrackerTest,StartNewProcess)61 TEST_F(ProcessTrackerTest, StartNewProcess) {
62   auto upid = context.process_tracker->StartNewProcess(
63       1000, 0u, 123, kNullStringId, ThreadNamePriority::kFtrace);
64   ASSERT_EQ(context.process_tracker->GetOrCreateProcess(123), upid);
65   ASSERT_EQ(context.storage->process_table().start_ts()[upid], 1000);
66 }
67 
TEST_F(ProcessTrackerTest,PushTwoProcessEntries_SamePidAndName)68 TEST_F(ProcessTrackerTest, PushTwoProcessEntries_SamePidAndName) {
69   context.process_tracker->SetProcessMetadata(1, std::nullopt, "test",
70                                               base::StringView());
71   context.process_tracker->SetProcessMetadata(1, std::nullopt, "test",
72                                               base::StringView());
73   auto opt_upid = context.process_tracker->UpidForPidForTesting(1);
74   ASSERT_EQ(opt_upid.value_or(-1), 1u);
75 }
76 
TEST_F(ProcessTrackerTest,PushTwoProcessEntries_DifferentPid)77 TEST_F(ProcessTrackerTest, PushTwoProcessEntries_DifferentPid) {
78   context.process_tracker->SetProcessMetadata(1, std::nullopt, "test",
79                                               base::StringView());
80   context.process_tracker->SetProcessMetadata(3, std::nullopt, "test",
81                                               base::StringView());
82   auto opt_upid = context.process_tracker->UpidForPidForTesting(1);
83   ASSERT_EQ(opt_upid.value_or(-1), 1u);
84   opt_upid = context.process_tracker->UpidForPidForTesting(3);
85   ASSERT_EQ(opt_upid.value_or(-1), 2u);
86 }
87 
TEST_F(ProcessTrackerTest,AddProcessEntry_CorrectName)88 TEST_F(ProcessTrackerTest, AddProcessEntry_CorrectName) {
89   context.process_tracker->SetProcessMetadata(1, std::nullopt, "test",
90                                               base::StringView());
91   auto name = context.storage->process_table().name().GetString(1);
92 
93   ASSERT_EQ(name, "test");
94 }
95 
TEST_F(ProcessTrackerTest,UpdateThreadCreate)96 TEST_F(ProcessTrackerTest, UpdateThreadCreate) {
97   context.process_tracker->UpdateThread(12, 2);
98 
99   // We expect 3 threads: Invalid thread, main thread for pid, tid 12.
100   ASSERT_EQ(context.storage->thread_table().row_count(), 3u);
101 
102   auto tid_it = context.process_tracker->UtidsForTidForTesting(12);
103   ASSERT_NE(tid_it.first, tid_it.second);
104   ASSERT_EQ(context.storage->thread_table().upid()[1].value(), 1u);
105   auto opt_upid = context.process_tracker->UpidForPidForTesting(2);
106   ASSERT_TRUE(opt_upid.has_value());
107   ASSERT_EQ(context.storage->process_table().row_count(), 2u);
108 }
109 
TEST_F(ProcessTrackerTest,PidReuseWithoutStartAndEndThread)110 TEST_F(ProcessTrackerTest, PidReuseWithoutStartAndEndThread) {
111   UniquePid p1 = context.process_tracker->StartNewProcess(
112       std::nullopt, std::nullopt, /*pid=*/1, kNullStringId,
113       ThreadNamePriority::kFtrace);
114   UniqueTid t1 = context.process_tracker->UpdateThread(/*tid=*/2, /*pid=*/1);
115 
116   UniquePid p2 = context.process_tracker->StartNewProcess(
117       std::nullopt, std::nullopt, /*pid=*/1, kNullStringId,
118       ThreadNamePriority::kFtrace);
119   UniqueTid t2 = context.process_tracker->UpdateThread(/*tid=*/2, /*pid=*/1);
120 
121   ASSERT_NE(p1, p2);
122   ASSERT_NE(t1, t2);
123 
124   // We expect 3 processes: idle process, 2x pid 1.
125   ASSERT_EQ(context.storage->process_table().row_count(), 3u);
126   // We expect 5 threads: Invalid thread, 2x (main thread + sub thread).
127   ASSERT_EQ(context.storage->thread_table().row_count(), 5u);
128 }
129 
TEST_F(ProcessTrackerTest,Cmdline)130 TEST_F(ProcessTrackerTest, Cmdline) {
131   UniquePid upid = context.process_tracker->SetProcessMetadata(
132       1, std::nullopt, "test", "cmdline blah");
133   ASSERT_EQ(context.storage->process_table().cmdline().GetString(upid),
134             "cmdline blah");
135 }
136 
TEST_F(ProcessTrackerTest,UpdateThreadName)137 TEST_F(ProcessTrackerTest, UpdateThreadName) {
138   auto name1 = context.storage->InternString("name1");
139   auto name2 = context.storage->InternString("name2");
140   auto name3 = context.storage->InternString("name3");
141 
142   context.process_tracker->UpdateThreadName(1, name1,
143                                             ThreadNamePriority::kFtrace);
144   ASSERT_EQ(context.storage->thread_table().row_count(), 2u);
145   ASSERT_EQ(context.storage->thread_table().name()[1], name1);
146 
147   context.process_tracker->UpdateThreadName(1, name2,
148                                             ThreadNamePriority::kProcessTree);
149   // The priority is higher: the name should change.
150   ASSERT_EQ(context.storage->thread_table().row_count(), 2u);
151   ASSERT_EQ(context.storage->thread_table().name()[1], name2);
152 
153   context.process_tracker->UpdateThreadName(1, name3,
154                                             ThreadNamePriority::kFtrace);
155   // The priority is lower: the name should stay the same.
156   ASSERT_EQ(context.storage->thread_table().row_count(), 2u);
157   ASSERT_EQ(context.storage->thread_table().name()[1], name2);
158 }
159 
TEST_F(ProcessTrackerTest,SetStartTsIfUnset)160 TEST_F(ProcessTrackerTest, SetStartTsIfUnset) {
161   auto upid = context.process_tracker->StartNewProcess(
162       /*timestamp=*/std::nullopt, 0u, 123, kNullStringId,
163       ThreadNamePriority::kFtrace);
164   context.process_tracker->SetStartTsIfUnset(upid, 1000);
165   ASSERT_EQ(context.storage->process_table().start_ts()[upid], 1000);
166 
167   context.process_tracker->SetStartTsIfUnset(upid, 3000);
168   ASSERT_EQ(context.storage->process_table().start_ts()[upid], 1000);
169 }
170 
TEST_F(ProcessTrackerTest,PidReuseAfterExplicitEnd)171 TEST_F(ProcessTrackerTest, PidReuseAfterExplicitEnd) {
172   UniquePid upid = context.process_tracker->GetOrCreateProcess(123);
173   context.process_tracker->EndThread(100, 123);
174 
175   UniquePid reuse = context.process_tracker->GetOrCreateProcess(123);
176   ASSERT_NE(upid, reuse);
177 }
178 
TEST_F(ProcessTrackerTest,TidReuseAfterExplicitEnd)179 TEST_F(ProcessTrackerTest, TidReuseAfterExplicitEnd) {
180   UniqueTid utid = context.process_tracker->UpdateThread(123, 123);
181   context.process_tracker->EndThread(100, 123);
182 
183   UniqueTid reuse = context.process_tracker->UpdateThread(123, 123);
184   ASSERT_NE(utid, reuse);
185 
186   UniqueTid reuse_again = context.process_tracker->UpdateThread(123, 123);
187   ASSERT_EQ(reuse, reuse_again);
188 }
189 
TEST_F(ProcessTrackerTest,EndThreadAfterProcessEnd)190 TEST_F(ProcessTrackerTest, EndThreadAfterProcessEnd) {
191   context.process_tracker->StartNewProcess(
192       100, std::nullopt, 123, kNullStringId, ThreadNamePriority::kFtrace);
193   context.process_tracker->UpdateThread(124, 123);
194 
195   context.process_tracker->EndThread(200, 123);
196   context.process_tracker->EndThread(201, 124);
197 
198   // We expect two processes: the idle process and 123.
199   ASSERT_EQ(context.storage->process_table().row_count(), 2u);
200 
201   // We expect three theads: the idle thread, 123 and 124.
202   ASSERT_EQ(context.storage->thread_table().row_count(), 3u);
203 }
204 
TEST_F(ProcessTrackerTest,UpdateTrustedPid)205 TEST_F(ProcessTrackerTest, UpdateTrustedPid) {
206   context.process_tracker->UpdateTrustedPid(/*trusted_pid=*/123, /*uuid=*/1001);
207   context.process_tracker->UpdateTrustedPid(/*trusted_pid=*/456, /*uuid=*/1002);
208 
209   ASSERT_EQ(context.process_tracker->GetTrustedPid(1001).value(), 123u);
210   ASSERT_EQ(context.process_tracker->GetTrustedPid(1002).value(), 456u);
211 
212   // PID reuse. Multiple track UUIDs map to the same trusted_pid.
213   context.process_tracker->UpdateTrustedPid(/*trusted_pid=*/123, /*uuid=*/1003);
214   ASSERT_EQ(context.process_tracker->GetTrustedPid(1001).value(), 123u);
215   ASSERT_EQ(context.process_tracker->GetTrustedPid(1003).value(), 123u);
216 }
217 
TEST_F(ProcessTrackerTest,NamespacedProcessesAndThreads)218 TEST_F(ProcessTrackerTest, NamespacedProcessesAndThreads) {
219   context.process_tracker->UpdateNamespacedProcess(/*pid=*/1001,
220                                                    /*nspid=*/{1001, 190, 1});
221   context.process_tracker->UpdateNamespacedThread(/*pid=*/1001, /*tid=*/1002,
222                                                   /*nstid=*/{1002, 192, 2});
223   context.process_tracker->UpdateNamespacedThread(1001, 1003, {1003, 193, 3});
224 
225   context.process_tracker->UpdateNamespacedProcess(/*pid=*/1023,
226                                                    /*nspid=*/{1023, 201, 21});
227   context.process_tracker->UpdateNamespacedThread(/*pid=*/1023, /*tid=*/1026,
228                                                   {1026, 196, 26});
229   context.process_tracker->UpdateNamespacedThread(/*pid=*/1023, /*tid=*/1027,
230                                                   {1027, 197, 27});
231 
232   context.process_tracker->UpdateNamespacedProcess(/*pid=*/1024,
233                                                    /*nspid=*/{1024, 202, 22});
234   context.process_tracker->UpdateNamespacedThread(/*pid=*/1024, /*tid=*/1028,
235                                                   /*nstid=*/{1028, 198, 28});
236   context.process_tracker->UpdateNamespacedThread(/*pid=*/1024, /*tid=*/1029,
237                                                   /*nstid=*/{1029, 198, 29});
238 
239   // Don't resolve if the process/thread isn't namespaced.
240   ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(2001, 2002),
241             std::nullopt);
242 
243   // Resolve from namespace-local PID to root-level PID.
244   ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1001, 1).value(),
245             1001u);
246   ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1023, 21).value(),
247             1023u);
248   ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1024, 22).value(),
249             1024u);
250 
251   // Resolve from namespace-local TID to root-level TID.
252   ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1001, 2).value(),
253             1002u);
254   ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1001, 3).value(),
255             1003u);
256   ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1023, 26).value(),
257             1026u);
258   ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1023, 27).value(),
259             1027u);
260   ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1024, 28).value(),
261             1028u);
262   ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1024, 29).value(),
263             1029u);
264 }
265 
266 }  // namespace
267 }  // namespace trace_processor
268 }  // namespace perfetto
269