Ejemplo n.º 1
0
    def test_container_input_output(self):

        from pyctrl.block.container import Container, Input, Output
        from pyctrl.block.system import Gain

        container = Container()

        container.add_signal('s1')

        container.add_source('input1', Input(), ['s1'])

        container.add_sink('ouput1', Output(), ['s1'])

        container.set_enabled(True)
        container.write(1)
        values = container.read()
        container.set_enabled(False)

        self.assertTrue(values == (1, ))

        container.add_sink('ouput2', Output(), ['s1'])

        container.set_enabled(True)
        container.write(1)
        values = container.read()
        container.set_enabled(False)

        self.assertTrue(values == (1, 1))

        container.add_source('input2', Input(), ['s2'])

        container.add_sink('ouput2', Output(), ['s2'])

        container.set_enabled(True)
        container.write(1, 2)
        values = container.read()
        container.set_enabled(False)

        self.assertTrue(values == (1, 2))

        container.add_filter('gain1', Gain(gain=3), ['s1'], ['s1'])

        container.set_enabled(True)
        container.write(1, 2)
        values = container.read()
        container.set_enabled(False)

        self.assertTrue(values == (3, 2))

        container.add_sink('ouput1', Output(), ['s3'])

        container.add_filter('gain1', Gain(gain=3), ['s1'], ['s3'])

        container.set_enabled(True)
        container.write(1, 2)
        values = container.read()
        container.set_enabled(False)

        self.assertTrue(values == (2, 3))
Ejemplo n.º 2
0
def test_timer_sub_container():

    import pyctrl
    import pyctrl.block as block

    from pyctrl.block.container import Container, Input, Output, ContainerException
    from pyctrl.block.system import Gain
    from pyctrl.block import Constant

    # create container first

    container = Container()

    container.add_signals('s1', 's2', 's3')

    # add subcontainer

    container.add_timer('container1',
                        Container(), ['s1'], ['s2', 's3'],
                        period=1,
                        repeat=False)

    container.add_signals('timer/container1/s1', 'timer/container1/s2',
                          'timer/container1/s3')

    container.add_source('timer/container1/input1', Input(), ['s1'])

    container.add_filter('timer/container1/gain1', Gain(gain=3), ['s1'],
                         ['s2'])

    container.add_filter('timer/container1/gain2', Gain(gain=5), ['s1'],
                         ['s3'])

    container.add_sink('timer/container1/output1', Output(), ['s2'])

    container.add_sink('timer/container1/output2', Output(), ['s3'])

    print(container.info('all'))

    container.set_enabled(True)
    container.set_signal('s1', 1)
    container.run()
    container.set_enabled(False)

    assert container.get_signal('s2') == 0
    assert container.get_signal('s3') == 0

    container.set_enabled(True)
    container.set_signal('s1', 1)
    container.run()
    time.sleep(1.1)
    container.run()
    container.set_enabled(False)

    assert container.get_signal('s2') == 3
    assert container.get_signal('s3') == 5
Ejemplo n.º 3
0
def test_sub_container():

    import pyctrl
    import pyctrl.block as block

    from pyctrl.block.container import Container, Input, Output, ContainerException
    from pyctrl.block.system import Gain, DTTF

    container = Container()

    container.add_signals('s1', 's2', 's3')

    # add subcontainer

    container1 = Container()
    container.add_filter('container1', container1, ['s1'], ['s2', 's3'])

    container.add_signals('container1/s1', 'container1/s2')

    container.add_source('container1/input1', Input(), ['s1'])

    container.add_filter('container1/gain1', Gain(gain=3), ['s1'], ['s2'])

    container.add_sink('container1/output1', Output(), ['s2'])

    # add subsubcontainer

    container.add_sink('container1/output2', Output(), ['s3'])

    container2 = Container()
    container.add_filter('container1/container2', container2, ['s1'], ['s3'])

    container.add_signals('container1/container2/s1',
                          'container1/container2/s2')

    container.add_source('container1/container2/input1', Input(), ['s1'])

    container.add_filter('container1/container2/gain1', Gain(gain=5), ['s1'],
                         ['s2'])

    container.add_sink('container1/container2/output1', Output(), ['s2'])

    print(container.info('all'))

    from pyctrl.flask import JSONEncoder, JSONDecoder

    json1 = JSONEncoder(sort_keys=True, indent=4).encode(container)

    obj = JSONDecoder().decode(json1)

    json2 = JSONEncoder(sort_keys=True, indent=4).encode(obj)

    assert json1 == json2

    print('json = \n{}'.format(json1))
Ejemplo n.º 4
0
    def test_sub_container_timer(self):

        from pyctrl.block.container import Container, Input, Output
        from pyctrl.block.system import Gain
        from pyctrl.block import Constant

        # create container first

        container = Container()

        container.add_signals('s1', 's2', 's3')

        # add subcontainer

        container.add_filter('container1', Container(), ['s1'], ['s2', 's3'])

        container.add_signals('container1/s1', 'container1/s2',
                              'container1/s3')

        container.add_source('container1/input1', Input(), ['s1'])

        container.add_filter('container1/gain1', Gain(gain=3), ['s1'], ['s2'])

        container.add_timer('container1/constant1',
                            Constant(value=5),
                            None, ['s3'],
                            period=1,
                            repeat=False)

        container.add_sink('container1/output1', Output(), ['s2'])

        container.add_sink('container1/output2', Output(), ['s3'])

        print(container.info('all'))

        container.set_enabled(True)
        container.set_signal('s1', 1)
        container.run()
        container.set_enabled(False)

        self.assertTrue(container.get_signal('s2') == 3)
        self.assertTrue(container.get_signal('s3') == 0)

        container.set_enabled(True)
        container.set_signal('s1', 1)
        container.run()
        time.sleep(1.1)
        container.run()
        container.set_enabled(False)

        self.assertTrue(container.get_signal('s2') == 3)
        self.assertTrue(container.get_signal('s3') == 5)
Ejemplo n.º 5
0
    def test_sub_sub_container(self):

        import pyctrl

        from pyctrl.block.container import Container, Input, Output, ContainerException
        from pyctrl.block.system import Gain

        # create container first

        container = Container()

        container.add_signals('s1', 's2', 's3')

        # add subcontainer

        container1 = Container()
        container.add_filter('container1', container1, ['s1'], ['s2', 's3'])

        self.assertTrue(
            container.resolve_label('container1') == (container, 'container1'))
        self.assertTrue(
            container.resolve_label('./container1') == (container,
                                                        'container1'))
        self.assertTrue(
            container.resolve_label('/container1') == (container,
                                                       'container1'))

        with self.assertRaises(pyctrl.block.container.ContainerException):
            container.resolve_label('/container2/something')

        with self.assertRaises(pyctrl.block.container.ContainerException):
            container.resolve_label('../something')

        container.add_signals('container1/s1', 'container1/s2')

        self.assertTrue(
            container.resolve_label('container1/s1') == (container1, 's1'))
        self.assertTrue(
            container.resolve_label('./container1/s1') == (container1, 's1'))
        self.assertTrue(
            container.resolve_label('/container1/s1') == (container1, 's1'))

        self.assertTrue(container1.resolve_label('../s1') == (container, 's1'))

        self.assertTrue(container1.resolve_label('s1') == (container1, 's1'))
        self.assertTrue(container1.resolve_label('./s1') == (container1, 's1'))
        self.assertTrue(
            container1.resolve_label('/container1/s1') == (container1, 's1'))

        container.add_source('container1/input1', Input(), ['s1'])

        container.add_filter('container1/gain1', Gain(gain=3), ['s1'], ['s2'])

        container.add_sink('container1/output1', Output(), ['s2'])

        container.set_enabled(True)
        container.set_signal('s1', 1)
        container.run()
        container.set_enabled(False)

        self.assertTrue(container.get_signal('s2') == 3)

        # add subsubcontainer

        container.add_sink('container1/output2', Output(), ['s3'])

        container2 = Container()
        container.add_filter('container1/container2', container2, ['s1'],
                             ['s3'])

        container.add_signals('container1/container2/s1',
                              'container1/container2/s2')

        self.assertTrue(
            container.resolve_label('container1/container2/s1') == (container2,
                                                                    's1'))
        self.assertTrue(
            container.resolve_label('./container1/container2/s1') == (
                container2, 's1'))
        self.assertTrue(
            container.resolve_label('/container1/container2/s1') == (
                container2, 's1'))

        self.assertTrue(
            container.resolve_label('container1/container2/s1') == (container2,
                                                                    's1'))
        self.assertTrue(
            container.resolve_label('./container1/container2/s1') == (
                container2, 's1'))
        self.assertTrue(
            container.resolve_label('/container1/container2/s1') == (
                container2, 's1'))

        self.assertTrue(
            container1.resolve_label('container2/s1') == (container2, 's1'))
        self.assertTrue(
            container1.resolve_label('./container2/s1') == (container2, 's1'))
        self.assertTrue(
            container1.resolve_label('/container1/container2/s1') == (
                container2, 's1'))

        self.assertTrue(container2.resolve_label('s1') == (container2, 's1'))
        self.assertTrue(container2.resolve_label('./s1') == (container2, 's1'))
        self.assertTrue(
            container2.resolve_label('/container1/container2/s1') == (
                container2, 's1'))

        self.assertTrue(
            container2.resolve_label('../s1') == (container1, 's1'))
        self.assertTrue(
            container2.resolve_label('../../s1') == (container, 's1'))
        self.assertTrue(
            container2.resolve_label('../container2/s1') == (container2, 's1'))

        container.add_source('container1/container2/input1', Input(), ['s1'])

        container.add_filter('container1/container2/gain1', Gain(gain=5),
                             ['s1'], ['s2'])

        container.add_sink('container1/container2/output1', Output(), ['s2'])

        print(container.info('all'))

        container.set_enabled(True)
        container.set_signal('s1', 1)
        container.run()
        container.set_enabled(False)

        self.assertTrue(container.get_signal('s2') == 3)
        self.assertTrue(container.get_signal('s3') == 5)
Ejemplo n.º 6
0
    def test_sub_container(self):

        from pyctrl.block.container import Container, Input, Output, ContainerException
        from pyctrl.block.system import Gain

        # create subcontainer first

        subcontainer = Container()

        subcontainer.add_signals('s1', 's2')

        subcontainer.add_source('input1', Input(), ['s1'])

        subcontainer.add_filter('gain1', Gain(gain=3), ['s1'], ['s2'])

        subcontainer.add_sink('output1', Output(), ['s2'])

        subcontainer.set_enabled(True)
        subcontainer.write(1)
        values = subcontainer.read()
        subcontainer.set_enabled(False)

        self.assertTrue(values == (3, ))

        # add to container

        container = Container()

        container.add_signals('s1', 's2')

        container.add_filter('container', subcontainer, ['s1'], ['s2'])

        container.set_enabled(True)
        container.set_signal('s1', 1)
        container.run()
        container.set_enabled(False)

        self.assertTrue(container.get_signal('s2') == 3)

        # signals in subcontainer
        container.set_signal('container/s1', 2)

        container.add_signal('container/s3')
        container.set_signal('container/s3', 4)

        self.assertTrue(container.get_signal('s1') == 1)
        self.assertTrue(container.get_signal('container/s1') == 2)
        self.assertTrue(container.get_signal('container/s3') == 4)

        container.remove_signal('container/s3')
        with self.assertRaises(KeyError):
            container.get_signal('container/s3')

        # sources in subcontainer
        self.assertTrue(container.get_source('container/input1', 'enabled'))

        container.set_source('container/input1', enabled=False)

        self.assertTrue(
            not container.get_source('container/input1', 'enabled'))

        container.add_source('container/source1', Input(), ['s1'])
        self.assertTrue(container.get_source('container/source1', 'enabled'))

        container.remove_source('container/source1')
        with self.assertRaises(ContainerException):
            container.get_source('container/source1')

        # sinks in subcontainer
        self.assertTrue(container.get_sink('container/output1', 'enabled'))

        container.set_sink('container/output1', enabled=False)

        self.assertTrue(not container.get_sink('container/output1', 'enabled'))

        container.add_sink('container/sink1', Output(), ['s1'])
        self.assertTrue(container.get_sink('container/sink1', 'enabled'))

        container.remove_sink('container/sink1')
        with self.assertRaises(ContainerException):
            container.get_sink('container/sink1')

        # filters in subcontainer
        self.assertTrue(container.get_filter('container/gain1', 'enabled'))

        container.set_filter('container/gain1', enabled=False)

        self.assertTrue(not container.get_filter('container/gain1', 'enabled'))

        container.add_filter('container/filter1', Gain(), ['s1'], ['s1'])
        self.assertTrue(container.get_filter('container/filter1', 'enabled'))

        container.remove_filter('container/filter1')
        with self.assertRaises(ContainerException):
            container.get_filter('container/filter1')
Ejemplo n.º 7
0
    def test_enable(self):

        from pyctrl.block.container import Container, Input, Output
        from pyctrl.block.system import Gain

        # create subcontainer first

        subcontainer = Container()

        subcontainer.add_signals('s1', 's2')

        subcontainer.add_source('input1', Input(), ['s1'], enable=True)

        subcontainer.add_filter('gain1', Gain(gain=3), ['s1'], ['s2'])

        subcontainer.add_sink('output1', Output(), ['s2'])

        print(subcontainer.info('all'))

        subcontainer.set_enabled(True)
        subcontainer.write(1)
        values = subcontainer.read()
        subcontainer.set_enabled(False)

        self.assertTrue(values == (3, ))

        print(subcontainer.info('all'))

        subcontainer.set_source('input1', enable=False)
        subcontainer.set_signal('s1', 0)

        print(subcontainer.info('all'))

        subcontainer.set_enabled(True)
        subcontainer.write(1)
        values = subcontainer.read()
        subcontainer.set_enabled(False)

        self.assertTrue(values == (0, ))

        subcontainer.set_source('input1', enable=True)
        subcontainer.set_filter('gain1', enable=True)

        subcontainer.set_enabled(True)
        subcontainer.write(1)
        values = subcontainer.read()
        subcontainer.set_enabled(False)

        self.assertTrue(values == (3, ))

        subcontainer.set_filter('gain1', enable=False)
        subcontainer.set_signal('s2', 0)

        subcontainer.set_enabled(True)
        subcontainer.write(1)
        values = subcontainer.read()
        subcontainer.set_enabled(False)

        self.assertTrue(values == (0, ))

        subcontainer.set_filter('gain1', enable=True)
        subcontainer.set_sink('output1', enable=True)
        subcontainer.set_signal('s2', 0)

        subcontainer.set_enabled(True)
        subcontainer.write(1)
        values = subcontainer.read()
        subcontainer.set_enabled(False)

        self.assertTrue(values == (3, ))

        subcontainer.set_sink('output1', enable=False)
        subcontainer.set_signal('s2', 0)

        subcontainer.set_enabled(True)
        subcontainer.write(1)
        values = subcontainer.read()
        subcontainer.set_enabled(False)

        self.assertTrue(values == (None, ))
Ejemplo n.º 8
0
def test_webserver():

    import subprocess
    import time
    import numpy
    from pyctrl.flask.server import JSONDecoder, JSONEncoder
        
    if start_server:
        
        # initiate server
        print('> Starting server')

        server = subprocess.Popen(["python3",
                                   "pyctrl/flask/server.py"],
                                  stdout = subprocess.PIPE)
        
        time.sleep(2)

    try:

        # reset controller
        url = "http://127.0.0.1:5000/reset"
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}
        
        assert result == answer
        
        # check index page
        answer = b"<div><p>&lt;class 'pyctrl.timer.Controller'&gt; with: 0 timer(s), 3 signal(s), 1 source(s), 0 filter(s), and 0 sink(s)</p><h2>timers</h2><ol></ol><h2>signals</h2><ol><li>clock</li><li>duty</li><li>is_running</li></ol><h2>sources</h2><ol><li>clock[TimerClock, disabled] &Gt; clock</li></ol><h2>filters</h2><ol></ol><h2>sinks</h2><ol></ol></div>"

        # check info page
        url = "http://127.0.0.1:5000/info"
        output = subprocess.check_output(["curl", url])
        assert output == answer

        # S I N K S
        
        # add sink
        url = r'"http://127.0.0.1:5000/add/sink/printer/pyctrl.block/Printer?inputs=\[\"clock\",\"is_running\"\]"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get sink
        url = "http://127.0.0.1:5000/get/sink/printer"
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)

        from pyctrl.block import Printer
        assert result['printer'].get() == Printer().get()

        # get attribute/sink
        url = r'"http://127.0.0.1:5000/get/sink/printer?keys=\"enabled\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': True}

        assert result == answer

        # get attribute/sink (multiple)
        url = '"http://127.0.0.1:5000/get/sink/printer?keys=\[\\"enabled\\",\\"endln\\"\]"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': True, 'endln': '\n'}

        assert result == answer
        
        # set attribute/sink
        url = 'http://127.0.0.1:5000/set/sink/printer?enabled=false'
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get attribute/sink
        url = '"http://127.0.0.1:5000/get/sink/printer?keys=\\"enabled\\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': False}

        assert result == answer
        
        # set attribute/sink
        url = '"http://127.0.0.1:5000/set/sink/printer?endln=\\"\\r\\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get attribute/sink
        url = '"http://127.0.0.1:5000/get/sink/printer?keys=\\"endln\\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'endln': '\r'}

        assert result == answer
        
        # set attribute/sink (multiple)
        url = '"http://127.0.0.1:5000/set/sink/printer?enabled=true&endln=\\"\\r\\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get attribute/sink (multiple)
        url = '"http://127.0.0.1:5000/get/sink/printer?keys=\[\\"enabled\\",\\"endln\\"\]"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': True, 'endln': '\r' }

        assert result == answer
        
        # add sink with parameter
        url = r'"http://127.0.0.1:5000/add/sink/printer/pyctrl.block/Printer?inputs=\[\"clock\",\"is_running\"\]&kwargs=\{\"endln\":\"\\r\"\}"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get attribute/sink (multiple)
        url = '"http://127.0.0.1:5000/get/sink/printer?keys=\[\\"enabled\\",\\"endln\\"\]"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': True, 'endln': '\r' }

        assert result == answer
        
        # S O U R C E
        
        # add source
        url = r'"http://127.0.0.1:5000/add/source/constant/pyctrl.block/Constant?outputs=\[\"signal\"\]&kwargs=\{\"value\":3\}"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get source
        url = "http://127.0.0.1:5000/get/source/constant"
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)

        from pyctrl.block import Constant
        assert result['constant'].get() == Constant(value = 3).get()

        # get attribute/source
        url = r'"http://127.0.0.1:5000/get/source/constant?keys=\"enabled\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': True}

        assert result == answer

        # get attribute/source (multiple)
        url = r'"http://127.0.0.1:5000/get/source/constant?keys=\[\"enabled\",\"value\"\]"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': True, 'value': 3}

        assert result == answer
        
        # set attribute/source
        url = 'http://127.0.0.1:5000/set/source/constant?enabled=false'
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get attribute/source
        url = '"http://127.0.0.1:5000/get/source/constant?keys=\\"enabled\\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': False}

        assert result == answer
        
        # set attribute/source
        url = '"http://127.0.0.1:5000/set/source/constant?value=4"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get attribute/source
        url = '"http://127.0.0.1:5000/get/source/constant?keys=\\"value\\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'value': 4}

        assert result == answer
        
        # set attribute/source (multiple)
        url = '"http://127.0.0.1:5000/set/source/constant?enabled=true&value=5"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get attribute/source (multiple)
        url = '"http://127.0.0.1:5000/get/source/constant?keys=\[\\"enabled\\",\\"value\\"\]"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': True, 'value': 5 }

        assert result == answer

        # F I L T E R
        
        # add filter
        url = r'"http://127.0.0.1:5000/add/filter/gain/pyctrl.block.system/Gain?inputs=\[\"inp\"\]&outputs=\[\"out\"\]&kwargs=\{\"gain\":3\}"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get filter
        url = "http://127.0.0.1:5000/get/filter/gain"
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)

        from pyctrl.block.system import Gain
        assert result['gain'].get() == Gain(gain = 3).get()

        # get attribute/filter
        url = r'"http://127.0.0.1:5000/get/filter/gain?keys=\"enabled\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': True}

        assert result == answer

        # get attribute/filter (multiple)
        url = r'"http://127.0.0.1:5000/get/filter/gain?keys=\[\"enabled\",\"gain\"\]"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': True, 'gain': 3}

        assert result == answer
        
        # set attribute/filter
        url = 'http://127.0.0.1:5000/set/filter/gain?enabled=false'
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get attribute/filter
        url = '"http://127.0.0.1:5000/get/filter/gain?keys=\\"enabled\\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': False}

        assert result == answer
        
        # set attribute/filter
        url = '"http://127.0.0.1:5000/set/filter/gain?gain=4"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get attribute/filter
        url = '"http://127.0.0.1:5000/get/filter/gain?keys=\\"gain\\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'gain': 4}

        assert result == answer
        
        # set attribute/filter (multiple)
        url = '"http://127.0.0.1:5000/set/filter/gain?enabled=true&gain=5"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get attribute/filter (multiple)
        url = '"http://127.0.0.1:5000/get/filter/gain?keys=\[\\"enabled\\",\\"gain\\"\]"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': True, 'gain': 5 }

        assert result == answer
        
        # T I M E R
        
        # add timer
        url = r'"http://127.0.0.1:5000/add/timer/gain/pyctrl.block.system/Gain?inputs=\[\"inp\"\]&outputs=\[\"out\"\]&kwargs=\{\"gain\":3\}&period=1"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get timer
        url = "http://127.0.0.1:5000/get/timer/gain"
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)

        from pyctrl.block.system import Gain
        assert result['gain'].get() == Gain(gain = 3).get()

        # get attribute/timer
        url = r'"http://127.0.0.1:5000/get/timer/gain?keys=\"enabled\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': True}

        assert result == answer

        # get attribute/timer (multiple)
        url = r'"http://127.0.0.1:5000/get/timer/gain?keys=\[\"enabled\",\"gain\"\]"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': True, 'gain': 3}

        assert result == answer
        
        # set attribute/timer
        url = 'http://127.0.0.1:5000/set/timer/gain?enabled=false'
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get attribute/timer
        url = '"http://127.0.0.1:5000/get/timer/gain?keys=\\"enabled\\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': False}

        assert result == answer
        
        # set attribute/timer
        url = '"http://127.0.0.1:5000/set/timer/gain?gain=4"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get attribute/timer
        url = '"http://127.0.0.1:5000/get/timer/gain?keys=\\"gain\\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'gain': 4}

        assert result == answer
        
        # set attribute/timer (multiple)
        url = '"http://127.0.0.1:5000/set/timer/gain?enabled=true&gain=5"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer

        # get attribute/timer (multiple)
        url = '"http://127.0.0.1:5000/get/timer/gain?keys=\[\\"enabled\\",\\"gain\\"\]"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'enabled': True, 'gain': 5 }

        assert result == answer

        answer = b"<div><p>&lt;class 'pyctrl.timer.Controller'&gt; with: 1 timer(s), 6 signal(s), 2 source(s), 1 filter(s), and 1 sink(s)</p><h2>timers</h2><ol><li>inp &Gt; gain[Gain, period = 1, repeat, enabled] &Gt; out</li></ol><h2>signals</h2><ol><li>clock</li><li>duty</li><li>inp</li><li>is_running</li><li>out</li><li>signal</li></ol><h2>sources</h2><ol><li>clock[TimerClock, disabled] &Gt; clock</li><li>constant[Constant, enabled] &Gt; signal</li></ol><h2>filters</h2><ol><li>inp &Gt; gain[Gain, enabled] &Gt; out</li></ol><h2>sinks</h2><ol><li>clock, is_running &Gt; printer[Printer, enabled]</li></ol></div>"
        
        # check info page
        url = "http://127.0.0.1:5000/info"
        output = subprocess.check_output(["curl", url])

        assert output == answer
        
        # reset controller
        
        url = "http://127.0.0.1:5000/set/controller/pyctrl/Controller"
        output = subprocess.check_output(["curl", url]).decode("utf-8")

        answer = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n<title>Redirecting...</title>\n<h1>Redirecting...</h1>\n<p>You should be redirected automatically to target URL: <a href="/">/</a>.  If not click the link.'
        
        assert output == answer
        
        # check info page
        url = "http://127.0.0.1:5000/info"
        output = subprocess.check_output(["curl", url])

        answer = b"<div><p>&lt;class 'pyctrl.Controller'&gt; with: 0 timer(s), 3 signal(s), 1 source(s), 0 filter(s), and 0 sink(s)</p><h2>timers</h2><ol></ol><h2>signals</h2><ol><li>clock</li><li>duty</li><li>is_running</li></ol><h2>sources</h2><ol><li>clock[Clock, disabled] &Gt; clock</li></ol><h2>filters</h2><ol></ol><h2>sinks</h2><ol></ol></div>"
        
        assert output == answer
        
        # reset controller
        url = "http://127.0.0.1:5000/set/controller/pyctrl.timer/Controller?kwargs=\{\"period\":1\}"
        output = subprocess.check_output(["curl", url]).decode("utf-8")

        answer = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n<title>Redirecting...</title>\n<h1>Redirecting...</h1>\n<p>You should be redirected automatically to target URL: <a href="/">/</a>.  If not click the link.'

        assert output == answer

        # get attribute/timer
        url = r'"http://127.0.0.1:5000/get/source/clock?keys=\"period\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'period': 1}
        
        assert result == answer

        # add logger
        url = r'"http://127.0.0.1:5000/add/sink/logger/pyctrl.block/Logger?inputs=\[\"clock\",\"is_running\"\]"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer
       
        # start
        url = "http://127.0.0.1:5000/start"
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}
        
        assert result == answer

        time.sleep(3)
        
        # stop
        url = "http://127.0.0.1:5000/stop"
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}
        
        assert result == answer

        # get log
        url = r'"http://127.0.0.1:5000/get/sink/logger?keys=\"log\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)['log']

        assert isinstance(result['clock'], numpy.ndarray)
        assert isinstance(result['is_running'], numpy.ndarray)
        assert result['is_running'].shape == result['clock'].shape
        assert result['clock'].shape[0] >= 3
        assert result['clock'].shape[1] == 1
        assert result['clock'][-1,0] - result['clock'][0,0] < 4
        
        # start
        url = "http://127.0.0.1:5000/start"
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}
        
        assert result == answer

        time.sleep(3)
        
        # stop
        url = "http://127.0.0.1:5000/stop"
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}
        
        assert result == answer
        
        # get log
        url = r'"http://127.0.0.1:5000/get/sink/logger?keys=\"log\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)['log']

        assert isinstance(result['clock'], numpy.ndarray)
        assert isinstance(result['is_running'], numpy.ndarray)
        assert result['is_running'].shape == result['clock'].shape
        assert result['clock'].shape[0] > 6
        assert result['clock'].shape[1] == 1
        assert result['clock'][-1,0] - result['clock'][0,0] > 6
        
        # add logger with auto_reset
        url = r'"http://127.0.0.1:5000/add/sink/logger/pyctrl.block/Logger?inputs=\[\"clock\",\"is_running\"\]&kwargs=\{\"auto_reset\":true\}"'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}

        assert result == answer
       
        # start
        url = "http://127.0.0.1:5000/start"
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}
        
        assert result == answer

        time.sleep(3)
        
        # stop
        url = "http://127.0.0.1:5000/stop"
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}
        
        assert result == answer

        # get log
        url = r'"http://127.0.0.1:5000/get/sink/logger?keys=\"log\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)['log']

        print('log = {}'.format(result))
        
        assert isinstance(result['clock'], numpy.ndarray)
        assert isinstance(result['is_running'], numpy.ndarray)
        assert result['is_running'].shape == result['clock'].shape
        assert result['clock'].shape[0] >= 3
        assert result['clock'].shape[1] == 1
        assert result['clock'][-1,0] - result['clock'][0,0] < 4
        
        # start
        url = "http://127.0.0.1:5000/start"
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}
        
        assert result == answer

        time.sleep(3)
        
        # stop
        url = "http://127.0.0.1:5000/stop"
        output = subprocess.check_output(["curl", url]).decode("utf-8")
        result = JSONDecoder().decode(output)
        answer = {'status': 'success'}
        
        assert result == answer
        
        # get log
        url = r'"http://127.0.0.1:5000/get/sink/logger?keys=\"log\""'
        output = subprocess.check_output('curl ' + url, shell=True).decode("utf-8")
        result = JSONDecoder().decode(output)['log']

        print('log = {}'.format(result))
        
        assert isinstance(result['clock'], numpy.ndarray)
        assert isinstance(result['is_running'], numpy.ndarray)
        assert result['is_running'].shape == result['clock'].shape
        assert result['clock'].shape[0] >= 3
        assert result['clock'].shape[1] == 1
        assert result['clock'][-1,0] - result['clock'][0,0] < 4
        
    except Exception as e:
        
        print('** EXCEPTION RAISED **')
        print(e)
        raise e
    
    finally:
        
        if start_server:
            
            # stop server
            print('> Terminating server')
            server.terminate()