Exemple #1
0
def test_session_scope():
    """Test the session scope object."""
    db = DB(connect_url=TEST_URL, web_app=False)
    db.init()
    with db.session() as session:
        session.add(User(user_id='U', name='U', secret='U', active=True))
    # Query all users. Expects two objects in the resulting list (te created
    # user and the default user).
    with db.session() as session:
        assert len(session.query(User).all()) == 2
    # Error when adding user with duplicate key.
    with pytest.raises(IntegrityError):
        with db.session() as session:
            session.add(User(user_id='U', name='U', secret='U', active=True))
    # Query all users. Still expects one object in the resulting list.
    with db.session() as session:
        assert len(session.query(User).all()) == 2
    # Raise an exception within the session scope.
    with pytest.raises(ValueError):
        with db.session() as session:
            session.add(User(user_id='W', name='W', secret='W', active=True))
            raise ValueError('some error')
    # Query all users. Still expects two object in the resulting list.
    with db.session() as session:
        assert len(session.query(User).all()) == 2
Exemple #2
0
def test_create_sqlite_dir(tmpdir):
    """Test function that creates the SQLite databse directory when creating
    an instance of the database object for a SQLite database.
    """
    DB(connect_url=TEST_DB(os.path.join(tmpdir, 'db')))
    assert os.path.isdir(os.path.join(tmpdir, 'db'))
    # Special case for file path without parent directory.
    DB(connect_url=TEST_DB(''))
def client(benchmark_id, tmpdir):
    """Create the app client."""
    # Set the environment variables and create the database.
    connect_url = TEST_DB(tmpdir)
    DB(connect_url=connect_url).init()
    # Create a single benchmark. Need to ensure that the API factory points to
    # the newly created database.
    from robflask.service import init_service
    init_service(basedir=tmpdir, database=connect_url)
    from robflask.service import service
    with service() as api:
        # Get the benchmark repository instance from the API
        api.workflows().create_workflow(identifier=benchmark_id,
                                        name='Hello World',
                                        description='Hello World Demo',
                                        source=BENCHMARK_DIR)
    # Set the maximum upload file size to 1KB
    os.environ[config.ROB_WEBAPI_CONTENTLENGTH] = '1024'
    # Set the UI path.
    os.environ[config.ROB_UI_PATH] = ROB_UI_PATH
    # Create the Flask app
    from robflask.api import create_app
    app = create_app({'TESTING': True})
    with app.test_client() as client:
        yield client
Exemple #4
0
def success_run(database: DB, fs: StorageVolume,
                basedir: str) -> Tuple[str, str, str, str]:
    """Create a successful run with two result files:

        - A.json
        - results/B.json

    Returns the identifier of the created workflow, group, run, and user.
    """
    # Setup temporary run folder.
    runfs = FileSystemStorage(basedir=os.path.join(basedir, 'tmprun'))
    runfs.store(file=io_file({'A': 1}), dst='A.json')
    runfs.store(file=io_file({'B': 1}), dst=util.join('results', 'B.json'))
    with database.session() as session:
        user_id = create_user(session, active=True)
        workflow_id = create_workflow(session)
        group_id = create_group(session, workflow_id, users=[user_id])
        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=run_id,
            state=state.start().success(files=['A.json', 'results/B.json']),
            runstore=runfs)
    return workflow_id, group_id, run_id, user_id
Exemple #5
0
def success_run(database: DB, fs: FileStore,
                basedir: str) -> Tuple[str, str, str, str]:
    """Create a successful run with two result files:

        - A.json
        - run/results/B.json

    Returns the identifier of the created workflow, group, run, and user.
    """
    # Setup temporary run folder.
    tmprundir = os.path.join(basedir, '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})
    f2 = os.path.join(tmpresultsdir, 'B.json')
    util.write_object(f2, {'B': 1})
    with database.session() as session:
        user_id = create_user(session, active=True)
        workflow_id = create_workflow(session)
        group_id = create_group(session, workflow_id, users=[user_id])
        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)
    assert not os.path.exists(tmprundir)
    return workflow_id, group_id, run_id, user_id
Exemple #6
0
def init(force=False):
    """Initialize database and base directories for the API."""
    if not force:
        click.echo('This will erase an existing database.')
        click.confirm('Continue?', default=True, abort=True)
    # Create a new instance of the database. Raise errors if the database URL
    # is not set.
    config = env()
    connect_url = config.get(FLOWSERV_DB)
    if connect_url is None:
        raise err.MissingConfigurationError('database Url')
    DB(connect_url=connect_url).init()
Exemple #7
0
def get_app(source: str, specfile: str, manifestfile: str,
            name: str) -> Workflow:
    """Get the application handle for the given workflow template.

    Creates a fresh database in the application cache directory and installes
    the given workflow.

    Parameters
    ----------
    source: string
        Path to local template, name or URL of the template in the
        repository.
    specfile: string
        Path to the workflow template specification file (absolute or
        relative to the workflow directory)
    manifestfile: string
        Path to manifest file. If not given an attempt is made to read one
        of the default manifest file names in the base directory.
    name: string
        Name of the application that will determine the base folder for all
        workflow files.

    Returns
    -------
    flowserv.client.app.workflow.Workflow
    """
    # Use the application cache directory for storing all workflow files.
    homedir = os.path.join(user_cache_dir(appname='flowapp'), name)
    util.cleardir(homedir)
    # Create new database.
    dburl = SQLITE_DB(dirname=homedir, filename='flowapp.db')
    DB(connect_url=dburl).init()
    # Install workflow template and return app handle.
    env = config\
        .env()\
        .basedir(homedir)\
        .database(dburl)\
        .volume(FStore(basedir=homedir, identifier=DEFAULT_STORE))\
        .open_access()\
        .run_sync()
    client = Flowserv(env=env)
    workflow_id = client.install(source=source,
                                 specfile=specfile,
                                 manifestfile=manifestfile)
    return client.open(identifier=workflow_id)
Exemple #8
0
def init_db(env: Dict) -> DB:
    """Create an instance of the database object based on the given configuration
    settings. Sets the respective variables to the default value if not set.

    Parameters
    ----------
    env: dict, default=None
        Dictionary that provides access to configuration parameter values.

    Returns
    -------
    flowserv.model.database.DB
    """
    # Get the web app flag. Use True as the default if the value is not set.
    if WEBAPP not in env:
        env[WEBAPP] = True
    web_app = env[WEBAPP]
    # Ensure that the databse connection Url is specified in the configuration.
    url = env.get(DATABASE)
    if url is None:
        # Use a SQLite database in the dabase directory as default.
        # This database needs to be initialized if it does not exist.
        dbfile = '{}/flowserv.db'.format(env[config.FLOWSERV_BASEDIR])
        url = 'sqlite:///{}'.format(dbfile)
        env[DATABASE] = url
        # Maintain a reference to the local database instance for use
        # when creating API instances.
        db = DB(connect_url=url, web_app=web_app)
        if not os.path.isfile(dbfile):
            # Initialize the database if the database if the configuration
            # references the default database and the database file does
            # not exist.
            db.init()
    else:
        # If the database Url is specified in the configuration we create the
        # database object for that Url. In this case we assume that the referenced
        # database has been initialized.
        db = DB(connect_url=env[DATABASE], web_app=web_app)
    # Return the created database object.
    return db
Exemple #9
0
def database():
    """Create a fresh instance of the database."""
    db = DB(connect_url=TEST_URL)
    db.init()
    return db
Exemple #10
0
def test_db_webapp(web_app, echo):
    """Basic tests to ensure that the different parameter options for DB
    instantiation work without generating errors.
    """
    db = DB(connect_url=TEST_URL, web_app=web_app, echo=echo)
    db.init()