Example #1
0
    def ProcessSubtabForm(self, post_data, mr):
        """Process the Rules subtab.

    Args:
      post_data: HTML form data for the HTTP request being processed.
      mr: commonly used info parsed from the request.

    Returns:
      The URL of the page to show after processing.
    """
        old_rules = self.services.features.GetFilterRules(
            mr.cnxn, mr.project_id)
        rules = filterrules_helpers.ParseRules(mr.cnxn, post_data,
                                               self.services.user, mr.errors)
        new_rules = filterrules_helpers.ParseRules(mr.cnxn,
                                                   post_data,
                                                   self.services.user,
                                                   mr.errors,
                                                   prefix='new_')
        rules.extend(new_rules)

        if not mr.errors.AnyErrors():
            config = self.services.features.UpdateFilterRules(
                mr.cnxn, mr.project_id, rules)

            if old_rules != rules:
                logging.info('recomputing derived fields')
                config = self.services.config.GetProjectConfig(
                    mr.cnxn, mr.project_id)
                filterrules_helpers.RecomputeAllDerivedFields(
                    mr.cnxn, self.services, mr.project, config)

        return urls.ADMIN_RULES
Example #2
0
    def testProcessEditComponent_RenameWithSubComponents(self):
        subcd_1 = tracker_bizobj.MakeComponentDef(2, self.project.project_id,
                                                  'BackEnd>Worker1', 'doc',
                                                  False, [], [111L], 0, 125L,
                                                  3, 126L)
        subcd_2 = tracker_bizobj.MakeComponentDef(3, self.project.project_id,
                                                  'BackEnd>Worker2', 'doc',
                                                  False, [], [111L], 0, 125L,
                                                  4, 127L)
        self.config.component_defs.extend([subcd_1, subcd_2])

        self.mox.StubOutWithMock(filterrules_helpers,
                                 'RecomputeAllDerivedFields')
        filterrules_helpers.RecomputeAllDerivedFields(self.mr.cnxn,
                                                      self.services,
                                                      self.mr.project,
                                                      self.config)
        self.mox.ReplayAll()
        post_data = fake.PostData(
            leaf_name=['BackEnds'],
            docstring=['This is where the magic happens'],
            deprecated=[True],
            admins=['*****@*****.**'],
            cc=['*****@*****.**'],
            labels=[''])

        self.servlet._ProcessEditComponent(self.mr, post_data, self.config,
                                           self.cd)

        self.mox.VerifyAll()
        config = self.services.config.GetProjectConfig(self.mr.cnxn,
                                                       self.mr.project_id)
        cd = tracker_bizobj.FindComponentDef('BackEnds', config)
        self.assertEqual('BackEnds', cd.path)
        subcd_1 = tracker_bizobj.FindComponentDef('BackEnds>Worker1', config)
        self.assertEqual('BackEnds>Worker1', subcd_1.path)
        # Assert that creator and modifier have not changed for subcd_1.
        self.assertEqual(125L, subcd_1.creator_id)
        self.assertEqual(0, subcd_1.created)
        self.assertEqual(126L, subcd_1.modifier_id)
        self.assertEqual(3, subcd_1.modified)

        subcd_2 = tracker_bizobj.FindComponentDef('BackEnds>Worker2', config)
        self.assertEqual('BackEnds>Worker2', subcd_2.path)
        # Assert that creator and modifier have not changed for subcd_2.
        self.assertEqual(125L, subcd_2.creator_id)
        self.assertEqual(0, subcd_2.created)
        self.assertEqual(127L, subcd_2.modifier_id)
        self.assertEqual(4, subcd_2.modified)
    def testRecomputeDerivedFields_Disabled(self):
        """Servlet should just call RecomputeAllDerivedFieldsNow with no bounds."""
        saved_flag = settings.recompute_derived_fields_in_worker
        settings.recompute_derived_fields_in_worker = False
        self.mox.ReplayAll()

        filterrules_helpers.RecomputeAllDerivedFields(self.cnxn, self.services,
                                                      self.project,
                                                      self.config)
        self.assertTrue(self.services.issue.get_all_issues_in_project_called)
        self.assertTrue(self.services.issue.update_issues_called)
        self.assertTrue(self.services.issue.enqueue_issues_called)

        self.mox.VerifyAll()
        settings.recompute_derived_fields_in_worker = saved_flag
    def testRecomputeDerivedFields_NoIssues(self):
        """Servlet should not call because there is no work to do."""
        saved_flag = settings.recompute_derived_fields_in_worker
        settings.recompute_derived_fields_in_worker = True
        self.mox.ReplayAll()

        filterrules_helpers.RecomputeAllDerivedFields(self.cnxn, self.services,
                                                      self.project,
                                                      self.config)
        self.assertFalse(self.services.issue.get_all_issues_in_project_called)
        self.assertFalse(self.services.issue.update_issues_called)
        self.assertFalse(self.services.issue.enqueue_issues_called)

        self.mox.VerifyAll()
        settings.recompute_derived_fields_in_worker = saved_flag
    def testRecomputeDerivedFields_LotsOfIssues(self):
        """Servlet should enqueue multiple work items."""
        saved_flag = settings.recompute_derived_fields_in_worker
        settings.recompute_derived_fields_in_worker = True
        self.services.issue.next_id = 12345
        num_calls = (self.services.issue.next_id // self.BLOCK + 1)
        for _ in range(num_calls):
            taskqueue.add(
                params=mox.IsA(dict),
                url='/_task/recomputeDerivedFields.do').WithSideEffects(
                    self.mock_task_queue.add)
        self.mox.ReplayAll()

        filterrules_helpers.RecomputeAllDerivedFields(self.cnxn, self.services,
                                                      self.project,
                                                      self.config)
        self.assertFalse(self.services.issue.get_all_issues_in_project_called)
        self.assertFalse(self.services.issue.update_issues_called)
        self.assertFalse(self.services.issue.enqueue_issues_called)

        work_items = self.mock_task_queue.work_items
        self.assertEqual(num_calls, len(work_items))
        url, params = work_items[0]['url'], work_items[0]['params']
        self.assertEqual(urls.RECOMPUTE_DERIVED_FIELDS_TASK + '.do', url)
        self.assertEqual(self.project.project_id, params['project_id'])
        self.assertEqual(12345 // self.BLOCK * self.BLOCK + 1,
                         params['lower_bound'])
        self.assertEqual(12345, params['upper_bound'])

        url, params = work_items[-1]['url'], work_items[-1]['params']
        self.assertEqual(urls.RECOMPUTE_DERIVED_FIELDS_TASK + '.do', url)
        self.assertEqual(self.project.project_id, params['project_id'])
        self.assertEqual(1, params['lower_bound'])
        self.assertEqual(self.BLOCK + 1, params['upper_bound'])

        self.mox.VerifyAll()
        settings.recompute_derived_fields_in_worker = saved_flag
    def testRecomputeDerivedFields_SomeIssues(self):
        """Servlet should enqueue one work item rather than call directly."""
        saved_flag = settings.recompute_derived_fields_in_worker
        settings.recompute_derived_fields_in_worker = True
        self.services.issue.next_id = 1234
        num_calls = (self.services.issue.next_id // self.BLOCK + 1)
        for _ in range(num_calls):
            taskqueue.add(
                params=mox.IsA(dict),
                url='/_task/recomputeDerivedFields.do').WithSideEffects(
                    self.mock_task_queue.add)
        self.mox.ReplayAll()

        filterrules_helpers.RecomputeAllDerivedFields(self.cnxn, self.services,
                                                      self.project,
                                                      self.config)
        self.assertFalse(self.services.issue.get_all_issues_in_project_called)
        self.assertFalse(self.services.issue.update_issues_called)
        self.assertFalse(self.services.issue.enqueue_issues_called)
        work_items = self.mock_task_queue.work_items
        self.assertEqual(num_calls, len(work_items))

        self.mox.VerifyAll()
        settings.recompute_derived_fields_in_worker = saved_flag
Example #7
0
  def _ProcessEditComponent(self, mr, post_data, config, component_def):
    """The user wants to edit this component definition."""
    parsed = component_helpers.ParseComponentRequest(
        mr, post_data, self.services)

    if not tracker_constants.COMPONENT_NAME_RE.match(parsed.leaf_name):
      mr.errors.leaf_name = 'Invalid component name'

    original_path = component_def.path
    if mr.component_path and '>' in mr.component_path:
      parent_path = mr.component_path[:mr.component_path.rindex('>')]
      new_path = '%s>%s' % (parent_path, parsed.leaf_name)
    else:
      new_path = parsed.leaf_name

    conflict = tracker_bizobj.FindComponentDef(new_path, config)
    if conflict and conflict.component_id != component_def.component_id:
      mr.errors.leaf_name = 'That name is already in use.'

    creator, created = self._GetUserViewAndFormattedTime(
        mr, component_def.creator_id, component_def.created)
    modifier, modified = self._GetUserViewAndFormattedTime(
        mr, component_def.modifier_id, component_def.modified)

    if mr.errors.AnyErrors():
      self.PleaseCorrect(
          mr, initial_leaf_name=parsed.leaf_name,
          initial_docstring=parsed.docstring,
          initial_deprecated=ezt.boolean(parsed.deprecated),
          initial_admins=parsed.admin_usernames,
          initial_cc=parsed.cc_usernames,
          initial_labels=parsed.label_strs,
          created=created,
          creator=creator,
          modified=modified,
          modifier=modifier,
      )
      return None

    new_modified = int(time.time())
    new_modifier_id = self.services.user.LookupUserID(
        mr.cnxn, mr.auth.email, autocreate=False)
    self.services.config.UpdateComponentDef(
        mr.cnxn, mr.project_id, component_def.component_id,
        path=new_path, docstring=parsed.docstring, deprecated=parsed.deprecated,
        admin_ids=parsed.admin_ids, cc_ids=parsed.cc_ids, modified=new_modified,
        modifier_id=new_modifier_id, label_ids=parsed.label_ids)

    update_rule = False
    if new_path != original_path:
      update_rule = True
      # If the name changed then update all of its subcomponents as well.
      subcomponent_ids = tracker_bizobj.FindMatchingComponentIDs(
          original_path, config, exact=False)
      for subcomponent_id in subcomponent_ids:
        if subcomponent_id == component_def.component_id:
          continue
        subcomponent_def = tracker_bizobj.FindComponentDefByID(
            subcomponent_id, config)
        subcomponent_new_path = subcomponent_def.path.replace(
            original_path, new_path, 1)
        self.services.config.UpdateComponentDef(
            mr.cnxn, mr.project_id, subcomponent_def.component_id,
            path=subcomponent_new_path)

    if (set(parsed.cc_ids) != set(component_def.cc_ids) or
        set(parsed.label_ids) != set(component_def.label_ids)):
      update_rule = True
    if update_rule:
      filterrules_helpers.RecomputeAllDerivedFields(
          mr.cnxn, self.services, mr.project, config)

    return framework_helpers.FormatAbsoluteURL(
        mr, urls.COMPONENT_DETAIL,
        component=new_path, saved=1, ts=int(time.time()))
Example #8
0
  def components_update(self, request):
    """Update a component."""
    mar = self.mar_factory(request)
    config = self._services.config.GetProjectConfig(mar.cnxn, mar.project_id)
    component_path = request.componentPath
    component_def = tracker_bizobj.FindComponentDef(
        component_path, config)
    if not component_def:
      raise config_svc.NoSuchComponentException(
          'The component %s does not exist.' % component_path)
    if not permissions.CanViewComponentDef(
        mar.auth.effective_ids, mar.perms, mar.project, component_def):
      raise permissions.PermissionException(
          'User is not allowed to view this component %s' % component_path)
    if not permissions.CanEditComponentDef(
        mar.auth.effective_ids, mar.perms, mar.project, component_def, config):
      raise permissions.PermissionException(
          'User is not allowed to edit this component %s' % component_path)

    original_path = component_def.path
    new_path = component_def.path
    new_docstring = component_def.docstring
    new_deprecated = component_def.deprecated
    new_admin_ids = component_def.admin_ids
    new_cc_ids = component_def.cc_ids
    update_filterrule = False
    for update in request.updates:
      if update.field == api_pb2_v1.ComponentUpdateFieldID.LEAF_NAME:
        leaf_name = update.leafName
        if not tracker_constants.COMPONENT_NAME_RE.match(leaf_name):
          raise config_svc.InvalidComponentNameException(
              'The component name %s is invalid.' % leaf_name)

        if '>' in original_path:
          parent_path = original_path[:original_path.rindex('>')]
          new_path = '%s>%s' % (parent_path, leaf_name)
        else:
          new_path = leaf_name

        conflict = tracker_bizobj.FindComponentDef(new_path, config)
        if conflict and conflict.component_id != component_def.component_id:
          raise config_svc.InvalidComponentNameException(
              'The name %s is already in use.' % new_path)
        update_filterrule = True
      elif update.field == api_pb2_v1.ComponentUpdateFieldID.DESCRIPTION:
        new_docstring = update.description
      elif update.field == api_pb2_v1.ComponentUpdateFieldID.ADMIN:
        user_ids_dict = self._services.user.LookupUserIDs(
            mar.cnxn, list(update.admin), autocreate=True)
        new_admin_ids = [user_ids_dict[email] for email in update.admin]
      elif update.field == api_pb2_v1.ComponentUpdateFieldID.CC:
        user_ids_dict = self._services.user.LookupUserIDs(
            mar.cnxn, list(update.cc), autocreate=True)
        new_cc_ids = [user_ids_dict[email] for email in update.cc]
        update_filterrule = True
      elif update.field == api_pb2_v1.ComponentUpdateFieldID.DEPRECATED:
        new_deprecated = update.deprecated
      else:
        logging.error('Unknown component field %r', update.field)

    new_modified = int(time.time())
    new_modifier_id = self._services.user.LookupUserID(
        mar.cnxn, mar.auth.email, autocreate=False)
    logging.info(
        'Updating component id %d: path-%s, docstring-%s, deprecated-%s,'
        ' admin_ids-%s, cc_ids-%s modified by %s', component_def.component_id,
        new_path, new_docstring, new_deprecated, new_admin_ids, new_cc_ids,
        new_modifier_id)
    self._services.config.UpdateComponentDef(
        mar.cnxn, mar.project_id, component_def.component_id,
        path=new_path, docstring=new_docstring, deprecated=new_deprecated,
        admin_ids=new_admin_ids, cc_ids=new_cc_ids, modified=new_modified,
        modifier_id=new_modifier_id)

    # TODO(sheyang): reuse the code in componentdetails
    if original_path != new_path:
      # If the name changed then update all of its subcomponents as well.
      subcomponent_ids = tracker_bizobj.FindMatchingComponentIDs(
          original_path, config, exact=False)
      for subcomponent_id in subcomponent_ids:
        if subcomponent_id == component_def.component_id:
          continue
        subcomponent_def = tracker_bizobj.FindComponentDefByID(
            subcomponent_id, config)
        subcomponent_new_path = subcomponent_def.path.replace(
            original_path, new_path, 1)
        self._services.config.UpdateComponentDef(
            mar.cnxn, mar.project_id, subcomponent_def.component_id,
            path=subcomponent_new_path)

    if update_filterrule:
      filterrules_helpers.RecomputeAllDerivedFields(
          mar.cnxn, self._services, mar.project, config)

    return message_types.VoidMessage()