• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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