| // 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 |