diff --git a/Android.bp b/Android.bp index 621eedc9e1..8611b0bf9b 100644 --- a/Android.bp +++ b/Android.bp @@ -5489,6 +5489,7 @@ genrule { "protos/perfetto/metrics/chrome/scroll_jank.proto", "protos/perfetto/metrics/chrome/scroll_jank_v3.proto", "protos/perfetto/metrics/chrome/slice_names.proto", + "protos/perfetto/metrics/chrome/study_hashes.proto", "protos/perfetto/metrics/chrome/test_chrome_metric.proto", "protos/perfetto/metrics/chrome/touch_jank.proto", "protos/perfetto/metrics/chrome/unsymbolized_args.proto", @@ -13249,6 +13250,7 @@ genrule { "src/trace_processor/metrics/sql/chrome/chrome_scroll_jank_v3.sql", "src/trace_processor/metrics/sql/chrome/chrome_slice_names.sql", "src/trace_processor/metrics/sql/chrome/chrome_stack_samples_for_task.sql", + "src/trace_processor/metrics/sql/chrome/chrome_study_hashes.sql", "src/trace_processor/metrics/sql/chrome/chrome_tasks.sql", "src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing.sql", "src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing_base.sql", diff --git a/BUILD b/BUILD index d4d3aff147..16b21a26ea 100644 --- a/BUILD +++ b/BUILD @@ -2555,6 +2555,7 @@ perfetto_filegroup( "src/trace_processor/metrics/sql/chrome/chrome_scroll_jank_v3.sql", "src/trace_processor/metrics/sql/chrome/chrome_slice_names.sql", "src/trace_processor/metrics/sql/chrome/chrome_stack_samples_for_task.sql", + "src/trace_processor/metrics/sql/chrome/chrome_study_hashes.sql", "src/trace_processor/metrics/sql/chrome/chrome_tasks.sql", "src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing.sql", "src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing_base.sql", @@ -5239,6 +5240,7 @@ perfetto_proto_library( "protos/perfetto/metrics/chrome/scroll_jank.proto", "protos/perfetto/metrics/chrome/scroll_jank_v3.proto", "protos/perfetto/metrics/chrome/slice_names.proto", + "protos/perfetto/metrics/chrome/study_hashes.proto", "protos/perfetto/metrics/chrome/test_chrome_metric.proto", "protos/perfetto/metrics/chrome/touch_jank.proto", "protos/perfetto/metrics/chrome/unsymbolized_args.proto", diff --git a/protos/perfetto/metrics/chrome/BUILD.gn b/protos/perfetto/metrics/chrome/BUILD.gn index c0b0c36881..341afda3b8 100644 --- a/protos/perfetto/metrics/chrome/BUILD.gn +++ b/protos/perfetto/metrics/chrome/BUILD.gn @@ -35,6 +35,7 @@ perfetto_proto_library("@TYPE@") { "scroll_jank.proto", "scroll_jank_v3.proto", "slice_names.proto", + "study_hashes.proto", "test_chrome_metric.proto", "touch_jank.proto", "unsymbolized_args.proto", diff --git a/protos/perfetto/metrics/chrome/all_chrome_metrics.proto b/protos/perfetto/metrics/chrome/all_chrome_metrics.proto index ebc0ac5c35..87a04ad589 100644 --- a/protos/perfetto/metrics/chrome/all_chrome_metrics.proto +++ b/protos/perfetto/metrics/chrome/all_chrome_metrics.proto @@ -23,6 +23,7 @@ import "protos/perfetto/metrics/chrome/args_class_names.proto"; import "protos/perfetto/metrics/chrome/dropped_frames.proto"; import "protos/perfetto/metrics/chrome/frame_times.proto"; import "protos/perfetto/metrics/chrome/histogram_hashes.proto"; +import "protos/perfetto/metrics/chrome/study_hashes.proto"; import "protos/perfetto/metrics/chrome/histogram_summaries.proto"; import "protos/perfetto/metrics/chrome/long_latency.proto"; import "protos/perfetto/metrics/chrome/media_metric.proto"; @@ -55,4 +56,5 @@ extend TraceMetrics { optional ChromeArgsClassNames chrome_args_class_names = 1015; optional ChromeScrollJankV3 chrome_scroll_jank_v3 = 1017; optional ChromeHistogramSummaries chrome_histogram_summaries = 1018; + optional ChromeStudyHashes chrome_study_hashes = 1019; } diff --git a/protos/perfetto/metrics/chrome/study_hashes.proto b/protos/perfetto/metrics/chrome/study_hashes.proto new file mode 100644 index 0000000000..5eed236003 --- /dev/null +++ b/protos/perfetto/metrics/chrome/study_hashes.proto @@ -0,0 +1,26 @@ +/* + * 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. + */ + +syntax = "proto2"; + +package perfetto.protos; + +// The list of Chrome Study hashes in trace track events. Use cases include +// translating study hashes to study names by getting this list, and prepending +// a translation table to the trace. +message ChromeStudyHashes { + repeated int64 hash = 1; +} diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto index 6104064909..08077f81b9 100644 --- a/protos/perfetto/trace/perfetto_trace.proto +++ b/protos/perfetto/trace/perfetto_trace.proto @@ -15531,6 +15531,7 @@ message TranslationTable { ChromePerformanceMarkTranslationTable chrome_performance_mark = 3; SliceNameTranslationTable slice_name = 4; ProcessTrackNameTranslationTable process_track_name = 5; + ChromeStudyTranslationTable chrome_study = 6; } } @@ -15560,6 +15561,11 @@ message ProcessTrackNameTranslationTable { map raw_to_deobfuscated_name = 1; }; +// Chrome study hash -> name translation rules. +message ChromeStudyTranslationTable { + map hash_to_name = 1; +}; + // End of protos/perfetto/trace/translation/translation_table.proto // Begin of protos/perfetto/trace/trigger.proto diff --git a/protos/perfetto/trace/translation/translation_table.proto b/protos/perfetto/trace/translation/translation_table.proto index b934cf7fbc..b2685f45dc 100644 --- a/protos/perfetto/trace/translation/translation_table.proto +++ b/protos/perfetto/trace/translation/translation_table.proto @@ -27,6 +27,7 @@ message TranslationTable { ChromePerformanceMarkTranslationTable chrome_performance_mark = 3; SliceNameTranslationTable slice_name = 4; ProcessTrackNameTranslationTable process_track_name = 5; + ChromeStudyTranslationTable chrome_study = 6; } } @@ -55,3 +56,8 @@ message SliceNameTranslationTable { message ProcessTrackNameTranslationTable { map raw_to_deobfuscated_name = 1; }; + +// Chrome study hash -> name translation rules. +message ChromeStudyTranslationTable { + map hash_to_name = 1; +}; diff --git a/src/trace_processor/importers/common/args_translation_table.cc b/src/trace_processor/importers/common/args_translation_table.cc index 8aa9a0d825..7dc072723b 100644 --- a/src/trace_processor/importers/common/args_translation_table.cc +++ b/src/trace_processor/importers/common/args_translation_table.cc @@ -70,6 +70,10 @@ ArgsTranslationTable::ArgsTranslationTable(TraceStorage* storage) storage->InternString(kChromePerformanceMarkMarkHashKey)), interned_chrome_performance_mark_mark_key_( storage->InternString(kChromePerformanceMarkMarkKey)), + interned_chrome_trigger_hash_key_( + storage->InternString(kChromeTriggerHashKey)), + interned_chrome_trigger_name_key_( + storage->InternString(kChromeTriggerNameKey)), interned_mojo_method_mapping_id_( storage->InternString(kMojoMethodMappingIdKey)), interned_mojo_method_rel_pc_(storage->InternString(kMojoMethodRelPcKey)), @@ -156,6 +160,17 @@ void ArgsTranslationTable::TranslateArgs( } break; } + case KeyType::kChromeTriggerHash: { + inserter.AddArg(interned_chrome_trigger_hash_key_, arg.value); + const std::optional translated_value = + TranslateChromeStudyHash(arg.value.uint_value); + if (translated_value) { + inserter.AddArg( + interned_chrome_trigger_name_key_, + Variadic::String(storage_->InternString(*translated_value))); + } + break; + } case KeyType::kMojoMethodMappingId: { mapping_id = arg.value.uint_value; break; @@ -192,6 +207,9 @@ ArgsTranslationTable::KeyIdAndTypeToEnum(StringId flat_key_id, if (key_id == interned_mojo_method_rel_pc_) { return KeyType::kMojoMethodRelPc; } + if (key_id == interned_chrome_trigger_hash_key_) { + return KeyType::kChromeTriggerHash; + } } else if (type == Variadic::Type::kString) { if (flat_key_id == interned_obfuscated_view_dump_class_name_flat_key_) { return KeyType::kClassName; @@ -238,6 +256,15 @@ ArgsTranslationTable::TranslateChromePerformanceMarkMarkHash( return base::StringView(*value); } +std::optional ArgsTranslationTable::TranslateChromeStudyHash( + uint64_t hash) const { + auto* value = chrome_study_hash_to_name_.Find(hash); + if (!value) { + return std::nullopt; + } + return base::StringView(*value); +} + std::optional ArgsTranslationTable::TranslateNativeSymbol(MappingId mapping_id, uint64_t rel_pc) const { diff --git a/src/trace_processor/importers/common/args_translation_table.h b/src/trace_processor/importers/common/args_translation_table.h index f5bb1b2d18..785dea8f68 100644 --- a/src/trace_processor/importers/common/args_translation_table.h +++ b/src/trace_processor/importers/common/args_translation_table.h @@ -76,6 +76,9 @@ class ArgsTranslationTable { base::StringView name) { chrome_performance_mark_mark_hash_to_name_.Insert(hash, name.ToStdString()); } + void AddChromeStudyTranslationRule(uint64_t hash, base::StringView name) { + chrome_study_hash_to_name_.Insert(hash, name.ToStdString()); + } void AddNativeSymbolTranslationRule(MappingId mapping_id, uint64_t rel_pc, const SourceLocation& loc) { @@ -102,6 +105,10 @@ class ArgsTranslationTable { TranslateChromePerformanceMarkMarkHashForTesting(uint64_t hash) const { return TranslateChromePerformanceMarkMarkHash(hash); } + std::optional TranslateChromeStudyHashForTesting( + uint64_t hash) const { + return TranslateChromeStudyHash(hash); + } std::optional TranslateClassNameForTesting( StringId obfuscated_class_name_id) const { return TranslateClassName(obfuscated_class_name_id); @@ -116,6 +123,7 @@ class ArgsTranslationTable { kMojoMethodMappingId = 4, kMojoMethodRelPc = 5, kClassName = 6, + kChromeTriggerHash = 7, }; static constexpr char kChromeHistogramHashKey[] = @@ -138,6 +146,9 @@ class ArgsTranslationTable { static constexpr char kChromePerformanceMarkMarkKey[] = "chrome_hashed_performance_mark.mark"; + static constexpr char kChromeTriggerHashKey[] = "chrome_trigger.name_hash"; + static constexpr char kChromeTriggerNameKey[] = "chrome_trigger.name"; + static constexpr char kMojoMethodMappingIdKey[] = "chrome_mojo_event_info.mojo_interface_method.native_symbol.mapping_id"; static constexpr char kMojoMethodRelPcKey[] = @@ -159,6 +170,8 @@ class ArgsTranslationTable { StringId interned_chrome_performance_mark_site_key_; StringId interned_chrome_performance_mark_mark_hash_key_; StringId interned_chrome_performance_mark_mark_key_; + StringId interned_chrome_trigger_hash_key_; + StringId interned_chrome_trigger_name_key_; StringId interned_mojo_method_mapping_id_; StringId interned_mojo_method_rel_pc_; @@ -175,6 +188,7 @@ class ArgsTranslationTable { chrome_performance_mark_site_hash_to_name_; base::FlatHashMap chrome_performance_mark_mark_hash_to_name_; + base::FlatHashMap chrome_study_hash_to_name_; base::FlatHashMap native_symbol_to_location_; // A translation mapping for obfuscated Java class names and its members. DeobfuscationMappingTable deobfuscation_mapping_table_; @@ -194,6 +208,7 @@ class ArgsTranslationTable { uint64_t hash) const; std::optional TranslateChromePerformanceMarkMarkHash( uint64_t hash) const; + std::optional TranslateChromeStudyHash(uint64_t hash) const; std::optional TranslateNativeSymbol(MappingId mapping_id, uint64_t rel_pc) const; diff --git a/src/trace_processor/importers/common/args_translation_table_unittest.cc b/src/trace_processor/importers/common/args_translation_table_unittest.cc index e44b0345d6..cf388475b7 100644 --- a/src/trace_processor/importers/common/args_translation_table_unittest.cc +++ b/src/trace_processor/importers/common/args_translation_table_unittest.cc @@ -82,6 +82,18 @@ TEST(ArgsTranslationTable, TranslatesPerformanceMarkMarkHashes) { std::nullopt); } +TEST(ArgsTranslationTable, TranslatesStudyHashes) { + TraceStorage storage; + ArgsTranslationTable table(&storage); + table.AddChromeStudyTranslationRule(1, "hash1"); + table.AddChromeStudyTranslationRule(10, "hash2"); + EXPECT_EQ(table.TranslateChromeStudyHashForTesting(1), + std::optional("hash1")); + EXPECT_EQ(table.TranslateChromeStudyHashForTesting(10), + std::optional("hash2")); + EXPECT_EQ(table.TranslateChromeStudyHashForTesting(2), std::nullopt); +} + TEST(ArgsTranslationTable, TranslateClassName) { TraceStorage storage; StringId xyz_id = storage.InternString("xyz"); diff --git a/src/trace_processor/importers/proto/metadata_module.cc b/src/trace_processor/importers/proto/metadata_module.cc index c82b01fe51..01024c5174 100644 --- a/src/trace_processor/importers/proto/metadata_module.cc +++ b/src/trace_processor/importers/proto/metadata_module.cc @@ -42,7 +42,11 @@ MetadataModule::MetadataModule(TraceProcessorContext* context) : context_(context), producer_name_key_id_(context_->storage->InternString("producer_name")), trusted_producer_uid_key_id_( - context_->storage->InternString("trusted_producer_uid")) { + context_->storage->InternString("trusted_producer_uid")), + chrome_trigger_name_id_( + context_->storage->InternString("chrome_trigger.name")), + chrome_trigger_hash_id_( + context_->storage->InternString("chrome_trigger.name_hash")) { RegisterForField(TracePacket::kUiStateFieldNumber, context); RegisterForField(TracePacket::kTriggerFieldNumber, context); RegisterForField(TracePacket::kChromeTriggerFieldNumber, context); @@ -133,11 +137,19 @@ void MetadataModule::ParseChromeTrigger(int64_t ts, ConstBytes blob) { if (trigger.has_trigger_name()) { name_id = context_->storage->InternString(trigger.trigger_name()); } else { - name_id = context_->storage->InternString( - base::StringView(base::IntToHexString(trigger.trigger_name_hash()))); + name_id = + context_->storage->InternString(base::StringView("chrome_trigger")); } - context_->slice_tracker->Scoped(ts, track_id, cat_id, name_id, - /* duration = */ 0); + context_->slice_tracker->Scoped( + ts, track_id, cat_id, name_id, + /* duration = */ 0, [&](ArgsTracker::BoundInserter* inserter) { + inserter->AddArg( + chrome_trigger_hash_id_, + Variadic::UnsignedInteger(trigger.trigger_name_hash())); + if (trigger.has_trigger_name()) { + inserter->AddArg(chrome_trigger_name_id_, Variadic::String(name_id)); + } + }); MetadataTracker* metadata = context_->metadata_tracker.get(); metadata->SetDynamicMetadata( diff --git a/src/trace_processor/importers/proto/metadata_module.h b/src/trace_processor/importers/proto/metadata_module.h index ca9b97e239..aabea03bda 100644 --- a/src/trace_processor/importers/proto/metadata_module.h +++ b/src/trace_processor/importers/proto/metadata_module.h @@ -55,6 +55,8 @@ class MetadataModule : public ProtoImporterModule { const StringId producer_name_key_id_; const StringId trusted_producer_uid_key_id_; + const StringId chrome_trigger_name_id_; + const StringId chrome_trigger_hash_id_; }; } // namespace trace_processor diff --git a/src/trace_processor/importers/proto/translation_table_module.cc b/src/trace_processor/importers/proto/translation_table_module.cc index f45e353268..011389581f 100644 --- a/src/trace_processor/importers/proto/translation_table_module.cc +++ b/src/trace_processor/importers/proto/translation_table_module.cc @@ -57,6 +57,8 @@ ModuleResult TranslationTableModule::TokenizePacket( ParseSliceNameRules(translation_table.slice_name()); } else if (translation_table.has_process_track_name()) { ParseProcessTrackNameRules(translation_table.process_track_name()); + } else if (translation_table.has_chrome_study()) { + ParseChromeStudyRules(translation_table.chrome_study()); } return ModuleResult::Handled(); } @@ -128,5 +130,17 @@ void TranslationTableModule::ParseProcessTrackNameRules( } } +void TranslationTableModule::ParseChromeStudyRules( + protozero::ConstBytes bytes) { + const auto chrome_study = + protos::pbzero::ChromeStudyTranslationTable::Decoder(bytes); + for (auto it = chrome_study.hash_to_name(); it; ++it) { + protos::pbzero::ChromeStudyTranslationTable::HashToNameEntry::Decoder entry( + *it); + context_->args_translation_table->AddChromeStudyTranslationRule( + entry.key(), entry.value()); + } +} + } // namespace trace_processor } // namespace perfetto diff --git a/src/trace_processor/importers/proto/translation_table_module.h b/src/trace_processor/importers/proto/translation_table_module.h index 62d4c725ba..51a8c52d27 100644 --- a/src/trace_processor/importers/proto/translation_table_module.h +++ b/src/trace_processor/importers/proto/translation_table_module.h @@ -47,6 +47,7 @@ class TranslationTableModule : public ProtoImporterModule { void ParseChromePerformanceMarkRules(protozero::ConstBytes bytes); void ParseSliceNameRules(protozero::ConstBytes bytes); void ParseProcessTrackNameRules(protozero::ConstBytes bytes); + void ParseChromeStudyRules(protozero::ConstBytes bytes); TraceProcessorContext* context_; }; diff --git a/src/trace_processor/metrics/sql/chrome/BUILD.gn b/src/trace_processor/metrics/sql/chrome/BUILD.gn index 7d10aebe6b..37e8bd8923 100644 --- a/src/trace_processor/metrics/sql/chrome/BUILD.gn +++ b/src/trace_processor/metrics/sql/chrome/BUILD.gn @@ -40,6 +40,7 @@ perfetto_sql_source_set("chrome_sql") { "chrome_scroll_jank_v3.sql", "chrome_slice_names.sql", "chrome_stack_samples_for_task.sql", + "chrome_study_hashes.sql", "chrome_tasks.sql", "chrome_tasks_delaying_input_processing.sql", "chrome_tasks_delaying_input_processing_base.sql", diff --git a/src/trace_processor/metrics/sql/chrome/chrome_study_hashes.sql b/src/trace_processor/metrics/sql/chrome/chrome_study_hashes.sql new file mode 100644 index 0000000000..535f07ae3e --- /dev/null +++ b/src/trace_processor/metrics/sql/chrome/chrome_study_hashes.sql @@ -0,0 +1,26 @@ +-- +-- Copyright 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 +-- +-- https://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. + +DROP VIEW IF EXISTS chrome_study_hashes_output; + +CREATE PERFETTO VIEW chrome_study_hashes_output AS +SELECT ChromeStudyHashes( + 'hash', ( + SELECT RepeatedField(int_value) + FROM args + WHERE key = 'chrome_trigger.name_hash' + ORDER BY int_value + ) +); diff --git a/test/trace_processor/diff_tests/metrics/chrome/tests.py b/test/trace_processor/diff_tests/metrics/chrome/tests.py index f0055561bc..b31863d026 100644 --- a/test/trace_processor/diff_tests/metrics/chrome/tests.py +++ b/test/trace_processor/diff_tests/metrics/chrome/tests.py @@ -142,6 +142,35 @@ def test_chrome_performance_mark_hashes(self): } """)) + # Chrome study + def test_chrome_study_hashes(self): + return DiffTestBlueprint( + trace=TextProto(r""" + packet { + trusted_packet_sequence_id: 1 + timestamp: 0 + incremental_state_cleared: true + chrome_trigger { + trigger_name_hash: 10 + } + } + packet { + trusted_packet_sequence_id: 1 + timestamp: 0 + incremental_state_cleared: true + chrome_trigger { + trigger_name_hash: 20 + } + } + """), + query=Metric('chrome_study_hashes'), + out=TextProto(r""" + [perfetto.protos.chrome_study_hashes]: { + hash: 10 + hash: 20 + } + """)) + # Chrome reliable range def test_chrome_reliable_range(self): return DiffTestBlueprint( diff --git a/test/trace_processor/diff_tests/parser/translated_args/chrome_trigger.out b/test/trace_processor/diff_tests/parser/translated_args/chrome_trigger.out new file mode 100644 index 0000000000..2577af72e8 --- /dev/null +++ b/test/trace_processor/diff_tests/parser/translated_args/chrome_trigger.out @@ -0,0 +1,6 @@ +"flat_key","key","int_value","string_value" +"chrome_trigger.name","chrome_trigger.name","[NULL]","study_name1" +"chrome_trigger.name","chrome_trigger.name","[NULL]","study_name2" +"chrome_trigger.name_hash","chrome_trigger.name_hash",10,"[NULL]" +"chrome_trigger.name_hash","chrome_trigger.name_hash",20,"[NULL]" +"chrome_trigger.name_hash","chrome_trigger.name_hash",30,"[NULL]" diff --git a/test/trace_processor/diff_tests/parser/translated_args/chrome_trigger.textproto b/test/trace_processor/diff_tests/parser/translated_args/chrome_trigger.textproto new file mode 100644 index 0000000000..4648a3a946 --- /dev/null +++ b/test/trace_processor/diff_tests/parser/translated_args/chrome_trigger.textproto @@ -0,0 +1,35 @@ +# Chrome study hashes translation rules +packet { + translation_table { + chrome_study { + hash_to_name { key: 10 value: "study_name1" } + hash_to_name { key: 20 value: "study_name2" } + } + } +} +# Known histogram hash, should be translated to a name +packet { + trusted_packet_sequence_id: 1 + timestamp: 1 + + chrome_trigger { + trigger_name_hash: 10 + } +} +# Another known hash, should be translated to a name +packet { + trusted_packet_sequence_id: 1 + timestamp: 2 + chrome_trigger { + trigger_name_hash: 20 + } +} +# Unknown hash, should not be translated to any name +packet { + trusted_packet_sequence_id: 1 + timestamp: 3 + chrome_trigger { + trigger_name_hash: 30 + } +} + diff --git a/test/trace_processor/diff_tests/parser/translated_args/tests.py b/test/trace_processor/diff_tests/parser/translated_args/tests.py index 3bada0dd76..d14b79aec2 100644 --- a/test/trace_processor/diff_tests/parser/translated_args/tests.py +++ b/test/trace_processor/diff_tests/parser/translated_args/tests.py @@ -93,6 +93,12 @@ def test_chrome_performance_mark(self): query=Path('chrome_args_test.sql'), out=Path('chrome_performance_mark.out')) + def test_chrome_trigger(self): + return DiffTestBlueprint( + trace=Path('chrome_trigger.textproto'), + query=Path('chrome_args_test.sql'), + out=Path('chrome_trigger.out')) + def test_slice_name(self): return DiffTestBlueprint( trace=Path('slice_name.textproto'),