def test_workflow_leaderboard_serialization(database, tmpdir): """Test serialization of a workflow leaderboard.""" config = Config().basedir(tmpdir) schema = validator('WorkflowLeaderboard') view = WorkflowSerializer() with database.session() as session: manager = WorkflowManager(session=session, fs=FileSystemStore(config)) workflow = manager.create_workflow(source=BENCHMARK_DIR, name='Test', specfile=SPEC_FILE) ts = util.utc_now() ranking = [ RunResult(run_id='0', group_id='1', group_name='A', created_at=ts, started_at=ts, finished_at=ts, values={ 'len': 1, 'count': 10 }) ] doc = view.workflow_leaderboard(workflow, ranking=ranking) schema.validate(doc)
def test_update_workflow_name(database, tmpdir): """Test updating workflow names.""" # -- Setup ---------------------------------------------------------------- # # Create two workflow templates. Workflow 1 does not have a description # and instructions while workflow 2 has. fs = FileSystemStore(env=Config().basedir(tmpdir)) with database.session() as session: manager = WorkflowManager(session=session, fs=fs) # Initialize the repository wf = manager.create_workflow(name='A', source=BENCHMARK_DIR) workflow_1 = wf.workflow_id wf = manager.create_workflow(name='My benchmark', description='desc', instructions=INSTRUCTION_FILE, source=BENCHMARK_DIR) workflow_2 = wf.workflow_id # -- Test update workflow name -------------------------------------------- with database.session() as session: manager = WorkflowManager(session=session, fs=fs) wf = manager.update_workflow(workflow_id=workflow_1, name='B') assert wf.name == 'B' # It is possible to change the name to an existing name only if it is # the same workflow. wf = manager.update_workflow(workflow_id=workflow_2, name='My benchmark') assert wf.name == 'My benchmark' # -- Error cases ---------------------------------------------------------- with database.session() as session: manager = WorkflowManager(session=session, fs=fs) # Cannot change name to existing name. with pytest.raises(err.ConstraintViolationError): manager.update_workflow(workflow_id=workflow_2, name='B')
def FS(env: Dict) -> FileStore: """Factory pattern to create file store instances for the service API. Uses the environment variables FLOWSERV_FILESTORE_MODULE and FLOWSERV_FILESTORE_CLASS to create an instance of the file store. If the environment variables are not set the FileSystemStore is returned as the default file store. Parameters ---------- env: dict Configuration dictionary that provides access to configuration parameters from the environment. Returns ------- flowserv.model.files.base.FileStore """ module_name = env.get(FLOWSERV_FILESTORE_MODULE) class_name = env.get(FLOWSERV_FILESTORE_CLASS) # If both environment variables are None return the default file store. # Otherwise, import the specified module and return an instance of the # controller class. An error is raised if only one of the two environment # variables is set. if module_name is None and class_name is None: from flowserv.model.files.fs import FileSystemStore return FileSystemStore(env=env) elif module_name is not None and class_name is not None: from importlib import import_module module = import_module(module_name) return getattr(module, class_name)(env=env) raise err.MissingConfigurationError('file store')
def test_workflow_listing_serialization(database, tmpdir): """Test serialization of workflow listings.""" config = Config().basedir(tmpdir) schema = validator('WorkflowListing') view = WorkflowSerializer() with database.session() as session: manager = WorkflowManager(session=session, fs=FileSystemStore(config)) model.create_workflow(session) model.create_workflow(session) workflows = manager.list_workflows() doc = view.workflow_listing(workflows) schema.validate(doc) assert len(doc[labels.WORKFLOW_LIST]) == 2
def test_group_handle_serialization(database, tmpdir): """Test serialization of workflow group handles.""" config = Config().basedir(tmpdir) view = WorkflowGroupSerializer() with database.session() as session: manager = WorkflowGroupManager(session=session, fs=FileSystemStore(config)) user_id = model.create_user(session, active=True) workflow_id = model.create_workflow(session) group_id = model.create_group(session, workflow_id, users=[user_id]) manager.upload_file(group_id=group_id, file=io_file(data={'A': 1}), name='a.json') group = manager.get_group(group_id) doc = view.group_handle(group) validator('UserGroupHandle').validate(doc) assert len(doc[labels.GROUP_MEMBERS]) == 1
def test_group_listing_serialization(database, tmpdir): """Test serialization of workflow group listing.""" config = Config().basedir(tmpdir) view = WorkflowGroupSerializer() with database.session() as session: manager = WorkflowGroupManager(session=session, fs=FileSystemStore(config)) user_id = model.create_user(session, active=True) workflow_id = model.create_workflow(session) model.create_group(session, workflow_id, users=[user_id]) model.create_group(session, workflow_id, users=[user_id]) groups = manager.list_groups(workflow_id=workflow_id, user_id=user_id) assert len(groups) == 2 doc = view.group_listing(groups) validator('UserGroupListing').validate(doc) assert len(doc[labels.GROUP_LIST]) == 2
def test_workflow_handle_serialization(database, tmpdir): """Test serialization of workflow handles.""" config = Config().basedir(tmpdir) schema = validator('WorkflowHandle') view = WorkflowSerializer() with database.session() as session: manager = WorkflowManager(session=session, fs=FileSystemStore(config)) workflow = manager.create_workflow(source=BENCHMARK_DIR, name='Test', specfile=SPEC_FILE) doc = view.workflow_handle(workflow) schema.validate(doc) workflow = manager.get_workflow(workflow.workflow_id) schema.validate(doc) assert doc[labels.WORKFLOW_NAME] == 'Test'
def test_list_workflow(database, tmpdir): """Test deleting a workflows from the repository.""" # -- Setup ---------------------------------------------------------------- # # Create two workflows. fs = FileSystemStore(env=Config().basedir(tmpdir)) with database.session() as session: manager = WorkflowManager(session=session, fs=fs) manager.create_workflow(source=BENCHMARK_DIR) manager.create_workflow(source=BENCHMARK_DIR) manager.create_workflow(source=BENCHMARK_DIR) # -- Test list workflows -------------------------------------------------- with database.session() as session: manager = WorkflowManager(session=session, fs=fs) workflows = manager.list_workflows() assert len(workflows) == 3
def test_workflow_name(database, tmpdir): """Test creating workflows with existing names.""" # -- Setup ---------------------------------------------------------------- # Initialize the repository. Create two workflows, one with name 'Workflow' # and the other with name 'Workflow (2)' fs = FileSystemStore(env=Config().basedir(tmpdir)) with database.session() as session: manager = WorkflowManager(session=session, fs=fs) manager.create_workflow(name='Workflow', source=BENCHMARK_DIR) manager.create_workflow(name='Workflow (2)', source=BENCHMARK_DIR) # Creating another workflow with name 'Workflow' will result in a workflow # with name 'Workflow (1)' and the 'Workflow (3)' with database.session() as session: manager = WorkflowManager(session=session, fs=fs) wf = manager.create_workflow(name='Workflow', source=BENCHMARK_DIR) assert wf.name == 'Workflow (1)' wf = manager.create_workflow(name='Workflow', source=BENCHMARK_DIR) assert wf.name == 'Workflow (3)'
def test_run_serialization(database, tmpdir): """Test serialization of run handles and run listings.""" config = Config().basedir(tmpdir) view = RunSerializer() fs = FileSystemStore(config) # Setup temporary run folder. tmprundir = os.path.join(tmpdir, 'tmprun') tmpresultsdir = os.path.join(tmprundir, 'run', 'results') os.makedirs(tmprundir) os.makedirs(tmpresultsdir) f1 = os.path.join(tmprundir, 'A.json') util.write_object(f1, {'A': 1}) # Create runs. with database.session() as session: user_id = model.create_user(session, active=True) workflow_id = model.create_workflow(session) group_id = model.create_group(session, workflow_id, users=[user_id]) # Create successful run. groups = WorkflowGroupManager(session=session, fs=fs) runs = RunManager(session=session, fs=fs) run = runs.create_run(group=groups.get_group(group_id)) run_id = run.run_id state = run.state() runs.update_run( run_id, state.start().success(files=['A.json', 'run/results/B.json']), rundir=tmprundir) run = runs.get_run(run_id) doc = view.run_handle(run) validator('RunHandle').validate(doc) # Create error run. run = runs.create_run(group=groups.get_group(group_id)) run_id = run.run_id state = run.state() runs.update_run(run_id=run_id, state=state) messages = ['There', 'were', 'many errors'] runs.update_run(run_id=run_id, state=state.error(messages)) run = runs.get_run(run_id) doc = view.run_handle(run) validator('RunHandle').validate(doc) # Validate run listing. doc = view.run_listing(runs=runs.list_runs(group_id)) validator('RunListing').validate(doc) assert len(doc[labels.RUN_LIST]) == 2
def test_file_listing_serialization(database, tmpdir): """Test serialization of file handles.""" config = Config().basedir(tmpdir) view = UploadFileSerializer() filename = 'data.json' with database.session() as session: manager = WorkflowGroupManager(session=session, fs=FileSystemStore(config)) user_id = model.create_user(session, active=True) workflow_id = model.create_workflow(session) group_id = model.create_group(session, workflow_id, users=[user_id]) fh = manager.upload_file(group_id=group_id, file=io_file(data={'A': 1}), name=filename) doc = view.file_handle(group_id=group_id, fh=fh) assert doc[labels.FILE_NAME] == filename validator('FileHandle').validate(doc) doc = view.file_listing( group_id=group_id, files=manager.list_uploaded_files(group_id=group_id)) validator('FileListing').validate(doc)
def test_update_workflow_description(database, tmpdir): """Test updating the name and description of a workflow.""" # -- Setup ---------------------------------------------------------------- # # Create one workflow without description and instructions. fs = FileSystemStore(env=Config().basedir(tmpdir)) with database.session() as session: manager = WorkflowManager(session=session, fs=fs) # Initialize the repository wf = manager.create_workflow(name='A', source=BENCHMARK_DIR) workflow_id = wf.workflow_id # -- Test update description and instruction text ------------------------- with database.session() as session: manager = WorkflowManager(session=session, fs=fs) wf = manager.update_workflow(workflow_id=workflow_id, description='The description', instructions='The instructions') assert wf.description == 'The description' assert wf.instructions == 'The instructions' # -- Test no update ------------------------------------------------------- with database.session() as session: manager = WorkflowManager(session=session, fs=fs) wf = manager.update_workflow(workflow_id=workflow_id) assert wf.name == 'A' assert wf.description == 'The description' assert wf.instructions == 'The instructions' # -- Test update all three properties ------------------------------------- with database.session() as session: manager = WorkflowManager(session=session, fs=fs) wf = manager.update_workflow(workflow_id=workflow_id, name='A name', description='A description', instructions='Some instructions') assert wf.name == 'A name' assert wf.description == 'A description' assert wf.instructions == 'Some instructions'
def create_store(store_id, basedir): """Create an instance of the file store with the given identifier.""" if store_id == 'BUCKET': return BucketStore(env=Config(), bucket=DiskBucket(basedir=basedir)) else: return FileSystemStore(env=Config().basedir(basedir))