Пример #1
0
    def _AddLongTestColumns(self, start_rev=15000, end_rev=16500, step=3):
        """Adds test data with long nested sub test to the mock datastore.

    Args:
      start_rev: Starting revision number.
      end_rev: Ending revision number.
      step: Difference between adjacent revisions.
    """
        master = graph_data.Master(id='master')
        master.put()
        bot = graph_data.Bot(id='bot', parent=master.key)
        bot.put()
        test = graph_data.Test(id='suite', parent=bot.key)
        test.put()

        rows = []
        for sub_name in ['sub1', 'sub2', 'sub3', 'sub4', 'sub5']:
            test = graph_data.Test(id=sub_name,
                                   parent=test.key,
                                   improvement_direction=anomaly.UP,
                                   has_rows=True)
            test.put()
            test_container_key = utils.GetTestContainerKey(test.key)
            for i in range(start_rev, end_rev, step):
                row = graph_data.Row(parent=test_container_key,
                                     id=i,
                                     value=float(i * 2),
                                     r_webkit=int(i * 0.25),
                                     a_str='some_string',
                                     buildnumber=i - start_rev,
                                     a_tracing_uri='http://trace/%d' % i,
                                     a_trace_rerun_options={'foo': '--foo'})
                rows.append(row)
        ndb.put_multi(rows)
Пример #2
0
 def _PutEntitiesAllExternal(self):
     """Puts entities (none internal-only) and returns the keys."""
     master = graph_data.Master(id='M').put()
     bot = graph_data.Bot(parent=master, id='b').put()
     keys = [
         graph_data.Test(id='a', parent=bot, internal_only=False).put(),
         graph_data.Test(id='b', parent=bot, internal_only=False).put(),
         graph_data.Test(id='c', parent=bot, internal_only=False).put(),
         graph_data.Test(id='d', parent=bot, internal_only=False).put(),
     ]
     return keys
Пример #3
0
 def _AddMockData(self):
   master = graph_data.Master(id='ChromiumPerf').put()
   bots = []
   for name in ['win7', 'mac']:
     bot = graph_data.Bot(id=name, parent=master).put()
     bots.append(bot)
     test = graph_data.Test(id='dromaeo', parent=bot).put()
     dom_test = graph_data.Test(id='dom', parent=test, has_rows=True).put()
     test_container_key = utils.GetTestContainerKey(dom_test)
     for i in range(15000, 16000, 5):
       graph_data.Row(parent=test_container_key, id=i, value=float(i * 2.5),
                      error=(i + 5)).put()
Пример #4
0
 def _AddMockData(self):
   """Adds mock data to the datastore, not updating stored_object."""
   master_key = graph_data.Master(id='ChromiumPerf').put()
   for bot_name in ['win7', 'mac']:
     bot_key = graph_data.Bot(id=bot_name, parent=master_key).put()
     test_key = graph_data.Test(id='dromaeo', parent=bot_key).put()
     subtest_key = graph_data.Test(
         id='dom', parent=test_key, has_rows=True).put()
     test_container_key = utils.GetTestContainerKey(subtest_key)
     for rev in range(15000, 16000, 5):
       row = graph_data.Row(parent=test_container_key,
                            id=rev, value=float(rev * 2.5))
       row.timestamp = datetime.datetime(2013, 8, 1)
       row.put()
Пример #5
0
 def testGetOrCreateAncestors_GetsExistingEntities(self):
     master_key = graph_data.Master(id='ChromiumPerf', parent=None).put()
     bot_key = graph_data.Bot(id='win7', parent=master_key).put()
     suite_key = graph_data.Test(id='dromaeo', parent=bot_key).put()
     subtest_key = graph_data.Test(id='dom', parent=suite_key).put()
     graph_data.Test(id='modify', parent=subtest_key).put()
     actual_parent = add_point_queue._GetOrCreateAncestors(
         'ChromiumPerf', 'win7', 'dromaeo/dom/modify')
     self.assertEqual('modify', actual_parent.key.id())
     # No extra Test or Bot objects should have been added to the database
     # beyond the four that were put in before the _GetOrCreateAncestors call.
     self.assertEqual(1, len(graph_data.Master.query().fetch()))
     self.assertEqual(1, len(graph_data.Bot.query().fetch()))
     self.assertEqual(3, len(graph_data.Test.query().fetch()))
Пример #6
0
 def testPutTestTruncatesDescription(self):
     master = graph_data.Master(id='M').put()
     bot = graph_data.Bot(parent=master, id='b').put()
     long_string = 500 * 'x'
     too_long = long_string + 'y'
     key = graph_data.Test(id='a', parent=bot, description=too_long).put()
     self.assertEqual(long_string, key.get().description)
Пример #7
0
    def testEdit_RemovePattern(self):
        """Tests removing a pattern from an AnomalyConfig."""
        self.SetCurrentUser('*****@*****.**', is_admin=True)
        anomaly_config_key = anomaly_config.AnomalyConfig(
            id='Test Config',
            config={
                'a': 10
            },
            patterns=['*/*/one', '*/*/two']).put()
        master = graph_data.Master(id='TheMaster').put()
        bot = graph_data.Bot(id='TheBot', parent=master).put()
        test_one = graph_data.Test(
            id='one',
            parent=bot,
            overridden_anomaly_config=anomaly_config_key,
            has_rows=True).put()
        test_two = graph_data.Test(
            id='two',
            parent=bot,
            overridden_anomaly_config=anomaly_config_key,
            has_rows=True).put()

        # Verify the state of the data before making the request.
        self.assertEqual(['*/*/one', '*/*/two'],
                         anomaly_config_key.get().patterns)
        self.assertEqual(['TheMaster/TheBot/one'],
                         list_tests.GetTestsMatchingPattern('*/*/one'))

        self.testapp.post(
            '/edit_anomaly_configs', {
                'add-edit': 'edit',
                'edit-name': 'Test Config',
                'config': '{"a": 10}',
                'patterns': ['*/*/two'],
                'xsrf_token': xsrf.GenerateToken(users.get_current_user()),
            })
        self.ExecuteTaskQueueTasks('/put_entities_task',
                                   edit_config_handler._TASK_QUEUE_NAME)

        self.assertEqual(['*/*/two'], anomaly_config_key.get().patterns)
        self.assertIsNone(test_one.get().overridden_anomaly_config)
        self.assertEqual('Test Config',
                         test_two.get().overridden_anomaly_config.string_id())
Пример #8
0
def _AddSubtest(parent_test_key, subtests_dict):
  """Helper function to recursively add sub-Tests to a Test.

  Args:
    parent_test_key: A Test key.
    subtests_dict: A dict of test names to dictionaries of subtests.
  """
  for test_name in subtests_dict:
    test_key = graph_data.Test(id=test_name, parent=parent_test_key).put()
    _AddSubtest(test_key, subtests_dict[test_name])
Пример #9
0
    def _AddTestColumns(self, start_rev=15000, end_rev=16500, step=3):
        """Adds a bunch of test data to the mock datastore.

    In particular, add Rows with revisions in the given range (but skipping
    some numbers, so the revisions are non-contiguous) under the dromaeo/dom
    test for winXP, win7, mac.

    Args:
      start_rev: Starting revision number.
      end_rev: Ending revision number.
      step: Difference between adjacent revisions.
    """
        master = graph_data.Master(id='ChromiumGPU')
        master.put()
        bots = []
        rows = []
        for name in ['winXP', 'win7', 'mac']:
            bot = graph_data.Bot(id=name, parent=master.key)
            bot.put()
            bots.append(bot)
            test = graph_data.Test(id='dromaeo', parent=bot.key)
            test.put()
            for sub_name in ['dom', 'jslib']:
                sub_test = graph_data.Test(id=sub_name,
                                           parent=test.key,
                                           improvement_direction=anomaly.UP,
                                           has_rows=True).put()
                test_container_key = utils.GetTestContainerKey(sub_test)
                for i in range(start_rev, end_rev, step):
                    # Add Rows for one bot with revision numbers that aren't lined up
                    # with the other bots.
                    rev = i + 1 if name == 'mac' else i
                    row = graph_data.Row(
                        parent=test_container_key,
                        id=rev,
                        value=float(i * 2),
                        r_webkit=int(i * 0.25),
                        a_str='some_string',
                        buildnumber=i - start_rev,
                        a_tracing_uri='http://trace/%d' % i,
                        a_trace_rerun_options={'foo': '--foo'})
                    rows.append(row)
        ndb.put_multi(rows)
Пример #10
0
    def testGetGraphJson_UnSelectedTrace(self):
        self._AddTestColumns(start_rev=15000, end_rev=15050)
        test_key = ndb.Key('Master', 'ChromiumGPU', 'Bot', 'win7', 'Test',
                           'dromaeo', 'Test', 'jslib')
        rows = graph_data.Row.query(
            graph_data.Row.parent_test == test_key).fetch()
        for row in rows:
            row.error = 1 + ((row.revision - 15000) * 0.25)
        ndb.put_multi(rows)

        # Insert sub tests to jslib.
        rows = []
        start_rev = 15000
        end_rev = 15050
        for name in ['sub_test_a', 'sub_test_b']:
            sub_test = graph_data.Test(id=name,
                                       parent=test_key,
                                       improvement_direction=anomaly.UP,
                                       has_rows=True).put()
            sub_test_container_key = utils.GetTestContainerKey(sub_test)
            for i in range(start_rev, end_rev, 3):
                # Add Rows for one bot with revision numbers that aren't lined up
                # with the other bots.
                row = graph_data.Row(parent=sub_test_container_key,
                                     id=i,
                                     value=float(i * 2),
                                     r_webkit=int(i * 0.25),
                                     a_str='some_string',
                                     buildnumber=i - start_rev,
                                     a_tracing_uri='http://trace/%d' % i,
                                     a_trace_rerun_options={'foo': '--foo'})
                rows.append(row)
        ndb.put_multi(rows)

        flot_json_str = graph_json.GetGraphJson(
            {
                'ChromiumGPU/win7/dromaeo/jslib': ['jslib'],
            },
            rev=15000,
            num_points=8,
            is_selected=False)
        flot = json.loads(flot_json_str)

        sub_test_a_index = self._GetSeriesIndex(
            flot, 'ChromiumGPU/win7/dromaeo/jslib/sub_test_a')
        sub_test_b_index = self._GetSeriesIndex(
            flot, 'ChromiumGPU/win7/dromaeo/jslib/sub_test_b')

        self.assertEqual(2, len(flot['data']))
        self.assertEqual(5, len(flot['data'][sub_test_a_index]['data']))
        self.assertEqual(2, len(flot['annotations']['series']))
        self.assertEqual(5,
                         len(flot['annotations'].get(sub_test_a_index).keys()))
        self.assertEqual(5,
                         len(flot['annotations'].get(sub_test_b_index).keys()))
Пример #11
0
 def _AddInternalSampleData(self):
     """Adds some internal-only test data."""
     master = graph_data.Master(id='XMaster').put()
     bot = graph_data.Bot(id='x-bot', parent=master,
                          internal_only=True).put()
     test = graph_data.Test(id='xtest', parent=bot,
                            internal_only=True).put()
     test_container_key = utils.GetTestContainerKey(test)
     for i in range(50):
         graph_data.Row(parent=test_container_key,
                        id=i + 1000,
                        value=i + 1000,
                        internal_only=True).put()
 def _AddSampleTestData(self):
     """Adds some sample data used in the tests below."""
     master = graph_data.Master(id='TheMaster').put()
     bot = graph_data.Bot(id='TheBot', parent=master).put()
     suite1 = graph_data.Test(id='Suite1', parent=bot).put()
     suite2 = graph_data.Test(id='Suite2', parent=bot).put()
     graph_data.Test(id='aaa', parent=suite1, has_rows=True).put()
     graph_data.Test(id='bbb', parent=suite1, has_rows=True).put()
     graph_data.Test(id='ccc', parent=suite2, has_rows=True).put()
     graph_data.Test(id='ddd', parent=suite2, has_rows=True).put()
Пример #13
0
def AddTests(masters, bots, tests_dict):
  """Adds data to the mock datastore.

  Args:
    masters: List of buildbot master names.
    bots: List of bot names.
    tests_dict: Nested dictionary of tests to add; keys are test names
        and values are nested dictionaries of tests to add.
  """
  for master_name in masters:
    master_key = graph_data.Master(id=master_name).put()
    for bot_name in bots:
      bot_key = graph_data.Bot(id=bot_name, parent=master_key).put()
      for test_name in tests_dict:
        test_key = graph_data.Test(id=test_name, parent=bot_key).put()
        _AddSubtest(test_key, tests_dict[test_name])
Пример #14
0
    def testGet_WithMaxTestsParam(self):
        master = graph_data.Master(id='XMaster').put()
        bot = graph_data.Bot(id='x-bot', parent=master).put()
        for i in range(20):
            test = graph_data.Test(id='xtest-%d' % i, parent=bot).put()
            test_container_key = utils.GetTestContainerKey(test)
            graph_data.Row(parent=test_container_key, id=1, value=1).put()

        response = self.testapp.get('/new_points', {
            'pattern': '*/*/*',
            'max_tests': '12'
        })

        self.assertIn('matched 20 tests', response.body)
        self.assertIn('first 12 tests', response.body)
        # 12 points across 12 tests, plus one row for the header.
        self.assertEqual(13, len(re.findall(r'<tr>', response.body)))
Пример #15
0
def _GetOrCreateTest(name, parent_key, properties):
  """Either gets an entity if it already exists, or creates one.

  If the entity already exists but the properties are different than the ones
  specified, then the properties will be updated first. This implies that a
  new point is being added for an existing Test, so if the Test has been
  previously marked as deprecated or associated with a stoppage alert, then it
  can be updated and marked as non-deprecated.

  If the entity doesn't yet exist, a new one will be created with the given
  properties.

  Args:
    name: The string ID of the Test to get or create.
    parent_key: The key of the parent entity.
    properties: A dictionary of properties that should be set.

  Returns:
    An entity (which has already been put).

  Raises:
    datastore_errors.BadRequestError: Something went wrong getting the entity.
  """
  existing = graph_data.Test.get_by_id(name, parent_key)

  if not existing:
    # Add improvement direction if this is a new test.
    if 'units' in properties:
      units = properties['units']
      direction = units_to_direction.GetImprovementDirection(units)
      properties['improvement_direction'] = direction
    new_entity = graph_data.Test(id=name, parent=parent_key, **properties)
    new_entity.put()
    return new_entity

  # Flag indicating whether we want to re-put the entity before returning.
  properties_changed = False

  if existing.deprecated:
    existing.deprecated = False
    properties_changed = True

  if existing.stoppage_alert:
    alert = existing.stoppage_alert.get()
    if alert:
      alert.recovered = True
      alert.put()
    else:
      logging.warning('Stoppage alert %s not found.', existing.stoppage_alert)
    existing.stoppage_alert = None
    properties_changed = True

  # Special case to update improvement direction from units for Test entities
  # when units are being updated. If an improvement direction is explicitly
  # provided in the properties, then it will be updated again below.
  units = properties.get('units')
  if units:
    direction = units_to_direction.GetImprovementDirection(units)
    if direction != existing.improvement_direction:
      existing.improvement_direction = direction
      properties_changed = True

  # Go through the list of general properties and update if necessary.
  for prop, value in properties.items():
    if (hasattr(existing, prop) and value is not None and
        getattr(existing, prop) != value):
      setattr(existing, prop, value)
      properties_changed = True

  if properties_changed:
    existing.put()
  return existing
Пример #16
0
    def testEdit_AddPattern(self):
        """Tests changing the patterns list of an existing AnomalyConfig."""
        self.SetCurrentUser('*****@*****.**', is_admin=True)
        master = graph_data.Master(id='TheMaster').put()
        bot = graph_data.Bot(id='TheBot', parent=master).put()
        suite1 = graph_data.Test(id='Suite1', parent=bot).put()
        suite2 = graph_data.Test(id='Suite2', parent=bot).put()
        test_aaa = graph_data.Test(id='aaa', parent=suite1,
                                   has_rows=True).put()
        test_bbb = graph_data.Test(id='bbb', parent=suite1,
                                   has_rows=True).put()
        test_ccc = graph_data.Test(id='ccc', parent=suite1,
                                   has_rows=True).put()
        test_ddd = graph_data.Test(id='ddd', parent=suite2,
                                   has_rows=True).put()
        anomaly_config.AnomalyConfig(id='1-Suite1-specific', config={
            'a': 10
        }).put()
        anomaly_config.AnomalyConfig(id='2-Suite1-general', config={
            'b': 20
        }).put()

        self.testapp.post(
            '/edit_anomaly_configs', {
                'add-edit': 'edit',
                'edit-name': '1-Suite1-specific',
                'config': '{"a": 10}',
                'patterns': '*/*/Suite1/aaa',
                'xsrf_token': xsrf.GenerateToken(users.get_current_user()),
            })
        self.ExecuteTaskQueueTasks('/put_entities_task',
                                   edit_config_handler._TASK_QUEUE_NAME)
        self.testapp.post(
            '/edit_anomaly_configs', {
                'add-edit': 'edit',
                'edit-name': '2-Suite1-general',
                'config': '{"b": 20}',
                'patterns': '*/*/Suite1/*',
                'xsrf_token': xsrf.GenerateToken(users.get_current_user()),
            })
        self.ExecuteTaskQueueTasks('/put_entities_task',
                                   edit_config_handler._TASK_QUEUE_NAME)

        # The lists of test patterns in the AnomalyConfig entities in the datastore
        # should be set based on what was added in the two requests above.
        self.assertEqual(['*/*/Suite1/*'],
                         anomaly_config.AnomalyConfig.get_by_id(
                             '2-Suite1-general').patterns)
        self.assertEqual(['*/*/Suite1/aaa'],
                         anomaly_config.AnomalyConfig.get_by_id(
                             '1-Suite1-specific').patterns)

        # The 1-Suite1-specific config applies instead of the other config
        # because its name comes first according to sort order.
        self.assertEqual('1-Suite1-specific',
                         test_aaa.get().overridden_anomaly_config.string_id())
        # The 2-Suite1-specific config applies to the other tests under Suite1.
        self.assertEqual('2-Suite1-general',
                         test_bbb.get().overridden_anomaly_config.string_id())
        self.assertEqual('2-Suite1-general',
                         test_ccc.get().overridden_anomaly_config.string_id())

        # Note that Suite2/ddd has no config, and nor do the parent tests.
        self.assertIsNone(test_ddd.get().overridden_anomaly_config)
        self.assertIsNone(suite1.get().overridden_anomaly_config)
        self.assertIsNone(suite2.get().overridden_anomaly_config)
 def _MakeSampleTest(self):
   """Makes a Test entity to be used in the tests below."""
   parent_key = ndb.Key('Master', 'm', 'Bot', 'b', 'Test', 'suite')
   return graph_data.Test(parent=parent_key, id='foo')