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: 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: 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 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 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 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 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) 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