def Delete(url):
    """Removes a config set info and its related objects.

  Args:
    url: source url of the config set to remove
  """

    prefix = ''.join([url, config_encoder.NAMESPACE_SEPARATOR])

    # Remove Test Suites
    test_keys = _GetEntityKeysByPrefix(ndb_models.Test, prefix)
    ndb.delete_multi(test_keys)

    # Remove Device Actions
    device_action_keys = _GetEntityKeysByPrefix(ndb_models.DeviceAction,
                                                prefix)
    ndb.delete_multi(device_action_keys)

    # Remove Test Run Actions
    test_run_action_keys = _GetEntityKeysByPrefix(ndb_models.TestRunAction,
                                                  prefix)
    ndb.delete_multi(test_run_action_keys)

    # Remove Config Set Info
    config_set_info_key = mtt_messages.ConvertToKey(ndb_models.ConfigSetInfo,
                                                    url)
    config_set_info_key.delete()
예제 #2
0
    def _ApplyQueryFilters(self, query, request):
        """Applies simple predicates (equality, AND) to a test run query."""
        if request.labels:
            for label in request.labels:
                query = query.filter(ndb_models.TestRunSummary.labels == label)

        if request.test:
            query = query.filter(
                ndb_models.TestRunSummary.test_name == request.test)

        if request.device_specs:
            query = query.filter(
                ndb_models.TestRunSummary.device_specs == request.device_specs)

        if request.test_package_info:
            filter_data = request.test_package_info.split()
            query = query.filter(
                ndb_models.TestRunSummary.test_package_info.name
                == filter_data[0]
                and ndb_models.TestRunSummary.test_package_info.version
                == filter_data[1])

        if request.prev_test_run_id:
            prev_key = mtt_messages.ConvertToKey(ndb_models.TestRun,
                                                 request.prev_test_run_id)
            query = query.filter(
                ndb_models.TestRunSummary.prev_test_run_key == prev_key)

        return query
  def testListSummaries_filterReruns(self):
    test = self._createMockTest()
    test_run = self._createMockTestRunSummaries(test=test)[0]

    res = self.app.get('/_ah/api/mtt/v1/test_runs?prev_test_run_id=%s' %
                       test_run.key.id())
    self.assertEqual('200 OK', res.status)
    test_run_msg = protojson.decode_message(messages.TestRunSummaryList,
                                            res.body).test_runs
    self.assertEqual(test_run_msg, [])

    test_run_key = messages.ConvertToKey(ndb_models.TestRun, test_run.key.id())
    retry_run = self._createMockTestRunSummaries(
        test=test, prev_test_run_key=test_run_key)[0]
    retry_run_msg = messages.Convert(retry_run, messages.TestRunSummary)
    separate_retry = self._createMockTestRunSummaries(
        test=test, prev_test_run_key=test_run_key)[0]
    separate_retry_msg = messages.Convert(separate_retry,
                                          messages.TestRunSummary)

    res = self.app.get('/_ah/api/mtt/v1/test_runs?prev_test_run_id=%s' %
                       test_run.key.id())
    test_run_msg = protojson.decode_message(messages.TestRunSummaryList,
                                            res.body).test_runs
    self.assertEqual(test_run_msg[0].id, separate_retry_msg.id)
    self.assertEqual(test_run_msg[1].id, retry_run_msg.id)
예제 #4
0
    def _Delete(self, test_run_id):
        """Deletes a test run and all related files if it is in a final state."""
        test_run_key = mtt_messages.ConvertToKey(ndb_models.TestRun,
                                                 test_run_id)
        test_run = test_run_key.get()

        if not test_run:
            raise endpoints.NotFoundException('Test run %s not found' %
                                              test_run_id)

        if not test_run.IsFinal():
            raise endpoints.BadRequestException(
                'Cannot delete non-final test run %s' % test_run_id)

        # Remove output files
        if test_run.output_path is not None:
            output_folder_url = file_util.GetAppStorageUrl(
                [test_run.output_path])
            output_folder = file_util.FileHandle.Get(output_folder_url)
            output_folder.DeleteDir()

        # Delete test results database
        with sql_models.db.Session() as session:
            session.query(sql_models.TestModuleResult).filter_by(
                test_run_id=test_run_id).delete()

        test_run_key.delete()
예제 #5
0
def _GetTestPlanAndStatus(test_plan_id):
    """Fetch a test plan and its status."""
    test_plan = messages.ConvertToKey(ndb_models.TestPlan, test_plan_id).get()
    if not test_plan:
        logging.warning('Test plan %s not found', test_plan_id)
        return None, None
    status = ndb_models.TestPlanStatus.query(ancestor=test_plan.key).get()
    return test_plan, status or ndb_models.TestPlanStatus(parent=test_plan.key)
 def _CreateMockDeviceAction(self,
                             action_id='action.id',
                             name='device action name'):
     """Creates a mock ndb_models.DeviceAction object."""
     device_action = ndb_models.DeviceAction(name=name)
     device_action.key = mtt_messages.ConvertToKey(ndb_models.DeviceAction,
                                                   action_id)
     device_action.put()
     return device_action
예제 #7
0
    def Delete(self, request):
        """Deletes a test suite.

    Parameters:
      test_id: Test ID
    """
        test_key = mtt_messages.ConvertToKey(ndb_models.Test, request.test_id)
        test_key.delete()
        return message_types.VoidMessage()
예제 #8
0
    def Delete(self, request):
        """Deletes an existing device action.

    Parameters:
      device_action_id: Device action ID
    """
        device_action_key = mtt_messages.ConvertToKey(ndb_models.DeviceAction,
                                                      request.device_action_id)
        device_action_key.delete()
        return message_types.VoidMessage()
  def Delete(self, request):
    """Deletes a build channel.

    Parameters:
      build_channel_id: Build channel ID
    """
    build_channel_key = mtt_messages.ConvertToKey(
        ndb_models.BuildChannelConfig, request.build_channel_id)
    build_channel_key.delete()
    return message_types.VoidMessage()
예제 #10
0
    def testRun(self, mock_test_plan_runner):
        """Tests test_plans.run API."""
        test_run_config = ndb_models.TestRunConfig(
            cluster='cluster',
            test_key=messages.ConvertToKey(ndb_models.Test, 'test'),
            run_target='target')
        test_plan = _CreateMockTestPlan('foo',
                                        test_run_configs=[test_run_config])

        self.app.post('/_ah/api/mtt/v1/test_plans/%s/run' % test_plan.key.id())
        mock_test_plan_runner.assert_called_with(test_plan.key.id())
예제 #11
0
    def Get(self, request):
        """Fetches a device action.

    Parameters:
      device_action_id: Device action ID
    """
        if request.device_action_id == '0':
            device_action = ndb_models.DeviceAction(name='')
        else:
            device_action = mtt_messages.ConvertToKey(
                ndb_models.DeviceAction, request.device_action_id).get()
        if not device_action:
            raise endpoints.NotFoundException('No device action with ID %s' %
                                              request.device_action_id)
        return mtt_messages.Convert(device_action, mtt_messages.DeviceAction)
예제 #12
0
    def Get(self, request):
        """Fetches a test suite.

    Parameters:
      test_id: Test ID, or zero for an empty test suite
    """
        if request.test_id == '0':
            # For ID 0, return an empty test object to use as a template in UI.
            test = ndb_models.Test(name='')
        else:
            test = mtt_messages.ConvertToKey(ndb_models.Test,
                                             request.test_id).get()
        if not test:
            raise endpoints.NotFoundException('no test found for ID %s' %
                                              request.test_id)
        return mtt_messages.Convert(test, mtt_messages.Test)
예제 #13
0
    def Get(self, request):
        """Fetches a test plan.

    Parameters:
      test_plan_id: Test plan ID, or zero for an empty test plan
    """
        if request.test_plan_id == '0':
            # For ID 0, return an empty test plan object to use as a template in UI.
            test_plan = ndb_models.TestPlan(id=0, name='')
        else:
            test_plan = mtt_messages.ConvertToKey(ndb_models.TestPlan,
                                                  request.test_plan_id).get()
        if not test_plan:
            raise endpoints.NotFoundException('No test plan with ID %s' %
                                              request.test_plan_id)
        return mtt_messages.Convert(test_plan, mtt_messages.TestPlan)
예제 #14
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()
예제 #15
0
    def Update(self, request):
        """Updates an existing device action.

    Body:
      Device action data
    Parameters:
      device_action_id: Device action ID
    """
        device_action = mtt_messages.ConvertToKey(
            ndb_models.DeviceAction, request.device_action_id).get()
        if not device_action:
            raise endpoints.NotFoundException(
                'no device action found for ID %s' % request.device_action_id)
        request.id = request.device_action_id
        device_action = mtt_messages.Convert(request, ndb_models.DeviceAction,
                                             mtt_messages.DeviceAction)
        device_action.put()
        return mtt_messages.Convert(device_action, mtt_messages.DeviceAction)
예제 #16
0
    def Update(self, request):
        """Updates a test suite.

    Body:
      Test suite data
    Parameters:
      test_id: Test ID
    """
        test = mtt_messages.ConvertToKey(ndb_models.Test,
                                         request.test_id).get()
        if not test:
            raise endpoints.NotFoundException('no test found for ID %s' %
                                              request.test_id)
        request.id = request.test_id
        test = mtt_messages.Convert(request, ndb_models.Test,
                                    mtt_messages.Test)
        test.put()
        return mtt_messages.Convert(test, mtt_messages.Test)
 def testCreate(self):
     data = {
         'name': 'testName',
         'id': '',
         'provider_name': 'Android',
         'options': [{
             'name': 'mock_option',
             'value': '123123123'
         }]
     }
     res = self.app.post_json('/_ah/api/mtt/v1/build_channels', data)
     msg = protojson.decode_message(messages.BuildChannelConfig, res.body)
     build_channel_config = messages.ConvertToKey(
         ndb_models.BuildChannelConfig, msg.id).get()
     self.assertIsNotNone(build_channel_config)
     self.assertEqual(data['name'], build_channel_config.name)
     self.assertEqual(data['provider_name'],
                      build_channel_config.provider_name)
     self.assertEqual(data['options'][0]['name'],
                      build_channel_config.options[0].name)
예제 #18
0
    def Update(self, request):
        """Updates a test plan.

    Body:
      Test plan data
    Parameters:
      test_plan_id: Test plan ID
    """
        test_plan_key = mtt_messages.ConvertToKey(ndb_models.TestPlan,
                                                  request.test_plan_id)
        if not test_plan_key.get():
            raise endpoints.NotFoundException()
        test_plan = mtt_messages.Convert(request,
                                         ndb_models.TestPlan,
                                         from_cls=mtt_messages.TestPlan)
        _ValidateTestPlan(test_plan)
        test_plan.key = test_plan_key
        test_plan.put()
        test_scheduler.ScheduleTestPlanCronJob(test_plan.key.id())
        return mtt_messages.Convert(test_plan, mtt_messages.TestPlan)
    def testCreate(self):
        data = {
            'name':
            'foo',
            'description':
            'description',
            'test_resource_defs': [
                {
                    'name': 'resource',
                    'default_download_url': 'resource_url'
                },
            ],
            'tradefed_target_preparers': [{
                'class_name':
                'com.android.foo',
                'option_values': [{
                    'name': 'option',
                    'values': ['value', 'value2']
                }]
            }]
        }

        res = self.app.post_json('/_ah/api/mtt/v1/device_actions', data)
        msg = protojson.decode_message(messages.DeviceAction, res.body)
        device_action = messages.ConvertToKey(ndb_models.DeviceAction,
                                              msg.id).get()
        self.assertIsNotNone(device_action)
        self.assertEqual(data['name'], device_action.name)
        self.assertEqual(data['description'], device_action.description)
        for d, obj in zip(data['test_resource_defs'],
                          device_action.test_resource_defs):
            self.assertEqual(d['name'], obj.name)
            self.assertEqual(d['default_download_url'],
                             obj.default_download_url)
        self.assertEqual(data['tradefed_target_preparers'][0]['class_name'],
                         device_action.tradefed_target_preparers[0].class_name)
        for d, obj in zip(
                data['tradefed_target_preparers'][0]['option_values'],
                device_action.tradefed_target_preparers[0].option_values):
            self.assertEqual(d['name'], obj.name)
            self.assertEqual(d['values'], obj.values)
예제 #20
0
def _ValidateTestPlan(test_plan):
    """Check validity of a given test plan.

  Args:
    test_plan: a ndb_models.TestPlan object.
  """
    if test_plan.cron_exp and not _IsValidCronExpression(test_plan.cron_exp):
        raise endpoints.BadRequestException((
            'Invalid cron expression (%s). Cron expression should be ordered as '
            'minute, hour, day of month, month, day of week.') %
                                            test_plan.cron_exp)

    plan_device_actions = ndb.get_multi(test_plan.before_device_action_keys)
    if not all(plan_device_actions):
        raise endpoints.BadRequestException(
            'Cannot find some device actions: %s -> %s' %
            (test_plan.before_device_action_keys, plan_device_actions))

    for config in test_plan.test_run_configs:
        if not config.test_key.get():
            raise endpoints.BadRequestException('test %s does not exist' %
                                                config.test_key.id())

        config_device_actions = ndb.get_multi(config.before_device_action_keys)
        if not all(config_device_actions):
            raise endpoints.BadRequestException(
                'Cannot find some device actions: %s -> %s' %
                (config.before_device_action_keys, config_device_actions))
        test_kicker.ValidateDeviceActions(plan_device_actions +
                                          config_device_actions)

    for pipe in test_plan.test_resource_pipes:
        build_locator = build.BuildLocator.ParseUrl(pipe.url)
        if build_locator and not mtt_messages.ConvertToKey(
                ndb_models.BuildChannelConfig,
                build_locator.build_channel_id).get():
            raise endpoints.BadRequestException(
                'build channel %s does not exist' %
                build_locator.build_channel_id)
 def _GetTestRunActionKey(self, action_id):
     """Convert a test run action ID to a key."""
     return mtt_messages.ConvertToKey(ndb_models.TestRunAction, action_id)
 def _CreateMockTest(self, test_id='test.id', name='test name'):
     """Creates a mock ndb_models.Test object."""
     test = ndb_models.Test(name=name, command='command')
     test.key = mtt_messages.ConvertToKey(ndb_models.Test, test_id)
     test.put()
     return test