def test_FC_name_overlap():
    pc1 = test.create_component(0, 0, 0, 0, 'fill_valve', 'A')
    pc2 = test.create_component(1, 1, 1, 1, 'remote_fill_valve', 'B')

    component_mapping = {
        'fill_valve': {
            1: 1,
            2: 2
        },
        'remote_fill_valve': {
            1: 2,
            2: 3
        }
    }

    pressures = {3: (100, False)}
    default_states = {'fill_valve': 'closed', 'remote_fill_valve': 'open'}
    plumb = top.PlumbingEngine(
        {'fill_valve': pc1, 'remote_fill_valve': pc2}, component_mapping, pressures, default_states)

    assert plumb.current_FC('fill_valve') == {
        (1, 2, 'fill_valve.A1'): utils.FC_MAX,
        (2, 1, 'fill_valve.A2'): utils.FC_MAX
    }

    # Since these edges belongs only to remote_fill_valve
    assert (2, 3, 'remote_fill_valve.B1') not in plumb.current_FC('fill_valve')
    assert (3, 2, 'remote_fill_valve.B2') not in plumb.current_FC('fill_valve')

    assert plumb.current_FC('remote_fill_valve') == {
        (2, 3, 'remote_fill_valve.B1'): utils.teq_to_FC(utils.s_to_micros(1)),
        (3, 2, 'remote_fill_valve.B2'): utils.teq_to_FC(utils.s_to_micros(1))
    }
def test_missing_component():
    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()
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_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_missing_node_pressure():
    wrong_node_name = 4
    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 = {wrong_node_name: (100, False), 2: (100, False)}
    default_states = {'valve1': 'closed', 'valve2': 'open'}
    with pytest.raises(exceptions.BadInputError) as err:
        _ = top.PlumbingEngine({
            'valve1': pc1,
            'valve2': pc2
        }, component_mapping, pressures, default_states)
    assert str(err.value) == f"Node {wrong_node_name} not found in graph."
def test_2():
    pc = test.create_component(1, 1, utils.CLOSED, utils.CLOSED, 'valve', 'A')
    mapping = {'valve': {1: 1, 2: 2}}
    pressures = {1: (100, False)}
    default_states = {'valve': 'open'}
    step_plumb = top.PlumbingEngine({'valve': pc}, mapping, pressures,
                                    default_states)
    step_plumb.set_component_state('valve', 'closed')
    curr_nodes = step_plumb.nodes()
    step_plumb.step()
    assert curr_nodes == step_plumb.nodes()

    steady_by = utils.s_to_micros(1)
    converged = {1: 50, 2: 50}

    step_plumb.set_component_state('valve', 'open')
    step_state = step_plumb.step(1e6)

    solve_plumb = top.PlumbingEngine({'valve': pc}, mapping, pressures,
                                     default_states)
    solve_state = solve_plumb.solve()

    len_plumb = top.PlumbingEngine({'valve': pc}, mapping, pressures,
                                   default_states)
    solve_len = len(len_plumb.solve(return_resolution=len_plumb.time_res))
    test.validate_plumbing_engine(step_plumb, solve_plumb, steady_by,
                                  converged, solve_state, step_state,
                                  solve_len, len_plumb.time_res)
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_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'
Example #9
0
def make_plumb():
    """
    The engine that's been set up looks like this:
    +-----+           +-----+           +-----+           +-----+
    |     |  --C-->   |     |  --40->   |     |  --5-->   |     |
    |  1  |           |  2  |           |  3  |           | atm |
    |     |  <-10--   |     |  <-45--   |     |  <-5---   |     |
    +-----+           +-----+           +-----+           +-----+
    100               100                100                 0

    Result annotation:
    - node 1 stays at 100 the entire duration because 1->2 is closed, so no pressure can flow out
        of node 1.

    - node 3's pressure drops much more quickly than node 2's because its teq to atm (5) is much
        lower than the teq in the 2->3 connection (50). Pressure from 3 flows into atm much faster
        than it's replenished by pressure from 2.

    - pressure at atm stays at 0, because pressure at atm is always 0.

    """

    ret = test.two_valve_setup(1, 1, utils.CLOSED, 10, 40, 45, 1, 1)
    comp = test.create_component(5, 5, utils.CLOSED, utils.CLOSED, 'vent', 'A')
    mapping = {
        1: 3,
        2: utils.ATM,
    }
    ret.add_component(comp, mapping, 'open')
    ret.set_pressure(1, 100)
    ret.set_pressure(2, 100)
    return ret
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_wrong_node_mapping():
    proper_node_name = 1
    wrong_node_name = 5
    pc1 = test.create_component(0, 0, 0, 0, 'valve1', 'A')
    pc2 = test.create_component(0, 0, 0, 0, 'valve2', 'B')

    component_mapping = {
        'valve1': {
            wrong_node_name: 1,
            2: 8
        },
        'valve2': {
            1: 8,
            2: 3
        }
    }

    pressures = {3: (100, False)}
    default_states = {'valve1': 'closed', 'valve2': 'open'}
    plumb = top.PlumbingEngine({
        'valve1': pc1,
        'valve2': pc2
    }, component_mapping, pressures, default_states)

    assert not plumb.is_valid()

    # Since the node name is wrong in the mapping, an error should be added
    # every time the mapping dict is accessed to find the matching graph node.
    # This translates to twice (once per component) when populating the main graph,
    # and twice (once per component) when assigning initial states by component,
    # since the component node stored in the component's states dict needs to be
    # translated into a main graph node. So 4 errors total, but they're identical
    # so we should get one original error and one multi-error note.
    assert len(plumb.errors()) == 2

    error = invalid.InvalidComponentNode(
        f"Component 'valve1', node {proper_node_name} not found in mapping dict.",
        'valve1', proper_node_name)

    duplicate_error = invalid.DuplicateError(
        invalid.multi_error_msg(
            f"Component 'valve1', node {proper_node_name} not found in mapping dict."
        ), error)

    assert error in plumb.errors()
    assert duplicate_error in plumb.errors()
def test_3():
    pc = test.create_component(1, 1, utils.CLOSED, utils.CLOSED, 'vent', 'A')
    mapping = {'vent': {1: 1, 2: utils.ATM}}
    pressures = {1: (100, False)}
    default_states = {'vent': 'closed'}
    plumb = top.PlumbingEngine({'vent': pc}, mapping, pressures,
                               default_states)
    test.assert_no_change(plumb)
def test_error_reset():
    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()

    plumb = top.PlumbingEngine()

    assert plumb.is_valid()
def test_invalid_engine():
    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()
    with pytest.raises(exceptions.InvalidEngineError) as err:
        plumb.step(5)
    assert str(
        err.value
    ) == "Step() cannot be called on an invalid engine. Check for errors."
def test_add_component_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."
def test_load_errorless_graph():
    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()

    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.load_graph(plumb0.component_dict, plumb0.mapping, pressures,
                     default_states)

    assert plumb.is_valid()
def test_engine_dicts_remain_unchanged():
    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'}
    component_dict = {'valve1': pc1, 'valve2': pc2}
    _ = top.PlumbingEngine(component_dict, component_mapping, pressures,
                           default_states)

    assert component_mapping == {
        'valve1': {
            1: 1,
            2: 2
        },
        'valve2': {
            1: 2,
            2: 3
        }
    }
    assert pressures == {3: (100, False)}
    assert default_states == {'valve1': 'closed', 'valve2': 'open'}
    assert component_dict == {'valve1': pc1, 'valve2': pc2}
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_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_reset_added_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.reset(True)

    plumb_initial = test.two_valve_setup(0.5, 0.2, 10, utils.CLOSED, 0.5, 0.2,
                                         10, utils.CLOSED)

    assert plumb.time == 0
    assert plumb.is_valid()
    assert plumb.time_res == plumb_initial.time_res
    assert plumb.edges() == plumb_initial.edges()
    assert plumb.nodes() == plumb_initial.nodes()
    assert plumb.current_state() == plumb_initial.current_state()
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_1():
    pc = test.create_component(1, 1, 1, 1, 'vent', 'A')
    mapping = {'vent': {1: 1, 2: utils.ATM}}
    pressures = {1: (100, False)}
    default_states = {'vent': 'open'}

    steady_by = utils.s_to_micros(1)
    converged = {1: 0, utils.ATM: 0}

    step_plumb = top.PlumbingEngine({'vent': pc}, mapping, pressures,
                                    default_states)
    step_state = step_plumb.step(1e6)

    solve_plumb = top.PlumbingEngine({'vent': pc}, mapping, pressures,
                                     default_states)
    solve_state = solve_plumb.solve()

    len_plumb = top.PlumbingEngine({'vent': pc}, mapping, pressures,
                                   default_states)
    solve_len = len(len_plumb.solve(return_resolution=len_plumb.time_res))
    test.validate_plumbing_engine(step_plumb, solve_plumb, steady_by,
                                  converged, solve_state, step_state,
                                  solve_len, len_plumb.time_res)