xref: /aosp_15_r20/external/perfetto/src/traced/probes/ftrace/ftrace_procfs_integrationtest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2017 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 <fstream>
18 #include <set>
19 #include <sstream>
20 #include <string>
21 
22 #include "perfetto/ext/base/file_utils.h"
23 #include "src/traced/probes/ftrace/ftrace_controller.h"
24 #include "src/traced/probes/ftrace/ftrace_procfs.h"
25 #include "test/gtest_and_gmock.h"
26 
27 using testing::Contains;
28 using testing::HasSubstr;
29 using testing::IsEmpty;
30 using testing::Not;
31 using testing::UnorderedElementsAre;
32 
33 // These tests run only on Android because on linux they require access to
34 // ftrace, which would be problematic in the CI when multiple tests run
35 // concurrently on the same machine. Android instead uses one emulator instance
36 // for each worker.
37 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
38 // On Android these tests conflict with traced_probes which expects to be the
39 // only one modifying tracing. This led to the Setup code which attempts to
40 // to skip these tests when traced_probes is using tracing. Unfortunately this
41 // is racey and we still see spurious failures in practice. For now disable
42 // these tests on Android also.
43 // TODO(b/150675975) Re-enable these tests.
44 #define ANDROID_ONLY_TEST(x) DISABLED_##x
45 #else
46 #define ANDROID_ONLY_TEST(x) DISABLED_##x
47 #endif
48 
49 namespace perfetto {
50 namespace {
51 
GetFtracePath()52 std::string GetFtracePath() {
53   auto ftrace_procfs = FtraceProcfs::CreateGuessingMountPoint();
54   if (!ftrace_procfs)
55     return "";
56   return ftrace_procfs->GetRootPath();
57 }
58 
ReadFile(const std::string & name)59 std::string ReadFile(const std::string& name) {
60   std::string result;
61   PERFETTO_CHECK(base::ReadFile(GetFtracePath() + name, &result));
62   return result;
63 }
64 
GetTraceOutput()65 std::string GetTraceOutput() {
66   std::string output = ReadFile("trace");
67   if (output.empty()) {
68     ADD_FAILURE() << "Could not read trace output";
69   }
70   return output;
71 }
72 
73 class FtraceProcfsIntegrationTest : public testing::Test {
74  public:
75   void SetUp() override;
76   void TearDown() override;
77 
78   std::unique_ptr<FtraceProcfs> ftrace_;
79 };
80 
SetUp()81 void FtraceProcfsIntegrationTest::SetUp() {
82   ftrace_ = FtraceProcfs::Create(GetFtracePath());
83   ASSERT_TRUE(ftrace_);
84   if (!ftrace_->IsTracingAvailable()) {
85     GTEST_SKIP() << "Something else is using ftrace, skipping";
86   }
87 
88   ftrace_->ClearTrace();
89   ftrace_->SetTracingOn(true);
90 }
91 
TearDown()92 void FtraceProcfsIntegrationTest::TearDown() {
93   ftrace_->DisableAllEvents();
94   ftrace_->ClearTrace();
95   ftrace_->SetTracingOn(false);
96 }
97 
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (CreateWithBadPath))98 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(CreateWithBadPath)) {
99   EXPECT_FALSE(FtraceProcfs::Create(GetFtracePath() + std::string("bad_path")));
100 }
101 
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (ClearTrace))102 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(ClearTrace)) {
103   ftrace_->WriteTraceMarker("Hello, World!");
104   ftrace_->ClearTrace();
105   EXPECT_THAT(GetTraceOutput(), Not(HasSubstr("Hello, World!")));
106 }
107 
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (TraceMarker))108 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(TraceMarker)) {
109   ftrace_->WriteTraceMarker("Hello, World!");
110   EXPECT_THAT(GetTraceOutput(), HasSubstr("Hello, World!"));
111 }
112 
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (EnableDisableEvent))113 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(EnableDisableEvent)) {
114   ASSERT_TRUE(ftrace_->EnableEvent("sched", "sched_switch"));
115   sleep(1);
116   ASSERT_TRUE(ftrace_->DisableEvent("sched", "sched_switch"));
117 
118   EXPECT_THAT(GetTraceOutput(), HasSubstr("sched_switch"));
119 
120   ftrace_->ClearTrace();
121   sleep(1);
122   EXPECT_THAT(GetTraceOutput(), Not(HasSubstr("sched_switch")));
123 }
124 
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (EnableDisableTraceBuffer))125 TEST_F(FtraceProcfsIntegrationTest,
126        ANDROID_ONLY_TEST(EnableDisableTraceBuffer)) {
127   ftrace_->WriteTraceMarker("Before");
128   ftrace_->SetTracingOn(false);
129   ftrace_->WriteTraceMarker("During");
130   ftrace_->SetTracingOn(true);
131   ftrace_->WriteTraceMarker("After");
132   EXPECT_THAT(GetTraceOutput(), HasSubstr("Before"));
133   EXPECT_THAT(GetTraceOutput(), Not(HasSubstr("During")));
134   EXPECT_THAT(GetTraceOutput(), HasSubstr("After"));
135 }
136 
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (IsTracingAvailable))137 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(IsTracingAvailable)) {
138   EXPECT_TRUE(ftrace_->IsTracingAvailable());
139   ftrace_->SetCurrentTracer("function");
140   EXPECT_FALSE(ftrace_->IsTracingAvailable());
141   ftrace_->SetCurrentTracer("nop");
142   EXPECT_TRUE(ftrace_->IsTracingAvailable());
143   ASSERT_TRUE(ftrace_->EnableEvent("sched", "sched_switch"));
144   EXPECT_FALSE(ftrace_->IsTracingAvailable());
145   ftrace_->DisableAllEvents();
146   EXPECT_TRUE(ftrace_->IsTracingAvailable());
147 }
148 
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (ReadFormatFile))149 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(ReadFormatFile)) {
150   std::string format = ftrace_->ReadEventFormat("ftrace", "print");
151   EXPECT_THAT(format, HasSubstr("name: print"));
152   EXPECT_THAT(format, HasSubstr("field:char buf"));
153 }
154 
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (CanOpenTracePipeRaw))155 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(CanOpenTracePipeRaw)) {
156   EXPECT_TRUE(ftrace_->OpenPipeForCpu(0));
157 }
158 
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (Clock))159 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(Clock)) {
160   std::set<std::string> clocks = ftrace_->AvailableClocks();
161   EXPECT_THAT(clocks, Contains("local"));
162   EXPECT_THAT(clocks, Contains("global"));
163 
164   EXPECT_TRUE(ftrace_->SetClock("global"));
165   EXPECT_EQ(ftrace_->GetClock(), "global");
166   EXPECT_TRUE(ftrace_->SetClock("local"));
167   EXPECT_EQ(ftrace_->GetClock(), "local");
168 }
169 
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (CanSetBufferSize))170 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(CanSetBufferSize)) {
171   EXPECT_TRUE(ftrace_->SetCpuBufferSizeInPages(4ul));
172   EXPECT_EQ(ReadFile("buffer_size_kb"), "16\n");  // (4096 * 4) / 1024
173   EXPECT_TRUE(ftrace_->SetCpuBufferSizeInPages(5ul));
174   EXPECT_EQ(ReadFile("buffer_size_kb"), "20\n");  // (4096 * 5) / 1024
175 }
176 
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (FtraceControllerHardReset))177 TEST_F(FtraceProcfsIntegrationTest,
178        ANDROID_ONLY_TEST(FtraceControllerHardReset)) {
179   ftrace_->SetCpuBufferSizeInPages(4ul);
180   ftrace_->EnableEvent("sched", "sched_switch");
181   ftrace_->WriteTraceMarker("Hello, World!");
182 
183   EXPECT_EQ(ReadFile("buffer_size_kb"), "16\n");
184   EXPECT_EQ(ReadFile("tracing_on"), "1\n");
185   EXPECT_EQ(ReadFile("events/enable"), "X\n");
186 
187   HardResetFtraceState();
188 
189   EXPECT_EQ(ReadFile("buffer_size_kb"), "4\n");
190   EXPECT_EQ(ReadFile("tracing_on"), "0\n");
191   EXPECT_EQ(ReadFile("events/enable"), "0\n");
192   EXPECT_THAT(GetTraceOutput(), Not(HasSubstr("Hello")));
193 }
194 
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (ReadEnabledEvents))195 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(ReadEnabledEvents)) {
196   EXPECT_THAT(ftrace_->ReadEnabledEvents(), IsEmpty());
197 
198   ftrace_->EnableEvent("sched", "sched_switch");
199   ftrace_->EnableEvent("kmem", "kmalloc");
200 
201   EXPECT_THAT(ftrace_->ReadEnabledEvents(),
202               UnorderedElementsAre("sched/sched_switch", "kmem/kmalloc"));
203 
204   ftrace_->DisableEvent("sched", "sched_switch");
205   ftrace_->DisableEvent("kmem", "kmalloc");
206 
207   EXPECT_THAT(ftrace_->ReadEnabledEvents(), IsEmpty());
208 }
209 
210 }  // namespace
211 }  // namespace perfetto
212