blob: 32488926f97332b899ce2fd96ea8d8bd003b418d [file] [log] [blame]
load('@stdlib//internal/graph.star', 'graph')
load('@stdlib//internal/luci/common.star', 'builder_ref', 'keys', 'triggerer')
### Toy builder+poller model.
def builder(bucket, name, triggered_by=[], triggers=[]):
k = keys.builder(bucket, name)
graph.add_node(k)
ref = builder_ref.add(k)
trg = triggerer.add(k)
for t in triggered_by:
graph.add_edge(keys.triggerer(t), ref)
for t in triggers:
graph.add_edge(trg, keys.builder_ref(t))
return k
def poller(bucket, name, triggers=[]):
k = keys.gitiles_poller(bucket, name)
graph.add_node(k)
trg = triggerer.add(k)
for t in triggers:
graph.add_edge(trg, keys.builder_ref(t))
return k
def targets(poller_key):
return [n.key for n in triggerer.targets(graph.node(poller_key))]
### Test cases.
def test_triggers():
p1 = poller('buck', 'p1', triggers=['buck1/b1', 'b2'])
p2 = poller('buck', 'p2', triggers=['b2'])
p3 = poller('buck', 'p3')
b1 = builder('buck1', 'b1')
b2 = builder('buck2', 'b2')
__native__.graph().finalize()
assert.eq(targets(p1), [b1, b2])
assert.eq(targets(p2), [b2])
assert.eq(targets(p3), [])
def test_triggered_by():
p1 = poller('buck', 'p1')
p2 = poller('buck', 'p2')
b1 = builder('buck1', 'b1', triggered_by=['buck/p1'])
b2 = builder('buck2', 'b2', triggered_by=['p1', 'p2'])
__native__.graph().finalize()
assert.eq(targets(p1), [b1, b2])
assert.eq(targets(p2), [b2])
def test_both_directions_not_an_error():
p1 = poller('buck', 'p1', triggers=['buck1/b1', 'b2'])
b1 = builder('buck1', 'b1', triggered_by=['p1'])
b2 = builder('buck2', 'b2', triggered_by=['buck/p1'])
__native__.graph().finalize()
assert.eq(targets(p1), [b1, b2])
def test_ambiguous_builder_ref():
p = poller('buck', 'p', triggers=['b'])
b1 = builder('buck1', 'b')
b2 = builder('buck2', 'b')
__native__.graph().finalize()
assert.fails(lambda: targets(p),
'ambiguous reference "b" in core.gitiles_poller\("buck/p"\), possible variants:\n' +
' core.builder\("buck1/b"\)\n' +
' core.builder\("buck2/b"\)'
)
def test_ambiguous_triggerer():
p1 = poller('buck1', 'p')
p2 = poller('buck2', 'p')
bp = builder('buck3', 'p')
b = builder('buck', 'b', triggered_by=['p'])
__native__.graph().finalize()
err_re = (
'ambiguous reference "p" in core.builder\("buck/b"\), possible variants:\n' +
' core.gitiles_poller\("buck1/p"\)\n' +
' core.gitiles_poller\("buck2/p"\)\n' +
' core.builder\("buck3/p"\)'
)
assert.fails(lambda: targets(p1), err_re)
assert.fails(lambda: targets(p2), err_re)
def test_triggering_cycle():
builder('buck', 'b1', triggers=['b2'])
assert.fails(
lambda: builder('buck', 'b2', triggers=['b1']), 'introduces a cycle')
### Test runner.
def with_clean_state(cbs):
for cb in cbs:
__native__.clear_state()
__native__.fail_on_errors()
cb()
with_clean_state([
test_triggers,
test_triggered_by,
test_both_directions_not_an_error,
test_ambiguous_builder_ref,
test_ambiguous_triggerer,
test_triggering_cycle,
])