Skip to content

Commit

Permalink
fix: Handle non-UTF-8 lines in plugin output for logging (#8399)
Browse files Browse the repository at this point in the history
* fix: Handle non-UTF-8 lines in plugin output for logging #8377

* Test change

---------

Co-authored-by: nKandel <npkand+3070@gmail.com>
Co-authored-by: Edgar Ramírez-Mondragón <edgar@meltano.com>
  • Loading branch information
3 people committed Feb 6, 2024
1 parent 1c0dd78 commit b06f1ea
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ jobs:
- name: Upload coverage report
with:
fail_ci_if_error: true
files: ./coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}
uses: codecov/codecov-action@v4.0.1

Expand Down
4 changes: 2 additions & 2 deletions src/meltano/core/logging/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ async def _write_line_writer(writer: SubprocessOutputWriter, line: bytes):
await writer.wait_closed()
return False
else:
writer.writeline(line.decode())
writer.writeline(line.decode(errors="replace"))

return True

Expand All @@ -214,7 +214,7 @@ async def capture_subprocess_output(
reader: asyncio.StreamReader | None,
*line_writers: SubprocessOutputWriter,
) -> None:
"""Capture in real time the output stream of a suprocess that is run async.
"""Capture in real time the output stream of a subprocess that is run async.
The stream has been set to asyncio.subprocess.PIPE and is provided using
reader to this function.
Expand Down
33 changes: 33 additions & 0 deletions tests/meltano/core/logging/test_logging_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from __future__ import annotations

import asyncio

import pytest

from meltano.core.logging.utils import capture_subprocess_output


class AsyncReader(asyncio.StreamReader):
def __init__(self, lines: list[bytes]):
self.lines = lines

def at_eof(self) -> bool:
return not self.lines

async def readline(self) -> bytes:
return self.lines.pop(0) if self.lines else b""


@pytest.mark.asyncio()
async def test_capture_subprocess_output():
INPUT_LINES = [b"LINE\n", b"LINE 2\n", b"\xed\n"]
OUTPUT_LINES = []

class LineWriter:
def writeline(self, line: str):
OUTPUT_LINES.append(line)

reader = AsyncReader(INPUT_LINES)

await capture_subprocess_output(reader, LineWriter())
assert ["LINE\n", "LINE 2\n", "�\n"] == OUTPUT_LINES

0 comments on commit b06f1ea

Please sign in to comment.