def test_reply_to_error_message(datetime_mock, caplog, event_loop):
    settings = MockSettings({})
    client = MockClient(settings)
    scheduler = Scheduler(settings, client, [], 'my_worker_id')

    with pytest.raises(SystemExit):
        datetime_mock.utcnow = mock.Mock(return_value=datetime(2000, 1, 1))
        event_loop.run_until_complete(
            scheduler.on_server_message(MessageType.Error.value, {
                'title': 'title',
                'body': 'body',
                'meta': {
                    'Name': 'Value',
                },
            }))

    assert error_messages(caplog) == [
        '\n'
        '\n'
        '    '
        '================================================================================\n'
        '\n'
        '    [ERROR] [CONQUER] title\n'
        '\n'
        '    body\n'
        '\n'
        '    [Name = Value]\n'
        '    [Timestamp = 2000-01-01T00:00:00]\n'
        '\n'
        '    '
        '================================================================================\n'
        '\n',
    ]
async def test_reply_to_done_message():
    settings = MockSettings({})
    client = MockClient(settings)
    scheduler = Scheduler(settings, client, [], 'my_worker_id')
    assert scheduler.more is True

    await scheduler.on_server_message(MessageType.Done.value, None)

    assert scheduler.more is False

    await scheduler.stop()
Beispiel #3
0
    async def run_task(self):
        global suite_items, schedulers, report_items_by_worker

        # init client
        client = Client(settings)
        client.subscribe(self.settings)

        # init scheduler
        scheduler = Scheduler(self.settings, client, suite_items, self.name)
        schedulers.append(scheduler)

        # connect to server
        await client.start()

        # work through test items
        next_tests = []
        report_items_by_worker[self.name] = []
        while not scheduler.done:
            pending_at = datetime.utcnow()
            schedule = await scheduler.next()
            if schedule is None:
                break  # happens when we are done
            started_at = datetime.utcnow()
            schedule_files = [item.file for item in schedule.items]
            schedule_tests = itertools.chain(
                *[tests_by_file[f] for f in schedule_files])
            for test in schedule_tests:
                test.__schedule_id__ = schedule.id
                next_tests.append(test)
            logger.info('preparing schedule took %sms',
                        str(started_at - pending_at))

            while next_tests:
                if len(next_tests) < 2 and not scheduler.done:
                    logger.info('requiring next schedule')
                    break  # we don't know the next test yet
                test = next_tests.pop(0)
                next_test = next_tests[0] if next_tests else None
                test.config.hook.pytest_runtest_protocol(item=test,
                                                         nextitem=next_test)
                if next_test is None or test.__schedule_id__ != next_test.__schedule_id__:
                    report = Report(test.__schedule_id__,
                                    report_items_by_worker[self.name],
                                    pending_at, started_at, datetime.utcnow())
                    await scheduler.report(report)
                    report_items_by_worker[self.name] = []

        # wrap things up
        await scheduler.stop()
        await client.stop()
async def test_reply_to_schedule_message():
    class MockSerializer:
        @staticmethod
        def deserialize_schedule(payload):
            return Schedule(payload['id'], payload['items'])

    settings = MockSettings({})
    client = MockClient(settings)
    scheduler = Scheduler(settings, client, [], 'my_worker_id', MockSerializer)

    payload = [{'id': 'ID', 'items': [['A'], ['B']]}]
    await scheduler.on_server_message(MessageType.Schedules.value, payload)

    assert await scheduler.next() == Schedule('ID', [['A'], ['B']])

    await scheduler.stop()
async def test_reply_to_config_message():
    class MockSerializer:
        @staticmethod
        def serialize_config(settings, worker_id):
            return (settings, worker_id)

    settings = MockSettings({})
    client = MockClient(settings)
    scheduler = Scheduler(settings, client, [], 'my_worker_id', MockSerializer)

    await scheduler.on_server_message(MessageType.Config.value, None)

    assert client.received == [
        (MessageType.Config, (settings, 'my_worker_id')),
    ]

    await scheduler.stop()
async def test_report():
    class MockSerializer:
        @staticmethod
        def serialize_report(report):
            return report

    settings = MockSettings({})
    client = MockClient(settings)
    scheduler = Scheduler(settings, client, [], 'my_worker_id', MockSerializer)

    report = Report('ID', '<items>', None, None, None)
    await scheduler.report(report)

    await scheduler.stop()  # flushes reports

    assert client.received == [
        (MessageType.Ack, {
            'schedule_id': 'ID',
            'status': 'success'
        }),
        (MessageType.Report, report),
    ]
async def test_reply_to_suite_message():
    class MockSerializer:
        @staticmethod
        def serialize_suite(suite_items):
            return suite_items

    settings = MockSettings({})
    client = MockClient(settings)
    suite_items = [
        SuiteItem(
            'test',
            Location('tests/IT/stub/stub_A.py', 'stub_A', 'TestClass',
                     'test_A', 1))
    ]
    scheduler = Scheduler(settings, client, suite_items, 'my_worker_id',
                          MockSerializer)

    await scheduler.on_server_message(MessageType.Suite.value, None)

    assert client.received == [
        (MessageType.Suite, suite_items),
    ]

    await scheduler.stop()
Beispiel #8
0
async def test_successful_server_communication(config, mock_server):
    os.environ['MY_CI'] = 'true'
    settings = MockSettings({
        'api_domain': mock_server.url,
        'api_key': 'api_key',
        'api_retry_limit': '1',
        'api_wait_limit': '0',
        'build_dir': '/app',
        'build_id': config['build']['id'],
        'build_job': 'job',
        'enabled': True,
        'vcs_branch': 'master',
        'vcs_repo': 'github.com/myrepo',
        'vcs_revision': 'asd43da',
        'vcs_revision_message': 'my commit',
    })
    client = Client(settings)
    client.subscribe(settings)
    suite_items = [
        SuiteItem(
            'test',
            Location('tests/IT/stub/stub_A.py', 'stub_A', 'TestClass',
                     'test_A', 1)),
        SuiteItem('test',
                  Location('tests/IT/stub/stub_B.py', 'stub_B', 'TestClass',
                           'test_B', 1),
                  tags=[Tag('my_group', False)]),
        SuiteItem('test',
                  Location('tests/IT/stub/stub_C.py', 'stub_C', 'TestClass',
                           'test_C', 1),
                  deps=[
                      SuiteItem(
                          'fixture',
                          Location('tests/IT/stub/stub_fixture.py', 'fixtures',
                                   'FixtureClass', 'test_C', 0)),
                  ]),
    ]
    scheduler = Scheduler(settings, client, suite_items, 'my_worker_id')

    # (1) CONNECT

    await client.start()

    # (2) SERVER REQUESTS ENV

    await mock_server.send(MessageType.Envs, [{
        'name': 'CI',
        'conditions': ['my_CI'],
        'mapping': {}
    }])

    # (3) CLIENT REPLIES WITH ENV

    await assert_received_eventually(mock_server, [
        (MessageType.Envs.value, 'CI'),
        (MessageType.Ack.value, {
            'message_num': 0,
            'status': 'success'
        }),
    ])

    # (4) SERVER REQUESTS CONFIG

    await mock_server.send(MessageType.Config, {})

    # (5) CLIENT REPLIES WITH CONFIG

    await assert_received_eventually(mock_server, [
        (MessageType.Config.value, {
            'build': {
                'dir': '/app',
                'id': config['build']['id'],
                'job': 'job',
                'node': 'random-uuid',
                'pool': 0,
                'project': None,
                'url': None
            },
            'client': {
                'capabilities':
                ['fixtures', 'lifecycle_timings', 'split_by_file'],
                'messages': [
                    'ack', 'config', 'done', 'envs', 'error', 'report',
                    'schedules', 'suite'
                ],
                'name':
                'pytest-conquer',
                'version':
                '1.0',
                'workers':
                1,
                'worker_id':
                'my_worker_id',
            },
            'platform': {
                'name': 'python',
                'version': '3.6'
            },
            'runner': {
                'args': ['arg1'],
                'name': None,
                'plugins': [],
                'root': None,
                'version': None
            },
            'system': {
                'context': {},
                'cpus': 3,
                'os': 'Linux',
                'os_version': '1.42',
                'provider': 'CI',
                'ram': 17179869184
            },
            'vcs': {
                'branch': 'master',
                'pr': None,
                'repo': 'github.com/myrepo',
                'revision': 'asd43da',
                'revision_message': 'my commit',
                'tag': None,
                'type': 'git'
            },
        }),
        (MessageType.Ack.value, {
            'message_num': 1,
            'status': 'success'
        }),
    ])

    # (6) SERVER REQUESTS SUITE

    await mock_server.send(MessageType.Suite, {})

    # (7) CLIENT SENDS SUITE

    await assert_received_eventually(mock_server, [
        (MessageType.Suite.value, {
            'items': [
                {
                    'type': 'test',
                    'location': {
                        'file': 'tests/IT/stub/stub_A.py',
                        'func': 'test_A',
                        'module': 'stub_A',
                        'class': 'TestClass',
                        'line': 1
                    }
                },
                {
                    'type': 'test',
                    'location': {
                        'file': 'tests/IT/stub/stub_B.py',
                        'func': 'test_B',
                        'module': 'stub_B',
                        'class': 'TestClass',
                        'line': 1
                    },
                    'tags': [{
                        'group': 'my_group'
                    }]
                },
                {
                    'type':
                    'test',
                    'location': {
                        'file': 'tests/IT/stub/stub_C.py',
                        'func': 'test_C',
                        'module': 'stub_C',
                        'class': 'TestClass',
                        'line': 1
                    },
                    'deps': [{
                        'type': 'fixture',
                        'location': {
                            'file': 'tests/IT/stub/stub_fixture.py',
                            'func': 'test_C',
                            'module': 'fixtures',
                            'class': 'FixtureClass'
                        }
                    }]
                },
            ],
        }),
        (MessageType.Ack.value, {
            'message_num': 2,
            'status': 'success'
        }),
    ])

    # (8) SERVER SENDS SCHEDULE #1

    await mock_server.send(MessageType.Schedules, [{
        'id':
        '0',
        'items': [
            {
                'file': 'tests/IT/stub/stub_A.py'
            },
            {
                'file': 'tests/IT/stub/stub_B.py'
            },
        ],
    }])

    await assert_received_eventually(mock_server, [
        (MessageType.Ack.value, {
            'message_num': 3,
            'status': 'success'
        }),
    ])

    assert await scheduler.next() == Schedule('0', [
        ScheduleItem('tests/IT/stub/stub_A.py'),
        ScheduleItem('tests/IT/stub/stub_B.py'),
    ])

    # (9) CLIENT SENDS REPORT #1

    await scheduler.report(
        Report('0', [
            ReportItem(
                'test',
                Location('tests/IT/stub/stub_A.py', 'stub_A', 'TestClass',
                         'test_A', 3), 'failed',
                Failure('AssertionError', 'assert 1 + 1 == 4'), time, time),
            ReportItem(
                'test',
                Location('tests/IT/stub/stub_B.py', 'stub_B', 'TestClass',
                         'test_B', 1), 'passed', None, time, time),
        ], time, time, time))

    await assert_received_eventually(mock_server, [
        (MessageType.Ack.value, {
            'schedule_id': '0',
            'status': 'success'
        }),
        (MessageType.Report.value, {
            'schedule_id':
            '0',
            'items': [{
                'type': 'test',
                'location': {
                    'file': 'tests/IT/stub/stub_A.py',
                    'func': 'test_A',
                    'module': 'stub_A',
                    'class': 'TestClass',
                    'line': 3
                },
                'status': 'failed',
                'started_at': '2000-01-01T00:00:00.000Z',
                'finished_at': '2000-01-01T00:00:00.000Z',
                'error': {
                    'type': 'AssertionError',
                    'message': 'assert 1 + 1 == 4'
                },
            }, {
                'type': 'test',
                'location': {
                    'file': 'tests/IT/stub/stub_B.py',
                    'func': 'test_B',
                    'module': 'stub_B',
                    'class': 'TestClass',
                    'line': 1
                },
                'status': 'passed',
                'started_at': '2000-01-01T00:00:00.000Z',
                'finished_at': '2000-01-01T00:00:00.000Z',
            }],
            'pending_at':
            '2000-01-01T00:00:00.000Z',
            'started_at':
            '2000-01-01T00:00:00.000Z',
            'finished_at':
            '2000-01-01T00:00:00.000Z',
        }),
    ])

    # (10) SERVER SENDS SCHEDULE #2

    await mock_server.send(MessageType.Schedules,
                           [{
                               'id': '1',
                               'items': [
                                   {
                                       'file': 'tests/IT/stub/stub_C.py'
                                   },
                               ],
                           }])

    await assert_received_eventually(mock_server, [
        (MessageType.Ack.value, {
            'message_num': 4,
            'status': 'success'
        }),
    ])

    assert await scheduler.next() == Schedule('1', [
        ScheduleItem('tests/IT/stub/stub_C.py'),
    ])

    # (12) CLIENT SENDS REPORT #2

    await scheduler.report(
        Report('1', [
            ReportItem(
                'test',
                Location('tests/IT/stub/stub_C.py', 'stub_C', 'TestClass',
                         'test_C', 1), 'passed', None, time, time),
        ], time, time, time))

    await assert_received_eventually(mock_server, [
        (MessageType.Ack.value, {
            'schedule_id': '1',
            'status': 'success'
        }),
        (MessageType.Report.value, {
            'schedule_id':
            '1',
            'items': [{
                'type': 'test',
                'location': {
                    'file': 'tests/IT/stub/stub_C.py',
                    'func': 'test_C',
                    'module': 'stub_C',
                    'class': 'TestClass',
                    'line': 1
                },
                'status': 'passed',
                'started_at': '2000-01-01T00:00:00.000Z',
                'finished_at': '2000-01-01T00:00:00.000Z',
            }],
            'pending_at':
            '2000-01-01T00:00:00.000Z',
            'started_at':
            '2000-01-01T00:00:00.000Z',
            'finished_at':
            '2000-01-01T00:00:00.000Z',
        }),
    ])

    # (13) SERVER SENDS DONE

    await mock_server.send(MessageType.Done, {})
    await asyncio.sleep(0.1)
    assert scheduler.more is False

    # (14) SHUTDOWN

    await scheduler.stop()
    await client.stop()