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()
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.
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