Ejemplo n.º 1
0
    def post(self):
        """Handles post requests from bad_bisect.html."""
        user = users.get_current_user()
        if not utils.IsValidSheriffUser():
            message = ERROR_INVALID_USER % user
            self.response.out.write(json.dumps({'error': message}))
            return

        if not self.request.get('try_job_id'):
            self.response.out.write(json.dumps({'error': ERROR_NO_TRYJOB}))
            return

        try:
            try_job_id = int(self.request.get('try_job_id'))
            job = try_job.TryJob.get_by_id(try_job_id)
            if not job:
                self.response.out.write(
                    json.dumps({'error': ERROR_TRYJOB_DOES_NOT_EXIST}))
                return

            # If there's a token, they're confirming they want to flag this bisect.
            if self.request.get('xsrf_token'):
                self._ConfirmBadBisect(user, job, try_job_id)
                return

            values = {}
            self.GetDynamicVariables(values)
            self.response.out.write(json.dumps(values))

        except ValueError:
            self.response.out.write(json.dumps({'error':
                                                ERROR_TRYJOB_INVALID}))
            return
Ejemplo n.º 2
0
  def post(self):
    """Performs one of several bisect-related actions depending on parameters.

    The only required parameter is "step", which indicates what to do.

    This end-point should always output valid JSON with different contents
    depending on the value of "step".
    """
    user = users.get_current_user()
    if not utils.IsValidSheriffUser():
      message = 'User "%s" not authorized.' % user
      self.response.out.write(json.dumps({'error': message}))
      return

    step = self.request.get('step')

    if step == 'prefill-info':
      result = _PrefillInfo(self.request.get('test_path'))
    elif step == 'perform-bisect':
      result = self._PerformBisectStep(user)
    elif step == 'perform-perf-try':
      result = self._PerformPerfTryStep(user)
    else:
      result = {'error': 'Invalid parameters.'}

    self.response.write(json.dumps(result))
Ejemplo n.º 3
0
    def get(self):
        """Response handler for the page used to group an alert with a bug.

    Request parameters:
      bug_id: Bug ID number, as a string (when submitting the form).
      project_id: Monorail project ID (when submitting the form).
      keys: Comma-separated alert keys in urlsafe format.
      confirm: If non-empty, associate alerts with a bug ID even if
          it appears that the alerts already associated with that bug
          have a non-overlapping revision range.

    Outputs:
      HTML with result.
    """
        if not utils.IsValidSheriffUser():
            user = users.get_current_user()
            self.ReportError('User "%s" not authorized.' % user, status=403)
            return

        urlsafe_keys = self.request.get('keys')
        if not urlsafe_keys:
            self.RenderHtml('bug_result.html',
                            {'error': 'No alerts specified to add bugs to.'})
            return

        is_confirmed = bool(self.request.get('confirm'))
        bug_id = self.request.get('bug_id')
        if bug_id:
            project_id = self.request.get('project_id', 'chromium')
            self._AssociateAlertsWithBug(bug_id, project_id, urlsafe_keys,
                                         is_confirmed)
        else:
            self._ShowCommentDialog(urlsafe_keys)
Ejemplo n.º 4
0
  def post(self):
    """Handles post requests from bad_bisect.html."""
    if not utils.IsValidSheriffUser():
      self._RenderError('No permission.')
      return
    if not self.request.get('try_job_id'):
      self._RenderError('Missing try_job_id.')
      return

    try_job_id = int(self.request.get('try_job_id'))
    job = try_job.TryJob.get_by_id(try_job_id)
    if not job:
      self._RenderError('TryJob doesn\'t exist.')
      return

    user = users.get_current_user()
    email = user.email()
    if not job.bad_result_emails:
      job.bad_result_emails = set()
    if email not in job.bad_result_emails:
      job.bad_result_emails.add(email)
      job.put()
      _LogFeedback(try_job_id, email)

    self.RenderHtml('result.html', {
        'headline': 'Confirmed bad bisect.  Thank you for reporting.'})
Ejemplo n.º 5
0
def PinpointParamsFromPerfTryParams(params):
  """Takes parameters from Dashboard's pinpoint-perf-job-dialog and returns
  a dict with parameters for a new Pinpoint job.

  Args:
    params: A dict in the following format:
    {
        'test_path': Test path for the metric being bisected.
        'start_commit': Git hash or commit position of earlier revision.
        'end_commit': Git hash or commit position of later revision.
        'extra_test_args': Extra args for the swarming job.
    }

  Returns:
    A dict of params for passing to Pinpoint to start a job, or a dict with an
    'error' field.
  """
  if not utils.IsValidSheriffUser():
    user = utils.GetEmail()
    raise InvalidParamsError('User "%s" not authorized.' % user)

  test_path = params['test_path']
  test_path_parts = test_path.split('/')
  bot_name = test_path_parts[1]
  suite = test_path_parts[2]

  start_commit = params['start_commit']
  end_commit = params['end_commit']
  start_git_hash = ResolveToGitHash(start_commit, suite)
  end_git_hash = ResolveToGitHash(end_commit, suite)
  story_filter = params['story_filter']

  # Pinpoint also requires you specify which isolate target to run the
  # test, so we derive that from the suite name. Eventually, this would
  # ideally be stored in a SparesDiagnostic but for now we can guess.
  target = _GetIsolateTarget(bot_name, suite, start_commit,
                             end_commit, only_telemetry=True)

  extra_test_args = params['extra_test_args']

  email = utils.GetEmail()
  job_name = 'Try job on %s/%s' % (bot_name, suite)

  pinpoint_params = {
      'comparison_mode': 'try',
      'configuration': bot_name,
      'benchmark': suite,
      'start_git_hash': start_git_hash,
      'end_git_hash': end_git_hash,
      'extra_test_args': extra_test_args,
      'target': target,
      'user': email,
      'name': job_name
  }

  if story_filter:
    pinpoint_params['story'] = story_filter

  return pinpoint_params
Ejemplo n.º 6
0
def PinpointParamsFromPerfTryParams(params):
  """Takes parameters from Dashboard's pinpoint-perf-job-dialog and returns
  a dict with parameters for a new Pinpoint job.

  Args:
    params: A dict in the following format:
    {
        'test_path': Test path for the metric being bisected.
        'start_commit': Git hash or commit position of earlier revision.
        'end_commit': Git hash or commit position of later revision.
        'extra_test_args': Extra args for the swarming job.
    }

  Returns:
    A dict of params for passing to Pinpoint to start a job, or a dict with an
    'error' field.
  """
  if not utils.IsValidSheriffUser():
    user = users.get_current_user()
    raise InvalidParamsError('User "%s" not authorized.' % user)

  test_path = params['test_path']
  test_path_parts = test_path.split('/')
  bot_name = test_path_parts[1]
  suite = test_path_parts[2]

  # Pinpoint also requires you specify which isolate target to run the
  # test, so we derive that from the suite name. Eventually, this would
  # ideally be stored in a SparesDiagnostic but for now we can guess.
  target = 'telemetry_perf_tests'
  if suite in _ISOLATE_TARGETS:
    raise InvalidParamsError('Only telemetry is supported at the moment.')
  elif 'webview' in bot_name:
    target = 'telemetry_perf_webview_tests'

  start_commit = params['start_commit']
  end_commit = params['end_commit']
  start_git_hash = ResolveToGitHash(start_commit)
  end_git_hash = ResolveToGitHash(end_commit)

  extra_test_args = params['extra_test_args']

  email = users.get_current_user().email()
  job_name = 'Job on [%s/%s] for [%s]' % (bot_name, suite, email)

  return {
      'configuration': bot_name,
      'benchmark': suite,
      'start_git_hash': start_git_hash,
      'end_git_hash': end_git_hash,
      'extra_test_args': extra_test_args,
      'auto_explore': 'false',
      'target': target,
      'user': email,
      'name': job_name
  }
Ejemplo n.º 7
0
  def _RenderForm(self):
    if not utils.IsValidSheriffUser():
      self._RenderError('No permission.')
      return
    if not self.request.get('try_job_id'):
      self._RenderError('Missing try_job_id.')
      return

    self.RenderHtml('bad_bisect.html',
                    {'try_job_id': self.request.get('try_job_id')})
Ejemplo n.º 8
0
    def post(self):
        user = users.get_current_user()
        if not utils.IsValidSheriffUser():
            message = 'User "%s" not authorized.' % user
            self.response.out.write(json.dumps({'error': message}))
            return

        job_params = dict(
            (a, self.request.get(a)) for a in self.request.arguments())
        job_params['email'] = user.email()

        self.response.write(json.dumps(pinpoint_service.NewJob(job_params)))
Ejemplo n.º 9
0
    def get(self):
        """Either shows the form to file a bug, or if filled in, files the bug.

    The form to file a bug is popped up from the triage-dialog polymer element.
    The default summary, description and label strings are constructed there.

    Request parameters:
      summary: Bug summary string.
      description: Bug full description string.
      keys: Comma-separated Alert keys in urlsafe format.
      finish: Boolean set to true when creating a bug, false otherwise.
      project_id: The Monorail project ID (used to create  a bug).
      labels: Bug labels (used to create  a bug).
      components: Bug components (used to create  a bug).
      owner: Bug owner email address (used to create  a bug).
      cc: Bug emails to CC (used to create  a bug).

    Outputs:
      HTML, using the template 'bug_result.html'.
    """
        if not utils.IsValidSheriffUser():
            self.RenderHtml(
                'bug_result.html', {
                    'error':
                    'You must be logged in with a chromium.org account '
                    'to file bugs.'
                })
            return

        summary = self.request.get('summary')
        description = self.request.get('description')
        keys = self.request.get('keys')

        if not keys:
            self.RenderHtml('bug_result.html',
                            {'error': 'No alerts specified to add bugs to.'})
            return

        if self.request.get('finish'):
            project_id = self.request.get('project_id', 'chromium')
            labels = self.request.get_all('label')
            components = self.request.get_all('component')
            owner = self.request.get('owner')
            cc = self.request.get('cc')
            self._CreateBug(owner, cc, summary, description, project_id,
                            labels, components, keys)
        else:
            self._ShowBugDialog(summary, description, keys)
Ejemplo n.º 10
0
    def post(self):
        """Allows adding or resetting bug IDs and invalid statuses to Alerts.

    Additionally, this endpoint is also responsible for changing the start
    and end revisions of Anomaly entities.

    Request parameters:
      keys: A comma-separated list of urlsafe keys of Anomaly entities.
      bug_id: The new bug ID. This should be either the string REMOVE
          (indicating resetting the bug ID to None), or an integer. A negative
          integer indicates an invalid or ignored alert. If this is given, then
          the start and end revision ranges are ignored.
      new_start_revision: New start revision value for the alert.
      new_end_revision: New end revision value for the alert.

    Outputs:
      JSON which indicates the result. If an error has occurred, the field
      "error" should be in the result. If successful, the response is still
      expected to be JSON.
    """
        if not utils.IsValidSheriffUser():
            user = users.get_current_user()
            self.ReportError('User "%s" not authorized.' % user, status=403)
            return

        # Get the list of alerts to modify.
        urlsafe_keys = self.request.get('keys')
        if not urlsafe_keys:
            self.response.out.write(
                json.dumps({'error': 'No alerts specified to add bugs to.'}))
            return
        keys = [ndb.Key(urlsafe=k) for k in urlsafe_keys.split(',')]
        alert_entities = ndb.get_multi(keys)

        # Get the parameters which specify the changes to make.
        bug_id = self.request.get('bug_id')
        new_start_revision = self.request.get('new_start_revision')
        new_end_revision = self.request.get('new_end_revision')
        result = None
        if bug_id:
            result = self.ChangeBugId(alert_entities, bug_id)
        elif new_start_revision and new_end_revision:
            result = self.NudgeAnomalies(alert_entities, new_start_revision,
                                         new_end_revision)
        else:
            result = {'error': 'No bug ID or new revision specified.'}
        self.response.out.write(json.dumps(result))
Ejemplo n.º 11
0
    def get(self):
        """Either shows the form to file a bug, or if filled in, files the bug.

    The form to file a bug is popped up from the triage-dialog polymer element.
    The default summary, description and label strings are constructed there.

    Request parameters:
      summary: Bug summary string.
      description: Bug full description string.
      owner: Bug owner email address.
      keys: Comma-separated Alert keys in urlsafe format.

    Outputs:
      HTML, using the template 'bug_result.html'.
    """
        if not utils.IsValidSheriffUser():
            # TODO(qyearsley): Simplify this message (after a couple months).
            self.RenderHtml(
                'bug_result.html', {
                    'error':
                    ('You must be logged in with a chromium.org account '
                     'in order to file bugs here! This is the case ever '
                     'since we switched to the Monorail issue tracker. '
                     'Note, viewing internal data should work for Googlers '
                     'that are logged in with the Chromium accounts. See '
                     'https://github.com/catapult-project/catapult/issues/2042'
                     )
                })
            return

        summary = self.request.get('summary')
        description = self.request.get('description')
        labels = self.request.get_all('label')
        components = self.request.get_all('component')
        keys = self.request.get('keys')
        if not keys:
            self.RenderHtml('bug_result.html',
                            {'error': 'No alerts specified to add bugs to.'})
            return

        if self.request.get('finish'):
            self._CreateBug(summary, description, labels, components, keys)
        else:
            self._ShowBugDialog(summary, description, keys)
Ejemplo n.º 12
0
    def get(self):
        """Either shows the form to file a bug, or if filled in, files the bug.

    The form to file a bug is popped up from the triage-dialog polymer element.
    The default summary, description and label strings are constructed there.

    Request parameters:
      summary: Bug summary string.
      description: Bug full description string.
      owner: Bug owner email address.
      keys: Comma-separated Alert keys in urlsafe format.

    Outputs:
      HTML, using the template 'bug_result.html'.
    """
        if not utils.IsValidSheriffUser():
            self.RenderHtml(
                'bug_result.html', {
                    'error':
                    'You must be logged in with a chromium.org account '
                    'to file bugs.'
                })
            return

        summary = self.request.get('summary')
        description = self.request.get('description')
        labels = self.request.get_all('label')
        components = self.request.get_all('component')
        keys = self.request.get('keys')
        if not keys:
            self.RenderHtml('bug_result.html',
                            {'error': 'No alerts specified to add bugs to.'})
            return

        if self.request.get('finish'):
            self._CreateBug(summary, description, labels, components, keys)
        else:
            self._ShowBugDialog(summary, description, keys)
Ejemplo n.º 13
0
def PinpointParamsFromBisectParams(params):
    """Takes parameters from Dashboard's pinpoint-job-dialog and returns
  a dict with parameters for a new Pinpoint job.

  Args:
    params: A dict in the following format:
    {
        'test_path': Test path for the metric being bisected.
        'start_git_hash': Git hash of earlier revision.
        'end_git_hash': Git hash of later revision.
        'start_repository': Repository for earlier revision.
        'end_repository': Repository for later revision.
        'bug_id': Associated bug.
    }

  Returns:
    A dict of params for passing to Pinpoint to start a job, or a dict with an
    'error' field.
  """
    if not utils.IsValidSheriffUser():
        user = users.get_current_user()
        raise InvalidParamsError('User "%s" not authorized.' % user)

    # Pinpoint takes swarming dimensions, so we need to map bot name to those.
    test_path = params['test_path']
    test_path_parts = test_path.split('/')
    bot_name = test_path_parts[1]
    suite = test_path_parts[2]
    story_filter = params['story_filter']

    # If functional bisects are speciied, Pinpoint expects these parameters to be
    # empty.
    bisect_mode = params['bisect_mode']
    if bisect_mode != 'performance' and bisect_mode != 'functional':
        raise InvalidParamsError('Invalid bisect mode %s specified.' %
                                 bisect_mode)

    tir_label = ''
    chart_name = ''
    trace_name = ''
    if bisect_mode == 'performance':
        tir_label, chart_name, trace_name = ParseTIRLabelChartNameAndTraceName(
            test_path_parts)

    dimensions = _BotDimensionsFromBotName(bot_name)

    # Pinpoint also requires you specify which isolate target to run the
    # test, so we derive that from the suite name. Eventually, this would
    # ideally be stored in a SparesDiagnostic but for now we can guess.
    target = 'telemetry_perf_tests'
    if suite in _ISOLATE_TARGETS:
        target = suite
    elif 'webview' in bot_name:
        target = 'telemetry_perf_webview_tests'

    start_repository = params['start_repository']
    end_repository = params['end_repository']
    start_commit = params['start_commit']
    end_commit = params['end_commit']

    start_git_hash = ResolveToGitHash(start_commit, start_repository)
    end_git_hash = ResolveToGitHash(end_commit, end_repository)

    supported_repositories = namespaced_stored_object.Get(
        _PINPOINT_REPOSITORIES)

    # Bail if it's not a supported repository to bisect on
    if not start_repository in supported_repositories:
        raise InvalidParamsError('Invalid repository: %s' % start_repository)
    if not end_repository in supported_repositories:
        raise InvalidParamsError('Invalid repository: %s' % end_repository)

    # Pinpoint only supports chromium at the moment, so just throw up a
    # different error for now.
    if start_repository != 'chromium' or end_repository != 'chromium':
        raise InvalidParamsError('Only chromium bisects supported currently.')

    email = users.get_current_user().email()
    job_name = 'Job on [%s/%s/%s] for [%s]' % (bot_name, suite, chart_name,
                                               email)

    browser = start_try_job.GuessBrowserName(bot_name)

    # Histogram names don't include the statistic, so split these
    chart_name, statistic_name = ParseStatisticNameFromChart(chart_name)

    return {
        'configuration': bot_name,
        'browser': browser,
        'benchmark': suite,
        'trace': trace_name,
        'chart': chart_name,
        'statistic': statistic_name,
        'tir_label': tir_label,
        'story': story_filter,
        'start_repository': start_repository,
        'end_repository': end_repository,
        'start_git_hash': start_git_hash,
        'end_git_hash': end_git_hash,
        'bug_id': params['bug_id'],
        'auto_explore': '1',
        'target': target,
        'dimensions': json.dumps(dimensions),
        'email': email,
        'name': job_name
    }
Ejemplo n.º 14
0
def PinpointParamsFromBisectParams(params):
    """Takes parameters from Dashboard's pinpoint-job-dialog and returns
  a dict with parameters for a new Pinpoint job.

  Args:
    params: A dict in the following format:
    {
        'test_path': Test path for the metric being bisected.
        'start_git_hash': Git hash of earlier revision.
        'end_git_hash': Git hash of later revision.
        'start_repository': Repository for earlier revision.
        'end_repository': Repository for later revision.
        'bug_id': Associated bug.
    }

  Returns:
    A dict of params for passing to Pinpoint to start a job, or a dict with an
    'error' field.
  """
    if not utils.IsValidSheriffUser():
        user = users.get_current_user()
        raise InvalidParamsError('User "%s" not authorized.' % user)

    bots_to_dimensions = namespaced_stored_object.Get(_BOTS_TO_DIMENSIONS)

    # Pinpoint takes swarming dimensions, so we need to map bot name to those.
    test_path = params.get('test_path')
    test_path_parts = test_path.split('/')
    bot_name = test_path_parts[1]
    suite = test_path_parts[2]
    story_filter = params.get('story_filter')

    tir_label, chart_name, trace_name = ParseTIRLabelChartNameAndTraceName(
        test_path_parts)

    dimensions = bots_to_dimensions.get(bot_name)
    if not dimensions:
        raise InvalidParamsError('No dimensions for bot %s defined.' %
                                 bot_name)

    # Pinpoint also requires you specify which isolate target to run the
    # test, so we derive that from the suite name. Eventually, this would
    # ideally be stored in a SparesDiagnostic but for now we can guess.
    isolate_targets = [
        'angle_perftests', 'cc_perftests', 'gpu_perftests',
        'load_library_perf_tests', 'media_perftests', 'net_perftests',
        'performance_browser_tests', 'telemetry_perf_tests',
        'telemetry_perf_webview_tests', 'tracing_perftests'
    ]

    target = 'telemetry_perf_tests'
    if suite in isolate_targets:
        target = suite
    elif 'webview' in bot_name:
        target = 'telemetry_perf_webview_tests'

    start_repository = params.get('start_repository')
    end_repository = params.get('end_repository')
    start_commit = params.get('start_commit')
    end_commit = params.get('end_commit')

    start_git_hash = ResolveToGitHash(start_commit, start_repository)
    end_git_hash = ResolveToGitHash(end_commit, end_repository)

    supported_repositories = namespaced_stored_object.Get(
        _PINPOINT_REPOSITORIES)

    # Bail if it's not a supported repository to bisect on
    if not start_repository in supported_repositories:
        raise InvalidParamsError('Invalid repository: %s' % start_repository)
    if not end_repository in supported_repositories:
        raise InvalidParamsError('Invalid repository: %s' % end_repository)

    # Pinpoint only supports chromium at the moment, so just throw up a
    # different error for now.
    if start_repository != 'chromium' or end_repository != 'chromium':
        raise InvalidParamsError('Only chromium bisects supported currently.')

    email = users.get_current_user().email()
    job_name = 'Job on [%s/%s/%s] for [%s]' % (bot_name, suite, chart_name,
                                               email)

    browser = start_try_job.GuessBrowserName(bot_name)

    return {
        'configuration': bot_name,
        'browser': browser,
        'benchmark': suite,
        'trace': trace_name,
        'chart': chart_name,
        'tir_label': tir_label,
        'story': story_filter,
        'start_repository': start_repository,
        'end_repository': end_repository,
        'start_git_hash': start_git_hash,
        'end_git_hash': end_git_hash,
        'bug_id': params.get('bug_id'),
        'auto_explore': '1',
        'target': target,
        'dimensions': json.dumps(dimensions),
        'email': email,
        'name': job_name
    }
Ejemplo n.º 15
0
def PinpointParamsFromBisectParams(params):
  """Takes parameters from Dashboard's pinpoint-job-dialog and returns
  a dict with parameters for a new Pinpoint job.

  Args:
    params: A dict in the following format:
    {
        'test_path': Test path for the metric being bisected.
        'start_git_hash': Git hash of earlier revision.
        'end_git_hash': Git hash of later revision.
        'bug_id': Associated bug.
    }

  Returns:
    A dict of params for passing to Pinpoint to start a job, or a dict with an
    'error' field.
  """
  if not utils.IsValidSheriffUser():
    user = users.get_current_user()
    raise InvalidParamsError('User "%s" not authorized.' % user)

  test_path = params['test_path']
  test_path_parts = test_path.split('/')
  bot_name = test_path_parts[1]
  suite = test_path_parts[2]
  story_filter = params['story_filter']

  # If functional bisects are speciied, Pinpoint expects these parameters to be
  # empty.
  bisect_mode = params['bisect_mode']
  if bisect_mode != 'performance' and bisect_mode != 'functional':
    raise InvalidParamsError('Invalid bisect mode %s specified.' % bisect_mode)

  tir_label = ''
  chart_name = ''
  trace_name = ''
  if bisect_mode == 'performance':
    tir_label, chart_name, trace_name = ParseTIRLabelChartNameAndTraceName(
        test_path_parts)

  # Pinpoint also requires you specify which isolate target to run the
  # test, so we derive that from the suite name. Eventually, this would
  # ideally be stored in a SparesDiagnostic but for now we can guess.
  target = 'telemetry_perf_tests'
  if suite in _ISOLATE_TARGETS:
    target = suite
  elif 'webview' in bot_name:
    target = 'telemetry_perf_webview_tests'

  start_commit = params['start_commit']
  end_commit = params['end_commit']
  start_git_hash = ResolveToGitHash(start_commit)
  end_git_hash = ResolveToGitHash(end_commit)

  email = users.get_current_user().email()
  job_name = 'Job on [%s/%s/%s] for [%s]' % (bot_name, suite, chart_name, email)

  # Histogram names don't include the statistic, so split these
  chart_name, statistic_name = ParseStatisticNameFromChart(chart_name)

  alert_key = ''
  if params.get('alerts'):
    alert_keys = json.loads(params.get('alerts'))
    if alert_keys:
      alert_key = alert_keys[0]

  return {
      'configuration': bot_name,
      'benchmark': suite,
      'trace': trace_name,
      'chart': chart_name,
      'statistic': statistic_name,
      'tir_label': tir_label,
      'story': story_filter,
      'start_git_hash': start_git_hash,
      'end_git_hash': end_git_hash,
      'bug_id': params['bug_id'],
      'auto_explore': 'true',
      'comparison_mode': bisect_mode,
      'target': target,
      'user': email,
      'name': job_name,
      'tags': json.dumps({
          'test_path': test_path,
          'alert': alert_key
      }),
  }
Ejemplo n.º 16
0
def PinpointParamsFromPerfTryParams(params):
    """Takes parameters from Dashboard's pinpoint-perf-job-dialog and returns
  a dict with parameters for a new Pinpoint job.

  Args:
    params: A dict in the following format:
    {
        'test_path': Test path for the metric being bisected.
        'start_commit': Git hash or commit position of earlier revision.
        'end_commit': Git hash or commit position of later revision.
        'start_repository': Repository for earlier revision.
        'end_repository': Repository for later revision.
        'extra_test_args': Extra args for the swarming job.
    }

  Returns:
    A dict of params for passing to Pinpoint to start a job, or a dict with an
    'error' field.
  """
    if not utils.IsValidSheriffUser():
        user = users.get_current_user()
        raise InvalidParamsError('User "%s" not authorized.' % user)

    test_path = params['test_path']
    test_path_parts = test_path.split('/')
    bot_name = test_path_parts[1]
    suite = test_path_parts[2]

    # Pinpoint also requires you specify which isolate target to run the
    # test, so we derive that from the suite name. Eventually, this would
    # ideally be stored in a SparesDiagnostic but for now we can guess.
    target = 'telemetry_perf_tests'
    if suite in _ISOLATE_TARGETS:
        raise InvalidParamsError('Only telemetry is supported at the moment.')
    elif 'webview' in bot_name:
        target = 'telemetry_perf_webview_tests'

    start_repository = params['start_repository']
    end_repository = params['end_repository']
    start_commit = params['start_commit']
    end_commit = params['end_commit']

    start_git_hash = ResolveToGitHash(start_commit, start_repository)
    end_git_hash = ResolveToGitHash(end_commit, end_repository)

    supported_repositories = namespaced_stored_object.Get(
        _PINPOINT_REPOSITORIES)

    # Bail if it's not a supported repository to bisect on
    if not start_repository in supported_repositories:
        raise InvalidParamsError('Invalid repository: %s' % start_repository)
    if not end_repository in supported_repositories:
        raise InvalidParamsError('Invalid repository: %s' % end_repository)

    # Pinpoint only supports chromium at the moment, so just throw up a
    # different error for now.
    if start_repository != 'chromium' or end_repository != 'chromium':
        raise InvalidParamsError(
            'Only chromium perf try jobs supported currently.')

    extra_test_args = params['extra_test_args']

    email = users.get_current_user().email()
    job_name = 'Job on [%s/%s] for [%s]' % (bot_name, suite, email)

    return {
        'configuration': bot_name,
        'benchmark': suite,
        'trace': '',
        'chart': '',
        'tir_label': '',
        'story': '',
        'start_repository': start_repository,
        'end_repository': end_repository,
        'start_git_hash': start_git_hash,
        'end_git_hash': end_git_hash,
        'extra_test_args': extra_test_args,
        'bug_id': '',
        'auto_explore': '0',
        'target': target,
        'email': email,
        'name': job_name
    }
Ejemplo n.º 17
0
def PinpointParamsFromBisectParams(params):
    """Takes parameters from Dashboard's pinpoint-job-dialog and returns
  a dict with parameters for a new Pinpoint job.

  Args:
    params: A dict in the following format:
    {
        'test_path': Test path for the metric being bisected.
        'start_git_hash': Git hash of earlier revision.
        'end_git_hash': Git hash of later revision.
        'bug_id': Associated bug.
        'project_id': Associated Monorail project.
    }

  Returns:
    A dict of params for passing to Pinpoint to start a job, or a dict with an
    'error' field.
  """
    if not utils.IsValidSheriffUser():
        user = utils.GetEmail()
        raise InvalidParamsError('User "%s" not authorized.' % user)

    test_path = params['test_path']
    test_path_parts = test_path.split('/')
    bot_name = test_path_parts[1]
    suite = test_path_parts[2]

    # If functional bisects are speciied, Pinpoint expects these parameters to be
    # empty.
    bisect_mode = params['bisect_mode']
    if bisect_mode != 'performance' and bisect_mode != 'functional':
        raise InvalidParamsError('Invalid bisect mode %s specified.' %
                                 bisect_mode)

    start_commit = params['start_commit']
    end_commit = params['end_commit']
    start_git_hash = ResolveToGitHash(start_commit, suite)
    end_git_hash = ResolveToGitHash(end_commit, suite)

    # Pinpoint also requires you specify which isolate target to run the
    # test, so we derive that from the suite name. Eventually, this would
    # ideally be stored in a SparesDiagnostic but for now we can guess.
    target = GetIsolateTarget(bot_name, suite)

    email = utils.GetEmail()
    job_name = '%s bisect on %s/%s' % (bisect_mode.capitalize(), bot_name,
                                       suite)

    alert_key = ''
    if params.get('alerts'):
        alert_keys = json.loads(params.get('alerts'))
        if alert_keys:
            alert_key = alert_keys[0]

    alert_magnitude = None
    if alert_key:
        alert = ndb.Key(urlsafe=alert_key).get()
        alert_magnitude = alert.median_after_anomaly - alert.median_before_anomaly

    if not alert_magnitude:
        alert_magnitude = FindMagnitudeBetweenCommits(utils.TestKey(test_path),
                                                      start_commit, end_commit)

    if isinstance(params['bug_id'], int):
        issue_id = params['bug_id'] if params['bug_id'] > 0 else None
    else:
        issue_id = int(
            params['bug_id']) if params['bug_id'].isdigit() else None
    issue = anomaly.Issue(project_id=params.get('project_id', 'chromium'),
                          issue_id=issue_id)

    return pinpoint_service.MakeBisectionRequest(
        test=utils.TestKey(test_path).get(),
        commit_range=pinpoint_service.CommitRange(start=start_git_hash,
                                                  end=end_git_hash),
        issue=issue,
        comparison_mode=bisect_mode,
        target=target,
        comparison_magnitude=alert_magnitude,
        user=email,
        name=job_name,
        story_filter=params['story_filter'],
        pin=params.get('pin'),
        tags={
            'test_path': test_path,
            'alert': alert_key,
        },
    )
Ejemplo n.º 18
0
 def _CheckUser(self):
   if not utils.IsValidSheriffUser():
     raise api_request_handler.ForbiddenError()
Ejemplo n.º 19
0
def PinpointParamsFromBisectParams(params):
    """Takes parameters from Dashboard's pinpoint-job-dialog and returns
  a dict with parameters for a new Pinpoint job.

  Args:
    params: A dict in the following format:
    {
        'test_path': Test path for the metric being bisected.
        'start_git_hash': Git hash of earlier revision.
        'end_git_hash': Git hash of later revision.
        'bug_id': Associated bug.
    }

  Returns:
    A dict of params for passing to Pinpoint to start a job, or a dict with an
    'error' field.
  """
    if not utils.IsValidSheriffUser():
        user = utils.GetEmail()
        raise InvalidParamsError('User "%s" not authorized.' % user)

    test_path = params['test_path']
    test_path_parts = test_path.split('/')
    bot_name = test_path_parts[1]
    suite = test_path_parts[2]
    story_filter = params['story_filter']
    pin = params.get('pin')

    # If functional bisects are speciied, Pinpoint expects these parameters to be
    # empty.
    bisect_mode = params['bisect_mode']
    if bisect_mode != 'performance' and bisect_mode != 'functional':
        raise InvalidParamsError('Invalid bisect mode %s specified.' %
                                 bisect_mode)

    tir_label = ''
    chart_name = ''
    trace_name = ''
    if bisect_mode == 'performance':
        tir_label, chart_name, trace_name = ParseTIRLabelChartNameAndTraceName(
            test_path_parts)

    start_commit = params['start_commit']
    end_commit = params['end_commit']
    start_git_hash = ResolveToGitHash(start_commit, suite)
    end_git_hash = ResolveToGitHash(end_commit, suite)

    # Pinpoint also requires you specify which isolate target to run the
    # test, so we derive that from the suite name. Eventually, this would
    # ideally be stored in a SparesDiagnostic but for now we can guess.
    target = _GetIsolateTarget(bot_name, suite, start_commit, end_commit)

    email = utils.GetEmail()
    job_name = '%s bisect on %s/%s' % (bisect_mode.capitalize(), bot_name,
                                       suite)

    # Histogram names don't include the statistic, so split these
    chart_name, statistic_name = ParseStatisticNameFromChart(chart_name)

    alert_key = ''
    if params.get('alerts'):
        alert_keys = json.loads(params.get('alerts'))
        if alert_keys:
            alert_key = alert_keys[0]

    alert_magnitude = None
    if alert_key:
        alert = ndb.Key(urlsafe=alert_key).get()
        alert_magnitude = alert.median_after_anomaly - alert.median_before_anomaly

    if not alert_magnitude:
        alert_magnitude = FindMagnitudeBetweenCommits(utils.TestKey(test_path),
                                                      start_commit, end_commit)

    pinpoint_params = {
        'configuration': bot_name,
        'benchmark': suite,
        'chart': chart_name,
        'start_git_hash': start_git_hash,
        'end_git_hash': end_git_hash,
        'bug_id': params['bug_id'],
        'comparison_mode': bisect_mode,
        'target': target,
        'user': email,
        'name': job_name,
        'tags': json.dumps({
            'test_path': test_path,
            'alert': alert_key
        }),
    }

    if alert_magnitude:
        pinpoint_params['comparison_magnitude'] = alert_magnitude
    if pin:
        pinpoint_params['pin'] = pin
    if statistic_name:
        pinpoint_params['statistic'] = statistic_name
    if story_filter:
        pinpoint_params['story'] = story_filter
    if tir_label:
        pinpoint_params['tir_label'] = tir_label
    if trace_name:
        pinpoint_params['trace'] = trace_name

    return pinpoint_params