def test_Worker_DAQ___rate():
    print_title("Worker_DAQ - INTERNAL_TIMER - DAQ rate")

    def DAQ_function():
        # Must return True when successful, False otherwise
        reply = dev.fake_query_1()
        dprint(" " * 50 + "%.1f Hz" % qdev.obtained_DAQ_rate_Hz)
        return reply[-4:] == "0101"

    app = create_QApplication()
    dev = FakeDevice()
    qdev = QDeviceIO(dev)
    # fmt: off
    qdev.create_worker_DAQ(DAQ_trigger=DAQ_TRIGGER.INTERNAL_TIMER,
                           DAQ_function=DAQ_function,
                           DAQ_interval_ms=10,
                           critical_not_alive_count=1,
                           debug=DEBUG)
    # fmt: on
    assert qdev.start() == True

    # Simulate device runtime
    start_time = time.perf_counter()
    while time.perf_counter() - start_time < 1.51:
        app.processEvents()
        time.sleep(0.001)  # Do not hog the CPU

    tprint("About to quit")
    app.processEvents()
    assert qdev.quit() == True
    app.quit()

    assert 9 <= qdev.obtained_DAQ_interval_ms <= 11
    assert 99 <= qdev.obtained_DAQ_rate_Hz <= 101
def test_Worker_jobs__quit_without_start():
    print_title("Worker_jobs - quit without start")

    app = create_QApplication()
    qdev = QDeviceIO(FakeDevice())
    qdev.create_worker_jobs()

    tprint("About to quit")
    app.processEvents()
    assert qdev.quit() == True
    app.quit()
def test_Worker_DAQ___CONTINUOUS(start_alive=True):
    print_title("Worker_DAQ - CONTINUOUS" +
                ("" if start_alive else " - start dead"))

    def DAQ_function():
        # Must return True when successful, False otherwise
        time.sleep(0.1)  # Simulate blocking processing time on the device
        reply = dev.fake_query_1()
        return reply[-4:] == "0101"

    app = create_QApplication()
    dev = FakeDevice(start_alive=start_alive)
    qdev = QDeviceIO(dev)
    # fmt: off
    qdev.create_worker_DAQ(
        DAQ_trigger=DAQ_TRIGGER.CONTINUOUS,
        DAQ_function=DAQ_function,
        critical_not_alive_count=1,
        debug=DEBUG,
    )
    # fmt: on

    qdev.signal_DAQ_updated.connect(process_DAQ_updated)
    qdev.signal_DAQ_paused.connect(process_DAQ_paused)

    assert qdev.start() == start_alive

    # Immediately fire a call to test if the worker is ready for it
    qdev.unpause_DAQ()

    # Simulate device runtime
    start_time = time.perf_counter()
    QtCore.QTimer.singleShot(300, qdev.pause_DAQ)
    QtCore.QTimer.singleShot(600, qdev.unpause_DAQ)
    QtCore.QTimer.singleShot(900, qdev.pause_DAQ)
    QtCore.QTimer.singleShot(1200, qdev.unpause_DAQ)
    while time.perf_counter() - start_time < 1.6:
        app.processEvents()
        if dev.count_commands == 12:
            break
        time.sleep(0.001)  # Do not hog the CPU

    tprint("About to quit")
    app.processEvents()
    assert qdev.quit() == True
    app.quit()

    if start_alive:
        assert dev.count_commands >= 10
        assert dev.count_replies >= 10
        assert (cnt_DAQ_updated >= 9
                )  # Last signal is not always received before thread is quit
        assert cnt_DAQ_paused == 3
def test_Worker_DAQ___lose_connection():
    print_title("Worker_DAQ - INTERNAL_TIMER - lose connection")

    def DAQ_function():
        # Must return True when successful, False otherwise
        if qdev.update_counter_DAQ == 10:
            dev.is_alive = False

        reply = dev.fake_query_1()
        return reply[-4:] == "0101"

    # NOTE: The global 'go' mechanism used here is a quick and dirty way to
    # pytest. In production, it should be implemented by an boolean external
    # class member.
    global go
    go = True

    @QtCore.pyqtSlot()
    def process_connection_lost():
        tprint("---> received: connection_lost")
        global go
        go = False

    app = create_QApplication()
    dev = FakeDevice()

    # Forcefully remove members as extra test
    del dev.name
    del dev.is_alive

    qdev = QDeviceIO(dev)
    # fmt: off
    qdev.create_worker_DAQ(DAQ_trigger=DAQ_TRIGGER.INTERNAL_TIMER,
                           DAQ_function=DAQ_function,
                           DAQ_interval_ms=20,
                           critical_not_alive_count=3,
                           debug=DEBUG)
    # fmt: on
    qdev.create_worker_jobs(debug=DEBUG)
    qdev.signal_connection_lost.connect(process_connection_lost)
    assert qdev.start() == True

    # Simulate device runtime
    while go:
        app.processEvents()
        time.sleep(0.001)  # Do not hog the CPU

    tprint("About to quit")
    app.processEvents()
    assert qdev.quit() == True
    assert qdev.quit() == True  # Twice, to check for msg 'already closed'.
    app.quit()
def test_Worker_jobs__jobs_function():
    print_title("Worker_jobs - jobs_function")

    def jobs_function(func, args):
        if func == "special command":
            dev.fake_query_2()
        else:
            # Default job handling where, e.g.
            # func = self.dev.write
            # args = ("toggle LED",)
            func(*args)

    app = create_QApplication()
    dev = FakeDevice()
    qdev = QDeviceIO(dev)
    qdev.create_worker_jobs(
        jobs_function=jobs_function,
        debug=DEBUG,
    )
    qdev.signal_jobs_updated.connect(process_jobs_updated)
    assert qdev.start() == True

    # Immediately fire a call to test if the worker is ready for it
    qdev.send(dev.fake_query_2)

    # fmt: off
    # Simulate device runtime
    start_time = time.perf_counter()
    QtCore.QTimer.singleShot(100, lambda: qdev.send("special command"))
    QtCore.QTimer.singleShot(
        200, lambda: qdev.send(dev.fake_command_with_argument, 0))
    # fmt: on
    while time.perf_counter() - start_time < 0.5:
        app.processEvents()
        time.sleep(0.001)  # Do not hog the CPU

    tprint("About to quit")
    app.processEvents()
    assert qdev.quit() == True
    app.quit()

    assert dev.count_commands == 3
    assert dev.count_replies == 2
    assert cnt_jobs_updated == 3
def test_Worker_jobs(start_alive=True):
    print_title("Worker_jobs" + ("" if start_alive else " - start dead"))

    app = create_QApplication()
    dev = FakeDevice(start_alive=start_alive)
    qdev = QDeviceIO(dev)
    qdev.create_worker_jobs(debug=DEBUG)
    qdev.signal_jobs_updated.connect(process_jobs_updated)
    assert qdev.start() == start_alive

    # Immediately fire a call to test if the worker is ready for it
    qdev.add_to_jobs_queue(dev.fake_query_2)

    # fmt: off
    # Simulate device runtime
    start_time = time.perf_counter()
    QtCore.QTimer.singleShot(100, qdev.process_jobs_queue)
    QtCore.QTimer.singleShot(200, lambda: qdev.send(dev.fake_query_2))
    QtCore.QTimer.singleShot(
        300, lambda: qdev.add_to_jobs_queue(dev.fake_command_with_argument, 0))
    QtCore.QTimer.singleShot(
        400, lambda: qdev.add_to_jobs_queue(dev.fake_command_with_argument, 0))
    QtCore.QTimer.singleShot(
        500, lambda: qdev.add_to_jobs_queue(dev.fake_command_with_argument, 0))
    QtCore.QTimer.singleShot(600, qdev.process_jobs_queue)
    QtCore.QTimer.singleShot(
        700, lambda: qdev.send("trigger_illegal_function_call_error"))
    # fmt: on
    while time.perf_counter() - start_time < 1:
        app.processEvents()
        time.sleep(0.001)  # Do not hog the CPU

    tprint("About to quit")
    app.processEvents()
    assert qdev.quit() == True
    app.quit()

    if start_alive:
        assert dev.count_commands == 5
        assert dev.count_replies == 2
        assert cnt_jobs_updated == 4
def test_Worker_DAQ___SINGLE_SHOT_WAKE_UP(start_alive=True):
    print_title("Worker_DAQ - SINGLE_SHOT_WAKE_UP" +
                ("" if start_alive else " - start dead"))

    def DAQ_function():
        # Must return True when successful, False otherwise
        reply = dev.fake_query_1()
        return reply[-4:] == "0101"

    app = create_QApplication()
    dev = FakeDevice(start_alive=start_alive)
    qdev = QDeviceIO(dev)
    # fmt: off
    qdev.create_worker_DAQ(DAQ_trigger=DAQ_TRIGGER.SINGLE_SHOT_WAKE_UP,
                           DAQ_function=DAQ_function,
                           critical_not_alive_count=1,
                           debug=DEBUG)
    # fmt: on
    qdev.signal_DAQ_updated.connect(process_DAQ_updated)
    assert qdev.start() == start_alive

    # Immediately fire a call to test if the worker is ready for it
    qdev.wake_up_DAQ()

    # Simulate device runtime
    start_time = time.perf_counter()
    QtCore.QTimer.singleShot(300, qdev.wake_up_DAQ)
    QtCore.QTimer.singleShot(600, qdev.wake_up_DAQ)
    while time.perf_counter() - start_time < 1:
        app.processEvents()
        time.sleep(0.001)  # Do not hog the CPU

    tprint("About to quit")
    app.processEvents()
    assert qdev.quit() == True
    app.quit()

    if start_alive:
        assert dev.count_commands == 3
        assert dev.count_replies == 3
        assert cnt_DAQ_updated == 3
def test_Worker_DAQ___INTERNAL_TIMER(start_alive=True):
    print_title("Worker_DAQ - INTERNAL_TIMER" +
                ("" if start_alive else " - start dead"))

    def DAQ_function():
        # Must return True when successful, False otherwise
        reply = dev.fake_query_1()
        return reply[-4:] == "0101"

    app = create_QApplication()
    dev = FakeDevice(start_alive=start_alive)
    qdev = QDeviceIO(dev)
    # fmt: off
    qdev.create_worker_DAQ(DAQ_trigger=DAQ_TRIGGER.INTERNAL_TIMER,
                           DAQ_function=DAQ_function,
                           DAQ_interval_ms=100,
                           critical_not_alive_count=10,
                           debug=DEBUG)
    # fmt: on
    qdev.signal_DAQ_updated.connect(process_DAQ_updated)
    assert qdev.start() == start_alive

    # Simulate device runtime
    start_time = time.perf_counter()
    while time.perf_counter() - start_time < 1:
        app.processEvents()
        if dev.count_commands == 3:
            break
        time.sleep(0.001)  # Do not hog the CPU

    tprint("About to quit")
    app.processEvents()
    assert qdev.quit() == True
    app.quit()

    if start_alive:
        assert dev.count_commands >= 3
        assert dev.count_replies >= 3
        assert (cnt_DAQ_updated >= 2
                )  # Last signal is not always received before thread is quit
def test_Worker_DAQ___INTERNAL_TIMER__subclassed():
    print_title("Worker_DAQ - INTERNAL_TIMER - subclassed")

    def DAQ_function():
        # Must return True when successful, False otherwise
        reply = dev.fake_query_1()
        return reply[-4:] == "0101"

    app = create_QApplication()
    dev = FakeDevice()
    qdev = QDeviceIO_subclassed(
        dev=dev,
        DAQ_function=DAQ_function,
        debug=DEBUG,
    )
    qdev.signal_DAQ_updated.connect(process_DAQ_updated)
    qdev.signal_jobs_updated.connect(process_jobs_updated)
    qdev.start()

    # fmt: off
    # Simulate device runtime
    start_time = time.perf_counter()
    QtCore.QTimer.singleShot(300, lambda: qdev.send(dev.fake_query_2))
    QtCore.QTimer.singleShot(
        600, lambda: qdev.send(dev.fake_command_with_argument, 0))
    # fmt: on
    while time.perf_counter() - start_time < 1:
        app.processEvents()
        time.sleep(0.001)  # Do not hog the CPU

    tprint("About to quit")
    app.processEvents()
    assert qdev.quit() == True
    app.quit()

    assert dev.count_commands >= 11
    assert dev.count_replies >= 10
    assert (cnt_DAQ_updated >= 9
            )  # Last signal is not always received before thread is quit
    assert cnt_jobs_updated == 2
def test_Worker_DAQ___ILLEGAL_DAQ_FUNCTION():
    print_title("Worker_DAQ - ILLEGAL_DAQ_FUNCTION")

    def DAQ_function():
        # Must return True when successful, False otherwise

        if qdev.update_counter_DAQ == 2:
            0 / 0
        else:
            reply = dev.fake_query_1()
            return reply[-4:] == "0101"

    app = create_QApplication()
    dev = FakeDevice()
    qdev = QDeviceIO(dev)
    # fmt: off
    qdev.create_worker_DAQ(DAQ_trigger=DAQ_TRIGGER.INTERNAL_TIMER,
                           DAQ_function=DAQ_function,
                           DAQ_interval_ms=100,
                           debug=DEBUG)
    # fmt: on
    qdev.signal_DAQ_updated.connect(process_DAQ_updated)
    assert qdev.start() == True

    # Simulate device runtime
    start_time = time.perf_counter()
    while time.perf_counter() - start_time < 1:
        app.processEvents()
        if dev.count_commands == 3:
            break
        time.sleep(0.001)  # Do not hog the CPU

    tprint("About to quit")
    app.processEvents()
    assert qdev.quit() == True
    app.quit()
    def update_chart(self):
        if DEBUG:
            tprint("update_curve")

        self.history_chart_curve.update()
def test_tprint():
    with mock.patch("sys.stdout", new=io.StringIO()) as fake_stdout:
        tprint("No color")

    assert fake_stdout.getvalue()[-9:] == "No color\n"
 def process_connection_lost():
     tprint("---> received: connection_lost")
     global go
     go = False
def process_jobs_updated():
    # In production code, your GUI update routine would go here
    tprint("---> received: jobs_updated")
    global cnt_jobs_updated
    cnt_jobs_updated += 1
Ejemplo n.º 15
0
    def update_chart(self):
        if DEBUG:
            tprint("update_chart")

        for tscurve in self.tscurves:
            tscurve.update()