diff mbox

[16/19] KVM test: kvm_subprocess: robustify the test for child process termination

Message ID 1252519932-30733-16-git-send-email-mgoldish@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Michael Goldish Sept. 9, 2009, 6:12 p.m. UTC
Don't rely on os.read() raising an exception; use waitpid() to check for child
termination:
- every 0.5 seconds, or
- when os.read() raises an exception, or
- when os.read() returns a zero-length string.

Signed-off-by: Michael Goldish <mgoldish@redhat.com>
---
 client/tests/kvm/kvm_subprocess.py |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)
diff mbox

Patch

diff --git a/client/tests/kvm/kvm_subprocess.py b/client/tests/kvm/kvm_subprocess.py
index d142ed9..c3c48cd 100755
--- a/client/tests/kvm/kvm_subprocess.py
+++ b/client/tests/kvm/kvm_subprocess.py
@@ -1102,10 +1102,11 @@  def _server_main():
 
         # Read from child and write to files/pipes
         while True:
+            check_termination = False
             # Make a list of reader pipes whose buffers are not empty
             fds = [fd for (i, fd) in enumerate(reader_fds) if buffers[i]]
             # Wait until there's something to do
-            r, w, x = select.select([shell_fd, inpipe_fd], fds, [])
+            r, w, x = select.select([shell_fd, inpipe_fd], fds, [], 0.5)
             # If a reader pipe is ready for writing --
             for (i, fd) in enumerate(reader_fds):
                 if fd in w:
@@ -1116,7 +1117,9 @@  def _server_main():
                 try:
                     data = os.read(shell_fd, 16384)
                 except OSError:
-                    break
+                    data = ""
+                if not data:
+                    check_termination = True
                 # Remove carriage returns from the data -- they often cause
                 # trouble and are normally not needed
                 data = data.replace("\r", "")
@@ -1124,14 +1127,18 @@  def _server_main():
                 output_file.flush()
                 for i in range(len(readers)):
                     buffers[i] += data
+            # If os.read() raised an exception or there was nothing to read --
+            if check_termination or shell_fd not in r:
+                pid, status = os.waitpid(shell_pid, os.WNOHANG)
+                if pid:
+                    status = os.WEXITSTATUS(status)
+                    break
             # If there's data to read from the client --
             if inpipe_fd in r:
                 data = os.read(inpipe_fd, 1024)
                 os.write(shell_fd, data)
 
-        # Wait for the shell process to exit and get its exit status
-        status = os.waitpid(shell_pid, 0)[1]
-        status = os.WEXITSTATUS(status)
+        # Write the exit status to a file
         file = open(status_filename, "w")
         file.write(str(status))
         file.close()