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 <sstream>
19
20 #include "gmock/gmock.h"
21 #include "google/protobuf/text_format.h"
22 #include "gtest/gtest.h"
23
24 #include "perfetto/base/build_config.h"
25 #include "perfetto/base/unix_task_runner.h"
26 #include "perfetto/base/utils.h"
27 #include "perfetto/ftrace_reader/ftrace_controller.h"
28 #include "perfetto/protozero/scattered_stream_writer.h"
29 #include "src/ftrace_reader/ftrace_procfs.h"
30 #include "src/ftrace_reader/test/scattered_stream_delegate_for_testing.h"
31
32 #include "perfetto/trace/ftrace/ftrace_event_bundle.pb.h"
33 #include "perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
34 #include "perfetto/trace/ftrace/test_bundle_wrapper.pb.h"
35 #include "perfetto/trace/ftrace/test_bundle_wrapper.pbzero.h"
36
37 using testing::HasSubstr;
38 using testing::Not;
39
40 namespace perfetto {
41 namespace {
42
43 constexpr char kTracingPath[] = "/sys/kernel/debug/tracing/";
44
45 using FtraceBundleHandle =
46 protozero::MessageHandle<protos::pbzero::FtraceEventBundle>;
47
48 class EndToEndIntegrationTest : public ::testing::Test,
49 public FtraceSink::Delegate {
50 public:
Finalize(protos::TestBundleWrapper * wrapper)51 void Finalize(protos::TestBundleWrapper* wrapper) {
52 message->set_after("--- Bundle wrapper after ---");
53 PERFETTO_CHECK(message);
54 size_t msg_size = message->Finalize();
55 std::unique_ptr<uint8_t[]> buffer = writer_delegate->StitchChunks(msg_size);
56 wrapper->ParseFromArray(buffer.get(), static_cast<int>(msg_size));
57 message.reset();
58 }
59
60 protected:
SetUp()61 virtual void SetUp() {
62 writer_delegate = std::unique_ptr<ScatteredStreamDelegateForTesting>(
63 new ScatteredStreamDelegateForTesting(base::kPageSize * 100));
64 writer = std::unique_ptr<protozero::ScatteredStreamWriter>(
65 new protozero::ScatteredStreamWriter(writer_delegate.get()));
66 writer_delegate->set_writer(writer.get());
67 message = std::unique_ptr<protos::pbzero::TestBundleWrapper>(
68 new protos::pbzero::TestBundleWrapper);
69 message->Reset(writer.get());
70 message->set_before("--- Bundle wrapper before ---");
71 }
72
GetBundleForCpu(size_t cpu)73 virtual FtraceBundleHandle GetBundleForCpu(size_t cpu) {
74 PERFETTO_CHECK(!currently_writing_);
75 currently_writing_ = true;
76 cpu_being_written_ = cpu;
77 return FtraceBundleHandle(message->add_bundle());
78 }
79
OnBundleComplete(size_t cpu,FtraceBundleHandle,const FtraceMetadata &)80 virtual void OnBundleComplete(size_t cpu,
81 FtraceBundleHandle,
82 const FtraceMetadata&) {
83 PERFETTO_CHECK(currently_writing_);
84 currently_writing_ = false;
85 EXPECT_NE(cpu_being_written_, 9999ul);
86 EXPECT_EQ(cpu_being_written_, cpu);
87 if (!count--)
88 runner_.Quit();
89 }
90
runner()91 base::UnixTaskRunner* runner() { return &runner_; }
92
93 private:
94 size_t count = 3;
95 base::UnixTaskRunner runner_;
96 bool currently_writing_ = false;
97 size_t cpu_being_written_ = 9999;
98 std::unique_ptr<ScatteredStreamDelegateForTesting> writer_delegate = nullptr;
99 std::unique_ptr<protozero::ScatteredStreamWriter> writer = nullptr;
100 std::unique_ptr<protos::pbzero::TestBundleWrapper> message = nullptr;
101 };
102
103 } // namespace
104
TEST_F(EndToEndIntegrationTest,DISABLED_SchedSwitchAndPrint)105 TEST_F(EndToEndIntegrationTest, DISABLED_SchedSwitchAndPrint) {
106 FtraceProcfs procfs(kTracingPath);
107 procfs.ClearTrace();
108 procfs.WriteTraceMarker("Hello, World!");
109
110 // Create a sink listening for our favorite events:
111 std::unique_ptr<FtraceController> ftrace = FtraceController::Create(runner());
112 FtraceConfig config;
113 *config.add_ftrace_events() = "print";
114 *config.add_ftrace_events() = "sched_switch";
115 std::unique_ptr<FtraceSink> sink = ftrace->CreateSink(config, this);
116
117 // Let some events build up.
118 sleep(1);
119
120 // Start processing the tasks (OnBundleComplete will quit the task runner).
121 runner()->Run();
122
123 // Disable events.
124 sink.reset();
125
126 // Read the output into a full proto so we can use reflection.
127 protos::TestBundleWrapper output;
128 Finalize(&output);
129
130 // Check we can see the guards:
131 EXPECT_THAT(output.before(), HasSubstr("before"));
132 EXPECT_THAT(output.after(), HasSubstr("after"));
133
134 std::string output_as_text;
135 // TODO(hjd): Use reflection print code.
136 printf("%s\n", output_as_text.c_str());
137 }
138
139 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
TEST_F(EndToEndIntegrationTest,DISABLED_Atrace)140 TEST_F(EndToEndIntegrationTest, DISABLED_Atrace) {
141 FtraceProcfs procfs(kTracingPath);
142 procfs.ClearTrace();
143
144 // Create a sink listening for our favorite events:
145 std::unique_ptr<FtraceController> ftrace = FtraceController::Create(runner());
146 FtraceConfig config;
147 *config.add_ftrace_events() = "print";
148 *config.add_ftrace_events() = "sched_switch";
149 std::unique_ptr<FtraceSink> sink = ftrace->CreateSink(config, this);
150
151 // Let some events build up.
152 sleep(1);
153
154 // Start processing the tasks (OnBundleComplete will quit the task runner).
155 runner()->Run();
156
157 // Disable events.
158 sink.reset();
159
160 // Read the output into a full proto so we can use reflection.
161 protos::TestBundleWrapper output;
162 Finalize(&output);
163
164 // Check we can see the guards:
165 EXPECT_THAT(output.before(), HasSubstr("before"));
166 EXPECT_THAT(output.after(), HasSubstr("after"));
167
168 std::string output_as_text;
169 printf("%s\n", output_as_text.c_str());
170 }
171 #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
172
173 } // namespace perfetto
174