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