コード例 #1
0
def test_build_package():
    event_loop = new_event_loop()
    asyncio.set_event_loop(event_loop)
    try:
        with TemporaryDirectory(prefix='test_colcon_') as tmp_path_str:
            tmp_path = Path(tmp_path_str)
            python_build_task = PythonBuildTask()
            package = PackageDescriptor(tmp_path / 'src')
            package.name = 'test_package'
            package.type = 'python'

            context = TaskContext(
                pkg=package,
                args=SimpleNamespace(
                    path=str(tmp_path / 'src'),
                    build_base=str(tmp_path / 'build'),
                    install_base=str(tmp_path / 'install'),
                    symlink_install=False,
                ),
                dependencies={}
            )
            python_build_task.set_context(context=context)

            pkg = python_build_task.context.pkg

            pkg.path.mkdir()
            (pkg.path / 'setup.py').write_text(
                'from setuptools import setup\n'
                'setup(\n'
                '    name="test_package",\n'
                '    packages=["my_module"],\n'
                ')\n'
            )
            (pkg.path / 'my_module').mkdir()
            (pkg.path / 'my_module' / '__init__.py').touch()

            src_base = Path(python_build_task.context.args.path)

            source_files_before = set(src_base.rglob('*'))
            event_loop.run_until_complete(python_build_task.build())
            source_files_after = set(src_base.rglob('*'))
            assert source_files_before == source_files_after

            build_base = Path(python_build_task.context.args.build_base)
            assert 1 == len(list(build_base.rglob('my_module/__init__.py')))

            install_base = Path(python_build_task.context.args.install_base)
            assert 1 == len(list(install_base.rglob('my_module/__init__.py')))

            pkg_info, = install_base.rglob('PKG-INFO')
            assert 'Name: test-package' in pkg_info.read_text().splitlines()
    finally:
        event_loop.close()
コード例 #2
0
    def execute(self, args, jobs, *, on_error=OnError.interrupt):  # noqa: D102
        # avoid debug message from asyncio when colcon uses debug log level
        asyncio_logger = logging.getLogger('asyncio')
        asyncio_logger.setLevel(logging.INFO)

        loop = new_event_loop()
        asyncio.set_event_loop(loop)

        coro = self._execute(args, jobs, on_error=on_error)
        future = asyncio.ensure_future(coro, loop=loop)
        try:
            logger.debug('run_until_complete')
            loop.run_until_complete(future)
        except KeyboardInterrupt:
            logger.debug('run_until_complete was interrupted')
            # override job rc with special SIGINT value
            for job in self._ongoing_jobs:
                job.returncode = SIGINT_RESULT
            # ignore further SIGINTs
            signal.signal(signal.SIGINT, signal.SIG_IGN)
            # wait for jobs which have also received a SIGINT
            if not future.done():
                logger.debug('run_until_complete again')
                loop.run_until_complete(future)
                assert future.done()
            # read potential exception to avoid asyncio error
            _ = future.exception()
            logger.debug('run_until_complete finished')
            return signal.SIGINT
        except Exception as e:  # noqa: F841
            exc = traceback.format_exc()
            logger.error('Exception in job execution: {e}\n{exc}'.format_map(
                locals()))
            return 1
        finally:
            # HACK on Windows closing the event loop seems to hang after Ctrl-C
            # even though no futures are pending
            if sys.platform != 'win32':
                logger.debug('closing loop')
                loop.close()
                logger.debug('loop closed')
        result = future.result()
        logger.debug("run_until_complete finished with '{result}'".format_map(
            locals()))
        return result
コード例 #3
0
def test_run_cancel():
    # with callbacks, canceled
    stdout_lines = []

    def stdout_callback(line):
        nonlocal stdout_lines
        stdout_lines.append(line)

    coroutine = run([
        sys.executable, '-c',
        r"import time; time.sleep(1); print('line1\nline2')"
    ], stdout_callback, None)
    loop = new_event_loop()
    asyncio.set_event_loop(loop)
    task = asyncio.Task(coroutine, loop=loop)
    assert task.cancel() is True
    try:
        with pytest.raises(asyncio.CancelledError):
            loop.run_until_complete(task)
    finally:
        loop.close()
コード例 #4
0
    def execute(self, args, jobs, *, on_error=OnError.interrupt):  # noqa: D102
        # avoid debug message from asyncio when colcon uses debug log level
        asyncio_logger = logging.getLogger('asyncio')
        asyncio_logger.setLevel(logging.INFO)

        rc = 0
        loop = new_event_loop()
        asyncio.set_event_loop(loop)
        jobs = jobs.copy()
        try:
            while jobs:
                name, job = jobs.popitem(last=False)
                coro = job()
                future = asyncio.ensure_future(coro, loop=loop)
                try:
                    logger.debug(
                        "run_until_complete '{name}'".format_map(locals()))
                    loop.run_until_complete(future)
                except KeyboardInterrupt:
                    logger.debug(
                        "run_until_complete '{name}' was interrupted"
                        .format_map(locals()))
                    # override job rc with special SIGINT value
                    job.returncode = SIGINT_RESULT
                    # ignore further SIGINTs
                    signal.signal(signal.SIGINT, signal.SIG_IGN)
                    # wait for job which has also received a SIGINT
                    if not future.done():
                        logger.debug(
                            "run_until_complete '{name}' again"
                            .format_map(locals()))
                        loop.run_until_complete(future)
                        assert future.done()
                    # read potential exception to avoid asyncio error
                    _ = future.exception()  # noqa: F841
                    logger.debug(
                        "run_until_complete '{name}' finished"
                        .format_map(locals()))
                    return signal.SIGINT
                except Exception as e:  # noqa: F841
                    exc = traceback.format_exc()
                    logger.error(
                        "Exception in job execution '{name}': {e}\n{exc}"
                        .format_map(locals()))
                    return 1
                result = future.result()
                logger.debug(
                    "run_until_complete '{name}' finished with '{result}'"
                    .format_map(locals()))
                if result:
                    if not rc:
                        rc = result
                    if on_error in (OnError.interrupt, OnError.skip_pending):
                        # skip pending jobs
                        return rc
                    if on_error == OnError.skip_downstream:
                        # skip downstream jobs of failed one
                        for pending_name, pending_job in list(jobs.items()):
                            if job.identifier in pending_job.dependencies:
                                del jobs[pending_name]

        finally:
            for task in asyncio.Task.all_tasks():
                if not task.done():
                    logger.error("Task '{task}' not done".format_map(locals()))
            # HACK on Windows closing the event loop seems to hang after Ctrl-C
            # even though no futures are pending
            if sys.platform != 'win32':
                logger.debug('closing loop')
                loop.close()
                logger.debug('loop closed')
        return rc