/* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "src/trace_redaction/collect_system_info.h" #include "src/base/test/status_matchers.h" #include "src/trace_processor/util/status_macros.h" #include "test/gtest_and_gmock.h" #include "protos/perfetto/trace/ftrace/ftrace_event.gen.h" #include "protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.h" #include "protos/perfetto/trace/ftrace/sched.gen.h" #include "protos/perfetto/trace/trace_packet.gen.h" namespace perfetto::trace_redaction { class CollectSystemInfoTest : public testing::Test { protected: base::Status Collect() { auto buffer = packet_.SerializeAsString(); protos::pbzero::TracePacket::Decoder decoder(buffer); RETURN_IF_ERROR(collect_.Begin(&context_)); RETURN_IF_ERROR(collect_.Collect(decoder, &context_)); return collect_.End(&context_); } void AppendFtraceEvent(uint32_t event_cpu, uint32_t pid) { auto* events = packet_.mutable_ftrace_events(); events->set_cpu(event_cpu); auto* event = events->add_event(); event->set_pid(pid); } void AppendSchedSwitch(int32_t next_pid) { auto& event = packet_.mutable_ftrace_events()->mutable_event()->back(); auto* sched_switch = event.mutable_sched_switch(); sched_switch->set_prev_pid(static_cast(event.pid())); sched_switch->set_next_pid(next_pid); } protos::gen::TracePacket packet_; Context context_; CollectSystemInfo collect_; }; TEST_F(CollectSystemInfoTest, UpdatesCpuCountUsingFtraceEvents) { AppendFtraceEvent(7, 8); AppendSchedSwitch(9); ASSERT_OK(Collect()); ASSERT_EQ(context_.system_info->cpu_count(), 8u); AppendFtraceEvent(11, 8); AppendSchedSwitch(9); ASSERT_OK(Collect()); ASSERT_EQ(context_.system_info->cpu_count(), 12u); } // The first synth thread pid should be beyond the range of valid pids. TEST(SystemInfoTest, FirstSynthThreadPidIsNotAValidPid) { SystemInfo info; auto pid = info.AllocateSynthThread(); ASSERT_GT(pid, 1 << 22); } TEST(BuildSyntheticProcessTest, CreatesThreadsPerCpu) { Context context; context.system_info.emplace(); // The first CPU is always 0, so CPU 7 means there are 8 CPUs. context.system_info->ReserveCpu(7); BuildSyntheticThreads build; ASSERT_OK(build.Build(&context)); ASSERT_NE(context.synthetic_process->tgid(), 0); // One main thread and 1 thread per CPU. ASSERT_EQ(context.synthetic_process->tids().size(), 9u); } } // namespace perfetto::trace_redaction