Пример #1
0
def engine(request):
    db.setup_local_pg_cluster(request, DATADIR, PORT)
    uri = 'postgresql://localhost:{}/postgres'.format(PORT)
    e = create_engine(uri)
    reworkschema.init(e, drop=True)
    ruischema.init(e)
    api.freeze_operations(e)
    return e
Пример #2
0
def cleanup():
    tasks = api.__task_registry__.copy()
    yield
    api.__task_registry__.clear()
    api.__task_registry__.update(tasks)
    if ENGINE:
        with ENGINE.begin() as cn:
            cn.execute('delete from rework.operation')
        api.freeze_operations(ENGINE)
Пример #3
0
def test_domain_map(engine, cleanup):
    with engine.begin() as cn:
        cn.execute('delete from rework.operation')

    api.freeze_operations(engine,
                          domain='nondefault',
                          domain_map={'nondefault': 'fancy'})

    with workers(engine, maxruns=1, domain='fancy'):
        t1 = api.schedule(engine, 'run_in_non_default_domain')
        t1.join()
        assert t1.status == 'done'
Пример #4
0
def engine(request):
    db.setup_local_pg_cluster(request, DATADIR, PORT, {
        'timezone': 'UTC',
        'log_timezone': 'UTC'
    })
    e = create_engine('postgresql://localhost:{}/postgres'.format(PORT))
    schema.init(e, drop=True)
    api.freeze_operations(e)
    # help the `cleanup` fixture
    # (for some reason, working with a fresh engine therein won't work)
    global ENGINE
    ENGINE = e
    return e
Пример #5
0
def test_schedule_domain(engine, cleanup):
    reset_ops(engine)
    from . import task_testenv
    from . import task_prodenv

    api.freeze_operations(engine, domain='test')
    api.freeze_operations(engine, domain='production')
    api.freeze_operations(engine, domain='production', hostid='192.168.122.42')

    with pytest.raises(ValueError) as err:
        api.schedule(engine, 'foo')
    assert err.value.args[0] == 'Ambiguous operation selection'

    api.schedule(engine, 'foo', domain='test')
    # there two of them but .schedule will by default pick the one
    # matching the *current* host
    api.schedule(engine, 'foo', domain='production')
    api.schedule(engine, 'foo', domain='production', hostid='192.168.122.42')
    api.schedule(engine, 'foo', domain='production', hostid=host())

    hosts = [
        host for host, in engine.execute(
            'select host from rework.task as t, rework.operation as op '
            'where t.operation = op.id').fetchall()
    ]
    assert hosts.count(host()) == 3
    assert hosts.count('192.168.122.42') == 1

    with pytest.raises(Exception):
        api.schedule(engine, 'foo', domain='production', hostid='172.16.0.1')

    with pytest.raises(Exception):
        api.schedule(engine, 'foo', domain='bogusdomain')
Пример #6
0
def register_operations(dburi, module, domain=None, asdomain=None):
    """register operations from a python module containing
    python functions decorated with `api.task`

    It is possible to filter by domain and also to specify a
    subtitution domain.

    The registered operations will be relative to the current host.
    """
    mod = imp.load_source('operations', module)
    engine = create_engine(find_dburi(dburi))
    ok, ko = api.freeze_operations(engine, domain)

    print('registered {} new operation ({} already known)'.format(
        len(ok), len(ko)))
Пример #7
0
def test_freeze_ops(engine, cleanup):
    reset_ops(engine)
    register_tasks()
    api.freeze_operations(engine)

    res = engine.execute(
        'select name, domain from rework.operation order by domain, name'
    ).fetchall()
    assert res == [('cheesy', 'cheese'), ('foo', 'default'), ('hammy', 'ham')]

    reset_ops(engine)
    register_tasks()
    api.freeze_operations(engine, domain='default')
    api.freeze_operations(engine, domain='ham')

    res = engine.execute(
        'select name, domain from rework.operation order by domain, name'
    ).fetchall()
    assert res == [('foo', 'default'), ('hammy', 'ham')]
Пример #8
0
def test_tasks_table(engine, client, refresh):
    with engine.begin() as cn:
        cn.execute('delete from rework.task')

    with workers(engine):
        res = client.get('/tasks-table')
        assert res.text == '<p>Table under construction ...</p>'

        res = client.get('/tasks-table-hash')
        assert res.text == 'no-hash-yet'

        taskstable.refresh_tasks_file(engine)
        res = client.get('/tasks-table')
        assert res.text == (
            '<br>\n'
            '<table class="table table-sm table-bordered table-striped table-hover">\n'
            '<thead class="thead-inverse"><tr><th>#</th><th>service</th><th>domain</th>'
            '<th>queued</th><th>started</th><th>finished</th>'
            '<th>user</th><th>worker</th><th>status</th><th>action</th></tr></thead>\n</table>'
        )

        res = client.get('/tasks-table-hash')
        assert res.text == 'd751713988987e9331980363e24189ce'
        res = client.get('/tasks-table-hash?domain=all')
        assert res.text == 'no-hash-yet'
        res = client.get('/tasks-table-hash?domain=default')
        assert res.text == 'd751713988987e9331980363e24189ce'

        t = api.schedule(engine, 'good_job', metadata={'user': '******'})
        t.join()
        taskstable.refresh_tasks_file(engine)

        res = client.get('/tasks-table')
        refpath = DATADIR / 'tasks-table.html'
        if refresh:
            refpath.write_bytes(scrub(res.text).encode('utf-8'))
        assert scrub(res.text) == refpath.read_bytes().decode('utf-8')

        count = engine.execute('select count(*) from rework.taskstable').scalar()
        assert count == 1 # only default domains, 'all' appears with many domains

        t = api.schedule(engine, 'bad_job', metadata={'user': '******'})
        t.join()
        taskstable.refresh_tasks_file(engine)
        res = client.get('/tasks-table')

        srcpath = re.compile('File "(.*)"')
        def edit(elt):
            if 'title' in elt.attrib:
                elt.attrib['title'] = srcpath.sub('/path/to/src/file', elt.attrib['title'])
            return elt

        html = edittag('td', edit, res.text).decode('utf-8')
        refpath = DATADIR / 'tasks-table-error.html'
        if refresh:
            refpath.write_bytes(scrub(html).encode('utf-8'))

        assert scrub(html) == refpath.read_bytes().decode('utf-8')

    # declare an new domain
    from . import tasks
    api.freeze_operations(engine)
    with workers(engine, domain='uranus'):
        t = api.schedule(engine, 'justdoit', domain='uranus', metadata={'user': '******'})
        t.join()
        taskstable.refresh_tasks_file(engine)
        res = client.get('/tasks-table-hash?domain=uranus')
        assert res.text == '05265be5adad9bb8b0ee50f837535cfa'
        res = client.get('/tasks-table?domain=uranus')
        refpath = DATADIR / 'tasks-table-uranus.html'
        if refresh:
            refpath.write_bytes(scrub(res.text).encode('utf-8'))
        assert scrub(res.text) == refpath.read_bytes().decode('utf-8')