Ejemplo n.º 1
0
    def __init__(self, pav_cfg, config,
                 build_tracker=None, var_man=None, _id=None,
                 rebuild=False, build_only=False):
        """Create an new TestRun object. If loading an existing test
    instance, use the ``TestRun.from_id()`` method.

:param pav_cfg: The pavilion configuration.
:param dict config: The test configuration dictionary.
:param builder.MultiBuildTracker build_tracker: Tracker for watching
    and managing the status of multiple builds.
:param variables.VariableSetManager var_man: The variable set manager for this
    test.
:param bool build_only: Only build this test run, do not run it.
:param bool rebuild: After determining the build name, deprecate it and select
    a new, non-deprecated build.
:param int _id: The test id of an existing test. (You should be using
    TestRun.load).
"""

        # Just about every method needs this
        self._pav_cfg = pav_cfg

        self.load_ok = True

        self.scheduler = config['scheduler']

        # Create the tests directory if it doesn't already exist.
        tests_path = pav_cfg.working_dir/'test_runs'

        self.config = config

        self.id = None  # pylint: disable=invalid-name

        self._attrs = {}

        # Mark the run to build locally.
        self.build_local = config.get('build', {}) \
                                 .get('on_nodes', 'false').lower() != 'true'

        # If a test access group was given, make sure it exists and the
        # current user is a member.
        self.group = config.get('group')
        if self.group is not None:
            try:
                group_data = grp.getgrnam(self.group)
                user = utils.get_login()
                if self.group != user and user not in group_data.gr_mem:
                    raise TestConfigError(
                        "Test specified group '{}', but the current user '{}' "
                        "is not a member of that group."
                        .format(self.group, user))
            except KeyError as err:
                raise TestConfigError(
                    "Test specified group '{}', but that group does not "
                    "exist on this system. {}"
                    .format(self.group, err))

        self.umask = config.get('umask')
        if self.umask is not None:
            try:
                self.umask = int(self.umask, 8)
            except ValueError:
                raise RuntimeError(
                    "Invalid umask. This should have been enforced by the "
                    "by the config format.")

        self.build_only = build_only
        self.rebuild = rebuild

        self.suite_path = None
        if self.config.get('suite_path') is not None:
            try:
                self.suite_path = Path(self.config['suite_path'])
            except ValueError:
                pass

        # Get an id for the test, if we weren't given one.
        if _id is None:
            self.id, self.path = self.create_id_dir(tests_path)
            with PermissionsManager(self.path, self.group, self.umask):
                self._save_config()
                if var_man is None:
                    var_man = variables.VariableSetManager()
                self.var_man = var_man
                self._variables_path = self.path / 'variables'
                self.var_man.save(self._variables_path)

            self.save_attributes()
        else:
            self.id = _id
            self.path = utils.make_id_path(tests_path, self.id)
            self._variables_path = self.path / 'variables'
            if not self.path.is_dir():
                raise TestRunNotFoundError(
                    "No test with id '{}' could be found.".format(self.id))
            try:
                self.var_man = variables.VariableSetManager.load(
                    self._variables_path
                )
            except RuntimeError as err:
                raise TestRunError(*err.args)

            self.load_attributes()

        name_parts = [
            self.config.get('suite', '<unknown>'),
            self.config.get('name', '<unnamed>'),
        ]
        subtitle = self.config.get('subtitle')
        # Don't add undefined or empty subtitles.
        if subtitle:
            name_parts.append(subtitle)

        self.name = '.'.join(name_parts)

        # Set a logger more specific to this test.
        self.logger = logging.getLogger('pav.TestRun.{}'.format(self.id))

        # This will be set by the scheduler
        self._job_id = None

        with PermissionsManager(self.path/'status', self.group, self.umask):
            # Setup the initial status file.
            self.status = StatusFile(self.path/'status')
            if _id is None:
                self.status.set(STATES.CREATED,
                                "Test directory and status file created.")

        self.run_timeout = self.parse_timeout(
            'run', config.get('run', {}).get('timeout'))
        self.build_timeout = self.parse_timeout(
            'build', config.get('build', {}).get('timeout'))

        self._attributes = {}

        self.build_name = None
        self.run_log = self.path/'run.log'
        self.results_path = self.path/'results.json'
        self.build_origin_path = self.path/'build_origin'

        build_config = self.config.get('build', {})

        if (build_config.get('source_path') is None and
                build_config.get('source_url') is not None):
            raise TestConfigError(
                "Build source_url specified, but not a source_path.")

        self.build_script_path = self.path/'build.sh'  # type: Path
        self.build_path = self.path/'build'
        if _id is None:
            self._write_script(
                'build',
                path=self.build_script_path,
                config=build_config)

        build_name = None
        self._build_name_fn = self.path / 'build_name'
        if _id is not None:
            build_name = self._load_build_name()

        try:
            self.builder = builder.TestBuilder(
                pav_cfg=pav_cfg,
                test=self,
                mb_tracker=build_tracker,
                build_name=build_name
            )
        except builder.TestBuilderError as err:
            raise TestRunError(
                "Could not create builder for test {s.name} (run {s.id}): {err}"
                .format(s=self, err=err)
            )

        self.save_build_name()

        run_config = self.config.get('run', {})
        self.run_tmpl_path = self.path/'run.tmpl'
        self.run_script_path = self.path/'run.sh'

        if _id is None:
            self._write_script(
                'run',
                path=self.run_tmpl_path,
                config=run_config)

        if _id is None:
            self.status.set(STATES.CREATED, "Test directory setup complete.")

        self._results = None
        self._created = None

        self.skipped = self._get_skipped()
Ejemplo n.º 2
0
    def __init__(self,
                 pav_cfg,
                 config,
                 build_tracker=None,
                 var_man=None,
                 _id=None,
                 rebuild=False,
                 build_only=False):
        """Create an new TestRun object. If loading an existing test
    instance, use the ``TestRun.from_id()`` method.

:param pav_cfg: The pavilion configuration.
:param dict config: The test configuration dictionary.
:param builder.MultiBuildTracker build_tracker: Tracker for watching
    and managing the status of multiple builds.
:param variables.VariableSetManager var_man: The variable set manager for this
    test.
:param bool build_only: Only build this test run, do not run it.
:param bool rebuild: After determining the build name, deprecate it and select
    a new, non-deprecated build.
:param int _id: The test id of an existing test. (You should be using
    TestRun.load).
"""

        # Just about every method needs this
        self._pav_cfg = pav_cfg
        self.scheduler = config['scheduler']

        # Create the tests directory if it doesn't already exist.
        tests_path = pav_cfg.working_dir / 'test_runs'

        self.config = config

        group, umask = self.get_permissions(pav_cfg, config)

        # Get an id for the test, if we weren't given one.
        if _id is None:
            id_tmp, run_path = dir_db.create_id_dir(tests_path, group, umask)
            super().__init__(path=run_path, group=group, umask=umask)

            # Set basic attributes
            self.id = id_tmp
            self.build_only = build_only
            self.complete = False
            self.created = dt.datetime.now()
            self.name = self.make_name(config)
            self.rebuild = rebuild
            self.suite_path = Path(config.get('suite_path', '.'))
            self.user = utils.get_login()
            self.uuid = str(uuid.uuid4())
        else:
            # Load the test info from the given id path.
            super().__init__(path=dir_db.make_id_path(tests_path, _id),
                             group=group,
                             umask=umask)
            self.load_attributes()

        self.test_version = config.get('test_version')

        if not self.path.is_dir():
            raise TestRunNotFoundError(
                "No test with id '{}' could be found.".format(self.id))

        # Mark the run to build locally.
        self.build_local = config.get('build', {}) \
                                 .get('on_nodes', 'false').lower() != 'true'

        self._variables_path = self.path / 'variables'

        if _id is None:
            with PermissionsManager(self.path, self.group, self.umask):
                self._save_config()
                if var_man is None:
                    var_man = variables.VariableSetManager()
                self.var_man = var_man
                self.var_man.save(self._variables_path)

            self.sys_name = self.var_man.get('sys_name', '<unknown>')
        else:
            try:
                self.var_man = variables.VariableSetManager.load(
                    self._variables_path)
            except RuntimeError as err:
                raise TestRunError(*err.args)

        # This will be set by the scheduler
        self._job_id = None

        with PermissionsManager(self.path / 'status', self.group, self.umask):
            # Setup the initial status file.
            self.status = StatusFile(self.path / 'status')
            if _id is None:
                self.status.set(STATES.CREATED,
                                "Test directory and status file created.")

        self.run_timeout = self.parse_timeout(
            'run',
            config.get('run', {}).get('timeout'))
        self.build_timeout = self.parse_timeout(
            'build',
            config.get('build', {}).get('timeout'))

        self.run_log = self.path / 'run.log'
        self.build_log = self.path / 'build.log'
        self.results_log = self.path / 'results.log'
        self.results_path = self.path / 'results.json'
        self.build_origin_path = self.path / 'build_origin'
        self.build_timeout_file = config.get('build', {}).get('timeout_file')

        # Use run.log as the default run timeout file
        self.timeout_file = self.run_log
        run_timeout_file = config.get('run', {}).get('timeout_file')
        if run_timeout_file is not None:
            self.timeout_file = self.path / run_timeout_file

        build_config = self.config.get('build', {})

        self.build_script_path = self.path / 'build.sh'  # type: Path
        self.build_path = self.path / 'build'
        if _id is None:
            self._write_script('build',
                               path=self.build_script_path,
                               config=build_config)

        try:
            self.builder = builder.TestBuilder(pav_cfg=pav_cfg,
                                               test=self,
                                               mb_tracker=build_tracker,
                                               build_name=self.build_name)
            self.build_name = self.builder.name
        except builder.TestBuilderError as err:
            raise TestRunError(
                "Could not create builder for test {s.name} (run {s.id}): {err}"
                .format(s=self, err=err))

        run_config = self.config.get('run', {})
        self.run_tmpl_path = self.path / 'run.tmpl'
        self.run_script_path = self.path / 'run.sh'

        if _id is None:
            self._write_script('run',
                               path=self.run_tmpl_path,
                               config=run_config)

        if _id is None:
            self.save_attributes()
            self.status.set(STATES.CREATED, "Test directory setup complete.")

        self._results = None

        self.skipped = self._get_skipped()  # eval skip.
Ejemplo n.º 3
0
    def __init__(self,
                 pav_cfg,
                 config,
                 build_tracker=None,
                 var_man=None,
                 _id=None,
                 **options):
        """Create an new TestRun object. If loading an existing test
    instance, use the ``TestRun.from_id()`` method.

:param pav_cfg: The pavilion configuration.
:param dict config: The test configuration dictionary.
:param builder.MultiBuildTracker build_tracker: Tracker for watching
    and managing the status of multiple builds.
:param variables.VariableSetManager var_man: The variable set manager for this
    test.
:param bool build_only: Only build this test run, do not run it.
:param bool rebuild: After determining the build name, deprecate it and select
    a new, non-deprecated build.
:param int _id: The test id of an existing test. (You should be using
    TestRun.load).
"""

        # Just about every method needs this
        self._pav_cfg = pav_cfg

        self.load_ok = True

        # Compute the actual name of test, using the subtitle config parameter.
        self.name = '.'.join([
            config.get('suite', '<unknown>'),
            config.get('name', '<unnamed>')
        ])
        if 'subtitle' in config and config['subtitle']:
            self.name = self.name + '.' + config['subtitle']

        self.scheduler = config['scheduler']

        # Create the tests directory if it doesn't already exist.
        tests_path = pav_cfg.working_dir / 'test_runs'

        self.config = config

        self.id = None  # pylint: disable=invalid-name

        # Mark the run to build locally.
        self.build_local = config.get('build', {}) \
                                 .get('on_nodes', 'false').lower() != 'true'

        # Get an id for the test, if we weren't given one.
        if _id is None:
            self.id, self.path = self.create_id_dir(tests_path)
            self._save_config()
            if var_man is None:
                var_man = variables.VariableSetManager()
            self.var_man = var_man
            self._variables_path = self.path / 'variables'
            self.var_man.save(self._variables_path)
            self.opts = TestRunOptions(**options)
            self.opts.save(self)
        else:
            self.id = _id
            self.path = utils.make_id_path(tests_path, self.id)
            self._variables_path = self.path / 'variables'
            if not self.path.is_dir():
                raise TestRunNotFoundError(
                    "No test with id '{}' could be found.".format(self.id))
            try:
                self.var_man = variables.VariableSetManager.load(
                    self._variables_path)
            except RuntimeError as err:
                raise TestRunError(*err.args)

            self.opts = TestRunOptions.load(self)

        # Set a logger more specific to this test.
        self.logger = logging.getLogger('pav.TestRun.{}'.format(self.id))

        # This will be set by the scheduler
        self._job_id = None

        # Setup the initial status file.
        self.status = StatusFile(self.path / 'status')
        if _id is None:
            self.status.set(STATES.CREATED,
                            "Test directory and status file created.")

        self.run_timeout = self.parse_timeout(
            'run',
            config.get('run', {}).get('timeout'))
        self.build_timeout = self.parse_timeout(
            'build',
            config.get('build', {}).get('timeout'))

        self._started = None
        self._finished = None

        self.build_name = None
        self.run_log = self.path / 'run.log'
        self.results_path = self.path / 'results.json'
        self.build_origin_path = self.path / 'build_origin'

        build_config = self.config.get('build', {})

        # make sure build source_download_name is not set without
        # source_location
        try:
            if build_config['source_download_name'] is not None:
                if build_config['source_location'] is None:
                    msg = "Test could not be built. Need 'source_location'."
                    self.status.set(
                        STATES.BUILD_ERROR,
                        "'source_download_name is set without a "
                        "'source_location'")
                    raise TestConfigError(msg)
        except KeyError:
            # this is mostly for unit tests that create test configs without a
            # build section at all
            pass

        self.build_script_path = self.path / 'build.sh'  # type: Path
        self.build_path = self.path / 'build'
        if _id is None:
            self._write_script('build',
                               path=self.build_script_path,
                               config=build_config)

        build_name = None
        self._build_name_fn = self.path / 'build_name'
        if _id is not None:
            build_name = self._load_build_name()

        try:
            self.builder = builder.TestBuilder(pav_cfg=pav_cfg,
                                               test=self,
                                               mb_tracker=build_tracker,
                                               build_name=build_name)
        except builder.TestBuilderError as err:
            raise TestRunError(
                "Could not create builder for test {s.name} (run {s.id}): {err}"
                .format(s=self, err=err))

        self.save_build_name()

        run_config = self.config.get('run', {})
        self.run_tmpl_path = self.path / 'run.tmpl'
        self.run_script_path = self.path / 'run.sh'

        if _id is None:
            self._write_script('run',
                               path=self.run_tmpl_path,
                               config=run_config)

        if _id is None:
            self.status.set(STATES.CREATED, "Test directory setup complete.")

        self._results = None
        self._created = None