def testKickTestPlan_withError(self, create_test_run, set_test_run_state):
    """Tests that errors are handled when kicking off a test plan."""
    test = ndb_models.Test(id='test_id')
    test_run_config = ndb_models.TestRunConfig(
        test_key=test.key, cluster='cluster', run_target='run_target')
    test_plan = ndb_models.TestPlan(
        name='test_plan', test_run_configs=[test_run_config, test_run_config])
    test_plan.put()
    # First test run created successfully, but second fails even with retries
    test_run = ndb_models.TestRun(id='test_run_id')
    create_test_run.side_effect = (
        [test_run] +
        test_plan_kicker.MAX_RETRY_COUNT * [RuntimeError('test_run_error')])

    # Retries a few times before canceling test run and raising exception
    with self.assertRaises(RuntimeError):
      test_plan_kicker.KickTestPlan(test_plan.key.id())
    self.assertEqual(create_test_run.call_count,
                     1 + test_plan_kicker.MAX_RETRY_COUNT)
    set_test_run_state.assert_called_once_with('test_run_id',
                                               ndb_models.TestRunState.CANCELED)
    # Stores the canceled test run key and the error message
    status = ndb_models.TestPlanStatus.query(ancestor=test_plan.key).get()
    self.assertEqual(status.last_run_keys, [test_run.key])
    self.assertEqual(status.last_run_error, 'test_run_error')
  def testKickTestPlan_invalidTask(self):
    """Tests that a test plan kick is skipped if the task is invalid."""
    test_plan = ndb_models.TestPlan(name='test_plan')
    test_plan.put()
    ndb_models.TestPlanStatus(
        parent=test_plan.key, next_run_task_name='task_name').put()

    executed = test_plan_kicker.KickTestPlan(
        test_plan.key.id(), task_name='invalid_task_name')
    self.assertFalse(executed)
  def testKickTestPlan(self, create_test_run):
    """Tests that a test plan can be kicked off."""
    test = ndb_models.Test(id='test_id')
    test_device_action = ndb_models.DeviceAction(id='test_device_action')
    test_run_action = ndb_models.TestRunAction(id='test_run_action')
    # Create a test plan with multiple resources and actions
    test_plan = ndb_models.TestPlan(
        name='test_plan',
        labels=['label'],
        cron_exp='0 0 * * *',
        test_run_configs=[
            ndb_models.TestRunConfig(
                test_key=test.key,
                cluster='cluster',
                run_target='run_target',
                before_device_action_keys=[test_device_action.key],
                test_run_action_refs=[
                    ndb_models.TestRunActionRef(action_key=test_run_action.key),
                ],
                test_resource_objs=[
                    ndb_models.TestResourceObj(name='res_1', url='url_1')]),
        ])
    test_plan.put()
    # Test run will be created successfully
    test_run = ndb_models.TestRun(id='test_run_id')
    create_test_run.return_value = test_run

    executed = test_plan_kicker.KickTestPlan(test_plan.key.id())
    self.assertTrue(executed)

    # Test run is created with the right test and test plan components
    create_test_run.assert_called_with(
        labels=['label'],
        test_plan_key=test_plan.key,
        test_run_config=ndb_models.TestRunConfig(
            test_key=test.key,
            cluster='cluster',
            run_target='run_target',
            before_device_action_keys=[test_device_action.key],
            test_run_action_refs=[
                ndb_models.TestRunActionRef(action_key=test_run_action.key),
            ],
            test_resource_objs=[
                ndb_models.TestResourceObj(name='res_1', url='url_1')
            ]),
        )
    # Test run key is stored in the test plan status
    status = ndb_models.TestPlanStatus.query(ancestor=test_plan.key).get()
    self.assertEqual(status.last_run_keys, [test_run.key])
Example #4
0
    def Run(self, request):
        """Runs a test plan immediately.

    Parameters:
      test_plan_id: Test plan ID
    """
        test_plan = mtt_messages.ConvertToKey(ndb_models.TestPlan,
                                              request.test_plan_id).get()
        if not test_plan:
            raise endpoints.NotFoundException('Test plan %s does not exist' %
                                              request.test_plan_id)
        if not test_plan.test_run_configs:
            raise endpoints.BadRequestException(
                'No test run configs with ID %s' % request.test_plan_id)
        test_plan_kicker.KickTestPlan(test_plan.key.id())
        # TODO: returns a test plan job object.
        return message_types.VoidMessage()
  def testKickTestPlan_withRetry(self, create_test_run):
    """Tests that a test plan kick operations can be retried."""
    test = ndb_models.Test(id='test_id')
    test_run_config = ndb_models.TestRunConfig(
        test_key=test.key, cluster='cluster', run_target='run_target')
    test_plan = ndb_models.TestPlan(
        name='test_plan', test_run_configs=[test_run_config])
    test_plan.put()
    # First test run creation fails, but second attempt succeeds
    test_run = ndb_models.TestRun(id='test_run_id')
    create_test_run.side_effect = [RuntimeError('test_run_error'), test_run]

    executed = test_plan_kicker.KickTestPlan(test_plan.key.id())
    self.assertTrue(executed)

    # Create test run operation retried until successful
    self.assertEqual(create_test_run.call_count, 2)
    status = ndb_models.TestPlanStatus.query(ancestor=test_plan.key).get()
    # Test run key stored and error message is empty
    self.assertEqual(status.last_run_keys, [test_run.key])
    self.assertIsNone(status.last_run_error)
 def testKickTestPlan_notFound(self):
   """Tests that a test plan kick is skipped if the plan is not found."""
   test_plan = ndb_models.TestPlan(id='unknown')
   executed = test_plan_kicker.KickTestPlan(test_plan.key.id())
   self.assertFalse(executed)