blob: 1cc9a1dcf416077d78e6436d842b101ebcf12843 [file] [log] [blame]
#!/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()