Merge lp:~doanac/utah/bug1158743 into lp:utah/trunk

Proposed by Andy Doan
Status: Rejected
Rejected by: Javier Collado
Proposed branch: lp:~doanac/utah/bug1158743
Merge into: lp:utah/trunk
Diff against target: 135 lines (+80/-10)
4 files modified
debian/changelog (+3/-0)
tests/test_process.py (+44/-0)
utah/process.py (+25/-0)
utah/provisioning/baremetal/inventory.py (+8/-10)
To merge this branch: bzr merge lp:~doanac/utah/bug1158743
Reviewer Review Type Date Requested Status
Javier Collado (community) Approve
Max Brustkern (community) Approve
Review via email: mp+155264@code.launchpad.net

This proposal supersedes a proposal from 2013-03-22.

Description of the change

This should add the logging Javier was suggesting to understand what processes are actually using a machine.

Changed to proper branch

To post a comment you must log in.
Revision history for this message
Javier Collado (javier.collado) wrote : Posted in a previous version of this proposal

I see that you fixed the bug in a branch based on trunk and created the merge
for dev (which actually reveals an entry in debian/changelog that isn't in
dev). Is this the expected way to work with bugs?

Revision history for this message
Javier Collado (javier.collado) wrote : Posted in a previous version of this proposal

The use of a static private method suggests that `_in_use` is a utility method,
so I believe it should be moved to the `process` module which is expected to
have that kind of methods.

Revision history for this message
Andy Doan (doanac) wrote : Posted in a previous version of this proposal

On 03/25/2013 04:16 AM, Javier Collado wrote:
> I see that you fixed the bug in a branch based on trunk and created the merge
> for dev (which actually reveals an entry in debian/changelog that isn't in
> dev). Is this the expected way to work with bugs?
>
Nope - that was a mechanical error. I'll correct

lp:~doanac/utah/bug1158743 updated
270. By Andy Doan

move pid _in_use to process.py

As per Javier's review comment this moves the function to become a
generic helper. I also added some unit-testing logic for it

Revision history for this message
Andy Doan (doanac) wrote :

updated as per Javier's suggestion

Revision history for this message
Javier Collado (javier.collado) wrote :

Thanks for the update (specially for the test cases).

I've got a couple of commments:

- Exceptions

When getting the process object, TypeError and ValueError exceptions are
caught:
except (psutil.error.NoSuchProcess, TypeError, ValueError):

However, I think they shouldn't be caught since I'd like to get an exception
when I don't pass the right parameter type as in:
pid_in_use('string')

Otherwise, I misuse is not noticed by the end user.

- Documentation

I've seen you've made the effor to document everything. However the
documentation strings aren't pep257 (http://www.python.org/dev/peps/pep-0257/)
compliant and they don't follow the sphinx markup. If you could fix those
problems as well (just on the new code), that would be great.

To check documentation strings, I use the following tool and works quite well:
https://pypi.python.org/pypi/pep257/

With regard sphinx markup, please have a look at:
http://sphinx-doc.org/domains.html#info-field-lists

In particular, the fields that we've been using so far are:
:param <param>: to describe a parameter
:type <type>: to annotate the parameter type
:raises <exception>: to add exceptions that might be raised
:returns: to describe what is being returned
:rtype: to annotate the type of the return value

Revision history for this message
Andy Doan (doanac) wrote :

On 03/26/2013 12:35 PM, Javier Collado wrote:
> - Exceptions
>
> When getting the process object, TypeError and ValueError exceptions are
> caught:
> except (psutil.error.NoSuchProcess, TypeError, ValueError):
>
> However, I think they shouldn't be caught since I'd like to get an exception
> when I don't pass the right parameter type as in:
> pid_in_use('string')
>
> Otherwise, I misuse is not noticed by the end user.

Is this going to cause a possible regression that we need to test for?

@max - I think you suggested this, but i don't recall why

Revision history for this message
Max Brustkern (nuclearbob) wrote :

I think originally we caught TypeError and ValueError to allow is flexibility in the transition from a database without a pid column to a database with a pid column. As long as we do sufficient testing of an actual Inventory and verify things work, leaving those out should be fine.

Revision history for this message
Max Brustkern (nuclearbob) wrote :

I've tested this with an actual physical machine inventory on magners-orchestra, and I'm satisfied that it works correctly. Unfortunately, we're still not printing info to console by default, so the message won't be seen by some jobs. That's a different fix, however, so I'm in favor of merging this.

review: Approve
Revision history for this message
Max Brustkern (nuclearbob) wrote :

Can you add a debian changelog entry for this so it's sourced properly? I use
dch "Made a totally sweet change"
for that.

lp:~doanac/utah/bug1158743 updated
271. By Andy Doan

fix pep257 issues

272. By Andy Doan

add changelog entry

Revision history for this message
Max Brustkern (nuclearbob) wrote :

I removed TypeError and ValueError from the list of exceptions caught, and things still test out fine. I think those were probably mainly useful during the transition period when the database might or might not have a pid column.

Revision history for this message
Max Brustkern (nuclearbob) wrote :

This looks good to me.

review: Approve
Revision history for this message
Javier Collado (javier.collado) wrote :

My comment has been addressed in:
https://code.launchpad.net/~doanac/utah/bug11588743-part2/+merge/160498

Hence, I think these changes are fine.

review: Approve
Revision history for this message
Max Brustkern (nuclearbob) wrote :

This appears to already be in dev, but the target of this proposal is trunk. Is this something we want to release as a bugfix, or can we just wait until the next release?

Revision history for this message
Andy Doan (doanac) wrote :

hmm - i think i originally was going to target this as a fix, but then we started using dev for everything. So i think we are good here.

Revision history for this message
Javier Collado (javier.collado) wrote :

Rejecting the merge request as per the previous comment.

Unmerged revisions

272. By Andy Doan

add changelog entry

271. By Andy Doan

fix pep257 issues

270. By Andy Doan

move pid _in_use to process.py

As per Javier's review comment this moves the function to become a
generic helper. I also added some unit-testing logic for it

269. By Andy Doan

add logging for unavailable machines

this should help us understand who is using a machine in the event
one isn't available.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2013-03-27 15:33:54 +0000
3+++ debian/changelog 2013-04-10 15:39:35 +0000
4@@ -28,6 +28,9 @@
5 * Overhauled exception handling based on code review
6 * Made all shell scripts POSIX-compliant
7
8+ [ Andy Doan ]
9+ * Log process that has machine reserved. (LP: #1158743)
10+
11 -- Max Brustkern <max@canonical.com> Fri, 15 Mar 2013 13:55:24 -0400
12
13 utah (0.8ubuntu1) quantal; urgency=low
14
15=== added file 'tests/test_process.py'
16--- tests/test_process.py 1970-01-01 00:00:00 +0000
17+++ tests/test_process.py 2013-04-10 15:39:35 +0000
18@@ -0,0 +1,44 @@
19+# Ubuntu Testing Automation Harness
20+# Copyright 2013 Canonical Ltd.
21+
22+# This program is free software: you can redistribute it and/or modify it
23+# under the terms of the GNU General Public License version 3, as published
24+# by the Free Software Foundation.
25+
26+# This program is distributed in the hope that it will be useful, but
27+# WITHOUT ANY WARRANTY; without even the implied warranties of
28+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
29+# PURPOSE. See the GNU General Public License for more details.
30+
31+# You should have received a copy of the GNU General Public License along
32+# with this program. If not, see <http://www.gnu.org/licenses/>.
33+
34+"""Unit tests for the utah.process module."""
35+
36+import os
37+import unittest
38+
39+from utah.process import pid_in_use
40+
41+
42+class TestProcess(unittest.TestCase):
43+
44+ """Tests the functions of the utah.process module."""
45+
46+ def test_is_running(self):
47+ """Ensure simple test of pid_in_use works for a pid running."""
48+ pid = os.getpid()
49+ self.assertIsNotNone(pid_in_use(pid))
50+ self.assertIsNotNone(pid_in_use(pid, ['test_']))
51+ # make sure we don't return when the command line doesn't match
52+ self.assertIsNone(pid_in_use(pid, ['blah']))
53+
54+ def test_is_not_running(self):
55+ """Ensure simple test of pid_in_use works for a pid not running."""
56+ pid = os.fork()
57+ if pid == 0:
58+ os.execv('/bin/true', ['/bin/true'])
59+ os.waitpid(pid, 0)
60+ # the child should be dead so this will return None
61+ self.assertIsNone(pid_in_use(pid))
62+ self.assertIsNone(pid_in_use(pid, ['true']))
63
64=== modified file 'utah/process.py'
65--- utah/process.py 2012-12-08 02:10:12 +0000
66+++ utah/process.py 2013-04-10 15:39:35 +0000
67@@ -19,6 +19,31 @@
68 import psutil
69
70
71+def pid_in_use(pid, arg_patterns=None):
72+ """Test if the given pid is running.
73+
74+ If arg_patterns is provided then the pid's command line will be compared
75+ to make sure it matches an expected value.
76+
77+ :returns: proc object if the pid is active and optionally matches one of
78+ the arg_patterns, otherwise None
79+ :rtype: psutil.Process
80+
81+ """
82+ try:
83+ proc = psutil.Process(pid)
84+ except (psutil.error.NoSuchProcess, TypeError, ValueError):
85+ return None
86+
87+ cmdline = ' '.join(proc.cmdline)
88+ if arg_patterns:
89+ for p in arg_patterns:
90+ if p in cmdline:
91+ return proc
92+ return None
93+ return proc
94+
95+
96 class ProcessChecker(object):
97 """
98 Check all running process looking for a given pattern
99
100=== modified file 'utah/provisioning/baremetal/inventory.py'
101--- utah/provisioning/baremetal/inventory.py 2013-01-22 14:13:17 +0000
102+++ utah/provisioning/baremetal/inventory.py 2013-04-10 15:39:35 +0000
103@@ -17,8 +17,10 @@
104 Provide inventory functions specific to bare metal deployments.
105 """
106
107+import logging
108 import os
109-import psutil
110+
111+from utah.process import pid_in_use
112 from utah.provisioning.inventory.exceptions import \
113 UTAHProvisioningInventoryException
114 from utah.provisioning.inventory.sqlite import SQLiteInventory
115@@ -65,15 +67,11 @@
116 for minfo in result:
117 machineinfo = dict(minfo)
118 pid = machineinfo['pid']
119- try:
120- if not (psutil.pid_exists(pid) and ('utah' in
121- ' '.join(psutil.Process(pid).cmdline)
122- or 'run_test' in
123- ' '.join(psutil.Process(pid).cmdline))):
124- return self._take(machineinfo, machinetype,
125- *args, **kw)
126- except ValueError:
127- continue
128+ proc = pid_in_use(pid, ['utah', 'run_test'])
129+ if not proc:
130+ return self._take(machineinfo, machinetype, *args, **kw)
131+ else:
132+ logging.info('machine in use by: %s', proc.cmdline)
133
134 raise UTAHProvisioningInventoryException(
135 'All machines meeting criteria are currently unavailable')

Subscribers

People subscribed via source and target branches

to all changes: