def plugins(): plugins = {} plugins['rcv0'] = RunCreateView( [TextField('param0', 'Parameter 0', default='Some default value 0')]) plugins['rcv1'] = RunCreateView( [TextField('param1', 'Parameter 1', default='Some default value 1')]) plugins['view_keys1'] = ("id", "name", "some-other-data"), plugins['runner0'] = MM() plugins['runner1'] = MM() # create Plugin objects plugins['rt0'] = Plugin( 'swansea.ac.uk/1', 'My First Type', plugins['rcv0'], runner=plugins['runner0']) plugins['rt1'] = Plugin( 'swansea.ac.uk/2', 'My Second Type', plugins['rcv1'], view_keys=plugins['view_keys1'], runner=plugins['runner1']) plugins['plugins'] = [plugins['rt0'], plugins['rt1']] return plugins
def setUp(self): self.widgets = [ TextField('key', 'My Label', default="My Default"), TextField('another_key', 'My Other Label', default="My Other Default"), ] self.run_create_view = RunCreateView(self.widgets) self.runner = lambda run_manager, data: None self.domain = 'swansea.ac.uk' self.type_name = 'My Run Type'
def test_throws_error_without_host(self): run_create_view = RunCreateView([ TextField('Some Parameter', 'param', default='Some default value') ]) connection = MM() connection.run_command.return_value = (0, "std out", "std err") # job_id is a hack to get the run id out of the runner function job_id = [] def runner(run_manager, data): datastore = MM() defaults = [] host_pattern = [('#FAKE num_nodes={}', 'nodes'), ('#FAKE memory={}', 'memory')] pattern_parser = PatternParser(host_pattern, 'submit_cmd', defaults) rid = run_manager.new(nodes=10, memory=10000, host=Host(pattern_parser, connection, datastore), script='my_command') job_id.append(rid) rt = Plugin(self.domain, self.type_name, run_create_view, runner) button = qtest_helpers.find_QPushButton(rt.create_view, 'ok') qtest_helpers.button_callback(method=rt.create, button=button) connection.put_file_content.assert_called_once_with( '#FAKE num_nodes=10\n#FAKE memory=10000\nmy_command\n', f'{job_id[0]}/jobcard') connection.run_command.assert_called_once_with('submit_cmd', pwd=f'{job_id[0]}')
def __init__(self, plugin_id, name, create_view=None, runner=None, view_keys=None, labels=None, build_index_view=None, parent=None): ''' Parameters ---------- `plugin_id`: str A string giving a globally unique name for the plugin. Clients on different machines will use this name to associate jobs with a given Plugin class. The recommended appraoach is to use a web URL (such as a github repository URL) which is unique for this plugin. This string is never displayed in the UI by default. `name`: str A string giving the human readable Plugin name. This is the string which is displayed to the user in the UI to identify the runs of this plugin. `create_view` : RunCreateView / iterable of BaseField Defines the view used by the application user to configure a job, and the mapping of that configuration to a set of options which will be passed to Run. `runner`: callable A function which will be called to run a job. Typically this function will instantiate one or more objects of type Run. The input to the method will be a dictionary in which the keys correspond to the 'key' properties of the visible UI objects in the . See the RynCreateView class documentation for details of keys. If not specified, all keys of the RynCreateView object will be passed as keyword arguments to instantiate a single Run object. In this case, the keys of the children of the RynCreateView should correspond directly to keyword arguments of Run. `view_keys`: iterable of strings A list of keys to show in the (default) main/index view `labels`: dict ,optional Dictionary giving a human readable name for each label. If not specified, the values of the key of each entry in is used. `view`: callable A callable that when called returns a QWidget object (this should be a QWidget class or a function which returns a QWidget instance). If not set, RynCreateView will be used. view keyword argument which can be used to override the default main/index view to render for a Plugin. ''' super().__init__(parent) self.name = name self.plugin_id = plugin_id self.create_view = create_view self.actions = [] self.runner = runner self.labels = labels if build_index_view is not None: self.build_index_view = build_index_view if view_keys is not None: self.view_keys = view_keys if isinstance(view_keys, str): raise ValueError( 'view_keys kwarg tuple or list expected, not string') if not isinstance(self.create_view, RunCreateView): self.create_view = RunCreateView(self.create_view) if create_view is not None: self.create_view.accepted.connect(self.config_accepted)
class Plugin(QObject): ''' The runner object (function) is the thing that is responsible for running the job, usually by creating a Run object. Links the GUI/UI and the 'run' logic. (see design.org example) ''' build_index_view = None view_keys = [] runs_changed = Signal() def __init__(self, plugin_id, name, create_view=None, runner=None, view_keys=None, labels=None, build_index_view=None, parent=None): ''' Parameters ---------- `plugin_id`: str A string giving a globally unique name for the plugin. Clients on different machines will use this name to associate jobs with a given Plugin class. The recommended appraoach is to use a web URL (such as a github repository URL) which is unique for this plugin. This string is never displayed in the UI by default. `name`: str A string giving the human readable Plugin name. This is the string which is displayed to the user in the UI to identify the runs of this plugin. `create_view` : RunCreateView / iterable of BaseField Defines the view used by the application user to configure a job, and the mapping of that configuration to a set of options which will be passed to Run. `runner`: callable A function which will be called to run a job. Typically this function will instantiate one or more objects of type Run. The input to the method will be a dictionary in which the keys correspond to the 'key' properties of the visible UI objects in the . See the RynCreateView class documentation for details of keys. If not specified, all keys of the RynCreateView object will be passed as keyword arguments to instantiate a single Run object. In this case, the keys of the children of the RynCreateView should correspond directly to keyword arguments of Run. `view_keys`: iterable of strings A list of keys to show in the (default) main/index view `labels`: dict ,optional Dictionary giving a human readable name for each label. If not specified, the values of the key of each entry in is used. `view`: callable A callable that when called returns a QWidget object (this should be a QWidget class or a function which returns a QWidget instance). If not set, RynCreateView will be used. view keyword argument which can be used to override the default main/index view to render for a Plugin. ''' super().__init__(parent) self.name = name self.plugin_id = plugin_id self.create_view = create_view self.actions = [] self.runner = runner self.labels = labels if build_index_view is not None: self.build_index_view = build_index_view if view_keys is not None: self.view_keys = view_keys if isinstance(view_keys, str): raise ValueError( 'view_keys kwarg tuple or list expected, not string') if not isinstance(self.create_view, RunCreateView): self.create_view = RunCreateView(self.create_view) if create_view is not None: self.create_view.accepted.connect(self.config_accepted) def _run(self, config): run_manager = RunManager(self.plugin_id, config) if self.runner is None: run = run_manager.new(**data) else: self.runner(run_manager, config) run_manager.store() def add_action(self, label, function): action = RunAction(label, function) self.actions.append(action) return action def create(self): if self.create_view is None: self._run({}) else: # display configuration window self.create_view.show() def config_accepted(self): if len(self.create_view.invalid()) == 0: data = Box(self.create_view.data()) self._run(data) else: raise Exception() def stop_run(self, run_data): raise NotImplementedError() def manages(self, plugin_id): ''' Checks if plugin_id is the id of this plugin instance. Implemented to maintain compatibility with PluginCollection. ''' return plugin_id == self.plugin_id
from rynner.main import MainView from rynner.create_view import RunCreateView, TextField from rynner.plugin import Plugin, PluginCollection, RunAction from rynner.run import RunManager from rynner.host_patterns import host_patterns from rynner.logs import Logger from tests.host_env import * defaults = [] #--------------------------------------------------------- # PLUGIN SCRIPT #--------------------------------------------------------- # Create a fake run_create_view view1 = RunCreateView( [TextField('Message', 'message', default='Hello, World!')]) def runner(run_manager, data): run = run_manager.new( ntasks=1, memory_per_task_MB=10000, host=hosts[0], script='echo "Hello from Sunbird!" > "my-job-output"') # create Plugin objects plugin1 = Plugin( 'swansea.ac.uk/1', 'Hello, World!', view1,