Merge lp:~soren/nova/lp733609 into lp:~hudson-openstack/nova/trunk

Proposed by Soren Hansen
Status: Merged
Approved by: Rick Harris
Approved revision: 797
Merged at revision: 822
Proposed branch: lp:~soren/nova/lp733609
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 143 lines (+93/-10)
2 files modified
nova/tests/test_utils.py (+78/-0)
nova/utils.py (+15/-10)
To merge this branch: bzr merge lp:~soren/nova/lp733609
Reviewer Review Type Date Requested Status
Rick Harris (community) Approve
Paul Voccio (community) Approve
Review via email: mp+53321@code.launchpad.net

Commit message

Make utils.execute not overwrite std{in,out,err} args to Popen on retries.
Make utils.execute reject unknown kwargs.

Add a couple of unit tests for utils.execute.

To post a comment you must log in.
Revision history for this message
Paul Voccio (pvo) wrote :

lgtm

review: Approve
Revision history for this message
Rick Harris (rconradharris) wrote :

Patch looks really good.

Received a few pep8 nits from the test-suite: http://paste.openstack.org/show/921/

review: Needs Fixing
Revision history for this message
Soren Hansen (soren) wrote :

> Patch looks really good.
>
> Received a few pep8 nits from the test-suite:
> http://paste.openstack.org/show/921/

*sigh* Fixed. I keep forgetting to run pep8 manually (because I have that test case that fails due to non-ascii stuff in the help text, so run_tests.sh skips pep8). I've given myself a good shouting at. Apologies. :(

lp:~soren/nova/lp733609 updated
797. By Soren Hansen

pep8

Revision history for this message
Rick Harris (rconradharris) wrote :

lgtm, thanks for the fixes.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'nova/tests/test_utils.py'
--- nova/tests/test_utils.py 2011-02-23 22:07:08 +0000
+++ nova/tests/test_utils.py 2011-03-17 20:46:29 +0000
@@ -14,11 +14,89 @@
14# License for the specific language governing permissions and limitations14# License for the specific language governing permissions and limitations
15# under the License.15# under the License.
1616
17import os
18import tempfile
19
17from nova import test20from nova import test
18from nova import utils21from nova import utils
19from nova import exception22from nova import exception
2023
2124
25class ExecuteTestCase(test.TestCase):
26 def test_retry_on_failure(self):
27 fd, tmpfilename = tempfile.mkstemp()
28 _, tmpfilename2 = tempfile.mkstemp()
29 try:
30 fp = os.fdopen(fd, 'w+')
31 fp.write('''#!/bin/sh
32# If stdin fails to get passed during one of the runs, make a note.
33if ! grep -q foo
34then
35 echo 'failure' > "$1"
36fi
37# If stdin has failed to get passed during this or a previous run, exit early.
38if grep failure "$1"
39then
40 exit 1
41fi
42runs="$(cat $1)"
43if [ -z "$runs" ]
44then
45 runs=0
46fi
47runs=$(($runs + 1))
48echo $runs > "$1"
49exit 1
50''')
51 fp.close()
52 os.chmod(tmpfilename, 0755)
53 self.assertRaises(exception.ProcessExecutionError,
54 utils.execute,
55 tmpfilename, tmpfilename2, attempts=10,
56 process_input='foo',
57 delay_on_retry=False)
58 fp = open(tmpfilename2, 'r+')
59 runs = fp.read()
60 fp.close()
61 self.assertNotEquals(runs.strip(), 'failure', 'stdin did not '
62 'always get passed '
63 'correctly')
64 runs = int(runs.strip())
65 self.assertEquals(runs, 10,
66 'Ran %d times instead of 10.' % (runs,))
67 finally:
68 os.unlink(tmpfilename)
69 os.unlink(tmpfilename2)
70
71 def test_unknown_kwargs_raises_error(self):
72 self.assertRaises(exception.Error,
73 utils.execute,
74 '/bin/true', this_is_not_a_valid_kwarg=True)
75
76 def test_no_retry_on_success(self):
77 fd, tmpfilename = tempfile.mkstemp()
78 _, tmpfilename2 = tempfile.mkstemp()
79 try:
80 fp = os.fdopen(fd, 'w+')
81 fp.write('''#!/bin/sh
82# If we've already run, bail out.
83grep -q foo "$1" && exit 1
84# Mark that we've run before.
85echo foo > "$1"
86# Check that stdin gets passed correctly.
87grep foo
88''')
89 fp.close()
90 os.chmod(tmpfilename, 0755)
91 utils.execute(tmpfilename,
92 tmpfilename2,
93 process_input='foo',
94 attempts=2)
95 finally:
96 os.unlink(tmpfilename)
97 os.unlink(tmpfilename2)
98
99
22class GetFromPathTestCase(test.TestCase):100class GetFromPathTestCase(test.TestCase):
23 def test_tolerates_nones(self):101 def test_tolerates_nones(self):
24 f = utils.get_from_path102 f = utils.get_from_path
25103
=== modified file 'nova/utils.py'
--- nova/utils.py 2011-03-16 20:36:22 +0000
+++ nova/utils.py 2011-03-17 20:46:29 +0000
@@ -133,13 +133,14 @@
133133
134134
135def execute(*cmd, **kwargs):135def execute(*cmd, **kwargs):
136 process_input = kwargs.get('process_input', None)136 process_input = kwargs.pop('process_input', None)
137 addl_env = kwargs.get('addl_env', None)137 addl_env = kwargs.pop('addl_env', None)
138 check_exit_code = kwargs.get('check_exit_code', 0)138 check_exit_code = kwargs.pop('check_exit_code', 0)
139 stdin = kwargs.get('stdin', subprocess.PIPE)139 delay_on_retry = kwargs.pop('delay_on_retry', True)
140 stdout = kwargs.get('stdout', subprocess.PIPE)140 attempts = kwargs.pop('attempts', 1)
141 stderr = kwargs.get('stderr', subprocess.PIPE)141 if len(kwargs):
142 attempts = kwargs.get('attempts', 1)142 raise exception.Error(_('Got unknown keyword args '
143 'to utils.execute: %r') % kwargs)
143 cmd = map(str, cmd)144 cmd = map(str, cmd)
144145
145 while attempts > 0:146 while attempts > 0:
@@ -149,8 +150,11 @@
149 env = os.environ.copy()150 env = os.environ.copy()
150 if addl_env:151 if addl_env:
151 env.update(addl_env)152 env.update(addl_env)
152 obj = subprocess.Popen(cmd, stdin=stdin,153 obj = subprocess.Popen(cmd,
153 stdout=stdout, stderr=stderr, env=env)154 stdin=subprocess.PIPE,
155 stdout=subprocess.PIPE,
156 stderr=subprocess.PIPE,
157 env=env)
154 result = None158 result = None
155 if process_input != None:159 if process_input != None:
156 result = obj.communicate(process_input)160 result = obj.communicate(process_input)
@@ -176,7 +180,8 @@
176 raise180 raise
177 else:181 else:
178 LOG.debug(_("%r failed. Retrying."), cmd)182 LOG.debug(_("%r failed. Retrying."), cmd)
179 greenthread.sleep(random.randint(20, 200) / 100.0)183 if delay_on_retry:
184 greenthread.sleep(random.randint(20, 200) / 100.0)
180185
181186
182def ssh_execute(ssh, cmd, process_input=None,187def ssh_execute(ssh, cmd, process_input=None,