示例#1
0
 def testNoFailedAttempts(self):
     quests = [quest_test.QuestPass()]
     state = job_state.JobState(quests)
     state.AddChange(change_test.Change(1))
     state.AddChange(change_test.Change(2))
     state.ScheduleWork()
     self.assertFalse(state.FirstOrLastChangeFailed())
示例#2
0
    def testDifferentWithMidpoint(self):
        quests = [
            quest_test.QuestByChange({
                change_test.Change(1):
                quest_test.QuestPass(),
                change_test.Change(9):
                quest_test.QuestFail(),
            })
        ]
        state = job_state.JobState(quests,
                                   comparison_mode=job_state.PERFORMANCE)
        state.AddChange(change_test.Change(1))
        state.AddChange(change_test.Change(9))

        state.ScheduleWork()
        state.Explore()

        # The Changes are different. Add the midpoint.
        expected = [
            change_test.Change(1),
            change_test.Change(5),
            change_test.Change(9)
        ]
        self.assertEqual(state._changes, expected)
        attempt_count_1 = len(state._attempts[change_test.Change(1)])
        attempt_count_2 = len(state._attempts[change_test.Change(5)])
        attempt_count_3 = len(state._attempts[change_test.Change(9)])
        self.assertEqual(attempt_count_1, attempt_count_2)
        self.assertEqual(attempt_count_2, attempt_count_3)
        self.assertEqual([], state.Differences())
示例#3
0
    def testUnknown(self):
        quests = [quest_test.QuestPass()]
        state = job_state.JobState(quests,
                                   comparison_mode=job_state.FUNCTIONAL,
                                   comparison_magnitude=0.2)
        state.AddChange(change_test.Change(1))
        state.AddChange(change_test.Change(9))

        state.ScheduleWork()
        state.Explore()

        # Need more information. Add more attempts to one Change.
        self.assertEqual(len(state._changes), 2)
        attempt_count_1 = len(state._attempts[change_test.Change(1)])
        attempt_count_2 = len(state._attempts[change_test.Change(9)])
        self.assertGreaterEqual(attempt_count_1, attempt_count_2)

        state.ScheduleWork()
        state.Explore()

        # We still need more information. Add more attempts to the other Change.
        self.assertEqual(len(state._changes), 2)
        attempt_count_1 = len(state._attempts[change_test.Change(1)])
        attempt_count_2 = len(state._attempts[change_test.Change(9)])
        self.assertEqual(attempt_count_1, attempt_count_2)
示例#4
0
 def New(cls, arguments, quests, auto_explore, bug_id=None, tags=None):
     # Create job.
     return cls(arguments=arguments,
                auto_explore=auto_explore,
                bug_id=bug_id,
                tags=tags,
                state=job_state.JobState(quests))
示例#5
0
 def testWorkLeft(self):
   quests = [
       quest_test.QuestCycle(quest_test.QuestPass(), quest_test.QuestSpin())
   ]
   state = job_state.JobState(quests)
   state.AddChange(change_test.Change(123))
   self.assertTrue(state.ScheduleWork())
示例#6
0
  def New(cls, quests, changes, arguments=None, auto_explore=False,
          bug_id=None, comparison_mode=None, pin=None, tags=None, user=None):
    """Creates a new Job, adds Changes to it, and puts it in the Datstore.

    Args:
      quests: An iterable of Quests for the Job to run.
      changes: An iterable of the initial Changes to run on.
      arguments: A dict with the original arguments used to start the Job.
      auto_explore: If True, the Job should automatically add additional
          Attempts and Changes based on comparison of results values.
      bug_id: A monorail issue id number to post Job updates to.
      comparison_mode: A member of the ComparisonMode enum, which the Job uses
          to figure out whether to perform a functional or performance bisect.
          If None, the Job will not automatically add any Attempts or Changes.
      pin: A Change (Commits + Patch) to apply to every Change in this Job.
      tags: A dict of key-value pairs used to filter the Jobs listings.
      user: The email of the Job creator.

    Returns:
      A Job object.
    """
    job = cls(state=job_state.JobState(quests, pin=pin),
              arguments=arguments or {},
              auto_explore=auto_explore,
              bug_id=bug_id,
              comparison_mode=comparison_mode,
              tags=tags,
              user=user)

    for c in changes:
      job.AddChange(c)

    job.put()
    return job
示例#7
0
 def testAllAttemptsFail(self):
     q = _QuestStub(_ExecutionFail, _ExecutionFail, _ExecutionFail2)
     state = job_state.JobState([q])
     state.AddChange('change')
     expected_regexp = '7/10.*\nException: Expected error for testing.$'
     self.assertTrue(state.ScheduleWork())
     with self.assertRaisesRegexp(Exception, expected_regexp):
         self.assertFalse(state.ScheduleWork())
示例#8
0
    def New(cls,
            quests,
            changes,
            arguments=None,
            bug_id=None,
            comparison_mode=None,
            comparison_magnitude=None,
            gerrit_server=None,
            gerrit_change_id=None,
            name=None,
            pin=None,
            tags=None,
            user=None):
        """Creates a new Job, adds Changes to it, and puts it in the Datstore.

    Args:
      quests: An iterable of Quests for the Job to run.
      changes: An iterable of the initial Changes to run on.
      arguments: A dict with the original arguments used to start the Job.
      bug_id: A monorail issue id number to post Job updates to.
      comparison_mode: Either 'functional' or 'performance', which the Job uses
          to figure out whether to perform a functional or performance bisect.
          If None, the Job will not automatically add any Attempts or Changes.
      comparison_magnitude: The estimated size of the regression or improvement
          to look for. Smaller magnitudes require more repeats.
      gerrit_server: Server of the Gerrit code review to update with job
          results.
      gerrit_change_id: Change id of the Gerrit code review to update with job
          results.
      name: The user-provided name of the Job.
      pin: A Change (Commits + Patch) to apply to every Change in this Job.
      tags: A dict of key-value pairs used to filter the Jobs listings.
      user: The email of the Job creator.

    Returns:
      A Job object.
    """
        state = job_state.JobState(quests,
                                   comparison_mode=comparison_mode,
                                   comparison_magnitude=comparison_magnitude,
                                   pin=pin)
        job = cls(state=state,
                  arguments=arguments or {},
                  bug_id=bug_id,
                  comparison_mode=comparison_mode,
                  gerrit_server=gerrit_server,
                  gerrit_change_id=gerrit_change_id,
                  name=name,
                  tags=tags,
                  user=user,
                  started=False,
                  cancelled=False)

        for c in changes:
            job.AddChange(c)

        job.put()
        return job
示例#9
0
 def testFailedAttempt(self):
     quests = [quest_test.QuestPass()]
     state = job_state.JobState(quests)
     state.AddChange(change_test.Change(1))
     state.AddChange(change_test.Change(2))
     state.ScheduleWork()
     for attempt in state._attempts[change_test.Change(1)]:
         attempt._last_execution._exception = "Failed"
     self.assertTrue(state.FirstOrLastChangeFailed())
示例#10
0
 def testAllAttemptsFail(self):
   quests = [quest_test.QuestCycle(
       quest_test.QuestFail, quest_test.QuestFail, quest_test.QuestFail2)]
   state = job_state.JobState(quests)
   state.AddChange(change_test.Change(123))
   expected_regexp = '7/10.*\nException: Expected error for testing.$'
   self.assertTrue(state.ScheduleWork())
   with self.assertRaisesRegexp(Exception, expected_regexp):
     self.assertFalse(state.ScheduleWork())
示例#11
0
 def testDifferences(self):
   quests = [quest_test.QuestPass()]
   state = job_state.JobState(
       quests, comparison_mode=job_state.FUNCTIONAL, comparison_magnitude=0.2)
   change_a = change_test.Change(1)
   change_b = change_test.Change(9)
   state.AddChange(change_a)
   state.AddChange(change_b)
   self.assertEqual([], state.Differences())
示例#12
0
 def testNoAttempts(self):
     quests = [quest_test.QuestPass()]
     state = job_state.JobState(quests)
     state.AddChange(change_test.Change(1))
     state.AddChange(change_test.Change(2))
     state.ScheduleWork()
     # It shouldn't happen that a change has no attempts, but we should cope
     # gracefully if that somehow happens.
     del state._attempts[change_test.Change(1)][:]
     del state._attempts[change_test.Change(2)][:]
     self.assertFalse(state.FirstOrLastChangeFailed())
示例#13
0
  def testPending(self):
    quests = [quest_test.QuestSpin()]
    state = job_state.JobState(quests, comparison_mode=job_state.PERFORMANCE)
    state.AddChange(change_test.Change(1))
    state.AddChange(change_test.Change(9))

    state.Explore()

    # The results are pending. Do not add any Attempts or Changes.
    self.assertEqual(len(state._changes), 2)
    attempt_count_1 = len(state._attempts[change_test.Change(1)])
    attempt_count_2 = len(state._attempts[change_test.Change(9)])
    self.assertEqual(attempt_count_1, attempt_count_2)
示例#14
0
 def New(cls,
         arguments,
         quests,
         auto_explore,
         comparison_mode=None,
         user=None,
         bug_id=None,
         tags=None):
     # Create job.
     return cls(arguments=arguments,
                auto_explore=auto_explore,
                comparison_mode=comparison_mode,
                user=user,
                bug_id=bug_id,
                tags=tags,
                state=job_state.JobState(quests))
示例#15
0
  def testDifferentNoMidpoint(self):
    quests = [quest_test.QuestByChange({
        change_test.Change(1): quest_test.QuestPass(),
        change_test.Change(2): quest_test.QuestFail(),
    })]
    state = job_state.JobState(quests, comparison_mode=job_state.PERFORMANCE)
    state.AddChange(change_test.Change(1))
    state.AddChange(change_test.Change(2))

    state.ScheduleWork()
    state.Explore()

    # The Changes are different, but there's no midpoint. We're done.
    self.assertEqual(len(state._changes), 2)
    attempt_count_1 = len(state._attempts[change_test.Change(1)])
    attempt_count_2 = len(state._attempts[change_test.Change(2)])
    self.assertEqual(attempt_count_1, attempt_count_2)
示例#16
0
  def testSame(self):
    quests = [quest_test.QuestPass()]
    state = job_state.JobState(quests, comparison_mode=job_state.FUNCTIONAL)
    state.AddChange(change_test.Change(1))
    state.AddChange(change_test.Change(9))
    for _ in xrange(5):
      # More Attempts give more confidence that they are, indeed, the same.
      state.AddAttempts(change_test.Change(1))
      state.AddAttempts(change_test.Change(9))

    state.ScheduleWork()
    state.Explore()

    # The Changes are the same. Do not add any Attempts or Changes.
    self.assertEqual(len(state._changes), 2)
    attempt_count_1 = len(state._attempts[change_test.Change(1)])
    attempt_count_2 = len(state._attempts[change_test.Change(9)])
    self.assertEqual(attempt_count_1, attempt_count_2)
示例#17
0
    def testDifferentWithMidpoint(self):
        quests = [
            quest_test.QuestByChange({
                change_test.Change(1):
                quest_test.QuestPass(),
                change_test.Change(9):
                quest_test.QuestFail(),
            })
        ]
        state = job_state.JobState(quests,
                                   comparison_mode=job_state.PERFORMANCE)
        state.AddChange(change_test.Change(1))
        state.AddChange(change_test.Change(9))

        state.ScheduleWork()
        state.Explore()

        # The Changes are different. Add the speculated modpoints in a two-level
        # deep bisection tree, which include 3, 5 (the midpoint between 0 and 9),
        # and 7.
        expected = [
            change_test.Change(1),
            change_test.Change(3),
            change_test.Change(5),
            change_test.Change(7),
            change_test.Change(9),
        ]

        # View the whole diff in case of failure.
        self.maxDiff = None
        self.assertEqual(state._changes, expected)
        attempt_count_1 = len(state._attempts[change_test.Change(1)])
        attempt_count_2 = len(state._attempts[change_test.Change(3)])
        attempt_count_3 = len(state._attempts[change_test.Change(5)])
        attempt_count_4 = len(state._attempts[change_test.Change(7)])
        attempt_count_5 = len(state._attempts[change_test.Change(9)])
        self.assertEqual(attempt_count_1, attempt_count_2)
        self.assertEqual(attempt_count_2, attempt_count_3)
        self.assertEqual(attempt_count_3, attempt_count_4)
        self.assertEqual(attempt_count_4, attempt_count_5)
        self.assertEqual([], state.Differences())
示例#18
0
    def New(cls,
            quests,
            changes,
            arguments=None,
            bug_id=None,
            comparison_mode=None,
            comparison_magnitude=None,
            gerrit_server=None,
            gerrit_change_id=None,
            name=None,
            pin=None,
            tags=None,
            user=None,
            use_execution_engine=False):
        """Creates a new Job, adds Changes to it, and puts it in the Datstore.

    Args:
      quests: An iterable of Quests for the Job to run.
      changes: An iterable of the initial Changes to run on.
      arguments: A dict with the original arguments used to start the Job.
      bug_id: A monorail issue id number to post Job updates to.
      comparison_mode: Either 'functional' or 'performance', which the Job uses
        to figure out whether to perform a functional or performance bisect. If
        None, the Job will not automatically add any Attempts or Changes.
      comparison_magnitude: The estimated size of the regression or improvement
        to look for. Smaller magnitudes require more repeats.
      gerrit_server: Server of the Gerrit code review to update with job
        results.
      gerrit_change_id: Change id of the Gerrit code review to update with job
        results.
      name: The user-provided name of the Job.
      pin: A Change (Commits + Patch) to apply to every Change in this Job.
      tags: A dict of key-value pairs used to filter the Jobs listings.
      user: The email of the Job creator.
      use_execution_engine: A bool indicating whether to use the experimental
        execution engine. Currently defaulted to False, but will be switched to
        True and eventually removed as an option later.

    Returns:
      A Job object.
    """
        state = job_state.JobState(quests,
                                   comparison_mode=comparison_mode,
                                   comparison_magnitude=comparison_magnitude,
                                   pin=pin)
        args = arguments or {}
        job = cls(state=state,
                  arguments=args,
                  bug_id=bug_id,
                  comparison_mode=comparison_mode,
                  gerrit_server=gerrit_server,
                  gerrit_change_id=gerrit_change_id,
                  name=name,
                  tags=tags,
                  user=user,
                  started=False,
                  cancelled=False,
                  use_execution_engine=use_execution_engine)

        # Pull out the benchmark arguments to the top-level.
        job.benchmark_arguments = BenchmarkArguments.FromArgs(args)

        if use_execution_engine:
            # Short-circuit the process because we don't need any further processing
            # here when we're using the execution engine.
            job.put()
            return job

        for c in changes:
            job.AddChange(c)

        job.put()

        # At this point we already have an ID, so we should go through each of the
        # quests associated with the state, and provide the Job ID through a common
        # API.
        job.state.PropagateJob(job)
        job.put()
        return job
示例#19
0
 def testNoWorkLeft(self):
   quests = [quest_test.QuestPass()]
   state = job_state.JobState(quests)
   state.AddChange(change_test.Change(123))
   self.assertTrue(state.ScheduleWork())
   self.assertFalse(state.ScheduleWork())
示例#20
0
 def testNoAttempts(self):
   state = job_state.JobState(())
   self.assertFalse(state.ScheduleWork())
示例#21
0
 def testNoChanges(self):
     state = job_state.JobState(())
     self.assertFalse(state.FirstOrLastChangeFailed())
示例#22
0
 def testNoWorkLeft(self):
     state = job_state.JobState([_QuestStub(_ExecutionPass)])
     state.AddChange('change')
     self.assertTrue(state.ScheduleWork())
     self.assertFalse(state.ScheduleWork())