blob: 3dab9df3b524089bca4f33a13110782a250d6cbe [file] [log] [blame]
# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import unittest
import xml.dom.minidom
import expand_owners
import histogram_paths
import merge_xml
class MergeXmlTest(unittest.TestCase):
def testMergeFiles(self):
"""Checks that enums.xml and histograms.xml can merge successfully."""
merged = merge_xml.PrettyPrintMergedFiles([
histogram_paths.TEST_ENUMS_XML, histogram_paths.TEST_HISTOGRAMS_XML,
histogram_paths.TEST_SUFFIXES_XML
])
# If ukm.xml is not provided, there is no need to populate the
# UkmEventNameHash enum.
expected_merged_xml = """
<histogram-configuration>
<enums>
<enum name="Enum1">
<int value="0" label="Value0"/>
<int value="1" label="Value1"/>
</enum>
<enum name="TestEnum">
<int value="0" label="Value0"/>
<int value="1" label="Value1"/>
</enum>
<enum name="UkmEventNameHash">
<summary>
Placeholder enum. The values are UKM event name hashes truncated to 31 bits.
This gets populated by the GetEnumsNodes function in merge_xml.py when
producing the merged XML file.
</summary>
</enum>
</enums>
<histograms>
<variants name="TestToken">
<variant name="Variant1" summary="Label1"/>
<variant name="Variant2" summary="Label2"/>
</variants>
<histogram name="Foo.Bar" units="xxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyzzzz"
expires_after="M85">
<owner>person@chromium.org</owner>
<component>Component</component>
<summary>Foo</summary>
</histogram>
<histogram name="Test.EnumHistogram" enum="TestEnum" expires_after="M81">
<obsolete>
Obsolete message
</obsolete>
<owner>uma@chromium.org</owner>
<summary>A enum histogram.</summary>
</histogram>
<histogram name="Test.Histogram" units="microseconds" expires_after="M85">
<obsolete>
Removed 6/2020.
</obsolete>
<owner>person@chromium.org</owner>
<summary>Summary 2</summary>
</histogram>
<histogram name="Test.TokenHistogram{TestToken}" units="microseconds"
expires_after="M85">
<obsolete>
Removed 6/2020.
</obsolete>
<owner>person@chromium.org</owner>
<summary>Summary 2</summary>
<token key="TestToken" variants="TestToken"/>
</histogram>
</histograms>
<histogram_suffixes_list>
<histogram_suffixes name="Test.EnumHistogramSuffixes" separator="."
ordering="prefix,2">
<suffix name="TestEnumSuffix" label="The enum histogram_suffixes"/>
<affected-histogram name="Test.EnumHistogram"/>
</histogram_suffixes>
<histogram_suffixes name="Test.HistogramSuffixes" separator=".">
<suffix name="TestSuffix" label="A histogram_suffixes"/>
<affected-histogram name="Test.Histogram"/>
</histogram_suffixes>
</histogram_suffixes_list>
</histogram-configuration>
"""
self.maxDiff = None
self.assertMultiLineEqual(expected_merged_xml.strip(), merged.strip())
def testMergeFiles_WithXmlEvents(self):
"""Checks that the UkmEventNameHash enum is populated correctly.
If ukm.xml is provided, populate a list of ints to the UkmEventNameHash enum
where each value is a truncated hash of the event name and each label is the
corresponding event name, with obsolete label when applicable.
"""
merged = merge_xml.PrettyPrintMergedFiles(histogram_paths.ALL_TEST_XMLS)
expected_merged_xml = """
<histogram-configuration>
<enums>
<enum name="Enum1">
<int value="0" label="Value0"/>
<int value="1" label="Value1"/>
</enum>
<enum name="TestEnum">
<int value="0" label="Value0"/>
<int value="1" label="Value1"/>
</enum>
<enum name="UkmEventNameHash">
<summary>
Placeholder enum. The values are UKM event name hashes truncated to 31 bits.
This gets populated by the GetEnumsNodes function in merge_xml.py when
producing the merged XML file.
</summary>
<int value="151676257" label="AbusiveExperienceHeuristic.TestEvent1"/>
<int value="898353372"
label="AbusiveExperienceHeuristic.TestEvent2 (Obsolete)"/>
<int value="1052089961" label="Autofill.TestEvent3"/>
<int value="1758741469" label="FullyObsolete.TestEvent4 (Obsolete)"/>
</enum>
</enums>
<histograms>
<variants name="TestToken">
<variant name="Variant1" summary="Label1"/>
<variant name="Variant2" summary="Label2"/>
</variants>
<histogram name="Foo.Bar" units="xxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyzzzz"
expires_after="M85">
<owner>person@chromium.org</owner>
<component>Component</component>
<summary>Foo</summary>
</histogram>
<histogram name="Test.EnumHistogram" enum="TestEnum" expires_after="M81">
<obsolete>
Obsolete message
</obsolete>
<owner>uma@chromium.org</owner>
<summary>A enum histogram.</summary>
</histogram>
<histogram name="Test.Histogram" units="microseconds" expires_after="M85">
<obsolete>
Removed 6/2020.
</obsolete>
<owner>person@chromium.org</owner>
<summary>Summary 2</summary>
</histogram>
<histogram name="Test.TokenHistogram{TestToken}" units="microseconds"
expires_after="M85">
<obsolete>
Removed 6/2020.
</obsolete>
<owner>person@chromium.org</owner>
<summary>Summary 2</summary>
<token key="TestToken" variants="TestToken"/>
</histogram>
</histograms>
<histogram_suffixes_list>
<histogram_suffixes name="Test.EnumHistogramSuffixes" separator="."
ordering="prefix,2">
<suffix name="TestEnumSuffix" label="The enum histogram_suffixes"/>
<affected-histogram name="Test.EnumHistogram"/>
</histogram_suffixes>
<histogram_suffixes name="Test.HistogramSuffixes" separator=".">
<suffix name="TestSuffix" label="A histogram_suffixes"/>
<affected-histogram name="Test.Histogram"/>
</histogram_suffixes>
</histogram_suffixes_list>
</histogram-configuration>
"""
self.maxDiff = None
self.assertMultiLineEqual(expected_merged_xml.strip(), merged.strip())
def testMergeFiles_InvalidPrimaryOwner(self):
histograms_without_valid_first_owner = xml.dom.minidom.parseString("""
<histogram-configuration>
<histograms>
<histogram name="Caffeination" units="mg">
<owner>culprit@evil.com</owner>
<summary>I like coffee.</summary>
</histogram>
</histograms>
</histogram-configuration>
""")
with self.assertRaisesRegex(
expand_owners.Error,
'The histogram Caffeination must have a valid primary owner, i.e. a '
'Googler with an @google.com or @chromium.org email address. Please '
'manually update the histogram with a valid primary owner.'):
merge_xml.MergeTrees([histograms_without_valid_first_owner],
should_expand_owners=True)
def testMergeFiles_WithComponentMetadata(self):
merged = merge_xml.PrettyPrintMergedFiles(
[histogram_paths.TEST_XML_WITH_COMPONENTS_RELATIVE])
expected_merged_xml = """
<histogram-configuration>
<histograms>
<histogram name="Test.Histogram" units="seconds" expires_after="M104">
<owner>person@chromium.org</owner>
<owner>team-alias@chromium.org</owner>
<component>Test&gt;Component</component>
<summary>Summary 2</summary>
</histogram>
<histogram name="Test.Histogram.WithComponent" enum="TestEnum"
expires_after="M104">
<owner>uma@chromium.org</owner>
<owner>team-alias@chromium.org</owner>
<component>First&gt;Component</component>
<component>Test&gt;Component</component>
<summary>A enum histogram.</summary>
</histogram>
</histograms>
<histogram_suffixes_list/>
</histogram-configuration>
"""
self.assertMultiLineEqual(expected_merged_xml.strip(), merged.strip())
if __name__ == '__main__':
unittest.main()