Skip to content

Commit 94e37fd

Browse files
pdxjohnnyterriko
andauthored
fix: async utils: aio_run_command(): check returncode (#1181)
Raise subprocess.CalledProcessError if subprocess fails with a non-zero return code. Fixes: #1177 Signed-off-by: John Andersen <[email protected]> Co-authored-by: Terri Oda <[email protected]>
1 parent 420886a commit 94e37fd

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

.github/workflows/pythonapp.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ jobs:
282282
test/test_output_engine.py
283283
test/test_util.py
284284
test/test_condensed_downloads.py
285+
test/test_async_utils.py
285286
test/test_package_list_parser.py
286287
test/test_merge.py
287288
- name: Run Synchronous test

cve_bin_tool/async_utils.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import itertools
1010
import os
1111
import shutil
12+
import subprocess
1213
import sys
1314
import tempfile
1415
from functools import partial, wraps
@@ -54,6 +55,10 @@ async def aio_run_command(args):
5455
stderr=asyncio.subprocess.PIPE,
5556
)
5657
stdout, stderr = await process.communicate()
58+
if process.returncode != 0:
59+
raise subprocess.CalledProcessError(
60+
args, process.returncode, output=stdout, stderr=stderr
61+
)
5762
return stdout, stderr # binary encoded
5863

5964

test/test_async_utils.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Copyright (C) 2021 Intel Corporation
2+
# SPDX-License-Identifier: GPL-3.0-or-later
3+
4+
"""
5+
CVE-bin-tool async util tests
6+
"""
7+
import dataclasses
8+
import subprocess
9+
import unittest.mock
10+
from typing import Callable, Coroutine, Tuple
11+
12+
import pytest
13+
14+
from cve_bin_tool.async_utils import aio_run_command
15+
16+
17+
@dataclasses.dataclass
18+
class FakeProcess:
19+
returncode: int
20+
21+
async def communicate(self) -> Tuple[bytes, bytes]:
22+
return b"", b""
23+
24+
25+
def mkexec(returncode: int) -> Callable[..., Coroutine[None, None, FakeProcess]]:
26+
async def return_fake_process(*args, **kwargs) -> FakeProcess:
27+
return FakeProcess(returncode=returncode)
28+
29+
return return_fake_process
30+
31+
32+
@pytest.mark.asyncio
33+
async def test_aio_run_command_success():
34+
with unittest.mock.patch("asyncio.create_subprocess_exec", new=mkexec(0)):
35+
await aio_run_command(("echo", "hello"))
36+
37+
38+
@pytest.mark.asyncio
39+
async def test_aio_run_command_returncode_non_zero():
40+
with unittest.mock.patch("asyncio.create_subprocess_exec", new=mkexec(1)):
41+
with pytest.raises(subprocess.CalledProcessError):
42+
await aio_run_command(("echo", "hello"))

0 commit comments

Comments
 (0)