blob: ed44b91bd73fed95743591985aceebdee896b834 [file]
#!/usr/bin/env python3
# Copyright 2021 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Tests for subprocess_utils."""
import os
import pathlib
import subprocess
import unittest
import git_metadata_utils, subprocess_utils
_COMMAND_PROCESS_ERROR_LOG_REGEX = (
r'Command ".*" failed with code \d+\.'
r'(\nSTDERR: .*)?(\nSTDOUT: .*)?'
)
class TestResolveCommands(unittest.TestCase):
"""Tests for util commands like resolve_{ninja,autoninja}."""
def setUp(self):
self.original_path = os.environ.get('PATH')
def tearDown(self):
if self.original_path is not None:
os.environ['PATH'] = self.original_path
else:
del os.environ['PATH']
def test_resolve_ninja_returns_command_if_in_path(self):
ninja_dir = str(
git_metadata_utils.get_chromium_src_path() / 'third_party/ninja'
)
os.environ['PATH'] = ninja_dir
self.assertEqual('ninja', subprocess_utils.resolve_ninja())
def test_resolve_ninja_returns_depot_path_if_not_in_path(self):
if 'PATH' in os.environ:
del os.environ['PATH']
ninja_path = str(
git_metadata_utils.get_chromium_src_path()
/ 'third_party/ninja/ninja'
)
self.assertEqual(ninja_path, subprocess_utils.resolve_ninja())
def test_resolve_autoninja_returns_command_if_in_path(self):
autoninja_dir = str(
git_metadata_utils.get_chromium_src_path()
/ 'third_party/depot_tools'
)
os.environ['PATH'] = autoninja_dir
self.assertEqual('autoninja', subprocess_utils.resolve_autoninja())
def test_resolve_autoninja_returns_depot_path_if_not_in_path(self):
if 'PATH' in os.environ:
del os.environ['PATH']
autoninja_path = str(
git_metadata_utils.get_chromium_src_path()
/ 'third_party/depot_tools/autoninja'
)
self.assertEqual(autoninja_path, subprocess_utils.resolve_autoninja())
class TestRunCommand(unittest.TestCase):
"""Tests for the run_command function."""
def test_run_command_no_args(self):
expected_cwd: str = os.getcwd()
pwd_output = subprocess_utils.run_command(['pwd'])
self.assertEqual(expected_cwd, pwd_output)
def test_run_command_custom_cwd(self):
expected_cwd = '/usr/local/bin'
pwd_output = subprocess_utils.run_command(['pwd'], cwd=expected_cwd)
self.assertEqual(expected_cwd, pwd_output)
def test_run_command_custom_cwd_path(self):
expected_cwd = '/usr/local/bin'
pwd_output = subprocess_utils.run_command(
['pwd'], cwd=pathlib.Path(expected_cwd).resolve(strict=True)
)
self.assertEqual(expected_cwd, pwd_output)
def test_run_command_multiple_args(self):
expected_output = 'some sample output'
command_output = subprocess_utils.run_command(
['echo', 'some', 'sample', 'output']
)
self.assertEqual(expected_output, command_output)
def test_run_command_strips_output_whitespace(self):
expected_output = 'Hello, world!'
command_output = subprocess_utils.run_command(
['echo', '\t Hello, world! \n']
)
self.assertEqual(expected_output, command_output)
def test_run_command_exitcode_only_returns_zero_on_success(self):
expected_output = 0
command_output = subprocess_utils.run_command(
['echo', '\t Hello, world! \n'], exitcode_only=True
)
self.assertEqual(expected_output, command_output)
def test_run_command_exitcode_only_returns_exitcode_on_failure(self):
expected_output = 1
command_output = subprocess_utils.run_command(
['git', 'foo'], exitcode_only=True
)
self.assertEqual(expected_output, command_output)
def test_run_command_process_error_no_output(self):
with (
self.assertRaises(subprocess.CalledProcessError) as error_cm,
self.assertLogs(level='ERROR') as logging_cm,
):
subprocess_utils.run_command(['false'])
self.assertEqual(1, error_cm.exception.returncode)
self.assertEqual(1, len(logging_cm.output))
self.assertRegex(logging_cm.output[0], _COMMAND_PROCESS_ERROR_LOG_REGEX)
def test_run_command_process_error_with_stderr_output(self):
expected_stderr_regex = r"git: 'foo' is not a git command.+"
with (
self.assertRaises(subprocess.CalledProcessError) as error_cm,
self.assertLogs(level='ERROR') as logging_cm,
):
subprocess_utils.run_command(['git', 'foo'])
self.assertEqual(1, error_cm.exception.returncode)
self.assertRegex(error_cm.exception.stderr, expected_stderr_regex)
self.assertEqual('', error_cm.exception.stdout)
self.assertEqual(1, len(logging_cm.output))
self.assertRegex(logging_cm.output[0], _COMMAND_PROCESS_ERROR_LOG_REGEX)
def test_run_command_process_error_with_stdout_output(self):
expected_stdout_regex = r'usage: git.+'
with (
self.assertRaises(subprocess.CalledProcessError) as error_cm,
self.assertLogs(level='ERROR') as logging_cm,
):
subprocess_utils.run_command(['git'])
self.assertEqual(1, error_cm.exception.returncode)
self.assertEqual('', error_cm.exception.stderr)
self.assertRegex(error_cm.exception.stdout, expected_stdout_regex)
self.assertEqual(1, len(logging_cm.output))
self.assertRegex(logging_cm.output[0], _COMMAND_PROCESS_ERROR_LOG_REGEX)
def test_run_command_not_found(self):
with self.assertRaises(FileNotFoundError) as error_cm:
subprocess_utils.run_command(['foo_cmd'])
self.assertEqual(2, error_cm.exception.errno)
self.assertEqual('foo_cmd', error_cm.exception.filename)
if __name__ == '__main__':
unittest.main()