Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1182)

Unified Diff: lib/cros_build_lib_unittest.py

Issue 6343001: Added 'env' and 'ignore_sigint' to RunCommand. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/chromite.git@master
Patch Set: Undid one space after period to be locally consistent in docstring. Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/cros_build_lib.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/cros_build_lib_unittest.py
diff --git a/lib/cros_build_lib_unittest.py b/lib/cros_build_lib_unittest.py
index 527815e4028fcc05818bd2ccbb1413772ed3fda0..ab89f01ad00ec948b681755bb152e31653a8f8da 100755
--- a/lib/cros_build_lib_unittest.py
+++ b/lib/cros_build_lib_unittest.py
@@ -7,6 +7,7 @@
import errno
import os
import shutil
+import signal
import subprocess
import tempfile
import unittest
@@ -17,13 +18,19 @@ import mox
class TestRunCommand(unittest.TestCase):
def setUp(self):
+ # Get the original value for SIGINT so our signal() mock can return the
+ # correct thing.
+ self._old_sigint = signal.getsignal(signal.SIGINT)
+
self.mox = mox.Mox()
self.mox.StubOutWithMock(subprocess, 'Popen', use_mock_anything=True)
+ self.mox.StubOutWithMock(signal, 'signal')
self.proc_mock = self.mox.CreateMockAnything()
self.error = 'test error'
self.output = 'test output'
def tearDown(self):
+ # Unset anything that we set with mox.
self.mox.UnsetStubs()
def _AssertCrEqual(self, expected, actual):
@@ -59,7 +66,7 @@ class TestRunCommand(unittest.TestCase):
expected_result.returncode = self.proc_mock.returncode
arg_dict = dict()
- for attr in 'cwd stdin stdout stderr shell'.split():
+ for attr in 'cwd env stdin stdout stderr shell'.split():
if attr in sp_kv:
arg_dict[attr] = sp_kv[attr]
else:
@@ -68,20 +75,41 @@ class TestRunCommand(unittest.TestCase):
else:
arg_dict[attr] = None
+ # If requested, RunCommand will ignore sigints; record that.
+ if rc_kv.get('ignore_sigint'):
+ signal.signal(signal.SIGINT, signal.SIG_IGN).AndReturn(self._old_sigint)
+
subprocess.Popen(real_cmd, **arg_dict).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 rc_kv.get('ignore_sigint'):
+ signal.signal(signal.SIGINT, self._old_sigint).AndReturn(signal.SIG_IGN)
+
self.mox.ReplayAll()
actual_result = cros_build_lib.RunCommand(cmd, **rc_kv)
self.mox.VerifyAll()
self._AssertCrEqual(expected_result, actual_result)
- def testReturnCodeZeroWithArrayCmd(self):
- """--enter_chroot=False and --cmd is an array of strings."""
+ def testReturnCodeZeroWithArrayCmd(self, ignore_sigint=False):
+ """--enter_chroot=False and --cmd is an array of strings.
+
+ 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.
+ """
self.proc_mock.returncode = 0
cmd_list = ['foo', 'bar', 'roger']
- self._TestCmd(cmd_list, cmd_list, rc_kv=dict(exit_code=True))
+ 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."""
+ self.testReturnCodeZeroWithArrayCmd(ignore_sigint=True)
+
def testReturnCodeZeroWithArrayCmdEnterChroot(self):
"""--enter_chroot=True and --cmd is an array of strings."""
@@ -96,17 +124,39 @@ class TestRunCommand(unittest.TestCase):
cmd = 'test cmd'
self._TestCmd(cmd, cmd, rc_kv=dict(error_ok=True))
- def testSubprocessCommunicateExceptionRaisesError(self):
- """Verify error raised by communicate() is caught."""
+ 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'
- subprocess.Popen(cmd, cwd=None, stdin=None, stdout=None, stderr=None,
+
+ # 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)
self.proc_mock.communicate(None).AndRaise(ValueError)
+ # 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(ValueError, cros_build_lib.RunCommand, cmd)
+ self.assertRaises(ValueError, cros_build_lib.RunCommand, cmd,
+ ignore_sigint=ignore_sigint)
self.mox.VerifyAll()
+ def testSignalRestoreExceptionCase(self):
+ """Test RunCommand() properly sets/restores sigint. Exception case."""
+ self.testSubprocessCommunicateExceptionRaisesError(ignore_sigint=True)
+
def testSubprocessCommunicateExceptionNotRaisesError(self):
"""Don't re-raise error from communicate() when --error_ok=True."""
cmd = 'test cmd'
@@ -114,7 +164,8 @@ class TestRunCommand(unittest.TestCase):
expected_result = cros_build_lib.CommandResult()
expected_result.cmd = real_cmd
- subprocess.Popen(real_cmd, cwd=None, stdin=None, stdout=None, stderr=None,
+ subprocess.Popen(real_cmd, cwd=None, env=None,
+ stdin=None, stdout=None, stderr=None,
shell=False).AndReturn(self.proc_mock)
self.proc_mock.communicate(None).AndRaise(ValueError)
@@ -125,6 +176,22 @@ class TestRunCommand(unittest.TestCase):
self._AssertCrEqual(expected_result, actual_result)
+ def testEnvWorks(self):
+ """Test RunCommand(..., env=xyz) works."""
+ # We'll put this bogus environment together, just to make sure
+ # subprocess.Popen gets passed it.
+ env = {'Tom': 'Jerry', 'Itchy': 'Scratchy'}
+
+ # 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=env),
+ rc_kv=dict(env=env, exit_code=True))
+
class TestListFiles(unittest.TestCase):
« no previous file with comments | « lib/cros_build_lib.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698