Exemple #1
0
def main():
    if os.name == 'nt':
        loop = asyncio.ProactorEventLoop()
        asyncio.set_event_loop(loop)
    else:
        loop = asyncio.get_event_loop()
    loop.run_until_complete(start(
        'sleep 2; wc', input=[b'foo bar baz\n'*300 for i in range(100)]))
    loop.close()
Exemple #2
0
 def setup_eventloop(self):
     """
     Sets up a new eventloop as the current one according to the OS.
     """
     if os.name == 'nt':
         self.eventloop = asyncio.ProactorEventLoop()
         if sys.version_info <= (3, 0):
             # FIXME: There appears to be a bug in the 2.7 version of trollius, wherein the selector retrieves an
             # object of value 0 and attempts to look for it in the weakref set, which raises an exception.
             # This hack sidesteps this issue, but does not solve it. If a proper fix is found, apply it!
             self.eventloop._selector._stopped_serving = set()
     else:
         self.eventloop = asyncio.new_event_loop()
     asyncio.set_event_loop(self.eventloop)
Exemple #3
0
def test_asyncserial_timeout_error():
    '''
    Verify serial device AsyncSerial instance is still tied up after closing.

    In Windows, it turns out that the serial port is tied up by an AsyncSerial
    instance until the corresponding event loop is closed.  This test tests
    that this is true.
    '''
    ports = serial.tools.list_ports.comports()
    if not ports:
        raise RuntimeError('No comports available.')

    kwargs = {'port': ports[0].device}

    @asyncio.coroutine
    def _open_asyncserial():
        with asyncserial.AsyncSerial(**kwargs) as async_device:
            yield asyncio.From(asyncio.sleep(5))

        raise asyncio.Return(None)

    def _open_serial(retries=1):
        for i in range(retries):
            try:
                with serial.Serial(**kwargs):
                    pass
                break
            except serial.SerialException as exception:
                pass
        else:
            raise exception

    _open_serial()

    try:
        loop = asyncio.ProactorEventLoop()
        asyncio.set_event_loop(loop)
        loop.run_until_complete(asyncio.wait_for(_open_asyncserial(),
                                                 timeout=2))
    except asyncio.TimeoutError:
        pass

    try:
        _open_serial()
    except serial.SerialException:
        raises(serial.SerialException)(_open_serial)()
Exemple #4
0
def test_asyncserial_timeout_workaround():
    '''
    Test closing event loop to free up device AsyncSerial instance.
    '''
    ports = serial.tools.list_ports.comports()
    if not ports:
        raise RuntimeError('No comports available.')

    kwargs = {'port': ports[0].device}

    @asyncio.coroutine
    def _open_asyncserial():
        with asyncserial.AsyncSerial(**kwargs) as async_device:
            yield asyncio.From(asyncio.sleep(5))

        raise asyncio.Return(None)

    def _open_serial(retries=1):
        for i in range(retries):
            try:
                with serial.Serial(**kwargs):
                    pass
                break
            except serial.SerialException as exception:
                pass
        else:
            raise exception

    _open_serial()

    try:
        loop = asyncio.ProactorEventLoop()
        asyncio.set_event_loop(loop)
        loop.run_until_complete(asyncio.wait_for(_open_asyncserial(),
                                                 timeout=2))
    except asyncio.TimeoutError:
        pass
    finally:
        # Close event loop.
        loop.close()

    try:
        _open_serial()
    except serial.SerialException:
        _open_serial()
    def run(self, command, *args, **kwargs):
        self_ = self

        class SubprocessProtocol(asyncio.SubprocessProtocol):
            def pipe_data_received(self, fd, data):
                self_._write(fd, re.sub(r'(\r?\n)+', r'\1', data))

            def connection_lost(self, exc):
                loop.stop()  # end loop.run_forever()

        if os.name == 'nt':
            # For subprocess' pipes on Windows
            loop = asyncio.ProactorEventLoop()
            asyncio.set_event_loop(loop)
        else:
            loop = asyncio.get_event_loop()

        try:
            if kwargs.pop('shell', False):
                proc = loop.subprocess_shell(SubprocessProtocol, command)
            else:
                proc = loop.subprocess_exec(SubprocessProtocol, *command)

            def _refresh_gui():
                refresh_gui()
                loop.call_soon(_refresh_gui)

            loop.call_soon(_refresh_gui)
            transport, protocol = loop.run_until_complete(proc)
            loop.run_forever()
        except Exception as exception:
            self._write(2, str(exception))
        else:
            return transport.get_returncode()
        finally:
            loop.close()
Exemple #6
0
 def setUp(self):
     self.loop = asyncio.ProactorEventLoop()
     self.set_event_loop(self.loop)
Exemple #7
0
sys_name = platform.system()

if sys_name == "Linux":
    import fcntl

    import clib as c
    from tunlib import *
    from linux import TapLinuxInterface
    TDInt = TapLinuxInterface

elif sys_name == "Windows" or sys_name == "cli":
    from winlib import *
    from win import TapWinInterface
    TDInt = TapWinInterface

    loop = asyncio.ProactorEventLoop()
    asyncio.set_event_loop(loop)
else:
    raise NotImplementedError("tap driver only available on linux and windows")

from time import sleep
usleep = lambda x: sleep(x / 1000000.0)

from ctypes import cast, pointer, POINTER, sizeof

from dev_fns import _device_setup, _enable_rx, _enable_tx
from link import _link_detect
from interrupt import _handle_interrupt


def async_msleep(self, t):
Exemple #8
0
def platform_setup(driver):
    driver.loop = asyncio.ProactorEventLoop()
    asyncio.set_event_loop(driver.loop)
    driver.kbd_h = GetStdHandle(STD_INPUT_HANDLE)
Exemple #9
0
def run_test(way_points,
             start_electrode,
             output_dir,
             video_dir=None,
             overwrite=False,
             svg_source=None,
             launch=False,
             resolution=(1280, 720),
             device_id=0,
             multi_sensing=False,
             voltage=115):
    '''
    Parameters
    ----------
    way_points : list[int]
        Contiguous list of waypoints, where test is routed as the shortest path
        between each consecutive pair of waypoints.
    start_electrode : int
        Waypoint to treat as starting point.

        If not the first waypoint in ``way_points``, the test route will "wrap
        around" until the ``start_electrode`` is reached again.
    output_dir : str
        Directory to write output files to.

        May include ``'%(uuid)s'`` as placeholder for chip UUID, e.g.,
        ``~/my_output_dir/%(uuid)s-results``.
    video_dir : str, optional
        Directory within which to search for videos corresponding to the start
        time of the test.

        If a related video is found, offer to move/rename the video with the
        same name and location as the output results file.
    overwrite : bool, optional
        If ``True``, overwrite output files.  Otherwise, ask before
        overwriting.
    svg_source : str or file-like, optional
        A file path, URI, or file-like object containing DropBot chip SVG
        source.
    launch : bool, optional
        Launch output path after creation (default: `False`).
    resolution : tuple[int, int], optional
        Target video resolution (may be ignored if not supported by device).
    device_id : int, optional
        OpenCV video capture device identifier (default=0).
    multi_sensing : bool, optional
        If `True`, run multi-sensing test.  Otherwise, run single-drop test
        (default: `False`).


    .. versionchanged:: 0.2
        Add ``video_dir`` keyword argument.
    .. versionchanged:: 0.3
        Add ``output_dir`` argument; and ``overwrite`` and ``svg_source``
        keyword arguments.
    .. versionchanged:: 0.4
        Write each test result a self-contained HTML file in the specified
        output directory.
    .. versionchanged:: 1.6.0
        Add ``launch`` keyword argument.
    .. versionchanged:: 0.7.0
        Add ``resolution`` and ``device_id`` keyword arguments.
    .. versionchanged:: 0.8.0
        Add ``multi_sensing`` keyword argument.
    .. versionchanged:: 0.9.0
        Update to support new return type from `connect()`, use ``proxy``
        attribute of ``monitor_task``, and ``channels_graph`` attribute of
        ``proxy``.
    .. versionchanged:: 0.10.0
        Explicitly execute a shorts detection test at the start of a chip test.
    .. versionchanged:: 0.10.0
        Add chip info to logged ``test-start`` message.
    .. versionchanged:: 0.11.0
        Add ``voltage`` keyword argument (actuation RMS voltage).
    .. versionchanged:: 0.11.1
        Remove shorted channels from adjacent channels graph.
    '''
    output_dir = ph.path(output_dir)

    if video_dir is not None:
        video_dir = ph.path(video_dir)

    ready = threading.Event()
    closed = threading.Event()

    loop = asyncio.ProactorEventLoop()
    asyncio.set_event_loop(loop)

    signals = blinker.Namespace()

    signals.signal('closed').connect(lambda sender: closed.set(), weak=False)

    logging.info('Wait for connection to DropBot...')
    monitor_task = connect(svg_source=svg_source)
    proxy = monitor_task.proxy
    G = proxy.channels_graph
    proxy.voltage = voltage

    def update_video(video, uuid):
        response = question('Attempt to set UUID in title of video file, '
                            '`%s`?' % video,
                            title='Update video?')
        if response == QMessageBox.StandardButton.Yes:
            try:
                f = mutagen.File(video)
                if ('\xa9nam' not in f.tags) or ('UUID'
                                                 not in f.tags['\xa9nam']):
                    f.tags['\xa9nam'] = \
                        'DMF chip QC - UUID: %s' % uuid
                    f.save()
                    logging.info('wrote UUID to video title: `%s`', video)
            except Exception:
                logging.warning('Error setting video title.', exc_info=True)
            # Substitute UUID into output directory path as necessary.
            path_subs_dict = {'uuid': uuid}
            path_subs_dict.update(_date_subs_dict())
            output_dir_ = ph.path(output_dir %
                                  path_subs_dict).expand().realpath()
            output_dir_.makedirs_p()
            output_path = output_dir_.joinpath('%s.mp4' % uuid)
            if not output_path.exists() or overwrite or \
                    (question('Output `%s` exists.  Overwrite?' % output_path,
                              title='Overwrite?') ==
                     QMessageBox.StandardButton.Yes):
                if output_path.exists():
                    output_path.remove()
                ph.path(video).move(output_path)
                logging.info('moved video to : `%s`', output_path)

    def on_chip_detected(sender, **kwargs):
        @ft.wraps(on_chip_detected)
        def wrapped(sender, **kwargs):
            signals.signal('chip-detected').disconnect(on_chip_detected)
            uuid = kwargs['decoded_objects'][0].data
            ready.uuid = uuid
            ready.set()

            # Wait for chip to be detected.
            response = None

            while response != QMessageBox.StandardButton.Yes:
                response = question('Chip detected: `%s`.\n\nReady to load '
                                    'electrode %s?' % (uuid, start_electrode),
                                    title='Chip detected')

            proxy.stop_switching_matrix()
            proxy.turn_off_all_channels()

            @asyncio.coroutine
            def _run():
                dropbot_events = []

                def log_event(message):
                    # Add UTC timestamp to each event.
                    message['utc_time'] = dt.datetime.utcnow().isoformat()
                    dropbot_events.append(message)

                # Log route events in memory.
                def log_route_event(event, message):
                    # Tag kwargs with route event name.
                    message['event'] = event
                    # Add chip, DropBot, and version info to `test-start`
                    # message.
                    if event == 'test-start':
                        message['uuid'] = uuid
                        message['dropbot.__version__'] = db.__version__
                        message['dropbot_chip_qc.__version__'] = __version__
                        message['dropbot'] = {
                            'system_info': db.self_test.system_info(proxy),
                            'i2c_scan': db.self_test.test_i2c(proxy)
                        }
                        message['dmf_chip.__version'] = dc.__version__
                        message['chip-info'] = copy.deepcopy(proxy.chip_info)
                    log_event(message)

                # Log results of shorts detection tests.
                proxy.signals.signal('shorts-detected').connect(log_event)

                if MULTI_SENSING_ENABLED and multi_sensing:
                    # Log multi-sensing capacitance events (in memory).
                    proxy.signals.signal('sensitive-capacitances')\
                        .connect(log_event)

                    # Use multi-sensing test implementation.
                    _run_test = _multi_run_test
                else:
                    # Use single-drop test implementation.
                    _run_test = _single_run_test

                loggers = {
                    e: ft.partial(
                        lambda event, sender, **kwargs: log_route_event(
                            event, kwargs), e)
                    for e in ('electrode-success', 'electrode-fail',
                              'electrode-skip', 'test-start', 'test-complete')
                }
                for event, logger in loggers.items():
                    signals.signal(event).connect(logger)

                # Explicitly execute a shorts detection test.
                for shorted_channel in proxy.detect_shorts():
                    if shorted_channel in G:
                        print('remove shorted channel: %s' % shorted_channel,
                              file=sys.stderr)
                        G.remove_node(shorted_channel)

                try:
                    start = time.time()
                    yield asyncio.From(
                        _run_test(signals,
                                  proxy,
                                  G,
                                  way_points,
                                  start=start_electrode))
                    if video_dir:
                        # A video directory was provided.  Look for a video
                        # corresponding to the same timeline as the test.
                        # Only consider videos that were created within 1
                        # minute of the start of the test.
                        videos = sorted(
                            (p for p in video_dir.expand().files('*.mp4')
                             if abs(p.ctime - start) < 60),
                            key=lambda x: -x.ctime)
                        if videos:
                            loop.call_soon_threadsafe(update_video, videos[-1],
                                                      uuid)
                except nx.NetworkXNoPath as exception:
                    logging.error('QC test failed: `%s`',
                                  exception,
                                  exc_info=True)

                def write_results():
                    # Substitute UUID into output directory path as necessary.
                    path_subs_dict = {'uuid': uuid}
                    path_subs_dict.update(_date_subs_dict())
                    output_dir_ = ph.path(output_dir %
                                          path_subs_dict).expand().realpath()
                    output_dir_.makedirs_p()

                    # Write logged events to file.
                    output_path = \
                        output_dir_.joinpath('Chip test report - %s.html' %
                                             uuid)
                    if not output_path.exists() or overwrite or \
                            (question('Output `%s` exists.  Overwrite?' %
                                     output_path, title='Overwrite?') ==
                             QMessageBox.StandardButton.Yes):
                        render_summary(dropbot_events,
                                       output_path,
                                       svg_source=svg_source)
                        logging.info('wrote events log to: `%s`', output_path)
                        if launch:
                            # Launch result using default system viewer.
                            output_path.launch()

                loop.call_soon_threadsafe(write_results)

                signals.signal('chip-detected').connect(on_chip_detected)

            qc_task = cancellable(_run)
            thread = threading.Thread(target=qc_task)
            thread.daemon = True
            thread.start()

        loop.call_soon_threadsafe(ft.partial(wrapped, sender, **kwargs))

    signals.signal('chip-detected').connect(on_chip_detected)

    thread = threading.Thread(target=chip_video_process,
                              args=(signals, resolution[0], resolution[1],
                                    device_id))
    thread.start()

    # Launch window to view chip video.
    loop.run_until_complete(show_chip(signals))

    # Close background thread.
    signals.signal('exit-request').send('main')
    closed.wait()