示例#1
0
class TestRunSummary(ndb.Model):
    """Partial test run information.

  Attributes:
    prev_test_run_key: ID of the previous (parent) test run.
    labels: list of strings users can use to categorize test runs.
    test_name: name of the Test to run.
    device_specs: device specs.
    run_target: run target.
    state: a test run state.
    test_package_info: a test package information
    test_devices: a list of TestDeviceInfo of DUTs
    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.
  """
    prev_test_run_key = ndb.KeyProperty(kind='TestRun')
    labels = ndb.StringProperty(repeated=True)
    test_name = ndb.StringProperty()
    device_specs = ndb.StringProperty(repeated=True)
    run_target = ndb.StringProperty()
    state = ndb.EnumProperty(TestRunState, default=TestRunState.UNKNOWN)
    test_package_info = ndb.StructuredProperty(TestPackageInfo)
    test_devices = ndb.StructuredProperty(TestDeviceInfo, repeated=True)
    total_test_count = ndb.IntegerProperty()
    failed_test_count = ndb.IntegerProperty()
    failed_test_run_count = ndb.IntegerProperty()
    create_time = ndb.DateTimeProperty()
    update_time = ndb.DateTimeProperty()
示例#2
0
class TestRunParameter(ndb.Model):
    """Test run parameter.

  Attributes:
    max_retry_on_test_failures: the max number of retry on test failure.
    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
  """
    max_retry_on_test_failures = ndb.IntegerProperty()
    invocation_timeout_seconds = ndb.IntegerProperty()
    output_idle_timeout_seconds = ndb.IntegerProperty()
示例#3
0
class UpgradableModel(ndb.Model):
    """Represents a NDB model whose schema can change."""

    schema_version = ndb.IntegerProperty()

    @property
    def _upgrade_steps(self):
        """A list of functions that actually perform the upgrades.

    Classes which extend UpgradableModel should override this.
    """
        raise NotImplementedError(
            'Upgradable models must specify _upgrade_steps')

    def _pre_put_hook(self):
        if self.schema_version is None:
            self.schema_version = len(self._upgrade_steps)

    @classmethod
    def _post_get_hook(cls, key, future):
        result = future.get_result()
        if result:
            result.Upgrade()

    def Upgrade(self):
        """Updates the object to the latest version if necessary.

    Raises:
      UpgradeError: If an upgrade step raises an exception.
      ValueError: If the object has a newer version than we know about.
    """
        if self.schema_version is None:
            self.schema_version = 0
        if self.schema_version > len(self._upgrade_steps):
            raise ValueError(
                'The schema version of the object is newer than the model.')
        if self.schema_version == len(self._upgrade_steps):
            return
        for step in self._upgrade_steps[self.schema_version:]:
            try:
                step(self)
            except Exception as e:
                raise UpgradeError(
                    'Something went wrong while performing {} on {}: {}'.
                    format(step.__name__,
                           self.key.urlsafe().decode(), e))
            self.schema_version += 1
        self.put()
示例#4
0
class PrivateNodeConfig(ndb.Model):
    """Non-shareable node configs.

  Attributes:
    ndb_version: Latest version the database has been updated to
    default_credentials: default service account credentials
    metrics_enabled: True to collect usage metrics.
    gms_client_id: Optional user-provided label to identify their company
    setup_wizard_completed: If false, trigger the setup wizard on startup
    server_uuid: node's unique identifier.
  """
    ndb_version = ndb.IntegerProperty()
    default_credentials = oauth2_util.CredentialsProperty()
    metrics_enabled = ndb.BooleanProperty()
    gms_client_id = ndb.StringProperty()
    setup_wizard_completed = ndb.BooleanProperty()
    server_uuid = ndb.StringProperty(required=True, default=str(uuid.uuid4()))
示例#5
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)
示例#6
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