Index: lib/cros_build_lib_unittest.py |
diff --git a/lib/cros_build_lib_unittest.py b/lib/cros_build_lib_unittest.py |
index bef81799bcdc7f66581e67d209923ae034e7a3d7..3a5ef0e1d691509d8f91abe6337547a610a9be96 100755 |
--- a/lib/cros_build_lib_unittest.py |
+++ b/lib/cros_build_lib_unittest.py |
@@ -1,12 +1,13 @@ |
#!/usr/bin/python |
# |
-# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
+# Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
# Use of this source code is governed by a BSD-style license that can be |
# found in the LICENSE file. |
import errno |
import os |
import shutil |
+import shlex |
import signal |
import subprocess |
import tempfile |
@@ -103,8 +104,8 @@ class TestRunCommand(unittest.TestCase): |
""" |
self.proc_mock.returncode = 0 |
cmd_list = ['foo', 'bar', 'roger'] |
- self._TestCmd(cmd_list, cmd_list, rc_kv=dict(exit_code=True, |
- ignore_sigint=ignore_sigint)) |
+ self._TestCmd(cmd_list, cmd_list, |
+ rc_kv=dict(exit_code=True, ignore_sigint=ignore_sigint)) |
def testSignalRestoreNormalCase(self): |
"""Test RunCommand() properly sets/restores sigint. Normal case.""" |
@@ -122,9 +123,11 @@ class TestRunCommand(unittest.TestCase): |
"""Raise error when proc.communicate() returns non-zero.""" |
self.proc_mock.returncode = 1 |
cmd = 'test cmd' |
- self._TestCmd(cmd, cmd, rc_kv=dict(error_ok=True)) |
+ real_cmd = [ '/bin/sh', '-c', cmd ] |
+ self._TestCmd(cmd, real_cmd, |
+ rc_kv=dict(error_ok=True, shell=True)) |
- def testSubprocessCommunicateExceptionRaisesError(self, ignore_sigint=False): |
+ def testCommandFailureRaisesError(self, ignore_sigint=False): |
"""Verify error raised by communicate() is caught. |
Parameterized so this can also be used by some other tests w/ alternate |
@@ -139,6 +142,36 @@ class TestRunCommand(unittest.TestCase): |
if ignore_sigint: |
signal.signal(signal.SIGINT, signal.SIG_IGN).AndReturn(self._old_sigint) |
+ subprocess.Popen(['/bin/sh', '-c', cmd ], cwd=None, env=None, |
+ stdin=None, stdout=None, stderr=None, |
+ shell=False).AndReturn(self.proc_mock) |
+ self.proc_mock.communicate(None).AndReturn((self.output, self.error)) |
+ |
+ # If it ignored them, RunCommand will restore sigints; record that. |
+ if ignore_sigint: |
+ signal.signal(signal.SIGINT, self._old_sigint).AndReturn(signal.SIG_IGN) |
+ |
+ self.mox.ReplayAll() |
+ self.assertRaises(cros_build_lib.RunCommandError, |
+ cros_build_lib.RunCommand, cmd, shell=True, |
+ ignore_sigint=ignore_sigint, error_ok=False) |
+ self.mox.VerifyAll() |
+ |
+ def testSubprocessCommunicateExceptionRaisesError(self, ignore_sigint=False): |
+ """Verify error raised by communicate() is caught. |
+ |
+ Parameterized so this can also be used by some other tests w/ alternate |
+ params to RunCommand(). |
+ |
+ Args: |
+ ignore_sigint: If True, we'll tell RunCommand to ignore sigint. |
+ """ |
+ cmd = ['test', 'cmd'] |
+ |
+ # If requested, RunCommand will ignore sigints; record that. |
+ if ignore_sigint: |
+ signal.signal(signal.SIGINT, signal.SIG_IGN).AndReturn(self._old_sigint) |
+ |
subprocess.Popen(cmd, cwd=None, env=None, |
stdin=None, stdout=None, stderr=None, |
shell=False).AndReturn(self.proc_mock) |
@@ -159,8 +192,8 @@ class TestRunCommand(unittest.TestCase): |
def testSubprocessCommunicateExceptionNotRaisesError(self): |
"""Don't re-raise error from communicate() when --error_ok=True.""" |
- cmd = 'test cmd' |
- real_cmd = './enter_chroot.sh -- %s' % cmd |
+ cmd = ['test', 'cmd'] |
+ real_cmd = ['./enter_chroot.sh', '--'] + cmd |
expected_result = cros_build_lib.CommandResult() |
expected_result.cmd = real_cmd |
@@ -192,6 +225,45 @@ class TestRunCommand(unittest.TestCase): |
sp_kv=dict(env=env), |
rc_kv=dict(env=env, exit_code=True)) |
+ def testExtraEnvOnlyWorks(self): |
+ """Test RunCommand(..., extra_env=xyz) works.""" |
+ # We'll put this bogus environment together, just to make sure |
+ # subprocess.Popen gets passed it. |
+ extra_env = {'Pinky' : 'Brain'} |
+ ## This is a little bit circular, since the same logic is used to compute |
+ ## the value inside, but at least it checks that this happens. |
+ total_env = os.environ.copy() |
+ total_env.update(extra_env) |
+ |
+ # This is a simple case, copied from testReturnCodeZeroWithArrayCmd() |
+ self.proc_mock.returncode = 0 |
+ cmd_list = ['foo', 'bar', 'roger'] |
+ |
+ # Run. We expect the env= to be passed through from sp (subprocess.Popen) |
+ # to rc (RunCommand). |
+ self._TestCmd(cmd_list, cmd_list, |
+ sp_kv=dict(env=total_env), |
+ rc_kv=dict(extra_env=extra_env, exit_code=True)) |
+ |
+ def testExtraEnvTooWorks(self): |
+ """Test RunCommand(..., env=xy, extra_env=z) works.""" |
+ # We'll put this bogus environment together, just to make sure |
+ # subprocess.Popen gets passed it. |
+ env = {'Tom': 'Jerry', 'Itchy': 'Scratchy'} |
+ extra_env = {'Pinky': 'Brain'} |
+ total_env = {'Tom': 'Jerry', 'Itchy': 'Scratchy', 'Pinky': 'Brain'} |
+ |
+ # This is a simple case, copied from testReturnCodeZeroWithArrayCmd() |
+ self.proc_mock.returncode = 0 |
+ cmd_list = ['foo', 'bar', 'roger'] |
+ |
+ # Run. We expect the env= to be passed through from sp (subprocess.Popen) |
+ # to rc (RunCommand). |
+ self._TestCmd(cmd_list, cmd_list, |
+ sp_kv=dict(env=total_env), |
+ rc_kv=dict(env=env, extra_env=extra_env, exit_code=True)) |
+ |
+ |
def testExceptionEquality(self): |
"""Verify equality methods for RunCommandError""" |