blob: eb75208bada1713f12aaa83f18bb2f8806779e5f [file] [log] [blame]
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
#include "perfetto/base/status.h"
#include "perfetto/ext/base/file_utils.h"
#include "src/base/test/status_matchers.h"
#include "src/base/test/tmp_dir_tree.h"
#include "src/base/test/utils.h"
#include "src/trace_redaction/build_timeline.h"
#include "src/trace_redaction/find_package_uid.h"
#include "src/trace_redaction/optimize_timeline.h"
#include "src/trace_redaction/scrub_task_rename.h"
#include "src/trace_redaction/trace_redaction_framework.h"
#include "src/trace_redaction/trace_redactor.h"
#include "test/gtest_and_gmock.h"
#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
#include "protos/perfetto/trace/trace.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
namespace perfetto::trace_redaction {
namespace {
using FtraceEvent = protos::pbzero::FtraceEvent;
constexpr std::string_view kTracePath =
"test/data/trace-redaction-general.pftrace";
// Set the package name to "just some package name". If a specific package name
// is needed, the test it should overwrite this value.
constexpr std::string_view kPackageName =
"com.Unity.com.unity.multiplayer.samples.coop";
class RenameEventsTraceRedactorIntegrationTest : public testing::Test {
protected:
void SetUp() override {
// In order for ScrubTaskRename to work, it needs the timeline. All
// registered primitives are there to generate the timeline.
redactor_.collectors()->emplace_back(new FindPackageUid());
redactor_.collectors()->emplace_back(new BuildTimeline());
redactor_.builders()->emplace_back(new OptimizeTimeline());
redactor_.transformers()->emplace_back(new ScrubTaskRename());
context_.package_name = kPackageName;
src_trace_ = base::GetTestDataPath(std::string(kTracePath));
dest_trace_ = tmp_dir_.AbsolutePath("dst.pftrace");
tmp_dir_.TrackFile("dst.pftrace");
}
base::Status Redact() {
return redactor_.Redact(src_trace_, dest_trace_, &context_);
}
base::StatusOr<std::string> LoadOriginal() const {
return ReadRawTrace(src_trace_);
}
base::StatusOr<std::string> LoadRedacted() const {
return ReadRawTrace(dest_trace_);
}
std::vector<uint32_t> GetAllRenamedPids(
protos::pbzero::Trace::Decoder trace) const {
std::vector<uint32_t> renamed_pids;
for (auto packet_it = trace.packet(); packet_it; ++packet_it) {
protos::pbzero::TracePacket::Decoder packet_decoder(*packet_it);
if (!packet_decoder.has_ftrace_events()) {
continue;
}
protos::pbzero::FtraceEventBundle::Decoder bundle_decoder(
packet_decoder.ftrace_events());
for (auto event_it = bundle_decoder.event(); event_it; ++event_it) {
protos::pbzero::FtraceEvent::Decoder event(*event_it);
if (event.has_task_rename()) {
renamed_pids.push_back(event.pid());
}
}
}
return renamed_pids;
}
private:
base::StatusOr<std::string> ReadRawTrace(const std::string& path) const {
std::string redacted_buffer;
if (base::ReadFile(path, &redacted_buffer)) {
return redacted_buffer;
}
return base::ErrStatus("Failed to read %s", path.c_str());
}
Context context_;
TraceRedactor redactor_;
base::TmpDirTree tmp_dir_;
std::string src_trace_;
std::string dest_trace_;
};
TEST_F(RenameEventsTraceRedactorIntegrationTest, RemovesUnwantedRenameTasks) {
auto result = Redact();
ASSERT_OK(result) << result.c_message();
auto original = LoadOriginal();
ASSERT_OK(original) << original.status().c_message();
auto redacted = LoadRedacted();
ASSERT_OK(redacted) << redacted.status().c_message();
auto original_rename_pids =
GetAllRenamedPids(protos::pbzero::Trace::Decoder(*original));
std::sort(original_rename_pids.begin(), original_rename_pids.end());
// The test trace has found rename events. This assert is just to document
// theme.
ASSERT_EQ(original_rename_pids.size(), 4u);
ASSERT_EQ(original_rename_pids[0], 7971u);
ASSERT_EQ(original_rename_pids[1], 7972u);
ASSERT_EQ(original_rename_pids[2], 7973u);
ASSERT_EQ(original_rename_pids[3], 7974u);
auto redacted_rename_pids =
GetAllRenamedPids(protos::pbzero::Trace::Decoder(*redacted));
ASSERT_TRUE(redacted_rename_pids.empty());
}
} // namespace
} // namespace perfetto::trace_redaction