blob: b0ae8f726d36695bfa44611f745096cfe8a2097c [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/tracing/perfetto/privacy_filtering_check.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/perfetto/protos/perfetto/trace/trace.pb.h"
#include "third_party/perfetto/protos/perfetto/trace/trace_packet.pb.h"
#include "third_party/perfetto/protos/perfetto/trace/track_event/process_descriptor.pb.h"
#include "third_party/perfetto/protos/perfetto/trace/track_event/thread_descriptor.pb.h"
#include "third_party/perfetto/protos/perfetto/trace/track_event/track_descriptor.pb.h"
#include "third_party/perfetto/protos/perfetto/trace/track_event/track_event.pb.h"
namespace tracing {
void FillDisallowedTestField(perfetto::protos::TracePacket* packet) {
auto* for_testing = packet->mutable_for_testing();
for_testing->set_str("TestField");
for_testing->set_counter(10);
}
perfetto::protos::Trace GetFilteredTrace(const perfetto::protos::Trace& trace) {
std::string serialized = trace.SerializeAsString();
PrivacyFilteringCheck check;
check.RemoveBlockedFields(serialized);
perfetto::protos::Trace filtered;
EXPECT_TRUE(filtered.ParseFromString(serialized));
return filtered;
}
TEST(PrivacyFilteringTest, EmptyTrace) {
perfetto::protos::Trace trace;
perfetto::protos::Trace filtered = GetFilteredTrace(trace);
ASSERT_EQ(0, filtered.packet_size());
}
TEST(PrivacyFilteringTest, SafeToplevelField) {
perfetto::protos::Trace trace;
trace.add_packet()->set_timestamp(10);
perfetto::protos::Trace filtered = GetFilteredTrace(trace);
ASSERT_EQ(1, filtered.packet_size());
EXPECT_EQ(10u, filtered.packet(0).timestamp());
}
TEST(PrivacyFilteringTest, SafeToplevelMessageField) {
perfetto::protos::Trace trace;
trace.add_packet()->mutable_track_event()->set_track_uuid(11);
perfetto::protos::Trace filtered = GetFilteredTrace(trace);
ASSERT_EQ(1, filtered.packet_size());
EXPECT_EQ(11u, filtered.packet(0).track_event().track_uuid());
}
TEST(PrivacyFilteringTest, RepeatedFields) {
perfetto::protos::Trace trace;
auto* track_event = trace.add_packet()->mutable_track_event();
track_event->add_debug_annotations()->set_name_iid(5);
track_event->add_debug_annotations()->set_name_iid(2);
track_event->add_debug_annotations()->set_name_iid(8);
track_event->add_flow_ids(3);
track_event->add_flow_ids(6);
track_event->add_flow_ids(9);
perfetto::protos::Trace filtered = GetFilteredTrace(trace);
ASSERT_EQ(1, filtered.packet_size());
EXPECT_EQ(0, filtered.packet(0).track_event().debug_annotations_size());
EXPECT_EQ(3u, filtered.packet(0).track_event().flow_ids(0));
EXPECT_EQ(6u, filtered.packet(0).track_event().flow_ids(1));
EXPECT_EQ(9u, filtered.packet(0).track_event().flow_ids(2));
}
TEST(PrivacyFilteringTest, UnsafeToplevelField) {
perfetto::protos::Trace trace;
FillDisallowedTestField(trace.add_packet());
perfetto::protos::Trace filtered = GetFilteredTrace(trace);
ASSERT_EQ(0, filtered.packet_size());
}
TEST(PrivacyFilteringTest, SafeMessageWithOnlyUnsafeFields) {
perfetto::protos::Trace trace;
auto* packet = trace.add_packet();
packet->mutable_track_event()->mutable_legacy_event();
auto* debug_annotations =
packet->mutable_track_event()->add_debug_annotations();
debug_annotations->set_name_iid(2);
debug_annotations->set_int_value(10);
packet->mutable_track_event()->mutable_log_message()->set_body_iid(1);
perfetto::protos::Trace filtered = GetFilteredTrace(trace);
ASSERT_EQ(0, filtered.packet_size());
}
TEST(PrivacyFilteringTest, SafeAndUnsafeFields) {
perfetto::protos::Trace trace;
perfetto::protos::TracePacket* packet = trace.add_packet();
FillDisallowedTestField(packet);
packet->mutable_trace_packet_defaults()->set_timestamp_clock_id(11);
perfetto::protos::Trace filtered = GetFilteredTrace(trace);
ASSERT_EQ(1, filtered.packet_size());
EXPECT_EQ(11u,
filtered.packet(0).trace_packet_defaults().timestamp_clock_id());
EXPECT_FALSE(filtered.packet(0).has_for_testing());
}
TEST(PrivacyFilteringTest, SafeAndUnsafePackets) {
perfetto::protos::Trace trace;
FillDisallowedTestField(trace.add_packet());
trace.add_packet()->mutable_trace_packet_defaults()->set_timestamp_clock_id(
11);
perfetto::protos::Trace filtered = GetFilteredTrace(trace);
ASSERT_EQ(1, filtered.packet_size());
EXPECT_FALSE(filtered.packet(0).has_for_testing());
EXPECT_EQ(11u,
filtered.packet(0).trace_packet_defaults().timestamp_clock_id());
}
TEST(PrivacyFilteringTest, NestedSafeAndUnsafeFields) {
perfetto::protos::Trace trace;
perfetto::protos::TracePacket* packet = trace.add_packet();
FillDisallowedTestField(packet);
packet->set_timestamp(50);
auto* track_event = packet->mutable_track_event();
track_event->set_track_uuid(11);
track_event->mutable_log_message()->set_body_iid(10);
track_event->set_name_iid(1);
track_event->add_category_iids(2);
auto* hist = track_event->mutable_chrome_histogram_sample();
hist->set_name_hash(4);
hist->set_name("hist");
hist->set_sample(5);
track_event->add_flow_ids(3);
track_event->add_debug_annotations()->set_name_iid(2);
track_event->add_flow_ids(6);
track_event->add_debug_annotations()->set_name_iid(5);
track_event->add_flow_ids(9);
track_event->add_debug_annotations()->set_name_iid(8);
perfetto::protos::Trace filtered = GetFilteredTrace(trace);
ASSERT_EQ(1, filtered.packet_size());
const auto& packet1 = filtered.packet(0);
EXPECT_FALSE(packet1.has_for_testing());
EXPECT_EQ(50u, packet1.timestamp());
const auto& event = packet1.track_event();
EXPECT_EQ(11u, event.track_uuid());
EXPECT_FALSE(event.has_log_message());
EXPECT_EQ(1u, event.name_iid());
ASSERT_EQ(1, event.category_iids_size());
EXPECT_EQ(2u, event.category_iids(0));
EXPECT_EQ(0, event.debug_annotations_size());
ASSERT_EQ(3, event.flow_ids_size());
EXPECT_EQ(3u, event.flow_ids(0));
EXPECT_EQ(6u, event.flow_ids(1));
EXPECT_EQ(9u, event.flow_ids(2));
const auto& histogram = event.chrome_histogram_sample();
EXPECT_EQ(4u, histogram.name_hash());
EXPECT_FALSE(histogram.has_name());
EXPECT_EQ(5, histogram.sample());
}
} // namespace tracing