예제 #1
0
class TestPlan(ndb.Model):
    """A test plan.

  Attributes:
    name: a test resource name.
    labels: list of strings users can use to categorize test runs and plans.
    cron_exp: a CRON expression.
    cron_exp_timezone: timezone to use when processing cron expression.
    test_run_configs: a list of test run configs.
    test_resource_pipes: a list of test resource pipes.
    before_device_action_keys: common before device actions for tests.
    test_run_action_refs: common test run actions to execute during tests.
  """
    name = ndb.StringProperty(required=True)
    labels = ndb.StringProperty(repeated=True)
    cron_exp = ndb.StringProperty()
    cron_exp_timezone = ndb.StringProperty(default='UTC')
    test_run_configs = ndb.LocalStructuredProperty(TestRunConfig,
                                                   repeated=True)
    test_resource_pipes = ndb.LocalStructuredProperty(
        TestResourcePipe, repeated=True)  # TODO: Deprecated
    before_device_action_keys = ndb.KeyProperty(
        DeviceAction, repeated=True)  # TODO: Deprecated
    test_run_action_refs = ndb.LocalStructuredProperty(TestRunActionRef,
                                                       repeated=True)

    @classmethod
    def _post_delete_hook(cls, key, future):
        status = TestPlanStatus.query(ancestor=key).get()
        if status:
            status.key.delete()
예제 #2
0
class NodeConfig(ndb.Model):
    """A MTT node configuration.

  Attributes:
    env_vars: default environment vars.
    test_resource_default_download_urls: default download URLs for test
        resources.
  """
    env_vars = ndb.LocalStructuredProperty(NameValuePair, repeated=True)
    test_resource_default_download_urls = ndb.LocalStructuredProperty(
        NameValuePair, repeated=True)
예제 #3
0
class TestRunConfig(ndb.Model):
    """A test run config.

  Attributes:
    test_key: a Test key.
    cluster: a cluster to run a test in.
    command: the command to run the test suite
    retry_command: the command to retry this test run
    device_specs: device requirements expressed in space-separated list of
        key-value pairs (e.g. "product:bramble sim_state:LOADED").
    run_target: (deprecated) a run target. Only used when device_specs is empty.
    run_count: a run count.
    shard_count: a shard count.
    sharding_mode: a sharding mode.
    extra_args: a string containing extra arguments.
    retry_extra_args: extra arguments used when retrying.
    max_retry_on_test_failures: the max number of retry on test failure.
    queue_timeout_seconds: how long a test run can stay in QUEUED state before
        being cancelled
    invocation_timeout_seconds: the maximum time for each invocation to run. If
        an invocation(attempt) runs longer than a given timeout, it would be
        force stopped.
    output_idle_timeout_seconds: how long a test run's output can be idle before
        attempting recovery
    before_device_action_keys: device actions to execute before running a test.
    test_run_action_refs: test run actions to execute during a test.
    test_resource_objs: path to the files to use for test resources.
    use_parallel_setup: a flag on whether to setup devices in parallel.
  """
    test_key = ndb.KeyProperty(kind=Test, required=True)
    cluster = ndb.StringProperty(required=True)
    command = ndb.StringProperty(required=True, default='')
    retry_command = ndb.StringProperty(required=True, default='')
    device_specs = ndb.StringProperty(repeated=True)
    run_target = ndb.StringProperty()
    run_count = ndb.IntegerProperty(required=True, default=1)
    shard_count = ndb.IntegerProperty(required=True, default=1)
    sharding_mode = ndb.EnumProperty(ShardingMode, default=ShardingMode.RUNNER)
    extra_args = ndb.StringProperty()  # TODO: Deprecated
    retry_extra_args = ndb.StringProperty()  # TODO: Deprecated
    max_retry_on_test_failures = ndb.IntegerProperty()
    queue_timeout_seconds = ndb.IntegerProperty(
        required=True, default=env.DEFAULT_QUEUE_TIMEOUT_SECONDS)
    invocation_timeout_seconds = ndb.IntegerProperty(
        default=env.DEFAULT_INVOCATION_TIMEOUT_SECONDS)
    output_idle_timeout_seconds = ndb.IntegerProperty(
        default=env.DEFAULT_OUTPUT_IDLE_TIMEOUT_SECONDS)
    before_device_action_keys = ndb.KeyProperty(DeviceAction, repeated=True)
    test_run_action_refs = ndb.LocalStructuredProperty(TestRunActionRef,
                                                       repeated=True)
    test_resource_objs = ndb.LocalStructuredProperty(TestResourceObj,
                                                     repeated=True)
    use_parallel_setup = ndb.BooleanProperty(default=True)
예제 #4
0
class TestContextObj(ndb.Model):
    """A test context object.

  The "Obj" suffix was added to avoid name collision with TFC TestContext.

  Attributes:
    command_line: a command line.
    env_vars: environment variables.
    test_resources: a list of TestResourceObj objects.
  """
    command_line = ndb.StringProperty()
    env_vars = ndb.LocalStructuredProperty(NameValuePair, repeated=True)
    test_resources = ndb.LocalStructuredProperty(TestResourceObj,
                                                 repeated=True)
예제 #5
0
class TestResourceDef(ndb.Model):
    """A test resource definition.

  Attributes:
    name: a test resource name.
    default_download_url: a default download URL.
    test_resource_type: a test resource type.
    decompress: whether the host should decompress the downloaded file.
    decompress_dir: the directory where the host decompresses the file.
    mount_zip: whether to mount zip file.
    params: test resource parameters.
  """
    name = ndb.StringProperty(required=True)
    default_download_url = ndb.StringProperty()
    test_resource_type = ndb.EnumProperty(TestResourceType)
    decompress = ndb.BooleanProperty()
    decompress_dir = ndb.StringProperty()
    mount_zip = ndb.BooleanProperty()
    params = ndb.LocalStructuredProperty(TestResourceParameters)

    def ToTestResourceObj(self):
        """Create a TestResourceObj from this definition."""
        return TestResourceObj(name=self.name,
                               url=self.default_download_url,
                               test_resource_type=self.test_resource_type,
                               decompress=self.decompress or False,
                               decompress_dir=self.decompress_dir or '',
                               mount_zip=self.mount_zip or False,
                               params=TestResourceParameters.Clone(
                                   self.params))
예제 #6
0
class TradefedConfigObject(ndb.Model):
    """A Tradefed object and its options.

  Attributes:
    class_name: a Tradefed config class name.
    option_values: a list of option name and value pairs.
  """
    class_name = ndb.StringProperty(required=True)
    option_values = ndb.LocalStructuredProperty(NameMultiValuePair,
                                                repeated=True)
예제 #7
0
class TestRunAction(ndb.Model):
    """Test run action, describes a specific hook execution.

  Attributes:
    name: action name.
    description: action description.
    hook_class_name: run hook class identifier.
    phases: phases during which hook should be triggered.
    options: key-value pairs to use when configuring the hook.
    tradefed_result_reporters: list of TF result reporters.
    credentials: stored OAuth2 credentials.
  """
    name = ndb.StringProperty(required=True)
    description = ndb.StringProperty()
    hook_class_name = ndb.StringProperty(required=True)
    phases = ndb.EnumProperty(TestRunPhase, repeated=True)
    options = ndb.LocalStructuredProperty(NameValuePair, repeated=True)
    tradefed_result_reporters = ndb.LocalStructuredProperty(
        TradefedConfigObject, repeated=True)
    credentials = oauth2_util.CredentialsProperty()
예제 #8
0
class DeviceAction(ndb.Model):
    """A device action.

  Attributes:
    name: a device action name.
    description: a description.
    test_resource_defs: a list of test resource definitions.
    tradefed_target_preparers: a list of Tradefed target preparers.
    device_type: the type of the devices that require the device action.
    tradefed_options: key-value pairs to be added to Tradefed configuration.
  """
    name = ndb.StringProperty(required=True)
    description = ndb.StringProperty()
    test_resource_defs = ndb.LocalStructuredProperty(TestResourceDef,
                                                     repeated=True)
    tradefed_target_preparers = ndb.LocalStructuredProperty(
        TradefedConfigObject, repeated=True)
    device_type = ndb.StringProperty()
    tradefed_options = ndb.LocalStructuredProperty(NameMultiValuePair,
                                                   repeated=True)
예제 #9
0
class TestRunSequence(ndb.Model):
    """A list of test run configs to be scheduled as retries.

  Attributes:
    state: completion state for this sequence
    test_run_configs: remaining retries to schedule
    finished_test_run_ids: list of completed runs scheduled for this sequence
  """
    state = ndb.EnumProperty(TestRunSequenceState, required=True)
    test_run_configs = ndb.LocalStructuredProperty(TestRunConfig,
                                                   repeated=True)
    finished_test_run_ids = ndb.StringProperty(repeated=True)
예제 #10
0
class TestRunActionRef(ndb.Model):
    """Test run action reference, with additional overridden options.

  Attributes:
    action_key: test run action to execute.
    options: additional key-value pairs to use when configuring the hook.
  """
    action_key = ndb.KeyProperty(TestRunAction, required=True)
    options = ndb.LocalStructuredProperty(NameValuePair, repeated=True)

    def ToAction(self):
        """Converts this ref into a test run action."""
        action = self.action_key.get()
        if not action:
            raise ValueError('Test run action %s not found' % self.action_key)
        options = NameValuePair.ToDict(action.options or [])
        options.update(NameValuePair.ToDict(self.options or []))
        action.options = NameValuePair.FromDict(options)
        return action
예제 #11
0
class Test(ndb.Model):
    """A test.

  Attributes:
    name: a test name.
    description: user-friendly string that describes the test suite.
    test_resource_defs: a list of test resource definitions.
    command: a TF command line.
    env_vars: a dict of environment variables to set before running a test.
    output_file_patterns: a list of file patterns to collect after a test run.
    result_file: XML result file path.
    setup_scripts: a list of scripts to run before running a test.
    jvm_options: a list of JVM options to be passed to TF.
    java_properties: a dict of Java properties to be passed to TF.
    context_file_dir: directory where the context file which needs to be
        passed across attempts is located.
    context_file_pattern: a regex pattern for the filename of the context file
        which needs to be passed across attempts.
    retry_command_line: a command line to use in retry invocations.
        attempts.
    runner_sharding_args: extra args to enable runner sharding. It can contain
        a reference to a desired shard count (e.g. ${TF_SHARD_COUNT})
    default_test_run_parameters: default test run parameters.
    module_config_pattern: a regex pattern for module config files.
    module_execution_args: extra args to run a specific module.
  """
    name = ndb.StringProperty(required=True)
    description = ndb.StringProperty()
    test_resource_defs = ndb.StructuredProperty(TestResourceDef, repeated=True)
    command = ndb.StringProperty(required=True)
    env_vars = ndb.StructuredProperty(NameValuePair, repeated=True)
    output_file_patterns = ndb.StringProperty(repeated=True)
    result_file = ndb.StringProperty()
    setup_scripts = ndb.StringProperty(repeated=True)
    jvm_options = ndb.StringProperty(repeated=True)
    java_properties = ndb.StructuredProperty(NameValuePair, repeated=True)
    context_file_dir = ndb.StringProperty()
    context_file_pattern = ndb.StringProperty()
    retry_command_line = ndb.StringProperty()
    runner_sharding_args = ndb.StringProperty()
    default_test_run_parameters = ndb.LocalStructuredProperty(TestRunParameter)
    module_config_pattern = ndb.StringProperty()
    module_execution_args = ndb.StringProperty()
예제 #12
0
class TestResourceObj(ndb.Model):
    """A test resource object.

  The "Obj" suffix was added to avoid name collistion with TFC TestResource.

  Attributes:
    name: a test resource name.
    url: a URL.
    cache_url: a URL for a cached copy.
    test_resource_type: a test resource type.
    decompress: whether the host should decompress the downloaded file.
    decompress_dir: the directory where the host decompresses the file.
    mount_zip: whether to mount a zip file.
    params: test resource parameters.
  """
    name = ndb.StringProperty(required=True)
    url = ndb.StringProperty()
    cache_url = ndb.StringProperty()
    test_resource_type = ndb.EnumProperty(TestResourceType)
    decompress = ndb.BooleanProperty()
    decompress_dir = ndb.StringProperty()
    mount_zip = ndb.BooleanProperty()
    params = ndb.LocalStructuredProperty(TestResourceParameters)
예제 #13
0
class TestRun(ndb.Model):
    """A test run.

  Attributes:
    prev_test_run_key: previous (parent) test run key.
    user: a user who scheduled a test run.
    labels: list of strings users can use to categorize test runs.
    test_plan_key: a test plan key.
    test: a Test object copy made at the test run schedule time.
    test_run_config: a TestRunConfig object.
    test_resources: a list of TestResourceObj objects.
    state: a test run state.
    is_finalized: True if post-run handlers were executed.
    output_path: a path to store test outputs to.
    output_url: a test output URL.
    prev_test_context: a previous test context object.
    next_test_context: a test context object from this test run.
    test_package_info: a test package information
    test_devices: a list of TestDeviceInfo of DUTs
    request_id: a TFC request ID.
    sequence_id: a TestRunSequence ID.
    total_test_count: the number of total test cases.
    failed_test_count: the number of failed test cases.
    failed_test_run_count: the number of test modules that failed to execute.
    create_time: time a test run is created.
    update_time: time a test run is last updated.
    before_device_actions: device actions used during the run.
    test_run_actions: test run actions executed during the run.
    hook_data: additional data used by hooks
    cancel_reason: cancellation reason
    error_reason: error reason
  """
    prev_test_run_key = ndb.KeyProperty(kind='TestRun')
    user = ndb.StringProperty()
    labels = ndb.StringProperty(repeated=True)
    test_plan_key = ndb.KeyProperty(TestPlan)
    test = ndb.StructuredProperty(Test)
    test_run_config = ndb.StructuredProperty(TestRunConfig)
    test_resources = ndb.StructuredProperty(TestResourceObj, repeated=True)
    state = ndb.EnumProperty(TestRunState, default=TestRunState.UNKNOWN)
    is_finalized = ndb.BooleanProperty()
    output_path = ndb.StringProperty()
    output_url = ndb.StringProperty()
    prev_test_context = ndb.LocalStructuredProperty(TestContextObj)
    next_test_context = ndb.LocalStructuredProperty(TestContextObj)
    test_package_info = ndb.StructuredProperty(TestPackageInfo)
    test_devices = ndb.StructuredProperty(TestDeviceInfo, repeated=True)
    request_id = ndb.StringProperty()
    sequence_id = ndb.StringProperty()
    total_test_count = ndb.IntegerProperty()
    failed_test_count = ndb.IntegerProperty()
    failed_test_run_count = ndb.IntegerProperty()

    create_time = ndb.DateTimeProperty(auto_now_add=True)
    update_time = ndb.DateTimeProperty(auto_now_add=True)

    # TODO improve action versioning
    # Snapshot of the actions executed by the run
    before_device_actions = ndb.LocalStructuredProperty(DeviceAction,
                                                        repeated=True)
    test_run_actions = ndb.LocalStructuredProperty(TestRunAction,
                                                   repeated=True)
    hook_data = ndb.JsonProperty(default={})

    cancel_reason = ndb.EnumProperty(common.CancelReason)
    error_reason = ndb.StringProperty()

    @classmethod
    def get_by_id(cls, id_, **kwargs):
        try:
            # support numeric (legacy) and uuid identifiers
            id_ = int(id_)
        except ValueError:
            pass
        return TestRun._get_by_id(id_, **kwargs)

    def _post_put_hook(self, future):
        self.ToSummary().put()

    @classmethod
    def _post_delete_hook(cls, key, future):
        ndb.delete_multi(ndb.Query(ancestor=key).iter(keys_only=True))

    def ToSummary(self):
        return TestRunSummary(parent=self.key,
                              id=self.key.id(),
                              prev_test_run_key=self.prev_test_run_key,
                              labels=self.labels,
                              test_name=self.test.name if self.test else None,
                              device_specs=(self.test_run_config.device_specs
                                            if self.test_run_config else []),
                              run_target=(self.test_run_config.run_target
                                          if self.test_run_config else None),
                              state=self.state,
                              test_package_info=self.test_package_info,
                              test_devices=self.test_devices,
                              total_test_count=self.total_test_count,
                              failed_test_count=self.failed_test_count,
                              failed_test_run_count=self.failed_test_run_count,
                              create_time=self.create_time,
                              update_time=self.update_time)

    def IsFinal(self):
        """Returns whether a test run is in a final state.

    Returns:
      True if a test run is in a final state. Otherwise false.
    """
        return self.state in FINAL_TEST_RUN_STATES

    def IsRerun(self):
        """Checks whether this is a rerun of another test run."""
        return self.prev_test_context is not None

    def IsLocalRerun(self):
        """Checks whether this is a rerun using a local test run ID."""
        return self.prev_test_run_key is not None

    def IsRemoteRerun(self):
        """Checks whether this is a rerun using an uploaded context file."""
        return self.IsRerun() and not self.IsLocalRerun()

    def GetRerunContextFile(self):
        """Fetches the rerun context file if it exists."""
        if not self.prev_test_context or not self.prev_test_context.test_resources:
            return None
        return self.prev_test_context.test_resources[0]

    def GetContext(self):
        """Returns a test run context dictionary."""
        ctx = {
            'MTT_USER':
            env.USER,
            'MTT_HOSTNAME':
            env.HOSTNAME,
            'MTT_VERSION':
            env.VERSION,
            'MTT_TEST_RUN_ID':
            self.key.id(),
            'MTT_TEST_ID':
            self.test_run_config.test_key.id(),
            'MTT_TEST_NAME':
            self.test.name,
            'MTT_TEST_PLAN_NAME':
            (self.test_plan_key.get().name if self.test_plan_key else ''),
            'MTT_TEST_RUN_CREATE_TIMESTAMP':
            ToTimestamp(self.create_time),
            'MTT_TEST_RUN_CREATE_TIMESTAMP_MILLIS':
            ToTimestamp(self.create_time) * 1000,
        }

        test_resource_map = {}
        for r in self.test_resources:
            m = re.match(r'mtt:///android_ci/(\S+)/(\S+)/(\S+)/.*', r.url)
            if m:
                test_resource_map[r.test_resource_type] = [
                    r.url, m.group(1),
                    m.group(2), m.group(3)
                ]
            else:
                test_resource_map[r.test_resource_type] = [
                    r.url, None, None, None
                ]
        for t in TestResourceType:
            if t == TestResourceType.UNKNOWN:
                continue
            url, branch, target, build_id = test_resource_map.get(
                t, [None, None, None, None])
            ctx['MTT_%s_URL' % t.name] = url or ''
            ctx['MTT_%s_BRANCH' % t.name] = branch or ''
            ctx['MTT_%s_BUILD_ID' % t.name] = build_id or ''
            ctx['MTT_%s_TARGET' % t.name] = target or ''
        return ctx