xref: /aosp_15_r20/external/perfetto/src/trace_redaction/collect_system_info_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2024 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_redaction/collect_system_info.h"
18 #include "src/base/test/status_matchers.h"
19 #include "src/trace_processor/util/status_macros.h"
20 #include "test/gtest_and_gmock.h"
21 
22 #include "protos/perfetto/trace/ftrace/ftrace_event.gen.h"
23 #include "protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.h"
24 #include "protos/perfetto/trace/ftrace/sched.gen.h"
25 #include "protos/perfetto/trace/trace_packet.gen.h"
26 
27 namespace perfetto::trace_redaction {
28 
29 class CollectSystemInfoTest : public testing::Test {
30  protected:
Collect()31   base::Status Collect() {
32     auto buffer = packet_.SerializeAsString();
33     protos::pbzero::TracePacket::Decoder decoder(buffer);
34 
35     RETURN_IF_ERROR(collect_.Begin(&context_));
36     RETURN_IF_ERROR(collect_.Collect(decoder, &context_));
37     return collect_.End(&context_);
38   }
39 
AppendFtraceEvent(uint32_t event_cpu,uint32_t pid)40   void AppendFtraceEvent(uint32_t event_cpu, uint32_t pid) {
41     auto* events = packet_.mutable_ftrace_events();
42     events->set_cpu(event_cpu);
43 
44     auto* event = events->add_event();
45     event->set_pid(pid);
46   }
47 
AppendSchedSwitch(int32_t next_pid)48   void AppendSchedSwitch(int32_t next_pid) {
49     auto& event = packet_.mutable_ftrace_events()->mutable_event()->back();
50 
51     auto* sched_switch = event.mutable_sched_switch();
52     sched_switch->set_prev_pid(static_cast<int32_t>(event.pid()));
53     sched_switch->set_next_pid(next_pid);
54   }
55 
56   protos::gen::TracePacket packet_;
57   Context context_;
58   CollectSystemInfo collect_;
59 };
60 
TEST_F(CollectSystemInfoTest,UpdatesCpuCountUsingFtraceEvents)61 TEST_F(CollectSystemInfoTest, UpdatesCpuCountUsingFtraceEvents) {
62   AppendFtraceEvent(7, 8);
63   AppendSchedSwitch(9);
64 
65   ASSERT_OK(Collect());
66   ASSERT_EQ(context_.system_info->cpu_count(), 8u);
67 
68   AppendFtraceEvent(11, 8);
69   AppendSchedSwitch(9);
70 
71   ASSERT_OK(Collect());
72   ASSERT_EQ(context_.system_info->cpu_count(), 12u);
73 }
74 
75 // The first synth thread pid should be beyond the range of valid pids.
TEST(SystemInfoTest,FirstSynthThreadPidIsNotAValidPid)76 TEST(SystemInfoTest, FirstSynthThreadPidIsNotAValidPid) {
77   SystemInfo info;
78 
79   auto pid = info.AllocateSynthThread();
80   ASSERT_GT(pid, 1 << 22);
81 }
82 
TEST(BuildSyntheticProcessTest,CreatesThreadsPerCpu)83 TEST(BuildSyntheticProcessTest, CreatesThreadsPerCpu) {
84   Context context;
85   context.system_info.emplace();
86 
87   // The first CPU is always 0, so CPU 7 means there are 8 CPUs.
88   context.system_info->ReserveCpu(7);
89 
90   BuildSyntheticThreads build;
91   ASSERT_OK(build.Build(&context));
92 
93   ASSERT_NE(context.synthetic_process->tgid(), 0);
94 
95   // One main thread and 1 thread per CPU.
96   ASSERT_EQ(context.synthetic_process->tids().size(), 9u);
97 }
98 
99 }  // namespace perfetto::trace_redaction
100