Pārlūkot izejas kodu

[Scripts/regression] Improve subprocess handling

This fixes two problems with subprocess handling:
 1. Use subprocess.communicate to avoid that the pipe can fill up.
 2. Use a process group to ensure that we also kill the subprocess'
    children in case of a timeout.

Note: This does not cover the case that the child returns successfully
but leaves other child processes running. AFAICS this is not easy since
subprocess.communicate() wait(2)s for the process so the pid is no
longer guaranteed to be valid to kill. So we leave this to the outside
environment (Jenkins or whatever).
Simon Gaiser 6 gadi atpakaļ
vecāks
revīzija
c482288936
1 mainītis faili ar 10 papildinājumiem un 20 dzēšanām
  1. 10 20
      Scripts/regression.py

+ 10 - 20
Scripts/regression.py

@@ -1,4 +1,4 @@
-import sys, os, subprocess, re, time
+import sys, os, subprocess, re, time, signal
 
 class Result:
     def __init__(self, out, log, code):
@@ -48,29 +48,19 @@ class Regression:
                 if self.prepare:
                     self.prepare(args)
 
-                time.sleep(0.1)
-
                 p = subprocess.Popen(args,
                                      stdout=subprocess.PIPE,
-                                     stderr=subprocess.PIPE)
-
-                sleep_time = 0
-                finish = False
-                while sleep_time < self.timeout:
-                    time.sleep(0.001)
-                    if p.poll() is not None:
-                        finish = True
-                        break
-                    sleep_time += 1
-
-                if not finish and p.poll() is None:
+                                     stderr=subprocess.PIPE,
+                                     preexec_fn=os.setpgrp)
+                try:
+                    out, log = p.communicate(timeout=self.timeout * 0.001)
+                except subprocess.TimeoutExpired:
                     timed_out = True
-                    p.kill()
-
-                time.sleep(0.1)
+                    os.killpg(p.pid, signal.SIGKILL)
+                    out, log = p.communicate()
 
-                out = p.stdout.read().decode('utf-8')
-                log = p.stderr.read().decode('utf-8')
+                out = out.decode('utf-8')
+                log = log.decode('utf-8')
 
                 outputs.append(Result(out, log, p.returncode))