Beispiel #1
0
def test_every_block_compilation(parser):
    """Make sure we can compile a simple every block."""

    parser.parse_file(get_path(u'basic_every_1min.sgf'))

    model = DeviceModel()
    parser.compile(model=model)

    sg = parser.sensor_graph
    log = sg.sensor_log
    for x in sg.dump_nodes():
        print(x)

    assert len(sg.nodes) == 7

    sg.load_constants()
    # Now make sure it produces the right output
    counter15 = log.create_walker(DataStreamSelector.FromString('counter 15'))
    counter16 = log.create_walker(DataStreamSelector.FromString('counter 16'))

    sim = SensorGraphSimulator(sg)
    sim.stop_condition('run_time 120 seconds')
    sim.run()

    assert counter15.count() == 2
    assert counter16.count() == 2
Beispiel #2
0
def test_on_block(parser):
    """Make sure on count(stream), on value(stream) and on stream work."""

    parser.parse_file(get_path(u'basic_on.sgf'))

    model = DeviceModel()
    parser.compile(model=model)

    sg = parser.sensor_graph
    log = sg.sensor_log
    for x in sg.dump_nodes():
        print(x)

    sg.load_constants()

    counter1 = log.create_walker(DataStreamSelector.FromString('counter 1'))
    counter2 = log.create_walker(DataStreamSelector.FromString('counter 2'))
    counter3 = log.create_walker(DataStreamSelector.FromString('counter 3'))

    sim = SensorGraphSimulator(sg)
    sim.step(DataStream.FromString('input 1'), 8)

    assert counter1.count() == 0
    assert counter2.count() == 0
    assert counter3.count() == 0

    for i in range(0, 10):
        sim.step(DataStream.FromString('input 1'), 5)

    assert counter1.count() == 10
    assert counter2.count() == 5
    assert counter3.count() == 5
def test_seek_walker():
    """Make sure we can seek a walker can count with an offset."""

    model = DeviceModel()
    log = SensorLog(model=model)

    stream = DataStream.FromString('buffered 1')
    reading = IOTileReading(stream.encode(), 0, 1)
    log.push(stream, reading)
    log.push(stream, reading)
    log.push(DataStream.FromString('buffered 2'), reading)
    log.push(stream, reading)

    walk = log.create_walker(DataStreamSelector.FromString('buffered 1'),
                             skip_all=False)
    assert walk.offset == 0
    assert walk.count() == 3

    walk.seek(1)
    assert walk.offset == 1
    assert walk.count() == 2

    # Make sure we can seek to a position corresponding to another stream
    walk.seek(2)
    assert walk.offset == 2
    assert walk.count() == 1

    # Make sure we can find a reading by reading ID
    walk = log.create_walker(DataStreamSelector.FromString('output 1'),
                             skip_all=False)

    output1 = DataStream.FromString('output 1')
    output2 = DataStream.FromString('output 2')
    log.push(output1, IOTileReading(0, 0, 1, reading_id=1))
    log.push(output1, IOTileReading(0, 0, 1, reading_id=2))
    log.push(output2, IOTileReading(0, 0, 1, reading_id=3))
    log.push(output1, IOTileReading(0, 0, 1, reading_id=4))

    exact = walk.seek(2, target='id')
    assert exact is True
    assert walk.count() == 2
    assert walk.offset == 1

    exact = walk.seek(3, target='id')
    assert exact is False
    assert walk.count() == 1
    assert walk.offset == 2

    # Verify exceptions thrown by seek()
    with pytest.raises(UnresolvedIdentifierError):
        walk.seek(5, target='id')

    with pytest.raises(UnresolvedIdentifierError):
        walk.seek(5, target=u'id')

    with pytest.raises(UnresolvedIdentifierError):
        walk.seek(5, target='offset')

    with pytest.raises(ArgumentError):
        walk.seek(2, target="unsupported")
def test_selector_parsing():
    """Make sure we can parse DataStreamSelector strings."""

    # Make sure parsing stream type works
    stream = DataStreamSelector.FromString('buffered 1')
    assert stream.match_type == DataStream.BufferedType
    stream = DataStreamSelector.FromString(u'buffered 1')
    assert stream.match_type == DataStream.BufferedType

    stream = DataStreamSelector.FromString('unbuffered 1')
    assert stream.match_type == DataStream.UnbufferedType
    stream = DataStreamSelector.FromString(u'unbuffered 1')
    assert stream.match_type == DataStream.UnbufferedType

    stream = DataStreamSelector.FromString('counter 1')
    assert stream.match_type == DataStream.CounterType
    stream = DataStreamSelector.FromString(u'counter 1')
    assert stream.match_type == DataStream.CounterType

    stream = DataStreamSelector.FromString('constant 1')
    assert stream.match_type == DataStream.ConstantType
    stream = DataStreamSelector.FromString(u'constant 1')
    assert stream.match_type == DataStream.ConstantType

    stream = DataStreamSelector.FromString('output 1')
    assert stream.match_type == DataStream.OutputType
    stream = DataStreamSelector.FromString(u'output 1')
    assert stream.match_type == DataStream.OutputType
Beispiel #5
0
def test_copy_statement(parser):
    """Make sure we can copy data using copy."""

    parser.parse_file(get_path(u'basic_copy.sgf'))

    model = DeviceModel()
    parser.compile(model=model)

    sg = parser.sensor_graph
    log = sg.sensor_log
    for x in sg.dump_nodes():
        print(x)

    sg.load_constants()

    output1 = log.create_walker(DataStreamSelector.FromString('output 1'))
    output2 = log.create_walker(DataStreamSelector.FromString('output 2'))
    output3 = log.create_walker(DataStreamSelector.FromString('output 3'))

    sim = SensorGraphSimulator(sg)
    sim.stop_condition('run_time 60 seconds')
    sim.run()

    assert output1.count() == 1
    assert output2.count() == 1
    assert output3.count() == 1
    val1 = output1.pop()
    val2 = output2.pop()
    val3 = output3.pop()

    assert val1.value == 0
    assert val2.value == 60
    assert val3.value == 1
Beispiel #6
0
def test_every_block_with_buffering(parser):
    """Make sure we can compile and simulate an every block with buffered data."""

    parser.parse_file(get_path(u'basic_output.sgf'))

    model = DeviceModel()
    parser.compile(model=model)

    sg = parser.sensor_graph
    log = sg.sensor_log
    for x in sg.dump_nodes():
        print(x)

    assert len(sg.nodes) == 7

    sg.load_constants()
    # Now make sure it produces the right output
    output1 = log.create_walker(DataStreamSelector.FromString('output 1'))
    buffered1 = log.create_walker(DataStreamSelector.FromString('buffered 1'))

    sim = SensorGraphSimulator(sg)
    sim.stop_condition('run_time 120 seconds')
    sim.run()

    assert output1.count() == 12
    assert buffered1.count() == 12
Beispiel #7
0
def test_every_block_splitting(parser):
    """Make sure we can split nodes in an every block."""

    parser.parse_file(get_path(u'basic_every_split.sgf'))

    model = DeviceModel()
    parser.compile(model=model)

    sg = parser.sensor_graph
    log = sg.sensor_log
    for x in sg.dump_nodes():
        print(x)

    assert len(sg.nodes) == 10

    # Now make sure it produces the right output
    counter15 = log.create_walker(DataStreamSelector.FromString('counter 15'))
    counter16 = log.create_walker(DataStreamSelector.FromString('counter 16'))
    counter17 = log.create_walker(DataStreamSelector.FromString('counter 16'))
    counter18 = log.create_walker(DataStreamSelector.FromString('counter 16'))

    sg.load_constants()

    sim = SensorGraphSimulator(sg)
    sim.stop_condition('run_time 120 seconds')
    sim.run()

    sg.load_constants()

    print([str(x) for x in log._last_values.keys()])

    assert counter15.count() == 2
    assert counter16.count() == 2
    assert counter17.count() == 2
    assert counter18.count() == 2
Beispiel #8
0
def test_root_buffering(parser):
    """Make sure that nodes with two inputs where only one of the inputs is a root node gets an unbuffered
    node in between. Furthermore, check that after topographic sorting, the root nodes are all at the top."""

    parser.parse_file(get_path(u'basic_root_buffering.sgf'))

    model = DeviceModel()
    parser.compile(model=model)

    sg = parser.sensor_graph
    log = sg.sensor_log
    for x in sg.dump_nodes():
        print(x)

    assert len(sg.nodes) == 21

    #This check is to ensure that all root (input) nodes at the beginning after sorting.
    root_node_section_passed = False
    for node in sg.nodes:
        if not root_node_section_passed:
            if 'input' not in str(node):
                root_node_section_passed = True
        else:
            assert 'input' not in str(node)

    # Now make sure it produces the right output
    output11 = log.create_walker(DataStreamSelector.FromString('output 11'))
    output12 = log.create_walker(DataStreamSelector.FromString('output 12'))
    output13 = log.create_walker(DataStreamSelector.FromString('output 13'))
    output14 = log.create_walker(DataStreamSelector.FromString('output 14'))
    output15 = log.create_walker(DataStreamSelector.FromString('output 15'))

    sg.load_constants()

    sim = SensorGraphSimulator(sg)
    sim.stop_condition('run_time 20 minutes')
    sim.stimulus("1 minute: input 1 = 1")
    sim.stimulus("1 minute: input 2 = 1")
    sim.stimulus("11 minute: input 1 = 2")

    sim.run()

    sg.load_constants()

    print([str(x) for x in log._last_values.keys()])

    assert output11.count() == 2
    assert output12.count() == 2
    assert output13.count() == 2
    assert output14.count() == 2
    assert output15.count() == 1
Beispiel #9
0
def test_copy_count_statement(parser):
    """Make sure we can copy data count using copy count."""

    parser.parse_file(get_path(u'count.sgf'))

    model = DeviceModel()
    parser.compile(model=model)

    sg = parser.sensor_graph
    log = sg.sensor_log

    for x in sg.dump_nodes():
        print(x)

    sg.load_constants()

    output = log.create_walker(DataStreamSelector.FromString('output 1'))

    sim = SensorGraphSimulator(sg)
    sim.stop_condition('run_time 3 seconds')
    sim.step(user_connected, 8)  # Simulates a connected user
    sim.run()
    print(output)
    assert output.count() == 1
    print(output)
Beispiel #10
0
def test_copy_constant_statement(parser):
    """Make sure we can copy constant values."""

    parser.parse_file(get_path(u'basic_copy_constant.sgf'))

    model = DeviceModel()
    parser.compile(model=model)

    sg = parser.sensor_graph
    log = sg.sensor_log
    for x in sg.dump_nodes():
        print(x)

    sg.load_constants()

    output1 = log.create_walker(DataStreamSelector.FromString('output 1'))

    sim = SensorGraphSimulator(sg)
    sim.stop_condition('run_time 10 seconds')
    sim.run()

    assert output1.count() == 1
    assert output1.pop().value == 15

    sim.step(DataStream.FromString('input 1'), 10)
    assert output1.count() == 1
    assert output1.pop().value == 0x10
Beispiel #11
0
def test_on_block_dual(parser):
    """Make sure on with two conditions works."""

    parser.parse_file(get_path(u'basic_on_dual.sgf'))

    model = DeviceModel()
    parser.compile(model=model)

    sg = parser.sensor_graph
    log = sg.sensor_log
    for x in sg.dump_nodes():
        print(x)

    sg.load_constants()

    counter1 = log.create_walker(DataStreamSelector.FromString('counter 1'))

    sim = SensorGraphSimulator(sg)
    sim.step(DataStream.FromString('input 1'), 5)

    assert counter1.count() == 0

    sim.step(DataStream.FromString('input 2'), 1)
    for _i in range(0, 10):
        sim.step(DataStream.FromString('input 1'), 5)

    assert counter1.count() == 11

    sim.step(DataStream.FromString('input 2'), 0)
    for _i in range(0, 10):
        sim.step(DataStream.FromString('input 1'), 5)

    assert counter1.count() == 11
Beispiel #12
0
def test_when_block_clock(parser):
    """Make sure we can compile when blocks (without identifiers)."""

    parser.parse_file(get_path(u'basic_when.sgf'))

    model = DeviceModel()
    parser.compile(model=model)

    sg = parser.sensor_graph
    log = sg.sensor_log
    for x in sg.dump_nodes():
        print(x)

    sg.load_constants()
    assert sg.get_tick('fast') == 1

    # Now make sure it produces the right output
    counter15 = log.create_walker(DataStreamSelector.FromString('counter 15'))
    sim = SensorGraphSimulator(sg)
    sim.stop_condition('run_time 60 seconds')
    sim.run()
    assert counter15.count() == 0

    sim.step(DataStream.FromString('system input 1025'), 8)
    assert counter15.count() == 1
    counter15.skip_all()

    sim.run()

    assert counter15.count() == 60

    counter15.skip_all()
    sim.step(DataStream.FromString('system input 1026'), 8)
    sim.run()
    assert counter15.count() == 0
Beispiel #13
0
def test_counter_walker():
    """Make sure counter walkers work correctly."""

    model = DeviceModel()
    log = SensorLog(model=model)

    walk = log.create_walker(DataStreamSelector.FromString('counter 1'))
    stream = DataStream.FromString('counter 1')
    reading = IOTileReading(0, 1, 1)

    assert walk.count() == 0
    log.push(stream, IOTileReading(0, 1, 1))
    assert walk.count() == 1
    assert walk.peek().value == 1

    log.push(stream, IOTileReading(0, 1, 3))
    assert walk.count() == 2
    assert walk.peek().value == 3

    val = walk.pop()
    assert walk.count() == 1
    assert val.value == 3

    val = walk.pop()
    assert walk.count() == 0
    assert val.value == 3

    with pytest.raises(StreamEmptyError):
        walk.pop()
Beispiel #14
0
def test_storage_streaming_walkers():
    """Make sure the storage and streaming walkers work simultaneously."""

    model = DeviceModel()
    log = SensorLog(model=model)


    storage_walk = log.create_walker(DataStreamSelector.FromString('buffered 1'))
    output_walk = log.create_walker(DataStreamSelector.FromString('output 1'))
    storage1 = DataStream.FromString('buffered 1')
    storage2 = DataStream.FromString('buffered 2')
    output1 = DataStream.FromString('output 1')
    output2 = DataStream.FromString('output 2')

    assert storage_walk.offset == 0
    assert output_walk.offset == 0

    for i in range(0, 5000):
        reading = IOTileReading(0, 0, i)
        log.push(storage1, reading)
        log.push(storage2, reading)
        log.push(output1, reading)
        log.push(output2, reading)

        assert storage_walk.count() == (i + 1)
        assert output_walk.count() == (i + 1)
        assert storage_walk.offset == 0
        assert output_walk.offset == 0

    for i in range(0, 5000):
        reading1 = storage_walk.pop()
        reading2 = output_walk.pop()

        assert reading1.value == i
        assert reading1.stream == storage1.encode()
        assert reading2.value == i
        assert reading2.stream == output1.encode()
        assert storage_walk.offset == (2 * i) + 1
        assert output_walk.offset == (2* i) + 1

    log.clear()

    assert storage_walk.count() == 0
    assert storage_walk.offset == 0

    assert output_walk.count() == 0
    assert output_walk.offset == 0
def test_encoding():
    """Test data stream and selector encoding."""

    sel = DataStreamSelector.FromString(u'all system output')
    assert sel.encode() == 0x5FFF

    sel = DataStreamSelector.FromString(u'all user output')
    assert sel.encode() == 0x57FF

    sel = DataStreamSelector.FromString(u'all output')
    assert sel.encode() == 0xD7FF

    sel = DataStreamSelector.FromString(u'all combined output')
    assert sel.encode() == 0xDFFF

    stream = DataStream.FromString('output 1')
    assert stream.encode() == 0x5001

    stream = DataStream.FromString('unbuffered 10')
    assert stream.encode() == 0x100a
def test_matching():
    """Test selector stream matching."""

    sel = DataStreamSelector.FromString(u'all system buffered')
    assert sel.matches(DataStream.FromString('system buffered 1'))
    assert not sel.matches(DataStream.FromString('buffered 1'))
    assert not sel.matches(DataStream.FromString('counter 1'))

    sel = DataStreamSelector.FromString(u'all user outputs')
    assert sel.matches(DataStream.FromString('output 1'))
    assert not sel.matches(DataStream.FromString('system output 1'))
    assert not sel.matches(DataStream.FromString('counter 1'))

    sel = DataStreamSelector.FromString(u'all combined outputs')
    assert sel.matches(DataStream.FromString('output 1'))
    assert sel.matches(DataStream.FromString('system output 1'))
    assert not sel.matches(DataStream.FromString('counter 1'))

    sel = DataStreamSelector.FromString(u'all outputs')
    assert sel.matches(DataStream.FromString('output 1'))
    assert sel.matches(DataStream.FromString('system output 1024'))
    assert not sel.matches(DataStream.FromString('system output 1'))
    assert not sel.matches(DataStream.FromString('counter 1'))
Beispiel #17
0
def test_subtract_statement(parser):
    """Make sure we can copy data using subtract."""

    parser.parse_file(get_path(u'basic_subtract.sgf'))

    model = DeviceModel()
    parser.compile(model=model)

    sg = parser.sensor_graph
    log = sg.sensor_log
    for x in sg.dump_nodes():
        print(x)

    sg.load_constants()

    output1 = log.create_walker(DataStreamSelector.FromString('unbuffered 1'))
    output2 = log.create_walker(DataStreamSelector.FromString('unbuffered 2'))
    output3 = log.create_walker(DataStreamSelector.FromString('unbuffered 3'))

    sg.process_input(DataStream.FromString('input 1'), IOTileReading(0, 0, 15),
                     None)
    sg.process_input(DataStream.FromString('input 2'), IOTileReading(0, 0, 20),
                     None)
    sg.process_input(DataStream.FromString('input 3'), IOTileReading(0, 0, 25),
                     None)

    assert output1.count() == 1
    assert output2.count() == 1
    assert output3.count() == 1

    val1 = output1.pop()
    val2 = output2.pop()
    val3 = output3.pop()

    assert val1.value == 5
    assert val2.value == 10
    assert val3.value == 25
def test_selector_from_encoded():
    """Make sure we can create a selector from an encoded value."""

    sel = DataStreamSelector.FromEncoded(0x5FFF)
    assert str(sel) == 'all system outputs'

    sel = DataStreamSelector.FromEncoded(0xD7FF)
    assert str(sel) == 'all outputs'

    sel = DataStreamSelector.FromEncoded(0x100a)
    assert str(sel) == 'unbuffered 10'

    assert str(
        DataStreamSelector.FromEncoded(
            DataStreamSelector.FromString(
                'all combined output').encode())) == 'all combined outputs'
Beispiel #19
0
def test_walker_at_beginning():
    """Make sure we can start a walker at the beginning of a stream."""

    model = DeviceModel()
    log = SensorLog(model=model)

    stream = DataStream.FromString('buffered 1')
    reading = IOTileReading(stream.encode(), 0, 1)
    log.push(stream, reading)
    log.push(stream, reading)
    log.push(DataStream.FromString('buffered 2'), reading)

    walk = log.create_walker(DataStreamSelector.FromString('buffered 1'),
                             skip_all=False)
    assert walk.offset == 0
    assert walk.count() == 2
def test_stream_selector_id_parsing():
    """Make sure we can parse stream ids."""

    stream = DataStreamSelector.FromString('buffered 1')
    assert stream.match_id == 1
    assert stream.match_spec == DataStreamSelector.MatchUserOnly

    stream = DataStreamSelector.FromString('buffered 0x100')
    assert stream.match_id == 0x100
    assert stream.match_spec == DataStreamSelector.MatchUserOnly

    stream = DataStreamSelector.FromString(u'buffered 1')
    assert stream.match_id == 1
    assert stream.match_spec == DataStreamSelector.MatchUserOnly

    stream = DataStreamSelector.FromString(u'buffered 0x100')
    assert stream.match_id == 0x100
    assert stream.match_spec == DataStreamSelector.MatchUserOnly

    stream = DataStreamSelector.FromString(u'system buffered 0x100')
    assert stream.match_id == 0x100
    assert stream.match_spec == DataStreamSelector.MatchSystemOnly

    stream = DataStreamSelector.FromString(u'all buffered')
    assert stream.match_id is None
    assert stream.match_spec == DataStreamSelector.MatchUserAndBreaks

    stream = DataStreamSelector.FromString(u'all user buffered')
    assert stream.match_id is None
    assert stream.match_spec == DataStreamSelector.MatchUserOnly

    stream = DataStreamSelector.FromString(u'all combined buffered')
    assert stream.match_id is None
    assert stream.match_spec == DataStreamSelector.MatchCombined

    stream = DataStreamSelector.FromString(u'all system buffered')
    assert stream.match_id is None
    assert stream.match_spec == DataStreamSelector.MatchSystemOnly
Beispiel #21
0
def test_constant_walker():
    """Make sure constant walkers can be read any number of times."""

    model = DeviceModel()
    log = SensorLog(model=model)

    walk = log.create_walker(DataStreamSelector.FromString('constant 1'))
    stream = DataStream.FromString('constant 1')
    reading = IOTileReading(0, 1, 1)

    log.push(stream, reading)
    assert walk.count() == 0xFFFFFFFF

    log.push(stream, reading)
    assert walk.count() == 0xFFFFFFFF

    val = walk.pop()
    assert walk.count() == 0xFFFFFFFF

    val = walk.pop()
    assert walk.count() == 0xFFFFFFFF
Beispiel #22
0
def test_storage_walker():
    """Make sure the storage walker works."""

    model = DeviceModel()
    log = SensorLog(model=model)

    walk = log.create_walker(DataStreamSelector.FromString('buffered 1'))
    stream = DataStream.FromString('buffered 1')

    storage_size = model.get('max_storage_buffer')
    erase_size = model.get('buffer_erase_size')

    for i in range(0, storage_size):
        reading = IOTileReading(0, stream.encode(), i)
        log.push(stream, reading)

        assert walk.count() == (i + 1)

    # Make sure the overwrite happens correctly
    old_count = walk.count()
    reading = IOTileReading(0, stream.encode(), storage_size)
    log.push(stream, reading)
    assert walk.count() == (old_count - erase_size + 1)
Beispiel #23
0
def test_latch_block(parser):
    """Make sure that we can compile and run latch blocks."""

    parser.parse_file(get_path(u'basic_latch.sgf'))

    model = DeviceModel()
    parser.compile(model=model)

    sg = parser.sensor_graph
    log = sg.sensor_log
    for x in sg.dump_nodes():
        print(x)

    sg.load_constants()
    assert sg.get_tick('fast') == 1

    # Now make sure it produces the right output
    counter15 = log.create_walker(DataStreamSelector.FromString('counter 15'))

    sim = SensorGraphSimulator(sg)
    sim.stop_condition('run_time 60 seconds')
    sim.run()
    assert counter15.count() == 0

    sim.step(DataStream.FromString('input 10'), 1)
    assert log.inspect_last(DataStream.FromString('constant 1')).value == 1
    assert log.inspect_last(DataStream.FromString('constant 1024')).value == 1
    counter15.skip_all()

    sim.run()

    assert counter15.count() == 60

    counter15.skip_all()
    sim.step(DataStream.FromString('input 10'), 0)
    sim.run()
    assert counter15.count() == 0
Beispiel #24
0
def test_unbuffered_walker():
    """Make sure unbuffered walkers hold only 1 reading."""

    model = DeviceModel()
    log = SensorLog(model=model)

    walk = log.create_walker(DataStreamSelector.FromString('unbuffered 1'))
    stream = DataStream.FromString('unbuffered 1')

    assert walk.count() == 0
    log.push(stream, IOTileReading(0, 1, 1))
    assert walk.count() == 1
    assert walk.peek().value == 1

    log.push(stream, IOTileReading(0, 1, 3))
    assert walk.count() == 1
    assert walk.peek().value == 3

    val = walk.pop()
    assert walk.count() == 0
    assert val.value == 3

    with pytest.raises(StreamEmptyError):
        walk.pop()
def test_buffered_pluralization():
    """Make sure we don't incorrectly pluralize buffered streams."""

    sel = DataStreamSelector.FromString('all buffered')
    assert str(sel) == 'all buffered'
Beispiel #26
0
def main(argv=None):
    """Main entry point for iotile sensorgraph simulator.

    This is the iotile-sgrun command line program.  It takes
    an optional set of command line parameters to allow for
    testing.

    Args:
        argv (list of str): An optional set of command line
            parameters.  If not passed, these are taken from
            sys.argv.
    """

    if argv is None:
        argv = sys.argv[1:]

    try:
        executor = None
        parser = build_args()
        args = parser.parse_args(args=argv)

        model = DeviceModel()

        parser = SensorGraphFileParser()
        parser.parse_file(args.sensor_graph)
        parser.compile(model)

        if not args.disable_optimizer:
            opt = SensorGraphOptimizer()
            opt.optimize(parser.sensor_graph, model=model)

        graph = parser.sensor_graph
        sim = SensorGraphSimulator(graph)

        for stop in args.stop:
            sim.stop_condition(stop)

        for watch in args.watch:
            watch_sel = DataStreamSelector.FromString(watch)
            graph.sensor_log.watch(watch_sel, watch_printer)

        # If we are semihosting, create the appropriate executor connected to the device
        if args.semihost_device is not None:
            executor = SemihostedRPCExecutor(args.port, args.semihost_device)
            sim.rpc_executor = executor

        for mock in args.mock_rpc:
            slot, rpc_id, value = process_mock_rpc(mock)
            sim.rpc_executor.mock(slot, rpc_id, value)

        for stim in args.stimulus:
            sim.stimulus(stim)

        graph.load_constants()

        if args.trace is not None:
            sim.record_trace()

        try:
            if args.connected:
                sim.step(user_connected, 8)

            sim.run(accelerated=not args.realtime)
        except KeyboardInterrupt:
            pass

        if args.trace is not None:
            sim.trace.save(args.trace)
    finally:
        if executor is not None:
            executor.hw.close()

    return 0
Beispiel #27
0
    def run(self, sensor_graph, model):
        """Run this optimization pass on the sensor graph

        If necessary, information on the device model being targeted
        can be found in the associated model argument.

        Args:
            sensor_graph (SensorGraph): The sensor graph to optimize
            model (DeviceModel): The device model we're using
        """

        # Try to remove a node whose operation is copy_latest_a
        # It inherently does nothing, so it can be removed if:
        # 1. There is only one input triggering it
        # 2. The input is from another node (i.e. not a global sg input)
        # 3. The type of the input is the same as the type of the output
        # 4. There are enough output links in the input node to
        #    handle all of the downstream connections.  Note that we will
        #    reclaim one free output when we do the replacement.
        #    If there are multiple nodes that write to this input, all
        #    must have an available output.
        # 5. The stream is not a sensor graph output
        # 6. The trigger conditions for both inputs and outputs are either
        #    count based or always or value based with the same value.
        #
        # For each node, check if 1-6 are valid so we can remove it

        found_node = None
        found_inputs = None
        found_outputs = None

        for node, inputs, outputs in sensor_graph.iterate_bfs():
            if node.func_name != u'copy_latest_a':
                continue

            # Check 1
            if node.num_inputs != 1:
                continue

            # Check 2
            if len(inputs) == 0:
                continue

            can_combine = True
            for curr_input in inputs:
                # Check 3
                if curr_input.stream.stream_type != node.stream.stream_type:
                    can_combine = False
                    break

                # Check 4 (keep in mind we free up one output when we do the swap)
                if (curr_input.free_outputs + 1) < len(outputs):
                    can_combine = False
                    break

            if not can_combine:
                continue

            # Check 5
            if sensor_graph.is_output(node.stream):
                continue

            # Check 6
            for out in outputs:
                i = out.find_input(node.stream)
                _, trigger = out.inputs[i]

                # We can't merge things that could result in producing
                # multiple readings at a time since then combining the
                # trigger might change what number of outputs are
                # produced since:
                # trigger every 600 copy_latest then trigger every 1 copy_all
                # would produce one reading every 600 ticks.
                #
                # but:
                # trigger every 1 copy_latest then trigger every 600 copy_all
                # would produce 600 readings one every 600 ticks.
                if out.func_name == u'copy_all_a':
                    can_combine = False
                    break

                if not self._can_combine(node.inputs[0][1], trigger):
                    can_combine = False
                    break

            if not can_combine:
                continue

            found_node = node
            found_inputs = inputs
            found_outputs = outputs
            break

        if found_node is None:
            return False

        sensor_graph.nodes.remove(found_node)

        for input_node in found_inputs:
            input_node.outputs.remove(found_node)

        for output in found_outputs:
            i = output.find_input(found_node.stream)
            old_walker, old_trigger = output.inputs[i]

            new_trigger = self._try_combine(found_node.inputs[0][1],
                                            old_trigger)
            new_walker = sensor_graph.sensor_log.create_walker(
                DataStreamSelector.FromString(
                    str(found_node.inputs[0][0].selector)))
            sensor_graph.sensor_log.destroy_walker(old_walker)

            output.inputs[i] = (new_walker, new_trigger)

            for input_node in found_inputs:
                input_node.connect_output(output)

        if found_node in sensor_graph.roots:
            sensor_graph.roots.remove(found_node)

        sensor_graph.sensor_log.destroy_walker(found_node.inputs[0][0])
        return True
Beispiel #28
0
def test_language_constructs():
    """Make sure the basic sensor graph language constructs work."""

    # Create the parser
    language.get_language()

    # Test time interval parsing
    parsed = language.time_interval.parseString('1 day')
    assert parsed.asList()[0] == 60*60*24

    # Test block id parsing
    parsed = language.block_id.parseString('every 1 day')
    assert parsed.asList()[0][1][0] == 60*60*24

    # Test block parsing
    parsed = language.block_bnf.parseString('every 1 day {}')
    assert parsed.asList()[0][0][1][0] == 60*60*24

    # Test stream parsing
    parsed = language.stream.parseString('output 1')
    assert isinstance(parsed.asList()[0], DataStream)

    # Test call_rpc statement
    parsed = language.callrpc_stmt.parseString(u'call 0x4001 on slot 1 => output 1;')
    assert parsed.asList()[0][0] == 0x4001

    # Test block with statement parsing
    parsed = language.block_bnf.parseString(u'every 1 day { call 0x5001 on slot 2 => output 1; }')
    assert parsed.asList()[0][0][1][0] == 60*60*24

    # Test parsing stream_trigger
    parsed = language.stream_trigger.parseString(u'value(input 2) == 10')
    assert parsed[0].getName() == u'stream_trigger'

    parsed = language.stream_trigger.parseString(u'count(output 1) <= 10')
    assert parsed[0].getName() == u'stream_trigger'

    # Test parsing on block with identifier
    parsed = language.block_bnf.parseString(u'on test_identifier {}')
    print(parsed)
    assert parsed[0][0][1][0][0].getName() == u'identifier'
    assert parsed[0][0][1][0][0][0] == u'test_identifier'

    parsed = language.block_bnf.parseString(u'on value(input 2) >= 5 {}')
    assert parsed[0][0][1][0][0].getName() == u'stream_trigger'
    assert parsed[0][0][1][0][0][0] == u'value'
    assert parsed[0][0][1][0][0][1] == DataStream.FromString('input 2')
    assert parsed[0][0][1][0][0][2] == u'>='
    assert parsed[0][0][1][0][0][3] == 5

    # Test parsing on block with 2 conditions
    parsed = language.block_bnf.parseString(u'on test_identifier and hello_id {}')
    assert parsed[0][0][1][0][0].getName() == u'identifier'
    assert parsed[0][0][1][0][0][0] == u'test_identifier'
    assert parsed[0][0][1][2][0].getName() == u'identifier'
    assert parsed[0][0][1][2][0][0] == u'hello_id'
    assert parsed[0][0][1][1] == u'and'

    parsed = language.block_bnf.parseString(u'on test_identifier or value(constant 1) == 2 {}')
    assert parsed[0][0][1][0][0].getName() == u'identifier'
    assert parsed[0][0][1][0][0][0] == u'test_identifier'
    assert parsed[0][0][1][1] == u'or'

    # Test parsing subtract statements
    parsed = language.subtract_stmt.parseString(u"subtract constant 1 => unbuffered 2, default 10;")
    assert parsed[0].getName() == 'subtract_statement'
    assert parsed[0][0] == DataStream.FromString('constant 1')
    assert parsed[0][1] == DataStream.FromString('unbuffered 2')
    assert parsed[0]['default'] == 10

    parsed = language.subtract_stmt.parseString(u"subtract constant 1 => unbuffered 2;")
    assert parsed[0].getName() == 'subtract_statement'
    assert parsed[0][0] == DataStream.FromString('constant 1')
    assert parsed[0][1] == DataStream.FromString('unbuffered 2')

    # Test parser streamer statements
    parsed = language.streamer_stmt.parseString(u'manual streamer on output 1;')
    assert parsed[0]['selector'] == DataStreamSelector.FromString('output 1')

    parsed = language.streamer_stmt.parseString(u'manual streamer on all system outputs;')
    assert parsed[0]['selector'] == DataStreamSelector.FromString('all system outputs')

    parsed = language.streamer_stmt.parseString(u'manual signed streamer on output 1 to slot 1;')
    assert parsed[0]['selector'] == DataStreamSelector.FromString('output 1')
    assert parsed[0]['explicit_tile'] == SlotIdentifier.FromString('slot 1')
    assert parsed[0]['security'] == u'signed'

    parsed = language.streamer_stmt.parseString(u'manual broadcast streamer on output 1 to slot 1;')
    assert parsed[0]['selector'] == DataStreamSelector.FromString('output 1')
    assert parsed[0]['explicit_tile'] == SlotIdentifier.FromString('slot 1')
    assert parsed[0]['broadcast'] == u'broadcast'


    # Test parsing copy statements
    parsed = language.simple_statement.parseString(u'copy unbuffered 1 => unbuffered 2;')
    assert parsed[0]['explicit_input'][0] == DataStream.FromString('unbuffered 1')

    parsed = language.simple_statement.parseString(u'copy 15 => unbuffered 2;')
    assert parsed[0]['constant_input'] == 15

    parsed = language.simple_statement.parseString(u'copy 0x20 => unbuffered 2;')
    assert parsed[0]['constant_input'] == 0x20
Beispiel #29
0
def test_dump_restore():
    """Make sure we can properly dump and restore a SensorLog."""

    model = DeviceModel()
    log = SensorLog(model=model)

    storage = DataStream.FromString('buffered 1')
    output = DataStream.FromString('output 1')

    reading = IOTileReading(0, 0, 1)

    for _i in range(0, 25):
        log.push(storage, reading)

    for _i in range(0, 20):
        log.push(output, reading)

    out1 = log.create_walker(DataStreamSelector.FromString('output 1'),
                             skip_all=False)
    store1 = log.create_walker(DataStreamSelector.FromString('buffered 1'),
                               skip_all=False)
    count1 = log.create_walker(DataStreamSelector.FromString('counter 1'))
    const1 = log.create_walker(DataStreamSelector.FromString('constant 1'))
    unbuf1 = log.create_walker(DataStreamSelector.FromString('unbuffered 1'))

    log.push(DataStream.FromString('counter 1'), reading)
    log.push(DataStream.FromString('counter 1'), reading)
    log.push(DataStream.FromString('constant 1'), reading)
    log.push(DataStream.FromString('unbuffered 1'), reading)

    state = log.dump()

    log.clear()
    log.destroy_all_walkers()

    out1 = log.create_walker(DataStreamSelector.FromString('output 1'),
                             skip_all=False)
    store1 = log.create_walker(DataStreamSelector.FromString('buffered 1'),
                               skip_all=False)
    count1 = log.create_walker(DataStreamSelector.FromString('counter 1'))
    const1 = log.create_walker(DataStreamSelector.FromString('constant 1'))
    unbuf1 = log.create_walker(DataStreamSelector.FromString('unbuffered 1'))

    log.restore(state)

    assert store1.count() == 25
    assert out1.count() == 20
    assert count1.count() == 2
    assert const1.count() == 0xFFFFFFFF
    assert unbuf1.count() == 1

    # Test permissive and non-permissive restores
    _unbuf2 = log.create_walker(DataStreamSelector.FromString('unbuffered 2'))

    with pytest.raises(ArgumentError):
        log.restore(state)

    log.clear()
    log.restore(state, permissive=True)
    assert store1.count() == 25
    assert out1.count() == 20
    assert count1.count() == 2
    assert const1.count() == 0xFFFFFFFF
    assert unbuf1.count() == 1

    # Test restoring a stream walker
    log.clear()
    log.destroy_all_walkers()
    walk = log.create_walker(DataStreamSelector.FromString(str(storage)))

    for _i in range(0, 25):
        log.push(storage, reading)

    assert walk.count() == 25
    dump = walk.dump()
    log.destroy_all_walkers()
    walk2 = log.restore_walker(dump)
    assert walk2.count() == 25