def test_avoid_infinite_loop_compute_all(): comp = Computation() comp.add_node('a', lambda c: c + 1) comp.add_node('b', lambda a: a + 1) comp.add_node('c', lambda b: b + 1) comp.insert('a', 1) comp.compute_all()
def test_value(): comp = Computation() comp.add_node('a', value=10) comp.add_node('b', lambda a: a + 1) comp.add_node('c', lambda a: 2 * a) comp.add_node('d', lambda c: 10 * c) comp.compute_all() assert comp['d'] == (States.UPTODATE, 200)
def test_repoint_missing_node(): comp = Computation() comp.add_node('a') comp.add_node('b', lambda a: a + 1) comp.insert('a', 1) comp.repoint('a', 'new_a') assert comp.s.new_a == States.PLACEHOLDER
def test_compute_multiple(): comp = Computation() comp.add_node('a', value=1) comp.add_node('b', lambda a: a + 1) comp.add_node('c', lambda a: 2 * a) comp.add_node('d', lambda b, c: b + c) comp.compute(['b', 'c']) assert comp.s.b == States.UPTODATE assert comp.s.c == States.UPTODATE assert comp.s.d != States.UPTODATE
def test_args(): def f(*args): return sum(args) comp = Computation() comp.add_node('a', value=1) comp.add_node('b', value=1) comp.add_node('c', value=1) comp.add_node('d', f, args=['a', 'b', 'c']) comp.compute_all() assert comp['d'] == (States.UPTODATE, 3)
def test_default_args_2(): comp = Computation() comp.add_node('x', value=1) comp.add_node('some_default', value=1) def bar(x, some_default=0): return x + some_default comp.add_node('foo', bar) assert set(comp.i.foo) == {'x', 'some_default'} comp.compute('foo') assert comp.v.foo == 2
def test_add_node_with_value_sets_descendents_stale(): comp = Computation() comp.add_node('a', value=1) comp.add_node('b', value=2) comp.add_node('c', lambda a, b: a + b) comp.compute_all() assert comp.s.a == States.UPTODATE assert comp.s.b == States.UPTODATE assert comp.s.c == States.UPTODATE comp.add_node('a', value=3) assert comp.s.a == States.UPTODATE assert comp.s.b == States.UPTODATE assert comp.s.c == States.COMPUTABLE
def test_state_map_with_adding_existing_node(): comp = Computation() comp.add_node('a', lambda: 1) assert comp._state_map[States.COMPUTABLE] == {'a'} assert comp._state_map[States.UPTODATE] == set() comp.compute('a') assert comp._state_map[States.COMPUTABLE] == set() assert comp._state_map[States.UPTODATE] == {'a'} comp.add_node('a', lambda: 1) assert comp._state_map[States.COMPUTABLE] == {'a'} assert comp._state_map[States.UPTODATE] == set() comp.compute('a') assert comp._state_map[States.COMPUTABLE] == set() assert comp._state_map[States.UPTODATE] == {'a'}
def test_get_item(): comp = Computation() comp.add_node('a', lambda: 1) comp.add_node('b', lambda a: a + 1) comp.compute_all() assert comp['a'] == (States.UPTODATE, 1) assert comp['b'] == (States.UPTODATE, 2)
def test_copy_2(): comp = Computation() comp.add_node('a') comp.add_node('b', lambda a: a + 1) comp.insert('a', 1) comp2 = comp.copy() assert comp2['a'] == (States.UPTODATE, 1) assert comp2.state('b') == States.COMPUTABLE comp2.compute_all() assert comp['a'] == (States.UPTODATE, 1) assert comp.state('b') == States.COMPUTABLE assert comp2['a'] == (States.UPTODATE, 1) assert comp2['b'] == (States.UPTODATE, 2)
def test_zero_parameter_functions(): comp = Computation() def a(): return 1 comp.add_node('a', a) assert comp.state('a') == States.COMPUTABLE comp.compute_all() assert comp.state('a') == States.UPTODATE assert comp.value('a') == 1
def test_compute_with_unpicklable_object(): class Unpicklable(object): def __getstate__(self): raise Exception("UNPICKLABLE") comp = Computation() comp.add_node('a', value=Unpicklable()) comp.add_node('b', lambda a: None) comp.compute('b')
def test_insert_many_nonexistent_causes_exception(): comp = Computation() comp.add_node('a') comp.insert('a', 0) with assert_raises(NonExistentNodeException): comp.insert_many([('a', 1), ('b', 2)]) assert comp.v.a == 0
def test_compute_with_args(): comp = Computation() comp.add_node('a', value=1) def f(foo): return foo + 1 comp.add_node('b', f, args=['a']) assert set(comp.nodes()) == {'a', 'b'} assert set(comp.dag.edges()) == {('a', 'b')} comp.compute_all() assert comp['b'] == (States.UPTODATE, 2)
def test_compute_fib_5(): n = 5 comp = Computation() def add(x, y): return x + y comp.add_node(0, value=1) comp.add_node(1, value=1) for i in range(2, n + 1): comp.add_node(i, add, kwds={'x': i - 2, 'y': i - 1}, inspect=False) comp.compute(n) assert comp.state(n) == States.UPTODATE
def test_constant_values(): comp = Computation() comp.add_node('a', value=1) def add(x, y): return x + y comp.add_node('b', add, args=['a', C(2)]) comp.add_node('c', add, args=[C(3), 'a']) comp.add_node('d', add, kwds={'x': C(4), 'y': 'a'}) comp.add_node('e', add, kwds={'y': C(5), 'x': 'a'}) comp.compute_all() assert comp.dag.nodes['b']['args'] == {1: 2} assert comp['b'] == (States.UPTODATE, 3) assert comp['c'] == (States.UPTODATE, 4) assert comp['d'] == (States.UPTODATE, 5) assert comp['e'] == (States.UPTODATE, 6)
def test_class_style_definition(): class FooComp(): a = input_node(value=3) @calc_node def b(a): return a + 1 @calc_node def c(a): return 2 * a @calc_node def d(b, c): return b + c comp = Computation(FooComp) comp.compute_all() assert comp.v.d == 10
def test_insert_many(): comp = Computation() l = list(range(100)) random.shuffle(l) prev = None for x in l: if prev is None: comp.add_node(x) else: comp.add_node(x, lambda n: n + 1, kwds={'n': prev}) prev = x comp.insert_many([(x, x) for x in range(100)]) for x in range(100): assert comp[x] == (States.UPTODATE, x)
def test_get_inputs_order(): comp = Computation() input_nodes = list(('inp', i) for i in range(100)) comp.add_node(input_node for input_node in input_nodes) random.shuffle(input_nodes) comp.add_node('res', lambda *args: args, args=input_nodes, inspect=False) assert comp.i.res == input_nodes
def test_decorator(): comp = Computation() comp.add_node('a', value=1) @node(comp) def b(a): return a + 1 comp.compute_all() assert comp['b'] == (States.UPTODATE, 2) @node(comp, name='c', args=['b']) def foo(x): return x + 1 comp.compute_all() assert comp['c'] == (States.UPTODATE, 3) @node(comp, kwds={'x': 'b', 'y': 'c'}) def d(x, y): return x + y comp.compute_all() assert comp['d'] == (States.UPTODATE, 5)
def test_thread_pool_executor(): sleep_time = 0.2 n = 10 def wait(c): sleep(sleep_time) return c comp = Computation(default_executor=ThreadPoolExecutor(n)) start_dt = datetime.utcnow() for c in range(n): comp.add_node(c, wait, kwds={'c': C(c)}) comp.compute_all() end_dt = datetime.utcnow() delta = (end_dt - start_dt).total_seconds() assert delta < (n - 1) * sleep_time
def test_node_specific_thread_pool_executor(): sleep_time = 0.2 n = 10 def wait(c): sleep(sleep_time) return c executor_map = {'foo': ThreadPoolExecutor(n)} comp = Computation(executor_map=executor_map) start_dt = datetime.utcnow() for c in range(n): comp.add_node(c, wait, kwds={'c': C(c)}, executor='foo') comp.compute_all() end_dt = datetime.utcnow() delta = (end_dt - start_dt).total_seconds() assert delta < (n - 1) * sleep_time
def test_insert_nonexistent_causes_exception(): comp = Computation() comp.insert('a', 1)
def test_state_map_updated_with_placeholder_args(): comp = Computation() comp.add_node('b', lambda x: x + 1, args=['a']) assert comp.s.a == States.PLACEHOLDER assert 'a' in comp._state_map[States.PLACEHOLDER]
def test_state_map_updated_with_placeholder(): comp = Computation() comp.add_node('b', lambda a: a + 1) assert comp.s.a == States.PLACEHOLDER assert 'a' in comp._state_map[States.PLACEHOLDER]
def test_tags(): comp = Computation() comp.add_node('a') comp.add_node('b', lambda a: a + 1) comp.set_tag('a', 'foo') assert 'foo' in comp.t.a assert 'foo' in comp.tags('a') assert 'a' in comp.nodes_by_tag('foo') comp.clear_tag('a', 'foo') assert 'foo' not in comp.t.a assert 'foo' not in comp.tags('a') assert 'a' not in comp.nodes_by_tag('foo') comp.set_tag('a', ['foo']) assert 'foo' in comp.t.a assert 'foo' in comp.tags('a') assert 'a' in comp.nodes_by_tag('foo') comp.clear_tag('a', ['foo']) assert 'foo' not in comp.t.a assert 'foo' not in comp.tags('a') assert 'a' not in comp.nodes_by_tag('foo') # This should not throw comp.clear_tag('a', 'bar') comp.clear_tag('a', ['bar']) # This should not throw comp.set_tag('a', ['foo']) comp.set_tag('a', ['foo']) assert 'foo' in comp.t.a # This should not throw comp.clear_tag('a', ['foo']) comp.clear_tag('a', ['foo']) assert 'foo' not in comp.t.a assert comp.nodes_by_tag('baz') == set() comp.set_tag(['a', 'b'], ['foo', 'bar']) assert 'foo' in comp.t.a assert 'bar' in comp.t.a assert 'foo' in comp.t.b assert 'bar' in comp.t.b assert {'a', 'b'} == comp.nodes_by_tag('foo') assert {'a', 'b'} == comp.nodes_by_tag('bar') assert {'a', 'b'} == comp.nodes_by_tag(['foo', 'bar']) comp.add_node('c', lambda a: 2 * a, tags=['baz']) assert 'baz' in comp.t.c assert {'c'} == comp.nodes_by_tag('baz')
def test_views(): comp = Computation() comp.add_node("a") comp.add_node("b", lambda a: a + 1) comp.add_node("c", lambda a: 2 * a) comp.add_node("d", lambda b, c: b + c) assert comp.s.a == States.UNINITIALIZED assert comp.s.b == States.UNINITIALIZED assert comp.s.c == States.UNINITIALIZED assert comp.s.d == States.UNINITIALIZED comp.insert("a", 1) assert comp.s.a == States.UPTODATE assert comp.s.b == States.COMPUTABLE assert comp.s.c == States.COMPUTABLE assert comp.s.d == States.STALE assert comp.v.a == 1 comp.compute_all() assert comp.s.a == States.UPTODATE assert comp.s.b == States.UPTODATE assert comp.s.c == States.UPTODATE assert comp.s.d == States.UPTODATE assert comp.v.a == 1 assert comp.v.b == 2 assert comp.v.c == 2 assert comp.v.d == 4
def test_delete_nonexistent_causes_exception(): comp = Computation() comp.delete_node('a')
def test_no_inspect(): comp = Computation() comp.add_node('a') comp.add_node('b', lambda a: a + 1, kwds={'a': 'a'}, inspect=False) comp.add_node('c', lambda a: 2 * a, kwds={'a': 'a'}, inspect=False) comp.add_node('d', lambda b, c: b + c, kwds={ 'b': 'b', 'c': 'c' }, inspect=False) comp.insert('a', 10) comp.compute_all() assert comp['b'] == (States.UPTODATE, 11) assert comp['c'] == (States.UPTODATE, 20) assert comp['d'] == (States.UPTODATE, 31)
def test_multiple_values(): comp = Computation() comp.add_node('a') comp.add_node('b', lambda a: a + 1, kwds={'a': 'a'}, inspect=False) comp.add_node('c', lambda a: 2 * a, kwds={'a': 'a'}, inspect=False) comp.add_node('d', lambda b, c: b + c, kwds={ 'b': 'b', 'c': 'c' }, inspect=False) comp.insert('a', 10) comp.compute_all() assert comp.value(['d', 'b']) == [31, 11]