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
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)
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'
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
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')
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)))
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')]
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')