Пример #1
0
    def __call__(self, event):  # noqa: D102
        data = event[0]

        if isinstance(data, JobStarted):
            print('Starting >>> {data.identifier}'.format_map(locals()),
                  flush=True)
            self._start_times[data.identifier] = time.monotonic()

        elif isinstance(data, TestFailure):
            job = event[1]
            self._with_test_failures.add(job)

        elif isinstance(data, JobEnded):
            if not data.rc:
                duration = \
                    time.monotonic() - self._start_times[data.identifier]
                duration_string = format_duration(duration)
                msg = 'Finished <<< {data.identifier} [{duration_string}]' \
                    .format_map(locals())
                job = event[1]
                if job in self._with_test_failures:
                    msg += '\t[ with test failures ]'
                writable = sys.stdout

            elif data.rc == SIGINT_RESULT:
                msg = 'Aborted  <<< {data.identifier}'.format_map(locals())
                writable = sys.stdout

            else:
                msg = 'Failed   <<< {data.identifier}\t' \
                    '[ Exited with code {data.rc} ]'.format_map(locals())
                writable = sys.stderr

            print(msg, file=writable, flush=True)
Пример #2
0
    def __call__(self, event):  # noqa: D102
        data = event[0]

        if isinstance(data, JobStarted):
            msg_template = bcolors.START + 'Starting ' + bcolors.STARTBR + '>>>' + bcolors.PKG_NAME + ' {data.identifier}' + bcolors.ENDC
            print(msg_template.format_map(locals()), flush=True)
            self._start_times[data.identifier] = time.time()

        elif isinstance(data, TestFailure):
            job = event[1]
            self._with_test_failures.add(job)

        elif isinstance(data, JobEnded):
            if not data.rc:
                duration = time.time() - self._start_times[data.identifier]
                duration_string = format_duration(duration)
                msg_template = bcolors.FIN + 'Finished ' + bcolors.FINBR + '<<<' + bcolors.PKG_NAME + ' {data.identifier}' + bcolors.ENDC + ' [' + bcolors.TIME + '{duration_string}' + bcolors.ENDC + ']'
                msg = msg_template.format_map(locals())
                job = event[1]
                if job in self._with_test_failures:
                    msg += '\t[ with test failures ]'
                writable = sys.stdout

            elif data.rc == SIGINT_RESULT:
                msg_template = bcolors.WARNING + 'Aborted  ' + '<<<' + bcolors.PKG_NAME + ' {data.identifier}' + bcolors.ENDC
                msg = msg_template.format_map(locals())
                writable = sys.stdout
            else:
                msg_template = bcolors.FAIL + 'Failed   ' + '<<<' + bcolors.PKG_NAME + ' {data.identifier}' + bcolors.ENDC + ' [' + bcolors.FAIL + 'Exited with code {data.rc}' + bcolors.ENDC + ']'
                msg = msg_template.format_map(locals())
                writable = sys.stderr

            print(msg, file=writable, flush=True)
Пример #3
0
    def _print_summary(self):
        # separate the summary from the previous output
        print()

        duration = time.monotonic() - self._start_time
        duration_string = format_duration(duration)

        count, job_type, _ = _msg_arguments(self._ended - self._interrupted -
                                            self._failed)
        print('Summary: {count} {job_type} finished '
              '[{duration_string}]'.format_map(locals()))

        if self._failed:
            count, job_type, names = _msg_arguments(self._failed)
            print('  {count} {job_type} failed: {names}'.format_map(locals()))

        if self._interrupted:
            count, job_type, names = _msg_arguments(self._interrupted)
            print('  {count} {job_type} aborted: {names}'.format_map(locals()))

        if self._with_stderr:
            count, job_type, names = _msg_arguments(self._with_stderr)
            print('  {count} {job_type} had stderr output: {names}'.format_map(
                locals()))

        if self._with_test_failures:
            count, job_type, names = _msg_arguments(self._with_test_failures)
            print('  {count} {job_type} had test failures: {names}'.format_map(
                locals()))

        if len(self._queued) > len(self._ended):
            count = len(self._queued - self._ended)
            job_type = get_job_type_word_form(count)
            print('  {count} {job_type} not processed'.format_map(locals()))
Пример #4
0
    def _print_summary(self):
        # separate the summary from the previous output
        print()

        duration = time.time() - self._start_time
        duration_string = format_duration(duration)

        count, plural_suffix, _ = _msg_arguments(self._ended -
                                                 self._interrupted -
                                                 self._failed)
        print('Summary: {count} package{plural_suffix} finished '
              '[{duration_string}]'.format_map(locals()))

        if self._failed:
            count, plural_suffix, names = _msg_arguments(self._failed)
            print(
                '  {count} package{plural_suffix} failed: {names}'.format_map(
                    locals()))

        if self._interrupted:
            count, plural_suffix, names = _msg_arguments(self._interrupted)
            print(
                '  {count} package{plural_suffix} aborted: {names}'.format_map(
                    locals()))

        if self._with_stderr:
            count, plural_suffix, names = _msg_arguments(self._with_stderr)
            print(
                '  {count} package{plural_suffix} had stderr output: {names}'.
                format_map(locals()))

        if self._with_test_failures:
            count, plural_suffix, names = _msg_arguments(
                self._with_test_failures)
            print(
                '  {count} package{plural_suffix} had test failures: {names}'.
                format_map(locals()))

        if len(self._queued) > len(self._ended):
            count = len(self._queued - self._ended)
            plural_suffix = 's' if count != 1 else ''
            print('  {count} package{plural_suffix} not processed'.format_map(
                locals()))
    def __call__(self, event):  # noqa: D102
        data = event[0]

        if isinstance(data, JobQueued):
            self._queued_count += 1

        elif isinstance(data, JobStarted):
            job = event[1]
            assert job not in self._running
            self._running[job] = {'start_time': time.monotonic()}

        elif isinstance(data, JobProgress):
            job = event[1]
            self._running[job]['progress'] = [data.progress]

        elif isinstance(data, StdoutLine):
            line = data.line
            if isinstance(line, bytes):
                line = line.decode(errors='replace')
            match = self._progress_pattern.match(line)
            if not match:
                return
            job = event[1]
            progress = self._running[job].get('progress', [])
            while len(progress) > 1:
                progress.pop()
            progress.append(match.group(1).lstrip() + '%')

        elif isinstance(data, JobEnded):
            job = event[1]
            self._ended[job] = self._running[job]
            self._ended[job]['end_time'] = time.monotonic()
            self._ended[job]['rc'] = data.rc
            del self._running[job]

        elif isinstance(data, TimerEvent):
            now = time.monotonic()
            blocks = []

            # runtime in seconds
            duration_string = format_duration(
                now - self._start_time, fixed_decimal_points=1)
            blocks.append('[{duration_string}]'.format_map(locals()))

            # number of completed jobs / number of jobs
            blocks.append(
                '[%d/%d complete]' %
                (len(self._ended), self._queued_count))

            # number of failed jobs if not zero
            failed_jobs = [
                j for j, d in self._ended.items()
                if d['rc'] and d['rc'] != SIGINT_RESULT]
            if failed_jobs:
                blocks.append('[%d failed]' % len(failed_jobs))

            # number of ongoing jobs if greater one
            if len(self._running) > 1:
                blocks.append('[%d ongoing]' % len(self._running))

            # job identifier, label and time for ongoing jobs
            for job, d in self._running.items():
                msg = job.task.context.pkg.name
                if 'progress' in d:
                    msg += ':%s' % ' '.join(d['progress'])
                duration_string = format_duration(
                    now - d['start_time'], fixed_decimal_points=1)
                blocks.append(
                    '[{msg} - {duration_string}]'.format_map(locals()))

            # determine blocks which fit into terminal width
            max_width = shutil.get_terminal_size().columns
            for i in reversed(range(len(blocks))):
                msg = ' '.join(blocks[0:i + 1])
                # append dots when skipping at least one block
                if i < len(blocks) - 1:
                    msg += ' ...'
                if len(msg) < max_width:
                    break
            else:
                return

            print(msg, end='\r')
            self._last_status_line_length = len(msg)

        elif isinstance(data, EventReactorShutdown):
            self._clear_last_status_line()
            atexit.unregister(self._clear_last_status_line)
Пример #6
0
def test_format_duration():
    # seconds below 10 with two decimal points
    assert format_duration(0) == '0.00s'
    assert format_duration(0.001) == '0.00s'
    assert format_duration(0.004999) == '0.00s'
    assert format_duration(0.005) == '0.01s'
    assert format_duration(9.99) == '9.99s'
    assert format_duration(9.994999) == '9.99s'
    assert format_duration(9.995) == '9.99s'  # floating point imprecision
    # seconds between 10 and 60 with one decimal points
    assert format_duration(9.995001) == '10.0s'
    assert format_duration(10) == '10.0s'
    assert format_duration(59.94) == '59.9s'
    # seconds above one minute with no decimal points
    assert format_duration(59.95) == '1min 0s'
    assert format_duration(83.45) == '1min 23s'
    assert format_duration(119.49) == '1min 59s'
    assert format_duration(119.5) == '2min 0s'
    assert format_duration(3599.4) == '59min 59s'
    # seconds above one hour with no decimal points
    assert format_duration(3599.5) == '1h 0min 0s'
    assert format_duration(5025.123) == '1h 23min 45s'
    assert format_duration(3599999) == '999h 59min 59s'
    # zero fixed decimal point
    assert format_duration(1.5, fixed_decimal_points=0) == '2s'
    assert format_duration(12.345, fixed_decimal_points=0) == '12s'
    # one fixed decimal points
    assert format_duration(1.5, fixed_decimal_points=1) == '1.5s'
    assert format_duration(12.345, fixed_decimal_points=1) == '12.3s'
    assert format_duration(34.5, fixed_decimal_points=1) == '34.5s'
    assert format_duration(3599.4, fixed_decimal_points=1) == '59min 59.4s'
    assert format_duration(4984.5, fixed_decimal_points=1) == '1h 23min 4.5s'
    # raise for negative parameter
    with pytest.raises(ValueError):
        format_duration(-1.0)