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 size_t i = 0;
54 while (!FtraceProcfs::Create(FtraceController::kTracingPaths[i])) {
55 i++;
56 }
57 return std::string(FtraceController::kTracingPaths[i]);
58 }
59
ReadFile(const std::string & name)60 std::string ReadFile(const std::string& name) {
61 std::string result;
62 PERFETTO_CHECK(base::ReadFile(GetFtracePath() + name, &result));
63 return result;
64 }
65
GetTraceOutput()66 std::string GetTraceOutput() {
67 std::string output = ReadFile("trace");
68 if (output.empty()) {
69 ADD_FAILURE() << "Could not read trace output";
70 }
71 return output;
72 }
73
74 class FtraceProcfsIntegrationTest : public testing::Test {
75 public:
76 void SetUp() override;
77 void TearDown() override;
78
79 std::unique_ptr<FtraceProcfs> ftrace_;
80 };
81
SetUp()82 void FtraceProcfsIntegrationTest::SetUp() {
83 ftrace_ = FtraceProcfs::Create(GetFtracePath());
84 ASSERT_TRUE(ftrace_);
85 if (ftrace_->IsTracingEnabled()) {
86 GTEST_SKIP() << "Something else is using ftrace, skipping";
87 }
88
89 ftrace_->DisableAllEvents();
90 ftrace_->ClearTrace();
91 ftrace_->EnableTracing();
92 }
93
TearDown()94 void FtraceProcfsIntegrationTest::TearDown() {
95 ftrace_->DisableAllEvents();
96 ftrace_->ClearTrace();
97 ftrace_->DisableTracing();
98 }
99
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (CreateWithBadPath))100 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(CreateWithBadPath)) {
101 EXPECT_FALSE(FtraceProcfs::Create(GetFtracePath() + std::string("bad_path")));
102 }
103
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (ClearTrace))104 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(ClearTrace)) {
105 ftrace_->WriteTraceMarker("Hello, World!");
106 ftrace_->ClearTrace();
107 EXPECT_THAT(GetTraceOutput(), Not(HasSubstr("Hello, World!")));
108 }
109
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (TraceMarker))110 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(TraceMarker)) {
111 ftrace_->WriteTraceMarker("Hello, World!");
112 EXPECT_THAT(GetTraceOutput(), HasSubstr("Hello, World!"));
113 }
114
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (EnableDisableEvent))115 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(EnableDisableEvent)) {
116 ASSERT_TRUE(ftrace_->EnableEvent("sched", "sched_switch"));
117 sleep(1);
118 ASSERT_TRUE(ftrace_->DisableEvent("sched", "sched_switch"));
119
120 EXPECT_THAT(GetTraceOutput(), HasSubstr("sched_switch"));
121
122 ftrace_->ClearTrace();
123 sleep(1);
124 EXPECT_THAT(GetTraceOutput(), Not(HasSubstr("sched_switch")));
125 }
126
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (EnableDisableTracing))127 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(EnableDisableTracing)) {
128 EXPECT_TRUE(ftrace_->IsTracingEnabled());
129 ftrace_->WriteTraceMarker("Before");
130 ftrace_->DisableTracing();
131 EXPECT_FALSE(ftrace_->IsTracingEnabled());
132 ftrace_->WriteTraceMarker("During");
133 ftrace_->EnableTracing();
134 EXPECT_TRUE(ftrace_->IsTracingEnabled());
135 ftrace_->WriteTraceMarker("After");
136 EXPECT_THAT(GetTraceOutput(), HasSubstr("Before"));
137 EXPECT_THAT(GetTraceOutput(), Not(HasSubstr("During")));
138 EXPECT_THAT(GetTraceOutput(), HasSubstr("After"));
139 }
140
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (ReadFormatFile))141 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(ReadFormatFile)) {
142 std::string format = ftrace_->ReadEventFormat("ftrace", "print");
143 EXPECT_THAT(format, HasSubstr("name: print"));
144 EXPECT_THAT(format, HasSubstr("field:char buf"));
145 }
146
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (CanOpenTracePipeRaw))147 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(CanOpenTracePipeRaw)) {
148 EXPECT_TRUE(ftrace_->OpenPipeForCpu(0));
149 }
150
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (Clock))151 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(Clock)) {
152 std::set<std::string> clocks = ftrace_->AvailableClocks();
153 EXPECT_THAT(clocks, Contains("local"));
154 EXPECT_THAT(clocks, Contains("global"));
155
156 EXPECT_TRUE(ftrace_->SetClock("global"));
157 EXPECT_EQ(ftrace_->GetClock(), "global");
158 EXPECT_TRUE(ftrace_->SetClock("local"));
159 EXPECT_EQ(ftrace_->GetClock(), "local");
160 }
161
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (CanSetBufferSize))162 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(CanSetBufferSize)) {
163 EXPECT_TRUE(ftrace_->SetCpuBufferSizeInPages(4ul));
164 EXPECT_EQ(ReadFile("buffer_size_kb"), "16\n"); // (4096 * 4) / 1024
165 EXPECT_TRUE(ftrace_->SetCpuBufferSizeInPages(5ul));
166 EXPECT_EQ(ReadFile("buffer_size_kb"), "20\n"); // (4096 * 5) / 1024
167 }
168
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (FtraceControllerHardReset))169 TEST_F(FtraceProcfsIntegrationTest,
170 ANDROID_ONLY_TEST(FtraceControllerHardReset)) {
171 ftrace_->SetCpuBufferSizeInPages(4ul);
172 ftrace_->EnableTracing();
173 ftrace_->EnableEvent("sched", "sched_switch");
174 ftrace_->WriteTraceMarker("Hello, World!");
175
176 EXPECT_EQ(ReadFile("buffer_size_kb"), "16\n");
177 EXPECT_EQ(ReadFile("tracing_on"), "1\n");
178 EXPECT_EQ(ReadFile("events/enable"), "X\n");
179
180 HardResetFtraceState();
181
182 EXPECT_EQ(ReadFile("buffer_size_kb"), "4\n");
183 EXPECT_EQ(ReadFile("tracing_on"), "0\n");
184 EXPECT_EQ(ReadFile("events/enable"), "0\n");
185 EXPECT_THAT(GetTraceOutput(), Not(HasSubstr("Hello")));
186 }
187
TEST_F(FtraceProcfsIntegrationTest,ANDROID_ONLY_TEST (ReadEnabledEvents))188 TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(ReadEnabledEvents)) {
189 EXPECT_THAT(ftrace_->ReadEnabledEvents(), IsEmpty());
190
191 ftrace_->EnableEvent("sched", "sched_switch");
192 ftrace_->EnableEvent("kmem", "kmalloc");
193
194 EXPECT_THAT(ftrace_->ReadEnabledEvents(),
195 UnorderedElementsAre("sched/sched_switch", "kmem/kmalloc"));
196
197 ftrace_->DisableEvent("sched", "sched_switch");
198 ftrace_->DisableEvent("kmem", "kmalloc");
199
200 EXPECT_THAT(ftrace_->ReadEnabledEvents(), IsEmpty());
201 }
202
203 } // namespace
204 } // namespace perfetto
205