aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/mtest.py
diff options
context:
space:
mode:
authorAleksey Filippov <alekseyf@google.com>2018-03-28 18:57:50 +0000
committerAleksey Filippov <alekseyf@google.com>2018-03-28 18:57:50 +0000
commit827d33c8b65aaecd4817d67d821f0b7db6048717 (patch)
treec972a1377bc72fc19fc8106f3a28a62b93a00984 /mesonbuild/mtest.py
parent0e8c69b7962bf668567f5aab2911ba25ded773ca (diff)
downloadmeson-827d33c8b65aaecd4817d67d821f0b7db6048717.zip
meson-827d33c8b65aaecd4817d67d821f0b7db6048717.tar.gz
meson-827d33c8b65aaecd4817d67d821f0b7db6048717.tar.bz2
Split SingleTestRunner.run()
Diffstat (limited to 'mesonbuild/mtest.py')
-rw-r--r--mesonbuild/mtest.py196
1 files changed, 97 insertions, 99 deletions
diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py
index d0b8d22..412896e 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -219,112 +219,110 @@ class SingleTestRunner:
def run(self):
cmd = self._get_cmd()
if cmd is None:
- res = TestResult.SKIP
- duration = 0.0
- stdo = 'Not run because can not execute cross compiled binaries.'
- stde = None
- returncode = GNU_SKIP_RETURNCODE
+ skip_stdout = 'Not run because can not execute cross compiled binaries.'
+ return TestRun(res=TestResult.SKIP, returncode=GNU_SKIP_RETURNCODE,
+ should_fail=self.test.should_fail, duration=0.0,
+ stdo=skip_stdout, stde=None, cmd=None, env=self.test.env)
else:
wrap = TestHarness.get_wrapper(self.options)
-
if self.options.gdb:
self.test.timeout = None
-
- cmd = wrap + cmd + self.test.cmd_args + self.options.test_args
- starttime = time.time()
-
- if len(self.test.extra_paths) > 0:
- self.env['PATH'] = os.pathsep.join(self.test.extra_paths + ['']) + self.env['PATH']
-
- # If MALLOC_PERTURB_ is not set, or if it is set to an empty value,
- # (i.e., the test or the environment don't explicitly set it), set
- # it ourselves. We do this unconditionally for regular tests
- # because it is extremely useful to have.
- # Setting MALLOC_PERTURB_="0" will completely disable this feature.
- if ('MALLOC_PERTURB_' not in self.env or not self.env['MALLOC_PERTURB_']) and not self.options.benchmark:
- self.env['MALLOC_PERTURB_'] = str(random.randint(1, 255))
-
- stdout = None
- stderr = None
- if not self.options.verbose:
- stdout = subprocess.PIPE
- stderr = subprocess.PIPE if self.options and self.options.split else subprocess.STDOUT
-
- # Let gdb handle ^C instead of us
+ return self._run_cmd(wrap + cmd + self.test.cmd_args + self.options.test_args)
+
+ def _run_cmd(self, cmd):
+ starttime = time.time()
+
+ if len(self.test.extra_paths) > 0:
+ self.env['PATH'] = os.pathsep.join(self.test.extra_paths + ['']) + self.env['PATH']
+
+ # If MALLOC_PERTURB_ is not set, or if it is set to an empty value,
+ # (i.e., the test or the environment don't explicitly set it), set
+ # it ourselves. We do this unconditionally for regular tests
+ # because it is extremely useful to have.
+ # Setting MALLOC_PERTURB_="0" will completely disable this feature.
+ if ('MALLOC_PERTURB_' not in self.env or not self.env['MALLOC_PERTURB_']) and not self.options.benchmark:
+ self.env['MALLOC_PERTURB_'] = str(random.randint(1, 255))
+
+ stdout = None
+ stderr = None
+ if not self.options.verbose:
+ stdout = subprocess.PIPE
+ stderr = subprocess.PIPE if self.options and self.options.split else subprocess.STDOUT
+
+ # Let gdb handle ^C instead of us
+ if self.options.gdb:
+ previous_sigint_handler = signal.getsignal(signal.SIGINT)
+ # Make the meson executable ignore SIGINT while gdb is running.
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
+
+ def preexec_fn():
if self.options.gdb:
- previous_sigint_handler = signal.getsignal(signal.SIGINT)
- # Make the meson executable ignore SIGINT while gdb is running.
- signal.signal(signal.SIGINT, signal.SIG_IGN)
-
- def preexec_fn():
- if self.options.gdb:
- # Restore the SIGINT handler for the child process to
- # ensure it can handle it.
- signal.signal(signal.SIGINT, signal.SIG_DFL)
- else:
- # We don't want setsid() in gdb because gdb needs the
- # terminal in order to handle ^C and not show tcsetpgrp()
- # errors avoid not being able to use the terminal.
- os.setsid()
-
- p = subprocess.Popen(cmd,
- stdout=stdout,
- stderr=stderr,
- env=self.env,
- cwd=self.test.workdir,
- preexec_fn=preexec_fn if not is_windows() else None)
- timed_out = False
- kill_test = False
- if self.test.timeout is None:
- timeout = None
- elif self.options.timeout_multiplier is not None:
- timeout = self.test.timeout * self.options.timeout_multiplier
+ # Restore the SIGINT handler for the child process to
+ # ensure it can handle it.
+ signal.signal(signal.SIGINT, signal.SIG_DFL)
else:
- timeout = self.test.timeout
- try:
- (stdo, stde) = p.communicate(timeout=timeout)
- except subprocess.TimeoutExpired:
- if self.options.verbose:
- print("%s time out (After %d seconds)" % (self.test.name, timeout))
- timed_out = True
- except KeyboardInterrupt:
- mlog.warning("CTRL-C detected while running %s" % (self.test.name))
- kill_test = True
- finally:
- if self.options.gdb:
- # Let us accept ^C again
- signal.signal(signal.SIGINT, previous_sigint_handler)
-
- if kill_test or timed_out:
- # Python does not provide multiplatform support for
- # killing a process and all its children so we need
- # to roll our own.
- if is_windows():
- subprocess.call(['taskkill', '/F', '/T', '/PID', str(p.pid)])
- else:
- try:
- os.killpg(os.getpgid(p.pid), signal.SIGKILL)
- except ProcessLookupError:
- # Sometimes (e.g. with Wine) this happens.
- # There's nothing we can do (maybe the process
- # already died) so carry on.
- pass
- (stdo, stde) = p.communicate()
- endtime = time.time()
- duration = endtime - starttime
- stdo = decode(stdo)
- if stde:
- stde = decode(stde)
- if timed_out:
- res = TestResult.TIMEOUT
- elif p.returncode == GNU_SKIP_RETURNCODE:
- res = TestResult.SKIP
- elif self.test.should_fail == bool(p.returncode):
- res = TestResult.OK
+ # We don't want setsid() in gdb because gdb needs the
+ # terminal in order to handle ^C and not show tcsetpgrp()
+ # errors avoid not being able to use the terminal.
+ os.setsid()
+
+ p = subprocess.Popen(cmd,
+ stdout=stdout,
+ stderr=stderr,
+ env=self.env,
+ cwd=self.test.workdir,
+ preexec_fn=preexec_fn if not is_windows() else None)
+ timed_out = False
+ kill_test = False
+ if self.test.timeout is None:
+ timeout = None
+ elif self.options.timeout_multiplier is not None:
+ timeout = self.test.timeout * self.options.timeout_multiplier
+ else:
+ timeout = self.test.timeout
+ try:
+ (stdo, stde) = p.communicate(timeout=timeout)
+ except subprocess.TimeoutExpired:
+ if self.options.verbose:
+ print("%s time out (After %d seconds)" % (self.test.name, timeout))
+ timed_out = True
+ except KeyboardInterrupt:
+ mlog.warning("CTRL-C detected while running %s" % (self.test.name))
+ kill_test = True
+ finally:
+ if self.options.gdb:
+ # Let us accept ^C again
+ signal.signal(signal.SIGINT, previous_sigint_handler)
+
+ if kill_test or timed_out:
+ # Python does not provide multiplatform support for
+ # killing a process and all its children so we need
+ # to roll our own.
+ if is_windows():
+ subprocess.call(['taskkill', '/F', '/T', '/PID', str(p.pid)])
else:
- res = TestResult.FAIL
- returncode = p.returncode
- return TestRun(res, returncode, self.test.should_fail, duration, stdo, stde, cmd, self.test.env)
+ try:
+ os.killpg(os.getpgid(p.pid), signal.SIGKILL)
+ except ProcessLookupError:
+ # Sometimes (e.g. with Wine) this happens.
+ # There's nothing we can do (maybe the process
+ # already died) so carry on.
+ pass
+ (stdo, stde) = p.communicate()
+ endtime = time.time()
+ duration = endtime - starttime
+ stdo = decode(stdo)
+ if stde:
+ stde = decode(stde)
+ if timed_out:
+ res = TestResult.TIMEOUT
+ elif p.returncode == GNU_SKIP_RETURNCODE:
+ res = TestResult.SKIP
+ elif self.test.should_fail == bool(p.returncode):
+ res = TestResult.OK
+ else:
+ res = TestResult.FAIL
+ return TestRun(res, p.returncode, self.test.should_fail, duration, stdo, stde, cmd, self.test.env)
class TestHarness: