# HG changeset patch # User Doug Simon # Date 1325759506 -3600 # Node ID 339cf8d4904dd166427044613b791e31a15bf250 # Parent 26336f60ec7aeb55c94c628a466c3362547943a4 Made mx.run work properly when stderr is redirected to stdout. Made outputparser redirect stderr to stdout. Added copyright headers to outputparser.py and sanitycheck.py. Reverted class path construction in mx.build() to use includeSelf=True to fix regression when running 'mx build -c'. diff -r 26336f60ec7a -r 339cf8d4904d mx/commands.py --- a/mx/commands.py Wed Jan 04 23:34:15 2012 +0100 +++ b/mx/commands.py Thu Jan 05 11:31:46 2012 +0100 @@ -1,5 +1,5 @@ # -# commands.py - the default commands available to gl.py +# commands.py - the GraalVM specific commands # # ---------------------------------------------------------------------------------------------------- # diff -r 26336f60ec7a -r 339cf8d4904d mx/outputparser.py --- a/mx/outputparser.py Wed Jan 04 23:34:15 2012 +0100 +++ b/mx/outputparser.py Thu Jan 05 11:31:46 2012 +0100 @@ -1,5 +1,31 @@ +# ---------------------------------------------------------------------------------------------------- +# +# Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ---------------------------------------------------------------------------------------------------- + import mx import commands +import subprocess class OutputParser: @@ -27,7 +53,7 @@ else : mx.log( line.rstrip()) - retcode = commands.vm(cmd, vm, nonZeroIsFatal=self.nonZeroIsFatal, out=parseLine, err=parseLine, cwd=cwd, vmbuild=vmbuild) + retcode = commands.vm(cmd, vm, nonZeroIsFatal=self.nonZeroIsFatal, out=parseLine, err=subprocess.STDOUT, cwd=cwd, vmbuild=vmbuild) return {'parsed' : ret, 'retcode' : retcode} class Matcher: @@ -50,7 +76,7 @@ def parsestr(self, match, key): if isinstance(key, tuple): if len(key) != 2: - raise Exception('Tuple arguments must have a lenght of 2') + raise Exception('Tuple arguments must have a length of 2') tup1, tup2 = key # check if key is a function if hasattr(tup1, '__call__'): diff -r 26336f60ec7a -r 339cf8d4904d mx/sanitycheck.py --- a/mx/sanitycheck.py Wed Jan 04 23:34:15 2012 +0100 +++ b/mx/sanitycheck.py Thu Jan 05 11:31:46 2012 +0100 @@ -1,3 +1,28 @@ +# ---------------------------------------------------------------------------------------------------- +# +# Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ---------------------------------------------------------------------------------------------------- + from outputparser import OutputParser, Matcher import re import mx @@ -62,23 +87,29 @@ tests.append(Test("Bootstrap", "Bootstrap-bigHeap", ['-version'], succesREs=[time], scoreMatchers=[scoreMatcher], vmOpts=['-Xms2g'])) return tests +""" +Encapsulates a single program that is a sanity test and/or a benchmark. +""" class Test: - def __init__(self, name, group, cmd, succesREs=[], failureREs=[], scoreMatchers=[], vmOpts=[]): + def __init__(self, name, group, cmd, successREs=[], failureREs=[], scoreMatchers=[], vmOpts=[]): self.name = name self.group = group - self.succesREs = succesREs + self.successREs = successREs self.failureREs = failureREs self.scoreMatchers = scoreMatchers self.vmOpts = vmOpts self.cmd = cmd def test(self, vm, cwd=None, opts=[], vmbuild=None): + """ + Run this program as a sanity test. + """ parser = OutputParser(nonZeroIsFatal = False) jvmError = re.compile(r"(?P([A-Z]:|/).*[/\\]hs_err_pid[0-9]+\.log)") parser.addMatcher(Matcher(jvmError, {'const:jvmError' : 'jvmerror'})) - for succesRE in self.succesREs: - parser.addMatcher(Matcher(succesRE, {'const:passed' : 'const:1'})) + for successRE in self.successREs: + parser.addMatcher(Matcher(successRE, {'const:passed' : 'const:1'})) for failureRE in self.failureREs: parser.addMatcher(Matcher(failureRE, {'const:failed' : 'const:1'})) @@ -104,6 +135,9 @@ return result['retcode'] is 0 and parsed.has_key('passed') and parsed['passed'] is '1' def bench(self, vm, cwd=None, opts=[], vmbuild=None): + """ + Run this program as a benchmark. + """ parser = OutputParser(nonZeroIsFatal = False) for scoreMatcher in self.scoreMatchers: diff -r 26336f60ec7a -r 339cf8d4904d mxtool/mx.py --- a/mxtool/mx.py Wed Jan 04 23:34:15 2012 +0100 +++ b/mxtool/mx.py Thu Jan 05 11:31:46 2012 +0100 @@ -535,8 +535,8 @@ Run a command in a subprocess, wait for it to complete and return the exit status of the process. If the exit status is non-zero and `nonZeroIsFatal` is true, then mx is exited with the same exit status. - Each line of the standard output and error streams of the subprocess are redirected to the - provided out and err functions if they are not None. + Each line of the standard output and error streams of the subprocess are redirected to + out and err if they are callable objects. """ assert isinstance(args, types.ListType), "'args' must be a list: " + str(args) @@ -550,19 +550,21 @@ timeout = _opts.timeout try: - if out is None and err is None and timeout is None: + if not callable(out) and not callable(err) and timeout is None: retcode = subprocess.call(args, cwd=cwd) else: def redirect(stream, f): for line in iter(stream.readline, ''): f(line) stream.close() - p = subprocess.Popen(args, cwd=cwd, stdout=None if out is None else subprocess.PIPE, stderr=None if err is None else subprocess.PIPE) - if out is not None: + stdout=out if not callable(out) else subprocess.PIPE + stderr=err if not callable(err) else subprocess.PIPE + p = subprocess.Popen(args, cwd=cwd, stdout=stdout, stderr=stderr) + if callable(out): t = Thread(target=redirect, args=(p.stdout, out)) t.daemon = True # thread dies with the program t.start() - if err is not None: + if callable(err): t = Thread(target=redirect, args=(p.stderr, err)) t.daemon = True # thread dies with the program t.start() @@ -833,7 +835,7 @@ else: os.mkdir(outputDir) - cp = classpath(p.name, includeSelf=False) + cp = classpath(p.name, includeSelf=True) sourceDirs = p.source_dirs() mustBuild = args.force if not mustBuild: @@ -885,7 +887,7 @@ self.c = 0 def eat(self, line): - if 'proprietary API': + if 'proprietary API' in line: self.c = 2 elif self.c != 0: self.c -= 1