Exemplo n.º 1
0
def main():
    """Prints the owners of histograms in a specific file or of all histograms.

  Args:
    argv[1]: Optional argument that is the relative path to a specific
        histograms.xml.

  Example usage to print owners of metadata/Accessibility/histograms.xml:
    python histogram_ownership.py metadata/Accessibility/histograms.xml

  Example usage to print owners of all histograms:
    python histogram_ownership.py
  """
    if len(sys.argv) == 1:
        merged_xml_string = merge_xml.MergeFiles(
            histogram_paths.ALL_XMLS, should_expand_owners=True).toxml()
        root = ET.fromstring(merged_xml_string)
    else:
        rel_path = path_util.GetInputFile(
            os.path.join('tools', 'metrics', 'histograms', sys.argv[1]))
        if not os.path.exists(rel_path):
            raise ValueError("A histograms.xml file does not exist in %s" %
                             rel_path)

        tree = ET.parse(rel_path)
        root = tree.getroot()

    PrintOwners(root)
def _GenerateFile(arguments):
  """Generates header file containing array with hashes of expired histograms.

  Args:
    arguments: An object with the following attributes:
      arguments.inputs: A list of xml files with histogram descriptions.
      arguments.header_filename: A filename of the generated header file.
      arguments.namespace: A namespace to contain generated array.
      arguments.output_dir: A directory to put the generated file.
      arguments.major_branch_date_filepath: File path for base date.
      arguments.milestone_filepath: File path for milestone information.
  """
  # Assert that the |--inputs| is the same as |histogram_paths.ALL_XMLS| to make
  # sure we have the most updated list of histogram descriptions. Otherwise,
  # inform the cl owner to update the --inputs.
  to_add, to_remove = CheckUnsyncedHistograms(arguments.inputs)
  assert len(to_add) == 0 and len(to_remove) == 0, (
      "The --inputs is not in sync with the most updated list of xmls. Please "
      "update the inputs in "
      "components/metrics/generate_expired_histograms_array.gni.\n"
      "  add: %s\n  remove: %s" % (', '.join(to_add), ', '.join(to_remove)))

  descriptions = merge_xml.MergeFiles(arguments.inputs)
  with open(arguments.major_branch_date_filepath, "r") as date_file:
    branch_file_content = date_file.read()
  with open(arguments.milestone_filepath, "r") as milestone_file:
    mstone_file_content = milestone_file.read()

  header_file_content = _GenerateFileContent(
      descriptions, branch_file_content, mstone_file_content,
      arguments.header_filename, arguments.namespace)

  with open(os.path.join(arguments.output_dir, arguments.header_filename),
            "w") as generated_file:
    generated_file.write(header_file_content)
Exemplo n.º 3
0
def _GenerateFile(arguments):
    """Generates header file containing array with hashes of expired histograms.

  Args:
    arguments: An object with the following attributes:
      arguments.inputs: A list of xml files with histogram descriptions.
      arguments.header_filename: A filename of the generated header file.
      arguments.namespace: A namespace to contain generated array.
      arguments.hash_datatype: Datatype of histogram names' hash.
      arguments.output_dir: A directory to put the generated file.

  Raises:
    Error if there is an error in input xml files.
  """
    descriptions = merge_xml.MergeFiles(arguments.inputs)
    histograms, had_errors = (
        extract_histograms.ExtractHistogramsFromDom(descriptions))
    if had_errors:
        raise Error("Error parsing inputs.")
    with open(arguments.major_branch_date_filepath, "r") as date_file:
        file_content = date_file.read()
    base_date = _GetBaseDate(file_content, _DATE_FILE_PATTERN)
    expired_histograms_names = _GetExpiredHistograms(histograms, base_date)
    expired_histograms_map = _GetHashToNameMap(expired_histograms_names)
    header_file_content = _GenerateHeaderFileContent(arguments.header_filename,
                                                     arguments.namespace,
                                                     expired_histograms_map)
    with open(os.path.join(arguments.output_dir, arguments.header_filename),
              "w") as generated_file:
        generated_file.write(header_file_content)
Exemplo n.º 4
0
def _GenerateFile(arguments):
    """Generates header file containing array with hashes of expired histograms.

  Args:
    arguments: An object with the following attributes:
      arguments.inputs: A list of xml files with histogram descriptions.
      arguments.header_filename: A filename of the generated header file.
      arguments.namespace: A namespace to contain generated array.
      arguments.output_dir: A directory to put the generated file.
      arguments.major_branch_date_filepath: File path for base date.
      arguments.milestone_filepath: File path for milestone information.
  """
    descriptions = merge_xml.MergeFiles(arguments.inputs)
    with open(arguments.major_branch_date_filepath, "r") as date_file:
        branch_file_content = date_file.read()
    with open(arguments.milestone_filepath, "r") as milestone_file:
        mstone_file_content = milestone_file.read()

    header_file_content = _GenerateFileContent(descriptions,
                                               branch_file_content,
                                               mstone_file_content,
                                               arguments.header_filename,
                                               arguments.namespace)

    with open(os.path.join(arguments.output_dir, arguments.header_filename),
              "w") as generated_file:
        generated_file.write(header_file_content)
Exemplo n.º 5
0
    def checkMetricTypeIsSpecified(self):
        """Check each metric is either specified with an enum or a unit."""
        errors = []
        warnings = []

        enum_tree = merge_xml.MergeFiles([histogram_paths.ENUMS_XML])
        enums, _ = extract_histograms.ExtractEnumsFromXmlTree(enum_tree)

        for event_node in self.config.getElementsByTagName('event'):
            for metric_node in event_node.getElementsByTagName('metric'):
                if metric_node.hasAttribute('enum'):
                    enum_name = metric_node.getAttribute('enum')
                    # Check if the enum is defined in enums.xml.
                    if enum_name not in enums:
                        errors.append(
                            "Unknown enum %s in ukm metric %s:%s." %
                            (enum_name, event_node.getAttribute('name'),
                             metric_node.getAttribute('name')))
                elif not metric_node.hasAttribute('unit'):
                    warnings.append(
                        "Warning: Neither \'enum\' or \'unit\' is specified "
                        "for ukm metric %s:%s." %
                        (event_node.getAttribute('name'),
                         metric_node.getAttribute('name')))

        isSuccess = not errors
        return (isSuccess, errors, warnings)
Exemplo n.º 6
0
def main():
    doc = merge_xml.MergeFiles(histogram_paths.ALL_XMLS)
    histograms, had_errors = extract_histograms.ExtractHistogramsFromDom(doc)
    if had_errors:
        raise Error("Error parsing inputs.")
    names = extract_histograms.ExtractNames(histograms)
    for name in names:
        print name
Exemplo n.º 7
0
def readAllXmlHistograms():
    """Parses all histogram names defined in |histogram_paths.ALL_XMLS|.

  Returns:
    A set containing the parsed histogram names.
  """
    merged = merge_xml.MergeFiles(histogram_paths.ALL_XMLS)
    histograms, _ = extract_histograms.ExtractHistogramsFromDom(merged)
    return set(extract_histograms.ExtractNames(histograms))
Exemplo n.º 8
0
def _ParseMergedXML():
    """Parses merged xml into different types of nodes"""
    merged_histograms = merge_xml.MergeFiles(histogram_paths.HISTOGRAMS_XMLS +
                                             [histogram_paths.OBSOLETE_XML])
    histogram_nodes = merged_histograms.getElementsByTagName('histogram')
    variants_nodes = merged_histograms.getElementsByTagName('variants')
    histogram_suffixes_nodes = merged_histograms.getElementsByTagName(
        'histogram_suffixes')
    return histogram_nodes, variants_nodes, histogram_suffixes_nodes
Exemplo n.º 9
0
def get_names(xml_files):
    """Returns all histogram names generated from a list of xml files.

  Args:
    xml_files: A list of open file objects containing histogram definitions.
  Returns:
    A tuple of (names, obsolete names), where the obsolete names is a subset of
    all names.
  """
    doc = merge_xml.MergeFiles(files=xml_files)
    histograms, had_errors = extract_histograms.ExtractHistogramsFromDom(doc)
    if had_errors:
        raise ValueError("Error parsing inputs.")
    names = set(extract_histograms.ExtractNames(histograms))
    obsolete_names = set(extract_histograms.ExtractObsoleteNames(histograms))
    return (names, obsolete_names)
def main(args):
    # Extract all histograms into a dict.
    doc = merge_xml.MergeFiles(filenames=histogram_paths.ALL_XMLS,
                               should_expand_owners=True)
    histograms, had_errors = extract_histograms.ExtractHistogramsFromDom(doc)
    if had_errors:
        raise ValueError("Error parsing inputs.")
    # Construct a dom tree that is similar to the normal histograms.xml so that
    # we can use histogram_configuration_model to pretty print it.
    doc = xml.dom.minidom.Document()
    configuration = doc.createElement('histogram-configuration')
    histograms_node = doc.createElement('histograms')
    for name, histogram in histograms.items():
        if re.match(args.pattern, name):
            histograms_node.appendChild(
                ConstructHistogram(doc, name, histogram))
    configuration.appendChild(histograms_node)
    doc.appendChild(configuration)
    print(histogram_configuration_model.PrettifyTree(doc))
Exemplo n.º 11
0
def main():
    doc = merge_xml.MergeFiles(histogram_paths.ALL_XMLS)
    _, errors = extract_histograms.ExtractHistogramsFromDom(doc)
    sys.exit(errors)
Exemplo n.º 12
0
    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 where each value is a xml event name hash truncated to 31 bits and
    each label is the corresponding event name.
    """
        merged = merge_xml.MergeFiles(histogram_paths.ALL_TEST_XMLS)
        expected_merged = xml.dom.minidom.parseString("""
<histogram-configuration><enums>

<enum name="Enum1">
  <int label="Value0" value="0"/>
  <int label="Value1" value="1"/>
</enum>

<enum name="TestEnum">
  <int label="Value0" value="0"/>
  <int label="Value1" value="1"/>
</enum>

<enum name="UkmEventNameHash">
<!-- 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. -->

<int label="AbusiveExperienceHeuristic.TabUnder" value="1621538456"/>\
<int label="Autofill.SelectedMaskedServerCard (Obsolete)" value="1913876024"/>\
</enum>

</enums><histograms>

<histogram name="Foo.Bar" units="xxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyzzzz">
  <summary>Foo</summary>
  <owner>[email protected]</owner>
  <component>Component</component>
</histogram>

<histogram name="Test.Histogram" units="microseconds">
  <obsolete>
    Removed 6/2020.
  </obsolete>
  <owner>[email protected]</owner>
  <summary>
    Summary 2
  </summary>
</histogram>

<histogram name="Test.EnumHistogram" enum="TestEnum" expires_after="M81">
  <owner>[email protected]</owner>
  <obsolete>
    Obsolete message
  </obsolete>
  <summary>
    A enum histogram.
  </summary>
</histogram>

</histograms><histogram_suffixes_list>

<histogram_suffixes name="Test.HistogramSuffixes" separator=".">
  <suffix label="A histogram_suffixes" name="TestSuffix"/>
  <affected-histogram name="Test.Histogram"/>
</histogram_suffixes>

</histogram_suffixes_list></histogram-configuration>
""")
        self.maxDiff = None
        self.assertEqual(expected_merged.toxml(), merged.toxml())
Exemplo n.º 13
0
    def testMergeFiles(self):
        """Checks that enums.xml and histograms.xml can merge successfully."""
        merged = merge_xml.MergeFiles([
            histogram_paths.TEST_ENUMS_XML, histogram_paths.TEST_HISTOGRAMS_XML
        ])
        # If ukm.xml is not provided, there is no need to populate the
        # UkmEventNameHash enum.
        expected_merged = xml.dom.minidom.parseString("""
<histogram-configuration><enums>

<enum name="Enum1">
  <int label="Value0" value="0"/>
  <int label="Value1" value="1"/>
</enum>

<enum name="TestEnum">
  <int label="Value0" value="0"/>
  <int label="Value1" value="1"/>
</enum>

<enum name="UkmEventNameHash">
<!-- 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. -->

</enum>

</enums><histograms>

<histogram name="Foo.Bar" units="xxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyzzzz">
  <summary>Foo</summary>
  <owner>[email protected]</owner>
  <component>Component</component>
</histogram>

<histogram name="Test.Histogram" units="microseconds">
  <obsolete>
    Removed 6/2020.
  </obsolete>
  <owner>[email protected]</owner>
  <summary>
    Summary 2
  </summary>
</histogram>

<histogram name="Test.EnumHistogram" enum="TestEnum" expires_after="M81">
  <owner>[email protected]</owner>
  <obsolete>
    Obsolete message
  </obsolete>
  <summary>
    A enum histogram.
  </summary>
</histogram>

</histograms><histogram_suffixes_list>

<histogram_suffixes name="Test.HistogramSuffixes" separator=".">
  <suffix label="A histogram_suffixes" name="TestSuffix"/>
  <affected-histogram name="Test.Histogram"/>
</histogram_suffixes>

</histogram_suffixes_list></histogram-configuration>
""")
        self.maxDiff = None
        self.assertEqual(expected_merged.toxml(), merged.toxml())
Exemplo n.º 14
0
def main():
    doc = merge_xml.MergeFiles(histogram_paths.ALL_XMLS,
                               should_expand_owners=True)
    _, errors = extract_histograms.ExtractHistogramsFromDom(doc)
    sys.exit(errors)
Exemplo n.º 15
0
def get_names(xml_files):
    doc = merge_xml.MergeFiles(files=xml_files)
    histograms, had_errors = extract_histograms.ExtractHistogramsFromDom(doc)
    if had_errors:
        raise Error("Error parsing inputs.")
    return extract_histograms.ExtractNames(histograms)