def test_load_graph_to_empty(): plumb0 = test.two_valve_setup(0.5, 0.2, 10, utils.CLOSED, 0.5, 0.2, 10, utils.CLOSED) pressures = {3: (100, False)} default_states = {'valve1': 'closed', 'valve2': 'open'} plumb = top.PlumbingEngine() plumb.load_graph(plumb0.component_dict, plumb0.mapping, pressures, default_states) assert plumb.time_res == int( utils.s_to_micros(0.2) / utils.DEFAULT_RESOLUTION_SCALE) assert plumb.edges() == [(1, 2, 'valve1.A1', { 'FC': utils.teq_to_FC(utils.s_to_micros(10)) }), (2, 1, 'valve1.A2', { 'FC': 0 }), (2, 3, 'valve2.B1', { 'FC': utils.teq_to_FC(utils.s_to_micros(0.5)) }), (3, 2, 'valve2.B2', { 'FC': utils.teq_to_FC(utils.s_to_micros(0.2)) })] assert plumb.nodes() == [(1, { 'body': top.GenericNode(0) }), (2, { 'body': top.GenericNode(0) }), (3, { 'body': top.GenericNode(100) })] assert plumb.current_state('valve1') == 'closed' assert plumb.current_state('valve2') == 'open'
def test_reset_keep_component(): plumb = test.two_valve_setup(0.5, 0.2, 10, utils.CLOSED, 0.5, 0.2, 10, utils.CLOSED) pc = test.create_component(0, 0, 0, 1, 'valve3', 'C') mapping = {1: 3, 2: 4} plumb.add_component(pc, mapping, 'closed', {4: (50, False)}) plumb.remove_component('valve2') plumb.reset() assert plumb.time == 0 assert plumb.is_valid() assert plumb.time_res == int( utils.s_to_micros(0.2) / utils.DEFAULT_RESOLUTION_SCALE) assert plumb.edges() == [(1, 2, 'valve1.A1', { 'FC': utils.teq_to_FC(utils.s_to_micros(10)) }), (2, 1, 'valve1.A2', { 'FC': 0 }), (3, 4, 'valve3.C1', { 'FC': utils.teq_to_FC(0) }), (4, 3, 'valve3.C2', { 'FC': utils.teq_to_FC(utils.s_to_micros(1)) })] assert plumb.nodes() == [(1, { 'body': top.GenericNode(0) }), (2, { 'body': top.GenericNode(0) }), (3, { 'body': top.GenericNode(100) }), (4, { 'body': top.GenericNode(0) })] assert plumb.current_state('valve1') == 'closed' assert plumb.current_state('valve3') == 'closed'
def test_reverse_orientation(): plumb = test.two_valve_setup(0.5, 0.2, 10, utils.CLOSED, 0.5, 0.2, 10, utils.CLOSED) plumb.reverse_orientation('valve1') assert plumb.is_valid() assert plumb.time_res == int( utils.s_to_micros(0.2) / utils.DEFAULT_RESOLUTION_SCALE) assert plumb.edges() == [(1, 2, 'valve1.A1', { 'FC': 0 }), (2, 1, 'valve1.A2', { 'FC': utils.teq_to_FC(utils.s_to_micros(10)) }), (2, 3, 'valve2.B1', { 'FC': utils.teq_to_FC(utils.s_to_micros(0.5)) }), (3, 2, 'valve2.B2', { 'FC': utils.teq_to_FC(utils.s_to_micros(0.2)) })] assert plumb.nodes() == [ (1, { 'body': top.GenericNode(0) }), (2, { 'body': top.GenericNode(0) }), (3, { 'body': top.GenericNode(100) }), ] assert plumb.current_state('valve1') == 'closed' assert plumb.current_state('valve2') == 'open'
def test_set_pressure(): plumb = test.two_valve_setup(0.5, 0.2, 10, utils.CLOSED, 0.5, 0.2, 10, utils.CLOSED) pc = test.create_component(0, 0, 0, 1, 'valve3', 'C') mapping = {1: 3, 2: 4} plumb.add_component(pc, mapping, 'closed', {4: (50, False)}) plumb.set_pressure(1, 200) plumb.set_pressure(2, 7000) assert plumb.nodes() == [(1, { 'body': top.GenericNode(200) }), (2, { 'body': top.GenericNode(7000) }), (3, { 'body': top.GenericNode(100) }), (4, { 'body': top.GenericNode(50) })] plumb.set_pressure(4, 10) plumb.set_pressure(1, 0) assert plumb.nodes() == [(1, { 'body': top.GenericNode(0) }), (2, { 'body': top.GenericNode(7000) }), (3, { 'body': top.GenericNode(100) }), (4, { 'body': top.GenericNode(10) })]
def test_remove_errors_wrong_component_name(): wrong_component_name = 'potato' pc1 = test.create_component(0, 0, 0, 0, 'valve1', 'A') pc2 = test.create_component(0, 0, 0, 0, 'valve2', 'B') component_mapping = {'valve1': {1: 1, 2: 2}, 'valve2': {1: 2, 2: 3}} pressures = {3: (100, False)} default_states = {'valve1': 'closed', 'valve2': 'open'} plumb = top.PlumbingEngine({ wrong_component_name: pc1, 'valve2': pc2 }, component_mapping, pressures, default_states) assert not plumb.is_valid() assert len(plumb.errors()) == 2 error1 = invalid.InvalidComponentName( f"Component with name '{wrong_component_name}' not found in mapping dict.", wrong_component_name) error2 = invalid.InvalidComponentName( f"Component '{wrong_component_name}' state not found in initial states dict.", wrong_component_name) assert error1 in plumb.errors() assert error2 in plumb.errors() plumb.remove_component(wrong_component_name) assert plumb.is_valid() assert plumb.time_res == int( utils.s_to_micros(0.2) / utils.DEFAULT_RESOLUTION_SCALE) assert plumb.edges() == [ (2, 3, 'valve2.B1', { 'FC': utils.teq_to_FC(utils.s_to_micros(0)) }), (3, 2, 'valve2.B2', { 'FC': utils.teq_to_FC(utils.s_to_micros(0)) }), ] assert plumb.nodes() == [ (2, { 'body': top.GenericNode(0) }), (3, { 'body': top.GenericNode(100) }), ] assert plumb.current_state('valve2') == 'open'
def test_generic_equality(): pressure = 10 node = top.GenericNode(pressure, True) same_node = top.GenericNode(pressure, True) assert node == same_node diff_pressure = top.GenericNode(0, True) diff_fixed = top.GenericNode(pressure, False) assert node != diff_pressure assert node != diff_fixed diff_type = top.AtmNode() assert node != diff_type
def test_set_pressure_errors(): plumb = test.two_valve_setup(0.5, 0.2, 10, utils.CLOSED, 0.5, 0.2, 10, utils.CLOSED) pc = test.create_component(0, 0, 0, 1, 'valve3', 'C') mapping = {1: 3, 2: 4} plumb.add_component(pc, mapping, 'closed', {4: (50, False)}) pc_vent = test.create_component(0, 0, 0, 0, 'vent', 'D') mapping_vent = {1: 4, 2: utils.ATM} plumb.add_component(pc_vent, mapping_vent, 'closed') negative_pressure = -20 not_a_number = 'potato' with pytest.raises(exceptions.BadInputError) as err: plumb.set_pressure(4, negative_pressure) assert str( err.value) == f"Negative pressure {negative_pressure} not allowed." with pytest.raises(exceptions.BadInputError) as err: plumb.set_pressure(4, not_a_number) assert str(err.value) == f"Pressure {not_a_number} must be a number." assert plumb.nodes() == [(1, { 'body': top.GenericNode(0) }), (2, { 'body': top.GenericNode(0) }), (3, { 'body': top.GenericNode(100) }), (4, { 'body': top.GenericNode(50) }), (utils.ATM, { 'body': top.AtmNode() })] nonexistent_node = 5 with pytest.raises(exceptions.BadInputError) as err: plumb.set_pressure(nonexistent_node, 100) assert str(err.value) == f"Node {nonexistent_node} not found in graph." plumb.set_pressure(4, 100) assert plumb.nodes() == [(1, { 'body': top.GenericNode(0) }), (2, { 'body': top.GenericNode(0) }), (3, { 'body': top.GenericNode(100) }), (4, { 'body': top.GenericNode(100) }), (utils.ATM, { 'body': top.AtmNode() })] with pytest.raises(exceptions.BadInputError) as err: plumb.set_pressure(utils.ATM, 100) assert str( err.value) == f"Pressure for atmosphere node ({utils.ATM}) must be 0."
def test_remove_add_errors(): plumb = test.two_valve_setup(0.5, 0.2, 10, utils.CLOSED, 0.5, 0.2, 10, utils.CLOSED) name = 'valve3' wrong_node = 3 right_node = 2 pc = test.create_component(0, 0, 0, 1, name, 'C') mapping = {1: 3, wrong_node: 4} with pytest.raises(exceptions.BadInputError) as err: plumb.add_component(pc, mapping, 'closed', {4: (50, False)}) assert str(err.value) ==\ f"Component '{name}', node {right_node} not found in mapping dict." plumb.remove_component(name) assert plumb.is_valid() assert plumb.time_res == int( utils.s_to_micros(0.2) / utils.DEFAULT_RESOLUTION_SCALE) assert plumb.edges() == [ (1, 2, 'valve1.A1', { 'FC': utils.teq_to_FC(utils.s_to_micros(10)) }), (2, 1, 'valve1.A2', { 'FC': 0 }), (2, 3, 'valve2.B1', { 'FC': utils.teq_to_FC(utils.s_to_micros(0.5)) }), (3, 2, 'valve2.B2', { 'FC': utils.teq_to_FC(utils.s_to_micros(0.2)) }), ] assert plumb.nodes() == [ (1, { 'body': top.GenericNode(0) }), (2, { 'body': top.GenericNode(0) }), (3, { 'body': top.GenericNode(100) }), ] assert plumb.current_state('valve1') == 'closed' assert plumb.current_state('valve2') == 'open'
def test_list_functions(): pc1 = test.create_component(0.5, 0.2, 10, utils.CLOSED, 'valve1', 'A') pc2 = test.create_component(0.5, 0.2, 10, utils.CLOSED, 'valve2', 'B') component_mapping = { 'valve1': { 1: 1, 2: 2 }, 'valve2': { 1: 2, 2: 3 } } negative_pressure = -50 pressures = {3: (negative_pressure, False)} default_states = {'valve1': 'closed', 'valve2': 'open'} plumb = top.PlumbingEngine( {'valve1': pc1, 'valve2': pc2}, component_mapping, pressures, default_states) assert plumb.edges() == [ (1, 2, 'valve1.A1', {'FC': utils.teq_to_FC(utils.s_to_micros(10))}), (2, 1, 'valve1.A2', {'FC': 0}), (2, 3, 'valve2.B1', {'FC': utils.teq_to_FC(utils.s_to_micros(0.5))}), (3, 2, 'valve2.B2', {'FC': utils.teq_to_FC(utils.s_to_micros(0.2))}) ] assert plumb.edges(data=False) == [ (1, 2, 'valve1.A1'), (2, 1, 'valve1.A2'), (2, 3, 'valve2.B1'), (3, 2, 'valve2.B2') ] # Pressure at node 3 will be 0, since the provided one was invalid assert plumb.nodes() == [ (1, {'body': top.GenericNode(0)}), (2, {'body': top.GenericNode(0)}), (3, {'body': top.GenericNode(0)}), ] assert plumb.nodes(data=False) == [1, 2, 3] assert plumb.errors() == { invalid.InvalidNodePressure(f"Negative pressure {negative_pressure} not allowed.", 3) }
def test_add_remove(): old_lowest_teq = 0.2 plumb = test.two_valve_setup(0.5, old_lowest_teq, 10, utils.CLOSED, 0.5, old_lowest_teq, 10, utils.CLOSED) new_lowest_teq = 0.1 pc = test.create_component(0, 0, 0, new_lowest_teq, 'valve3', 'C') mapping = {1: 3, 2: 4} plumb.add_component(pc, mapping, 'closed', {4: (50, False)}) assert plumb.time_res ==\ int(utils.s_to_micros(new_lowest_teq) / utils.DEFAULT_RESOLUTION_SCALE) plumb.remove_component('valve3') assert plumb.is_valid() assert plumb.time_res ==\ int(utils.s_to_micros(old_lowest_teq) / utils.DEFAULT_RESOLUTION_SCALE) assert plumb.edges() == [ (1, 2, 'valve1.A1', { 'FC': utils.teq_to_FC(utils.s_to_micros(10)) }), (2, 1, 'valve1.A2', { 'FC': 0 }), (2, 3, 'valve2.B1', { 'FC': utils.teq_to_FC(utils.s_to_micros(0.5)) }), (3, 2, 'valve2.B2', { 'FC': utils.teq_to_FC(utils.s_to_micros(0.2)) }), ] assert plumb.nodes() == [ (1, { 'body': top.GenericNode(0) }), (2, { 'body': top.GenericNode(0) }), (3, { 'body': top.GenericNode(100) }), ] assert plumb.current_state('valve1') == 'closed' assert plumb.current_state('valve2') == 'open'
def test_atm_equality(): atm_node = top.AtmNode() another_atm_node = top.AtmNode() assert atm_node == another_atm_node almost_atm_node = top.GenericNode(0, True) assert atm_node != almost_atm_node
def test_add_to_empty(): plumb = top.PlumbingEngine() pc = test.create_component(2, utils.CLOSED, 0, 0, 'valve', 'A') mapping = {1: 1, 2: 2} plumb.add_component(pc, mapping, 'open', {1: (20, False)}) assert plumb.is_valid() assert plumb.time_res == utils.DEFAULT_TIME_RESOLUTION_MICROS assert plumb.edges() == [(1, 2, 'valve.A1', { 'FC': utils.teq_to_FC(utils.s_to_micros(2)) }), (2, 1, 'valve.A2', { 'FC': 0 })] assert plumb.nodes() == [(1, { 'body': top.GenericNode(20) }), (2, { 'body': top.GenericNode(0) })] assert plumb.current_state('valve') == 'open'
def test_open_closed_valves(): plumb = test.two_valve_setup(0, 0, utils.CLOSED, utils.CLOSED, 0, 0, utils.CLOSED, utils.CLOSED) assert plumb.time_res == utils.DEFAULT_TIME_RESOLUTION_MICROS assert plumb.edges() == [(1, 2, 'valve1.A1', { 'FC': 0 }), (2, 1, 'valve1.A2', { 'FC': 0 }), (2, 3, 'valve2.B1', { 'FC': utils.FC_MAX }), (3, 2, 'valve2.B2', { 'FC': utils.FC_MAX })] assert plumb.nodes() == [(1, { 'body': top.GenericNode(0) }), (2, { 'body': top.GenericNode(0) }), (3, { 'body': top.GenericNode(100) })] assert plumb.current_state('valve1') == 'closed' assert plumb.current_state('valve2') == 'open'
def test_generic_node(): node = top.GenericNode() assert node.get_pressure() == 0 assert not node.get_fixed() new_pressure = 100 node.update_pressure(new_pressure) assert node.get_pressure() == new_pressure assert not node.get_fixed() node.update_fixed(True) assert node.get_pressure() == new_pressure assert node.get_fixed() # just make sure this doesn't error node.__str__()