예제 #1
0
async def test_conversion():
    '''
    Test message conversion between 2 queues
    '''
    bus = MessageBus()
    bus.add_queue('input')
    bus.add_queue(
        'output',
        maxsize=3)  # limit size to immediately stop execution for unit test
    assert isinstance(bus.queues['input'], asyncio.Queue)
    assert isinstance(bus.queues['output'], asyncio.Queue)
    assert bus.queues['input'].qsize() == 0
    assert bus.queues['output'].qsize() == 0

    await bus.send('input', 'test x')
    await bus.send('input', 'hello world.')
    await bus.send('output', 'lowercase')

    # Convert all strings from input in uppercase
    assert bus.queues['input'].qsize() == 2
    task = asyncio.create_task(bus.run(lambda x: x.upper(), 'input', 'output'))

    await bus.receive('output') == 'lowercase'
    await bus.receive('output') == 'TEST X'
    await bus.receive('output') == 'HELLO WORLD.'
    task.cancel()
    assert bus.queues['input'].qsize() == 0
    assert bus.queues['output'].qsize() == 0
예제 #2
0
class EventListener(object):
    '''
    Listen to external events and trigger new tasks
    '''
    def __init__(self, cache_root):
        # Create message bus shared amongst process
        self.bus = MessageBus()

        # Build client applications configuration
        # TODO: use simpler secret structure per client
        clients_conf = {h['type']: h for h in taskcluster.secrets['HOOKS']}
        code_review_conf = clients_conf.get('static-analysis-phabricator')
        code_coverage_conf = clients_conf.get('code-coverage')

        # Code Review Workflow
        if code_review_conf:
            self.code_review = CodeReview(
                api_key=taskcluster.secrets['PHABRICATOR']['token'],
                url=taskcluster.secrets['PHABRICATOR']['url'],
                publish=taskcluster.secrets['PHABRICATOR'].get(
                    'publish', False),
                risk_analysis_reviewers=code_review_conf.get(
                    'risk_analysis_reviewers', []))
            self.code_review.register(self.bus)

            # Build mercurial worker & queue
            self.mercurial = MercurialWorker(
                QUEUE_MERCURIAL,
                QUEUE_PHABRICATOR_RESULTS,
                repositories=self.code_review.get_repositories(
                    taskcluster.secrets['repositories'], cache_root),
            )
            self.mercurial.register(self.bus)

            # Create web server
            self.webserver = WebServer(QUEUE_WEB_BUILDS)
            self.webserver.register(self.bus)
        else:
            self.code_review = None
            self.mercurial = None
            self.webserver = None

        # Code Coverage Workflow
        if code_coverage_conf:
            self.code_coverage = CodeCoverage(code_coverage_conf, self.bus)

            # Setup monitoring for newly created tasks
            self.monitoring = Monitoring(QUEUE_MONITORING,
                                         taskcluster.secrets['ADMINS'],
                                         7 * 3600)
            self.monitoring.register(self.bus)

            # Create pulse listener for code coverage
            self.pulse = PulseListener(
                QUEUE_PULSE_CODECOV,
                'exchange/taskcluster-queue/v1/task-group-resolved',
                '#',
                taskcluster.secrets['PULSE_USER'],
                taskcluster.secrets['PULSE_PASSWORD'],
            )
            self.pulse.register(self.bus)

        else:
            self.code_coverage = None
            self.monitoring = None
            self.pulse = None

        assert self.code_review or self.code_coverage, 'No client applications to run !'

    def run(self):
        consumers = []

        if self.code_review:
            consumers += [
                # Code review main workflow
                self.code_review.run(),

                # Add mercurial task
                self.mercurial.run(),
            ]

            # Publish results on Phabricator
            if self.code_review.publish:
                consumers.append(
                    self.bus.run(self.code_review.publish_results,
                                 QUEUE_PHABRICATOR_RESULTS))

            # Start the web server in its own process
            self.webserver.start()

        if self.code_coverage:
            consumers += [
                # Code coverage main workflow
                self.code_coverage.run(),

                # Add monitoring task
                self.monitoring.run(),

                # Add pulse task
                self.pulse.run(),
            ]

        # Run all tasks concurrently
        run_tasks(consumers)

        # Stop the webserver when other async process are stopped
        if self.webserver:
            self.webserver.stop()