def testSuffixCanExtendPatternedHistograms(self):
     patterned_suffix = ("""
     <histogram-configuration>
     <histograms>
       <histogram name="Test{Version}" units="things"
         expires_after="2017-10-16">
         <owner>[email protected]</owner>
         <summary>
           Sample description.
         </summary>
         <token key="Version">
           <variant name=".First"/>
           <variant name=".Last"/>
         </token>
       </histogram>
     </histograms>
     <histogram_suffixes_list>
       <histogram_suffixes name="ExtendPatternedHist" separator=".">
         <suffix name="Found" label="Extending patterned histograms."/>
         <affected-histogram name="Test.First"/>
         <affected-histogram name="Test.Last"/>
       </histogram_suffixes>
     </histogram_suffixes_list>
     </histogram-configuration>""")
     # Only when the histogram is first extended by the token, can the
     # histogram_suffixes find those affected histograms.
     histograms_dict, had_errors = extract_histograms.ExtractHistogramsFromDom(
         xml.dom.minidom.parseString(patterned_suffix))
     self.assertFalse(had_errors)
     self.assertIn('Test.First.Found', histograms_dict)
     self.assertIn('Test.Last.Found', histograms_dict)
예제 #2
0
    def testBaseHistograms(self):
        histograms, had_errors = extract_histograms.ExtractHistogramsFromDom(
            xml.dom.minidom.parseString(TEST_BASE_HISTOGRAM_XML_CONTENT))
        self.assertFalse(had_errors)
        # Base histograms are implicitly marked as obsolete.
        self.assertIn('obsolete', histograms['Test.Base'])
        self.assertIn('obsolete', histograms['Test.Base.Obsolete'])

        # Other histograms shouldn't be implicitly marked as obsolete.
        self.assertNotIn('obsolete', histograms['Test.NotBase.Explicit'])
        self.assertNotIn('obsolete', histograms['Test.NotBase.Implicit'])

        # Suffixes applied to base histograms shouldn't be marked as obsolete...
        self.assertNotIn('obsolete', histograms['Test.Base.NonBaseSuffix'])
        # ... unless the suffix is marked as obsolete,
        self.assertIn('obsolete', histograms['Test.Base.ObsoleteSuffix'])
        # ... or the suffix is a base suffix,
        self.assertIn('obsolete', histograms['Test.Base.BaseSuffix'])
        # ... or the base histogram is marked as obsolete,
        self.assertIn('obsolete', histograms['Test.Base.Obsolete.BaseSuffix'])
        self.assertIn('obsolete',
                      histograms['Test.Base.Obsolete.NonBaseSuffix'])
        self.assertIn('obsolete',
                      histograms['Test.Base.Obsolete.ObsoleteSuffix'])

        # It should be possible to have multiple levels of suffixes for base
        # histograms.
        self.assertNotIn('obsolete', histograms['Test.Base.BaseSuffix.One'])
        self.assertNotIn('obsolete', histograms['Test.Base.BaseSuffix.Two'])
        self.assertNotIn('obsolete', histograms['Test.Base.NonBaseSuffix.One'])
        self.assertNotIn('obsolete', histograms['Test.Base.NonBaseSuffix.Two'])
def _GenerateFileContent(descriptions, branch_file_content,
                         mstone_file_content, header_filename, namespace):
  """Generates header file containing array with hashes of expired histograms.

  Args:
    descriptions: Combined histogram descriptions.
    branch_file_content: Content of file with base date.
    mstone_file_content: Content of file with milestone information.
    header_filename: A filename of the generated header file.
    namespace: A namespace to contain generated array.

  Raises:
    Error if there is an error in input xml files.
  """
  histograms, had_errors = (
      extract_histograms.ExtractHistogramsFromDom(descriptions))
  if had_errors:
    raise Error("Error parsing inputs.")
  base_date = _GetBaseDate(branch_file_content, _DATE_FILE_RE)
  base_date -= datetime.timedelta(weeks=_EXPIRE_GRACE_WEEKS)
  current_milestone = _GetCurrentMilestone(
      mstone_file_content, _CURRENT_MILESTONE_RE)
  current_milestone -= _EXPIRE_GRACE_MSTONES

  expired_histograms_names = _GetExpiredHistograms(
      histograms, base_date, current_milestone)
  expired_histograms_map = _GetHashToNameMap(expired_histograms_names)
  header_file_content = _GenerateHeaderFileContent(
      header_filename, namespace, expired_histograms_map)
  return header_file_content
예제 #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.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)
    def testComponentExtraction(self):
        """Checks that components are successfully extracted from histograms."""
        histogram = xml.dom.minidom.parseString("""
<histogram-configuration>
<histograms>
  <histogram name="Coffee" expires_after="2022-01-01">
    <owner>[email protected]</owner>
    <summary>An ode to coffee.</summary>
    <component>Liquid&gt;Hot</component>
    <component>Caffeine</component>
  </histogram>
</histograms>

<histogram_suffixes_list>
  <histogram_suffixes name="Brand" separator=".">
    <suffix name="Dunkies" label="The coffee is from Dunkin."/>
    <affected-histogram name="Coffee"/>
  </histogram_suffixes>
</histogram_suffixes_list>
</histogram-configuration>
""")
        histograms, _ = extract_histograms.ExtractHistogramsFromDom(histogram)
        self.assertEqual(histograms['Coffee']['components'],
                         ['Liquid>Hot', 'Caffeine'])
        self.assertEqual(histograms['Coffee.Dunkies']['components'],
                         ['Liquid>Hot', 'Caffeine'])
예제 #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
예제 #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))
예제 #8
0
    def testExpiryFormat(self):
        chrome_histogram_pattern = """<histogram-configuration>

<histograms>

<histogram name="Histogram.Name"{}>
  <owner>[email protected]</owner>
  <summary>Summary</summary>
</histogram>

</histograms>

</histogram-configuration>
"""
        chrome_histogram_correct_expiry_date = chrome_histogram_pattern.format(
            ' expires_after="2211-11-22"')
        _, had_errors = extract_histograms.ExtractHistogramsFromDom(
            xml.dom.minidom.parseString(chrome_histogram_correct_expiry_date))
        self.assertFalse(had_errors)

        chrome_histogram_wrong_expiry_date_format = chrome_histogram_pattern.format(
            ' expires_after="2211/11/22"')
        _, had_errors = extract_histograms.ExtractHistogramsFromDom(
            xml.dom.minidom.parseString(
                chrome_histogram_wrong_expiry_date_format))
        self.assertTrue(had_errors)

        chrome_histogram_wrong_expiry_date_value = chrome_histogram_pattern.format(
            ' expires_after="2211-22-11"')
        _, had_errors = extract_histograms.ExtractHistogramsFromDom(
            xml.dom.minidom.parseString(
                chrome_histogram_wrong_expiry_date_value))
        self.assertTrue(had_errors)

        chrome_histogram_correct_expiry_milestone = chrome_histogram_pattern.format(
            ' expires_after="M22"')
        _, had_errors = extract_histograms.ExtractHistogramsFromDom(
            xml.dom.minidom.parseString(
                chrome_histogram_correct_expiry_milestone))
        self.assertFalse(had_errors)

        chrome_histogram_wrong_expiry_milestone = chrome_histogram_pattern.format(
            ' expires_after="22"')
        _, had_errors = extract_histograms.ExtractHistogramsFromDom(
            xml.dom.minidom.parseString(
                chrome_histogram_wrong_expiry_milestone))
        self.assertTrue(had_errors)

        chrome_histogram_wrong_expiry_milestone = chrome_histogram_pattern.format(
            ' expires_after="MM22"')
        _, had_errors = extract_histograms.ExtractHistogramsFromDom(
            xml.dom.minidom.parseString(
                chrome_histogram_wrong_expiry_milestone))
        self.assertTrue(had_errors)

        chrome_histogram_no_expiry = chrome_histogram_pattern.format('')
        _, had_errors = extract_histograms.ExtractHistogramsFromDom(
            xml.dom.minidom.parseString(chrome_histogram_no_expiry))
        self.assertFalse(had_errors)
    def testNewSuffixWithoutLabel(self):
        suffix_without_label = xml.dom.minidom.parseString("""
<histogram-configuration>
<histogram_suffixes_list>
  <histogram_suffixes name="Suffixes" separator=".">
    <suffix base="true" name="BaseSuffix"/>
  </histogram_suffixes>
</histogram_suffixes_list>
</histogram-configuration>
""")
        _, have_errors = extract_histograms.ExtractHistogramsFromDom(
            suffix_without_label)
        self.assertTrue(have_errors)
예제 #10
0
    def testExpiryDateExtraction(self):
        chrome_histogram_pattern = """<histogram-configuration>

<histograms>

<histogram name="Histogram.Name"{}>
  <owner>[email protected]</owner>
  <summary>Summary</summary>
</histogram>

</histograms>

</histogram-configuration>
"""
        date_str = '2211-11-22'
        chrome_histogram_correct_expiry_date = chrome_histogram_pattern.format(
            ' expires_after="{}"'.format(date_str))
        histograms, _ = extract_histograms.ExtractHistogramsFromDom(
            xml.dom.minidom.parseString(chrome_histogram_correct_expiry_date))
        histogram_content = histograms['Histogram.Name']
        self.assertIn('expires_after', histogram_content)
        self.assertEqual(date_str, histogram_content['expires_after'])

        milestone_str = 'M22'
        chrome_histogram_correct_expiry_milestone = chrome_histogram_pattern.format(
            ' expires_after="{}"'.format(milestone_str))
        histograms, _ = extract_histograms.ExtractHistogramsFromDom(
            xml.dom.minidom.parseString(
                chrome_histogram_correct_expiry_milestone))
        histogram_content = histograms['Histogram.Name']
        self.assertIn('expires_after', histogram_content)
        self.assertEqual(milestone_str, histogram_content['expires_after'])

        chrome_histogram_no_expiry = chrome_histogram_pattern.format('')
        histograms, _ = extract_histograms.ExtractHistogramsFromDom(
            xml.dom.minidom.parseString(chrome_histogram_no_expiry))
        histogram_content = histograms['Histogram.Name']
        self.assertNotIn('expires_after', histogram_content)
예제 #11
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))
예제 #13
0
    def testSuffixObsoletion(self):
        histograms, had_errors = extract_histograms.ExtractHistogramsFromDom(
            xml.dom.minidom.parseString(TEST_SUFFIX_OBSOLETION_XML_CONTENT))
        self.assertFalse(had_errors)
        # Obsolete on suffixes doesn't affect the source histogram
        self.assertNotIn('obsolete', histograms['Test.Test1'])
        self.assertNotIn('obsolete', histograms['Test.Test2'])

        self.assertNotIn('obsolete', histograms['Test.Test1_NonObsolete1'])
        self.assertNotIn('obsolete', histograms['Test.Test1_NonObsolete2'])
        self.assertNotIn('obsolete', histograms['Test.Test2_NonObsolete1'])
        self.assertNotIn('obsolete', histograms['Test.Test2_NonObsolete2'])

        self.assertIn('obsolete',
                      histograms['Test.Test1_ObsoleteSuffixGroup1'])
        self.assertIn('obsolete',
                      histograms['Test.Test1_ObsoleteSuffixGroup2'])

        # Obsolete suffixes should apply to individual suffixes and not their group.
        self.assertIn('obsolete',
                      histograms['Test.Test2_ObsoleteSuffixNonObsoleteGroup1'])
        self.assertNotIn(
            'obsolete',
            histograms['Test.Test2_NonObsoleteSuffixNonObsoleteGroup2'])
        self.assertEqual(
            'This suffix is obsolete',
            histograms['Test.Test2_ObsoleteSuffixNonObsoleteGroup1']
            ['obsolete'])

        # Obsolete suffix reasons should overwrite the suffix group's obsoletion
        # reason.
        self.assertIn('obsolete',
                      histograms['Test.Test2_ObsoleteSuffixObsoleteGroup1'])
        self.assertIn('obsolete',
                      histograms['Test.Test2_NonObsoleteSuffixObsoleteGroup2'])
        self.assertEqual(
            'This suffix is obsolete',
            histograms['Test.Test2_ObsoleteSuffixObsoleteGroup1']['obsolete'])
        self.assertEqual(
            'This suffix group is obsolete',
            histograms['Test.Test2_NonObsoleteSuffixObsoleteGroup2']
            ['obsolete'])
    def testNewHistogramWithEnum(self):
        histogram_with_enum = xml.dom.minidom.parseString("""
<histogram-configuration>
<enums>
  <enum name="MyEnumType">
    <summary>This is an example enum type</summary>
    <int value="1" label="FIRST_VALUE">This is the first value.</int>
    <int value="2" label="SECOND_VALUE">This is the second value.</int>
  </enum>
</enums>

<histograms>
 <histogram name="Test.Histogram.Enum" enum="MyEnumType">
  <owner>[email protected]</owner>
  <summary> This is a summary </summary>
 </histogram>
</histograms>
</histogram-configuration>
""")
        _, have_errors = extract_histograms.ExtractHistogramsFromDom(
            histogram_with_enum)
        self.assertFalse(have_errors)
예제 #15
0
def main():
    doc = merge_xml.MergeFiles(histogram_paths.ALL_XMLS)
    _, errors = extract_histograms.ExtractHistogramsFromDom(doc)
    sys.exit(errors)
예제 #16
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)
예제 #17
0
def main():
    doc = merge_xml.MergeFiles(histogram_paths.ALL_XMLS,
                               should_expand_owners=True)
    _, errors = extract_histograms.ExtractHistogramsFromDom(doc)
    sys.exit(errors)