def _prepare_remote(self): """Transfer local data to remote host.""" import testplan.runners.pools.child as child self._child_paths['local'] = module_abspath(child, self._user) self._working_dirs = {'local': pwd()} self._workspace_paths['local'] = self.cfg.workspace if self.cfg.copy_workspace_check: cmd = self.cfg.copy_workspace_check(self.cfg.ssh_cmd, self.cfg.index, self._workspace_paths['local']) self._workspace_transferred = self._execute_cmd(cmd) != 0 if self._workspace_transferred is True: self._create_remote_dirs() self._copy_child_script() self._copy_dependencies_module() self._copy_workspace() self._working_dirs = { 'local': pwd(), 'remote': '{}{}'.format( self._workspace_paths['remote'], '/'.join(pwd().split(os.sep)).replace( '/'.join(self._workspace_paths['local'].split(os.sep)), '')) } else: self._child_paths['remote'] = self._child_paths['local'] self._working_dirs['remote'] = self._working_dirs['local'] self._workspace_paths['remote'] = self._workspace_paths['local']
def _copy_testplan_package(self): """Make testplan package available on remote host""" module_path = os.path.dirname(module_abspath(testplan)) self._testplan_import_path.local = os.path.abspath( os.path.join(module_path, '..')) if self.cfg.testplan_path: self._testplan_import_path.remote = self.cfg.testplan_path return # test if testplan package is available on remote host cmd = remote_filepath_exists(self.cfg.ssh_cmd, self.ssh_cfg, self._testplan_import_path.local) if 0 == execute_cmd(cmd, label='testplan package availability check', check=False, logger=self.logger): # exists on remote self._testplan_import_path.remote = self._testplan_import_path.local else: # copy to remote self._testplan_import_path.remote = os.path.join( self._remote_testplan_path, 'testplan_lib') # as module_path has no trailing / # this will copy the entire testplan subdir to testplan_lib self._transfer_data(source=module_path, target=self._testplan_import_path.remote, remote_target=True, deref_links=True)
def main(plan): """ Testplan decorated main function to add and execute MultiTests. :return: Testplan result object. :rtype: ``testplan.base.TestplanResult`` """ import testplan workspace = os.path.abspath( os.path.join(os.path.dirname(module_abspath(testplan)), '..', '..')) # Add a remote pool test execution resource to the plan of given size. pool = RemotePool(name='MyPool', hosts={socket.gethostname(): 3}, workspace=workspace) plan.add_resource(pool) # Add a given number of similar tests to the remote pool # to be executed in parallel. for idx in range(plan.args.tasks_num): # All Task arguments need to be serializable. task = Task(target='make_multitest', module='tasks', path='.', kwargs={'index': idx}) plan.schedule(task, resource='MyPool')
def test_pool_basic(): """Basic test scheduling.""" import testplan workspace = os.path.abspath( os.path.join(os.path.dirname(module_abspath(testplan)), '..', '..')) for remote_pool_type in ('thread', 'process'): schedule_tests_to_pool('RemotePlan', RemotePool, hosts={'localhost': 2}, ssh_cmd=mock_ssh, copy_cmd=strip_host, workspace=workspace, copy_workspace_check=None, pool_type=remote_pool_type)
def _add_testplan_import_path(self, cmd, flag=None): if self.cfg.testplan_path: if flag is not None: cmd.append(flag) cmd.append(self.cfg.testplan_path) return import testplan testplan_path = os.path.abspath( os.path.join(os.path.dirname(module_abspath(testplan)), '..')) # Import testplan from outside the local workspace if not testplan_path.startswith(self._workspace_paths['local']): return common_prefix = os.path.commonprefix( [testplan_path, self._workspace_paths['local']]) if flag is not None: cmd.append(flag) cmd.append('{}/{}'.format( self._workspace_paths['remote'], '/'.join( os.path.relpath(testplan_path, common_prefix).split(os.sep))))
def _copy_testplan_package(self): """Make testplan package available on remote host""" if self.cfg.testplan_path: self._execute_cmd_remote( cmd=link_cmd( path=self.cfg.testplan_path, link=self._testplan_import_path.remote, ), label="linking to testplan package (1).", ) return self._testplan_import_path.local = os.path.dirname( os.path.dirname(module_abspath(testplan))) # test if testplan package is available on remote host if 0 == self._execute_cmd_remote( cmd=filepath_exist_cmd(self._testplan_import_path.local), label="testplan package availability check", check=False, ): # exists on remote, make symlink self._execute_cmd_remote( cmd=link_cmd( path=self._testplan_import_path.local, link=self._testplan_import_path.remote, ), label="linking to testplan package (2).", ) else: # copy to remote self._transfer_data( # join with "" to add trailing "/" to source # this will copy everything under local import path to to testplan_lib source=os.path.join(self._testplan_import_path.local, ""), target=self._testplan_import_path.remote, remote_target=True, deref_links=True, )
def _get_testplan_import_path(self): return os.path.dirname(os.path.dirname(module_abspath(testplan)))
def main(plan): """ Testplan decorated main function to add and execute MultiTests. :return: Testplan result object. :rtype: ``testplan.base.TestplanResult`` """ import testplan workspace = os.path.abspath( os.path.join( os.path.dirname(module_abspath(testplan)), '..', '..')) # Create two temporary files locally. For demonstration, just write the # filename as the content of each. assert TEMP_DIR is not None for filename in ('file1', 'file2'): make_file(filename, TEMP_DIR, content=filename) # Explicitly specify the full paths to both the local source files just # created and the destination filepaths on the remote host. push_files = [ (os.path.join(TEMP_DIR, 'file1'), '/tmp/remote_example/file1'), (os.path.join(TEMP_DIR, 'file2'), '/tmp/remote_example/file2') ] # Check if the remote host has been specified in the environment. Remote # hosts can only be Linux systems. If none is specified when running on a # Linux system we can default to using the localhost as our "remote" # worker. Whichever remote host is used must be configured to accept SSH # connections from the localhost. remote_host = os.environ.get('TESTPLAN_REMOTE_HOST') if not remote_host: if os.name == 'posix': remote_host = socket.gethostname() else: raise RuntimeError( 'You must specify a remote host via the TESTPLAN_REMOTE_HOST ' 'environment var on non-Linux systems.') # Add a remote pool test execution resource to the plan of given size. pool = RemotePool(name='MyPool', # Create 3 workers on the same remote host. hosts={remote_host: 3}, # Allow the remote port to be overridden by the # environment. Default to 0, which will make testplan use # the default SSH port for connections. port=int(os.environ.get('TESTPLAN_REMOTE_PORT', 0)), setup_script=['/bin/bash', 'setup_script.ksh'], env={'LOCAL_USER': getpass.getuser(), 'LOCAL_WORKSPACE': workspace}, workspace_exclude=['.git/', '.cache/', 'doc/', 'test/'], # We push local files to the remote worker using the # explicit source and destination locations defined above. push=push_files, workspace=workspace) plan.add_resource(pool) # Add a given number of similar tests to the remote pool # to be executed in parallel. for idx in range(plan.args.tasks_num): # All Task arguments need to be serializable. task = Task(target='make_multitest', module='tasks', path='.', # We specify the full paths to files as they will be found # on the remote host. kwargs={'index': idx, 'files': ['/tmp/remote_example/file1', '/tmp/remote_example/file2']}) plan.schedule(task, resource='MyPool')