<commit_before># Copyright 2013 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.
"""Defines the commands provided by Telemetry: Run, List."""

import json
import logging
import optparse
import os
import sys

from telemetry import benchmark
from telemetry.internal.browser import browser_finder
from telemetry.internal.browser import browser_options
from telemetry.internal import story_runner
from telemetry.util import matching


def _SetExpectations(bench, path):
  if path and os.path.exists(path):
    with open(path) as fp:
      bench.AugmentExpectationsWithFile(fp.read())
  return bench.expectations


def _IsBenchmarkEnabled(bench, possible_browser, expectations_file):
  b = bench()
  expectations = _SetExpectations(b, expectations_file)
  expectations.SetTags(possible_browser.GetTypExpectationsTags())
  return (
      # Test that the current platform is supported.
      any(t.ShouldDisable(possible_browser.platform, possible_browser)
          for t in b.SUPPORTED_PLATFORMS) and
      # Test that expectations say it is enabled.
      not expectations.IsBenchmarkDisabled())


def _GetStoriesWithTags(b):
  """Finds all stories and their tags given a benchmark.

  Args:
    b: a subclass of benchmark.Benchmark
  Returns:
    A list of dicts for the stories, each of the form:
    {
      'name' : story.name
      'tags': list(story.tags)
    }
  """
  # Create a options object which hold default values that are expected
  # by Benchmark.CreateStoriesWithTags(options) method.
  parser = optparse.OptionParser()
  b.AddBenchmarkCommandLineArgs(parser)
  options, _ = parser.parse_args([])

  # Some benchmarks require special options, such as *.cluster_telemetry.
  # Just ignore them for now.
  try:
    story_set = b().CreateStorySet(options)
  # pylint: disable=broad-except
  except Exception as e:
    logging.warning('Unable to get stories for %s due to "%s"', b.Name(), e)
    story_set = []

  stories_info = []
  for s in story_set:
    stories_info.append({
        'name': s.name,
        'tags': list(s.tags)
    })
  return sorted(stories_info)


def PrintBenchmarkList(
    benchmarks, possible_browser, expectations_file, output_pipe=None,
    json_pipe=None):
  """ Print benchmarks that are not filtered in the same order of benchmarks in
  the |benchmarks| list.

  If json_pipe is available, a json file with the following contents will be
  written:
  [
      {
          "name": <string>,
          "description": <string>,
          "enabled": <boolean>,
          "story_tags": [
              <string>,
              ...
          ]
          ...
      },
      ...
  ]

  Args:
    benchmarks: the list of benchmarks to be printed (in the same order of the
      list).
    possible_browser: the possible_browser instance that's used for checking
      which benchmarks are enabled.
    output_pipe: the stream in which benchmarks are printed on.
    json_pipe: if available, also serialize the list into json_pipe.
  """
  if output_pipe is None:
    output_pipe = sys.stdout

  if not benchmarks:
    print >> output_pipe, 'No benchmarks found!'
    if json_pipe:
      print >> json_pipe, '[]'
    return

  bad_benchmark = next((b for b in benchmarks
                        if not issubclass(b, benchmark.Benchmark)), None)
  assert bad_benchmark is None, (
      '|benchmarks| param contains non benchmark class: %s' % bad_benchmark)

  all_benchmark_info = []
  for b in benchmarks:
    benchmark_info = {'name': b.Name(), 'description': b.Description()}
    benchmark_info['enabled'] = (
        not possible_browser or
        _IsBenchmarkEnabled(b, possible_browser, expectations_file))
    benchmark_info['stories'] = _GetStoriesWithTags(b)
    all_benchmark_info.append(benchmark_info)

  # Align the benchmark names to the longest one.
  format_string = '  %%-%ds %%s' % max(len(b['name'])
                                       for b in all_benchmark_info)

  # Sort the benchmarks by benchmark name.
  all_benchmark_info.sort(key=lambda b: b['name'])

  enabled = [b for b in all_benchmark_info if b['enabled']]
  if enabled:
    print >> output_pipe, 'Available benchmarks %sare:' % (
        'for %s ' % possible_browser.browser_type if possible_browser else '')
    for b in enabled:
      print >> output_pipe, format_string % (b['name'], b['description'])

  disabled = [b for b in all_benchmark_info if not b['enabled']]
  if disabled:
    print >> output_pipe, (
        '\nDisabled benchmarks for %s are (force run with -d):' %
        possible_browser.browser_type)
    for b in disabled:
      print >> output_pipe, format_string % (b['name'], b['description'])

  print >> output_pipe, (
      'Pass --browser to list benchmarks for another browser.\n')

  if json_pipe:
    print >> json_pipe, json.dumps(all_benchmark_info, indent=4,
                                   sort_keys=True, separators=(',', ': ')),


class List(object):
  """Lists the available benchmarks"""

  @classmethod
  def AddCommandLineArgs(cls, parser, args, environment):
    del args, environment  # Unused.
    parser.add_option('--json', action='store', dest='json_filename',
                      help='Output the list in JSON')

  @classmethod
  def CreateParser(cls):
    options = browser_options.BrowserFinderOptions()
    parser = options.CreateParser('%prog run [benchmark_name] [<options>]')
    return parser

  @classmethod
  def ProcessCommandLineArgs(cls, parser, options, environment):
    if environment.expectations_files:
      assert len(environment.expectations_files) == 1
      expectations_file = environment.expectations_files[0]<commit_msg>[Telemetry] Fix usage string for run_benchmark list.<commit_after># Copyright 2013 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.
"""Defines the commands provided by Telemetry: Run, List."""

import json
import logging
import optparse
import os
import sys

from telemetry import benchmark
from telemetry.internal.browser import browser_finder
from telemetry.internal.browser import browser_options
from telemetry.internal import story_runner
from telemetry.util import matching


def _SetExpectations(bench, path):
  if path and os.path.exists(path):
    with open(path) as fp:
      bench.AugmentExpectationsWithFile(fp.read())
  return bench.expectations


def _IsBenchmarkEnabled(bench, possible_browser, expectations_file):
  b = bench()
  expectations = _SetExpectations(b, expectations_file)
  expectations.SetTags(possible_browser.GetTypExpectationsTags())
  return (
      # Test that the current platform is supported.
      any(t.ShouldDisable(possible_browser.platform, possible_browser)
          for t in b.SUPPORTED_PLATFORMS) and
      # Test that expectations say it is enabled.
      not expectations.IsBenchmarkDisabled())


def _GetStoriesWithTags(b):
  """Finds all stories and their tags given a benchmark.

  Args:
    b: a subclass of benchmark.Benchmark
  Returns:
    A list of dicts for the stories, each of the form:
    {
      'name' : story.name
      'tags': list(story.tags)
    }
  """
  # Create a options object which hold default values that are expected
  # by Benchmark.CreateStoriesWithTags(options) method.
  parser = optparse.OptionParser()
  b.AddBenchmarkCommandLineArgs(parser)
  options, _ = parser.parse_args([])

  # Some benchmarks require special options, such as *.cluster_telemetry.
  # Just ignore them for now.
  try:
    story_set = b().CreateStorySet(options)
  # pylint: disable=broad-except
  except Exception as e:
    logging.warning('Unable to get stories for %s due to "%s"', b.Name(), e)
    story_set = []

  stories_info = []
  for s in story_set:
    stories_info.append({
        'name': s.name,
        'tags': list(s.tags)
    })
  return sorted(stories_info)


def PrintBenchmarkList(
    benchmarks, possible_browser, expectations_file, output_pipe=None,
    json_pipe=None):
  """ Print benchmarks that are not filtered in the same order of benchmarks in
  the |benchmarks| list.

  If json_pipe is available, a json file with the following contents will be
  written:
  [
      {
          "name": <string>,
          "description": <string>,
          "enabled": <boolean>,
          "story_tags": [
              <string>,
              ...
          ]
          ...
      },
      ...
  ]

  Args:
    benchmarks: the list of benchmarks to be printed (in the same order of the
      list).
    possible_browser: the possible_browser instance that's used for checking
      which benchmarks are enabled.
    output_pipe: the stream in which benchmarks are printed on.
    json_pipe: if available, also serialize the list into json_pipe.
  """
  if output_pipe is None:
    output_pipe = sys.stdout

  if not benchmarks:
    print >> output_pipe, 'No benchmarks found!'
    if json_pipe:
      print >> json_pipe, '[]'
    return

  bad_benchmark = next((b for b in benchmarks
                        if not issubclass(b, benchmark.Benchmark)), None)
  assert bad_benchmark is None, (
      '|benchmarks| param contains non benchmark class: %s' % bad_benchmark)

  all_benchmark_info = []
  for b in benchmarks:
    benchmark_info = {'name': b.Name(), 'description': b.Description()}
    benchmark_info['enabled'] = (
        not possible_browser or
        _IsBenchmarkEnabled(b, possible_browser, expectations_file))
    benchmark_info['stories'] = _GetStoriesWithTags(b)
    all_benchmark_info.append(benchmark_info)

  # Align the benchmark names to the longest one.
  format_string = '  %%-%ds %%s' % max(len(b['name'])
                                       for b in all_benchmark_info)

  # Sort the benchmarks by benchmark name.
  all_benchmark_info.sort(key=lambda b: b['name'])

  enabled = [b for b in all_benchmark_info if b['enabled']]
  if enabled:
    print >> output_pipe, 'Available benchmarks %sare:' % (
        'for %s ' % possible_browser.browser_type if possible_browser else '')
    for b in enabled:
      print >> output_pipe, format_string % (b['name'], b['description'])

  disabled = [b for b in all_benchmark_info if not b['enabled']]
  if disabled:
    print >> output_pipe, (
        '\nDisabled benchmarks for %s are (force run with -d):' %
        possible_browser.browser_type)
    for b in disabled:
      print >> output_pipe, format_string % (b['name'], b['description'])

  print >> output_pipe, (
      'Pass --browser to list benchmarks for another browser.\n')

  if json_pipe:
    print >> json_pipe, json.dumps(all_benchmark_info, indent=4,
                                   sort_keys=True, separators=(',', ': ')),


class List(object):
  """Lists the available benchmarks"""

  @classmethod
  def AddCommandLineArgs(cls, parser, args, environment):
    del args, environment  # Unused.
    parser.add_option('--json', action='store', dest='json_filename',
                      help='Output the list in JSON')

  @classmethod
  def CreateParser(cls):
    options = browser_options.BrowserFinderOptions()
    parser = options.CreateParser('%prog list [benchmark_name] [<options>]')
    return parser

  @classmethod
  def ProcessCommandLineArgs(cls, parser, options, environment):
    if environment.expectations_files:
      assert len(environment.expectations_files) == 1
      expectations_file = environment.expectations_files[0]
{'fraction_non_alphanumeric': 0.09783557339849887, 'fraction_numerical': 0.0012218537266538664, 'mean_word_length': 3.2377958579881656, 'pattern_counts': {'":': 8, '<': 13, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3739010', 'n_tokens_mistral': 3374, 'n_tokens_neox': 3252, 'n_words': 1043}