소스 검색

[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 년 전
부모
커밋
c482288936
1개의 변경된 파일10개의 추가작업 그리고 20개의 파일을 삭제
  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))