| # Copyright 2024 The Pigweed Authors |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| # use this file except in compliance with the License. You may obtain a copy of |
| # the License at |
| # |
| # https://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # License for the specific language governing permissions and limitations under |
| # the License. |
| """Tests for pw_cli.tool_runner.""" |
| |
| import subprocess |
| import sys |
| import unittest |
| from typing import Any, Iterable |
| |
| from pw_cli import tool_runner |
| from pw_cli.tool_runner import ToolRunner |
| |
| |
| class TestToolRunner(unittest.TestCase): |
| """Tests for tool_runner.TestToolRunner.""" |
| |
| def test_basic_subprocess_runner(self): |
| runner = tool_runner.BasicSubprocessRunner() |
| if sys.platform == 'win32': |
| result = runner('python.exe', ('-c', 'print("hello world")')) |
| else: |
| result = runner('echo', ('hello', 'world')) |
| self.assertEqual(result.returncode, 0) |
| self.assertIn('hello world', result.stdout.decode()) |
| |
| |
| class FakeTool(ToolRunner): |
| def __init__(self) -> None: |
| self.received_args: list[str] = [] |
| self.received_kwargs: dict[str, Any] = {} |
| |
| def _run_tool( |
| self, tool: str, args, **kwargs |
| ) -> subprocess.CompletedProcess: |
| self.received_args = list(args) |
| self.received_kwargs = kwargs |
| |
| full_command = ' '.join((tool, *tuple(args))) |
| |
| return subprocess.CompletedProcess( |
| args=full_command, |
| returncode=0xFF, |
| stderr=f'I do not know how to `{full_command}`'.encode(), |
| stdout=b'Failed to execute command', |
| ) |
| |
| |
| class FakeToolWithCustomArgs(FakeTool): |
| @staticmethod |
| def _custom_args() -> Iterable[str]: |
| return ['pw_custom_arg', 'pw_2_custom_2_arg'] |
| |
| |
| class ToolRunnerCallTest(unittest.TestCase): |
| """Tests argument forwarding to ToolRunner implementations.""" |
| |
| def test_fake_tool_without_custom_args(self): |
| tool = FakeTool() |
| |
| tool( |
| 'rm', |
| ('-rf', '/'), |
| capture_output=True, |
| pw_custom_arg='should not be forwarded', |
| ) |
| |
| self.assertEqual(tool.received_args, ['-rf', '/']) |
| self.assertEqual( |
| tool.received_kwargs, |
| { |
| 'capture_output': True, |
| 'stdout': subprocess.PIPE, |
| 'stderr': subprocess.PIPE, |
| }, |
| ) |
| |
| def test_fake_tool_with_custom_args(self): |
| tool = FakeToolWithCustomArgs() |
| |
| tool( |
| 'rm', |
| ('-rf', '/'), |
| capture_output=True, |
| pw_custom_arg='should be forwarded', |
| pw_2_custom_2_arg='this one too', |
| pw_foo='but not this', |
| ) |
| |
| self.assertEqual(tool.received_args, ['-rf', '/']) |
| self.assertEqual( |
| tool.received_kwargs, |
| { |
| 'capture_output': True, |
| 'stdout': subprocess.PIPE, |
| 'stderr': subprocess.PIPE, |
| 'pw_custom_arg': 'should be forwarded', |
| 'pw_2_custom_2_arg': 'this one too', |
| }, |
| ) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |