(context, initial_devices)
| 536 | |
| 537 | |
| 538 | async def logcat_task(context, initial_devices): |
| 539 | # Gradle may need to do some large downloads of libraries and emulator |
| 540 | # images. This will happen during find_device in --managed mode, or find_pid |
| 541 | # in --connected mode. |
| 542 | startup_timeout = 600 |
| 543 | serial = await wait_for(find_device(context, initial_devices), startup_timeout) |
| 544 | pid = await wait_for(find_pid(serial), startup_timeout) |
| 545 | |
| 546 | # `--pid` requires API level 24 or higher. |
| 547 | # |
| 548 | # `--binary` mode is used in order to detect which messages end with a |
| 549 | # newline, which most of the other modes don't indicate (except `--format |
| 550 | # long`). For example, every time pytest runs a test, it prints a "." and |
| 551 | # flushes the stream. Each "." becomes a separate log message, but we should |
| 552 | # show them all on the same line. |
| 553 | args = [adb, "-s", serial, "logcat", "--pid", pid, "--binary"] |
| 554 | logcat_started = False |
| 555 | async with async_process( |
| 556 | *args, stdout=subprocess.PIPE, stderr=None |
| 557 | ) as process: |
| 558 | while True: |
| 559 | try: |
| 560 | priority, tag, message = await read_logcat(process.stdout) |
| 561 | logcat_started = True |
| 562 | except asyncio.IncompleteReadError: |
| 563 | break |
| 564 | |
| 565 | # Exclude high-volume messages which are rarely useful. |
| 566 | if context.verbose < 2 and "from python test_syslog" in message: |
| 567 | continue |
| 568 | |
| 569 | # Put high-level messages on stderr so they're highlighted in the |
| 570 | # buildbot logs. This will include Python's own stderr. |
| 571 | stream = sys.stderr if priority >= LogPriority.WARN else sys.stdout |
| 572 | |
| 573 | # The app's stdout and stderr should be passed through transparently |
| 574 | # to our own corresponding streams. |
| 575 | if tag in ["python.stdout", "python.stderr"]: |
| 576 | global python_started |
| 577 | python_started = True |
| 578 | stream.write(message) |
| 579 | stream.flush() |
| 580 | else: |
| 581 | # Non-Python messages add a lot of noise, but they may |
| 582 | # sometimes help explain a failure. Format them in the same way |
| 583 | # as `logcat --format tag`. |
| 584 | formatted = f"{priority.name[0]}/{tag}: {message}" |
| 585 | if not formatted.endswith("\n"): |
| 586 | formatted += "\n" |
| 587 | log_verbose(context, formatted, stream) |
| 588 | |
| 589 | # If the device disconnects while logcat is running, which always |
| 590 | # happens in --managed mode, some versions of adb return non-zero. |
| 591 | # Distinguish this from a logcat startup error by checking whether we've |
| 592 | # received any logcat messages yet. |
| 593 | status = await wait_for(process.wait(), timeout=1) |
| 594 | if status != 0 and not logcat_started: |
| 595 | raise CalledProcessError(status, args) |
no test coverage detected
searching dependent graphs…