Home | History | Annotate | Download | only in ftrace_reader
      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