diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineIterator.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineIterator.java new file mode 100644 index 0000000000000000000000000000000000000000..961a59a4ceb4ad36ab677d014044624b4d2c4461 --- /dev/null +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineIterator.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2017, 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. + */ +package com.oracle.truffle.r.test.packages.analyzer; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.NoSuchElementException; +import java.util.logging.Logger; + +public class FileLineIterator extends LineIterator { + + private static final Logger LOGGER = Logger.getLogger(FileLineIterator.class.getName()); + + public static final int MAX_FILE_SIZE = 200 * 1024 * 1024; + + private BufferedReader reader; + private String lookahead = null; + + public FileLineIterator(Path p) { + try { + long size = Files.size(p); + if (size < MAX_FILE_SIZE) { + this.reader = Files.newBufferedReader(p); + nextLine(); + } else { + this.reader = new BufferedReader(new InputStreamReader(new LimitSizeInputStreamReader(Files.newInputStream(p), MAX_FILE_SIZE))); + LOGGER.fine(String.format("Will read at most %d bytes from file %s.", MAX_FILE_SIZE, p)); + this.reader = null; + } + } catch (IOException e) { + LOGGER.severe(String.format("I/O error occurred when reading %s: %s", p, e.getMessage())); + } + } + + @Override + public void close() throws IOException { + if (reader != null) { + reader.close(); + } + } + + private String nextLine() { + + String line = lookahead; + try { + lookahead = reader.readLine(); + } catch (OutOfMemoryError e) { + // If a single line is just too large, abort. + lookahead = null; + } catch (IOException e) { + lookahead = null; + } + return line; + } + + @Override + public boolean hasNext() { + return lookahead != null; + } + + @Override + public String next() { + if (hasNext()) { + return nextLine(); + } + throw new NoSuchElementException(); + } + + private static class LimitSizeInputStreamReader extends InputStream { + + private final long limit; + private final InputStream source; + private long consumed; + + protected LimitSizeInputStreamReader(InputStream source, long limit) { + this.source = source; + this.limit = limit; + } + + @Override + public int read() throws IOException { + if (consumed < limit) { + consumed++; + return source.read(); + } + return -1; + } + + @Override + public int read(byte[] b) throws IOException { + return read(b, 0, b.length); + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + int read = super.read(b, off, (int) Math.min(limit - consumed, len)); + consumed += read; + return read; + } + + @Override + public int available() throws IOException { + return Math.min((int) (limit - consumed), super.available()); + } + + } + +} diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineListReader.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineListReader.java new file mode 100644 index 0000000000000000000000000000000000000000..1dfe699153fcb01cebda5888f8355966a9adc860 --- /dev/null +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineListReader.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017, 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. + */ +package com.oracle.truffle.r.test.packages.analyzer; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +public class FileLineListReader extends FileLineReader { + + private final List<String> l; + + public FileLineListReader(List<String> lines) { + this.l = lines; + } + + @Override + public boolean isEmpty() { + return l.isEmpty(); + } + + @Override + public LineIterator iterator() { + return new LineIterator() { + + private final Iterator<String> it = l.iterator(); + + @Override + public void close() throws IOException { + // nothing to do + } + + @Override + public String next() { + return it.next(); + } + + @Override + public boolean hasNext() { + return it.hasNext(); + } + }; + } + +} diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineReader.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineReader.java new file mode 100644 index 0000000000000000000000000000000000000000..e8200cbcad560e6541b9d2cc91b49754605c5331 --- /dev/null +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineReader.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017, 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. + */ +package com.oracle.truffle.r.test.packages.analyzer; + +public abstract class FileLineReader implements Iterable<String> { + + public abstract boolean isEmpty(); + + @Override + public abstract LineIterator iterator(); + +} diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineStreamReader.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineStreamReader.java new file mode 100644 index 0000000000000000000000000000000000000000..bdb7d03bd63f060e83598983353d37f6636a9dbb --- /dev/null +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineStreamReader.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017, 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. + */ +package com.oracle.truffle.r.test.packages.analyzer; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public class FileLineStreamReader extends FileLineReader { + + private final Path p; + + public FileLineStreamReader(Path p) { + this.p = p; + + } + + @Override + public boolean isEmpty() { + try { + return Files.size(p) == 0; + } catch (IOException e) { + } + return true; + } + + @Override + public LineIterator iterator() { + return new FileLineIterator(p); + } + +} diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileTreeWalker.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileTreeWalker.java index 572124fc5f8eda8ae451c0a6127b145e1f4fef8e..a0626404dd0b8acf05080890de8b731d2f8d3338 100644 --- a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileTreeWalker.java +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileTreeWalker.java @@ -157,10 +157,13 @@ public class FileTreeWalker { lfParser.addDetector(ConfigureErrorDetector.INSTANCE); lfParser.addTestResultDetector(DiffDetector.INSTANCE); + long startTime = System.currentTimeMillis(); LogFile parseLogFile = lfParser.parseLogFile(); Collection<Problem> problems = parseLogFile.collectProblems(); pkgTestRun.setSuccess(parseLogFile.isSuccess()); pkgTestRun.setLogFile(parseLogFile.getPath()); + long endTime = System.currentTimeMillis(); + LOGGER.info(String.format("Finished in %d seconds", (endTime - startTime) / 1000L)); // log problems LOGGER.fine("Overall test result: " + (pkgTestRun.isSuccess() ? "OK" : "FAILED")); diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/LineIterator.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/LineIterator.java new file mode 100644 index 0000000000000000000000000000000000000000..c84f3f133dd3acd000597d104fbcf2cf34087c1d --- /dev/null +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/LineIterator.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017, 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. + */ +package com.oracle.truffle.r.test.packages.analyzer; + +import java.io.Closeable; +import java.util.Iterator; + +public abstract class LineIterator implements Iterator<String>, Closeable { + +} diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/PTAMain.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/PTAMain.java index f60d22af3eff08353b486d7392c4732ffd09b77a..bb5f388c3c907951d757ec5839dc756606ddd349 100644 --- a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/PTAMain.java +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/PTAMain.java @@ -204,6 +204,7 @@ public class PTAMain { sb.append(" --glob GLOB\t\tGlob-style directory filter for packages to consider (default: \"*\").").append(LF); sb.append(" --outDir PATH\tPath to directory for HTML output (default: \"html\").").append(LF); sb.append(" --console\t\tPrint output to console (by default, only errors are printed).").append(LF); + sb.append(" --verbose\t\tUse highest verbosity level.").append(LF); System.out.println(sb.toString()); System.exit(1); } diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/ConfigureErrorDetector.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/ConfigureErrorDetector.java index 008b48d83c91a50d2d99207db82de7a64e9bf304..2b7621d8b7439bb80a36b7f59eec1a853a94f524 100644 --- a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/ConfigureErrorDetector.java +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/ConfigureErrorDetector.java @@ -22,10 +22,12 @@ */ package com.oracle.truffle.r.test.packages.analyzer.detectors; +import java.io.IOException; import java.util.Collection; import java.util.LinkedList; -import java.util.List; +import com.oracle.truffle.r.test.packages.analyzer.LineIterator; +import com.oracle.truffle.r.test.packages.analyzer.FileLineReader; import com.oracle.truffle.r.test.packages.analyzer.Location; import com.oracle.truffle.r.test.packages.analyzer.Problem; import com.oracle.truffle.r.test.packages.analyzer.model.RPackageTestRun; @@ -45,17 +47,22 @@ public class ConfigureErrorDetector extends LineDetector { } @Override - public Collection<Problem> detect(RPackageTestRun pkgTestRun, Location startLocation, List<String> body) { + public Collection<Problem> detect(RPackageTestRun pkgTestRun, Location startLocation, FileLineReader body) { Collection<Problem> problems = new LinkedList<>(); assert body.isEmpty() || startLocation != null; int lineNr = startLocation != null ? startLocation.lineNr : 0; - for (String line : body) { - if (line.startsWith(PREFIX)) { - String message = line.substring(PREFIX.length()); - problems.add(new ConfigureErrorProblem(pkgTestRun, this, new Location(startLocation.file, lineNr), message)); - + try (LineIterator it = body.iterator()) { + while (it.hasNext()) { + String line = it.next(); + if (line.startsWith(PREFIX)) { + String message = line.substring(PREFIX.length()); + problems.add(new ConfigureErrorProblem(pkgTestRun, this, new Location(startLocation.file, lineNr), message)); + + } + ++lineNr; } - ++lineNr; + } catch (IOException e) { + // ignore } return problems; } diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/Detector.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/Detector.java index b71512b5e51415511a5add23996e8ed1c71343a0..f1e22de6a12f4e0b06fa4dd04b0af61fa424561a 100644 --- a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/Detector.java +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/Detector.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.test.packages.analyzer.detectors; +import java.io.IOException; import java.util.Collection; import java.util.LinkedList; diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/InstallationProblemDetector.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/InstallationProblemDetector.java index b63d31b1d5a274a6fcc4bee78685afc50b058885..8e4cb00b9fa85a76ac71111f1ed670636628619e 100644 --- a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/InstallationProblemDetector.java +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/InstallationProblemDetector.java @@ -22,12 +22,14 @@ */ package com.oracle.truffle.r.test.packages.analyzer.detectors; +import java.io.IOException; import java.util.Collection; import java.util.Collections; -import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.oracle.truffle.r.test.packages.analyzer.LineIterator; +import com.oracle.truffle.r.test.packages.analyzer.FileLineReader; import com.oracle.truffle.r.test.packages.analyzer.Location; import com.oracle.truffle.r.test.packages.analyzer.Problem; import com.oracle.truffle.r.test.packages.analyzer.model.RPackageTestRun; @@ -47,14 +49,19 @@ public class InstallationProblemDetector extends LineDetector { } @Override - public Collection<Problem> detect(RPackageTestRun pkg, Location startLocation, List<String> body) { + public Collection<Problem> detect(RPackageTestRun pkg, Location startLocation, FileLineReader body) { int lineNr = startLocation.lineNr; - for (String line : body) { - Matcher matcher = pattern.matcher(line); - if (matcher.matches()) { - return Collections.singletonList(new PackageInstallationProblem(pkg, this, new Location(startLocation.file, lineNr), line)); + try (LineIterator it = body.iterator()) { + while (it.hasNext()) { + String line = it.next(); + Matcher matcher = pattern.matcher(line); + if (matcher.matches()) { + return Collections.singletonList(new PackageInstallationProblem(pkg, this, new Location(startLocation.file, lineNr), line)); + } + ++lineNr; } - ++lineNr; + } catch (IOException e) { + // ignore } return Collections.emptyList(); } diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/LineDetector.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/LineDetector.java index a035f5eb1be6b1c0e38f41c051f60c5423894fc0..ac8f8610414280000a641b54672a0664d460312f 100644 --- a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/LineDetector.java +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/LineDetector.java @@ -22,9 +22,9 @@ */ package com.oracle.truffle.r.test.packages.analyzer.detectors; -import java.util.List; +import com.oracle.truffle.r.test.packages.analyzer.FileLineReader; -public abstract class LineDetector extends Detector<List<String>> { +public abstract class LineDetector extends Detector<FileLineReader> { protected LineDetector() { super(null); diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/RErrorDetector.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/RErrorDetector.java index 6f304037442499e61d0c18c2ed1673139cc08996..59a4525d2c205b472a588d79ab3d888677462f45 100644 --- a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/RErrorDetector.java +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/RErrorDetector.java @@ -22,13 +22,14 @@ */ package com.oracle.truffle.r.test.packages.analyzer.detectors; +import java.io.IOException; import java.util.Collection; -import java.util.Iterator; import java.util.LinkedList; -import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.oracle.truffle.r.test.packages.analyzer.LineIterator; +import com.oracle.truffle.r.test.packages.analyzer.FileLineReader; import com.oracle.truffle.r.test.packages.analyzer.Location; import com.oracle.truffle.r.test.packages.analyzer.Problem; import com.oracle.truffle.r.test.packages.analyzer.model.RPackageTestRun; @@ -48,28 +49,31 @@ public class RErrorDetector extends LineDetector { } @Override - public Collection<Problem> detect(RPackageTestRun pkg, Location startLocation, List<String> body) { + public Collection<Problem> detect(RPackageTestRun pkg, Location startLocation, FileLineReader body) { Collection<Problem> problems = new LinkedList<>(); assert body.isEmpty() || startLocation != null; int lineOffset = startLocation != null ? startLocation.lineNr : 0; int i = -1; - Iterator<String> it = body.iterator(); - while (it.hasNext()) { - String line = it.next(); - ++i; - Matcher matcher = PATTERN.matcher(line); - if (matcher.matches()) { - String callString = matcher.group("CALLSTR"); - String message = matcher.group("MSG"); - if (message.trim().isEmpty() && it.hasNext()) { - // message could be in the next line - message = it.next(); - ++i; + try (LineIterator it = body.iterator()) { + while (it.hasNext()) { + String line = it.next(); + ++i; + Matcher matcher = PATTERN.matcher(line); + if (matcher.matches()) { + String callString = matcher.group("CALLSTR"); + String message = matcher.group("MSG"); + if (message.trim().isEmpty() && it.hasNext()) { + // message could be in the next line + message = it.next(); + ++i; + } + problems.add(new RErrorProblem(pkg, this, new Location(startLocation.file, i + lineOffset), callString, message)); } - problems.add(new RErrorProblem(pkg, this, new Location(startLocation.file, i + lineOffset), callString, message)); } + } catch (IOException e) { + // ignore } return problems; diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/RInternalErrorDetector.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/RInternalErrorDetector.java index 56b5e78cedd8a748cc08ebf527e7f1632dedea1d..5f570e0344f312c95a30cd9031d2006e0b4cb5be 100644 --- a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/RInternalErrorDetector.java +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/RInternalErrorDetector.java @@ -22,10 +22,12 @@ */ package com.oracle.truffle.r.test.packages.analyzer.detectors; +import java.io.IOException; import java.util.Collection; import java.util.LinkedList; -import java.util.List; +import com.oracle.truffle.r.test.packages.analyzer.LineIterator; +import com.oracle.truffle.r.test.packages.analyzer.FileLineReader; import com.oracle.truffle.r.test.packages.analyzer.Location; import com.oracle.truffle.r.test.packages.analyzer.Problem; import com.oracle.truffle.r.test.packages.analyzer.model.RPackageTestRun; @@ -41,22 +43,25 @@ public class RInternalErrorDetector extends LineDetector { @Override public String getName() { - // TODO Auto-generated method stub return null; } @Override - public Collection<Problem> detect(RPackageTestRun pkg, Location startLocation, List<String> body) { + public Collection<Problem> detect(RPackageTestRun pkg, Location startLocation, FileLineReader body) { Collection<Problem> problems = new LinkedList<>(); - assert body.isEmpty() || startLocation != null; int lineNr = startLocation != null ? startLocation.lineNr : 0; - for (String line : body) { - int indexOf = line.indexOf(P); - if (indexOf != -1) { - String message = line.substring(indexOf + P.length()); - problems.add(new RInternalErrorProblem(pkg, this, new Location(startLocation.file, lineNr), message)); + try (LineIterator it = body.iterator()) { + while (it.hasNext()) { + String line = it.next(); + int indexOf = line.indexOf(P); + if (indexOf != -1) { + String message = line.substring(indexOf + P.length()); + problems.add(new RInternalErrorProblem(pkg, this, new Location(startLocation.file, lineNr), message)); + } + ++lineNr; } - ++lineNr; + } catch (IOException e) { + // ignore } return problems; } diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/SegfaultDetector.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/SegfaultDetector.java index f23d7933a922ec8d504301440eaf8c36fcc8a9d7..be6844240ffdaf2adbdc26444659bab33bb73b5c 100644 --- a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/SegfaultDetector.java +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/SegfaultDetector.java @@ -22,10 +22,12 @@ */ package com.oracle.truffle.r.test.packages.analyzer.detectors; +import java.io.IOException; import java.util.Collection; import java.util.Collections; -import java.util.List; +import com.oracle.truffle.r.test.packages.analyzer.LineIterator; +import com.oracle.truffle.r.test.packages.analyzer.FileLineReader; import com.oracle.truffle.r.test.packages.analyzer.Location; import com.oracle.truffle.r.test.packages.analyzer.Problem; import com.oracle.truffle.r.test.packages.analyzer.model.RPackageTestRun; @@ -44,28 +46,33 @@ public class SegfaultDetector extends LineDetector { } @Override - public Collection<Problem> detect(RPackageTestRun pkg, Location startLocation, List<String> body) { + public Collection<Problem> detect(RPackageTestRun pkg, Location startLocation, FileLineReader body) { StringBuilder segfaultMessage = new StringBuilder(); boolean collect = false; assert body.isEmpty() || startLocation != null; int lineNr = startLocation != null ? startLocation.lineNr : 0; boolean takeNextLine = false; - for (String line : body) { - if (line.contains(SIGSEGV_START)) { - collect = true; - } - if (collect) { - if (takeNextLine) { - segfaultMessage.append(line); - takeNextLine = false; + try (LineIterator it = body.iterator()) { + while (it.hasNext()) { + String line = it.next(); + if (line.contains(SIGSEGV_START)) { + collect = true; } - if (line.contains("Problematic frame")) { - takeNextLine = true; - } else if (!line.contains("#")) { - break; + if (collect) { + if (takeNextLine) { + segfaultMessage.append(line); + takeNextLine = false; + } + if (line.contains("Problematic frame")) { + takeNextLine = true; + } else if (!line.contains("#")) { + break; + } } + ++lineNr; } - ++lineNr; + } catch (IOException e) { + // ignore } if (collect) { return Collections.singleton(new SegfaultProblem(pkg, this, new Location(startLocation.file, lineNr), segfaultMessage.toString())); diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/SymbolLookupErrorDetector.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/SymbolLookupErrorDetector.java index bd218894e024d78ada9a40a34694e06cf24f472c..d69f84bd3b0ee83b91d3bb7cff7e18b4e6955888 100644 --- a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/SymbolLookupErrorDetector.java +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/SymbolLookupErrorDetector.java @@ -22,12 +22,14 @@ */ package com.oracle.truffle.r.test.packages.analyzer.detectors; +import java.io.IOException; import java.util.Collection; import java.util.LinkedList; -import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.oracle.truffle.r.test.packages.analyzer.LineIterator; +import com.oracle.truffle.r.test.packages.analyzer.FileLineReader; import com.oracle.truffle.r.test.packages.analyzer.Location; import com.oracle.truffle.r.test.packages.analyzer.Problem; import com.oracle.truffle.r.test.packages.analyzer.model.RPackageTestRun; @@ -47,17 +49,22 @@ public final class SymbolLookupErrorDetector extends LineDetector { } @Override - public Collection<Problem> detect(RPackageTestRun pkgTestRun, Location startLocation, List<String> body) { + public Collection<Problem> detect(RPackageTestRun pkgTestRun, Location startLocation, FileLineReader body) { Collection<Problem> problems = new LinkedList<>(); int lineNr = startLocation != null ? startLocation.lineNr : 0; - for (String line : body) { - Matcher matcher = PATTERN.matcher(line); - if (matcher.matches()) { - String message = matcher.group("MSG"); - problems.add(new SymbolLookupErrorProblem(pkgTestRun, this, new Location(startLocation.file, lineNr), message)); - + try (LineIterator it = body.iterator()) { + while (it.hasNext()) { + String line = it.next(); + Matcher matcher = PATTERN.matcher(line); + if (matcher.matches()) { + String message = matcher.group("MSG"); + problems.add(new SymbolLookupErrorProblem(pkgTestRun, this, new Location(startLocation.file, lineNr), message)); + + } + ++lineNr; } - ++lineNr; + } catch (IOException e) { + // ignore } return problems; } diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/UnsupportedSpecializationDetector.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/UnsupportedSpecializationDetector.java index 99f270940e23845ce25a4c3b260b9f278ca748d4..d5a3ea7b2ee5be3048ab1b4f6a3bdd3dddb47575 100644 --- a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/UnsupportedSpecializationDetector.java +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/detectors/UnsupportedSpecializationDetector.java @@ -22,12 +22,14 @@ */ package com.oracle.truffle.r.test.packages.analyzer.detectors; +import java.io.IOException; import java.util.Collection; import java.util.LinkedList; -import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.oracle.truffle.r.test.packages.analyzer.LineIterator; +import com.oracle.truffle.r.test.packages.analyzer.FileLineReader; import com.oracle.truffle.r.test.packages.analyzer.Location; import com.oracle.truffle.r.test.packages.analyzer.Problem; import com.oracle.truffle.r.test.packages.analyzer.model.RPackageTestRun; @@ -49,20 +51,25 @@ public class UnsupportedSpecializationDetector extends LineDetector { } @Override - public Collection<Problem> detect(RPackageTestRun pkg, Location startLocation, List<String> body) { + public Collection<Problem> detect(RPackageTestRun pkg, Location startLocation, FileLineReader body) { Collection<Problem> problems = new LinkedList<>(); String message = null; assert body.isEmpty() || startLocation != null; int lineNr = startLocation != null ? startLocation.lineNr : 0; int problemStartLine = lineNr; - for (String line : body) { - Matcher matcher = PATTERN.matcher(line); - if (matcher.find()) { - message = matcher.group("MSG"); - problemStartLine = lineNr; - problems.add(new UnsupportedSpecializationProblem(pkg, this, new Location(startLocation.file, problemStartLine), message)); + try (LineIterator it = body.iterator()) { + while (it.hasNext()) { + String line = it.next(); + Matcher matcher = PATTERN.matcher(line); + if (matcher.find()) { + message = matcher.group("MSG"); + problemStartLine = lineNr; + problems.add(new UnsupportedSpecializationProblem(pkg, this, new Location(startLocation.file, problemStartLine), message)); + } + ++lineNr; } - ++lineNr; + } catch (IOException e) { + // ignore } return problems; } diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/parser/LogFileParser.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/parser/LogFileParser.java index 57ddf81a2a6854017b216ab563a46937a7fa2df2..e50d913587ac7212ab39ecae67a7d43fafb62b8b 100644 --- a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/parser/LogFileParser.java +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/parser/LogFileParser.java @@ -27,7 +27,6 @@ import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Files; -import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.BasicFileAttributes; @@ -46,6 +45,9 @@ import java.util.logging.Logger; import java.util.stream.Collectors; import java.util.stream.Stream; +import com.oracle.truffle.r.test.packages.analyzer.FileLineListReader; +import com.oracle.truffle.r.test.packages.analyzer.FileLineReader; +import com.oracle.truffle.r.test.packages.analyzer.FileLineStreamReader; import com.oracle.truffle.r.test.packages.analyzer.Location; import com.oracle.truffle.r.test.packages.analyzer.Problem; import com.oracle.truffle.r.test.packages.analyzer.detectors.Detector; @@ -58,6 +60,8 @@ public class LogFileParser { private static final Logger LOGGER = Logger.getLogger(LogFileParser.class.getName()); + private static final long MAX_FILE_SIZE = 200 * 1024 * 1024; + private RPackageTestRun pkg; private BufferedReader reader; private Line curLine; @@ -93,28 +97,33 @@ public class LogFileParser { } public LogFile parseLogFile() throws IOException { - try (BufferedReader r = Files.newBufferedReader(logFile.path)) { - this.reader = r; - consumeLine(); + long size = Files.size(logFile.path); + if (size <= MAX_FILE_SIZE) { + try (BufferedReader r = Files.newBufferedReader(logFile.path)) { + this.reader = r; + consumeLine(); - Section installTest0 = parseInstallTest(); - logFile.addSection(installTest0); - if (!installTest0.isSuccess()) { - return logFile; - } - Section installTest1 = parseInstallTest(); - logFile.addSection(installTest1); - if (installTest1.isSuccess()) { - logFile.addSection(parseCheckResults()); + Section installTest0 = parseInstallTest(); + logFile.addSection(installTest0); + if (!installTest0.isSuccess()) { + return logFile; + } + Section installTest1 = parseInstallTest(); + logFile.addSection(installTest1); + if (installTest1.isSuccess()) { + logFile.addSection(parseCheckResults()); + } + TestResult overallResult = parseOverallStatus(); + logFile.setSuccess(overallResult.toBoolean()); + + // In the end, a recursive diff is executed which might produce error messages. + collectBody(); + expectEOF(); + } finally { + this.reader = null; } - TestResult overallResult = parseOverallStatus(); - logFile.setSuccess(overallResult.toBoolean()); - - // In the end, a recursive diff is executed which might produce error messages. - collectBody(); - expectEOF(); - } finally { - this.reader = null; + } else { + LOGGER.severe(String.format("Cannot analyze %s, file is too large (%d bytes, max=%d bytes)", logFile.path, size, MAX_FILE_SIZE)); } return logFile; } @@ -176,18 +185,15 @@ public class LogFileParser { if (Files.isReadable(outputFile)) { ignoreFiles.add(outputFile); - checkResults.problems.addAll(applyDetectors(Token.OUTPUT_MISMATCH_FASTR, outputFile, 0, Files.readAllLines(outputFile))); + checkResults.problems.addAll(applyDetectors(Token.OUTPUT_MISMATCH_FASTR, outputFile, 0, new FileLineStreamReader(outputFile))); } else { // try to find the file anywhere in the test run directory (there were some // cases) Optional<Path> findFirst = null; - try { - findFirst = Files.find(logFile.path.getParent(), 3, (path, attr) -> path.getFileName().equals(outputFile.getFileName())).findFirst(); - if (findFirst.isPresent()) { - ignoreFiles.add(findFirst.get()); - checkResults.problems.addAll(applyDetectors(Token.OUTPUT_MISMATCH_FASTR, findFirst.get(), 0, Files.readAllLines(findFirst.get()))); - } - } catch (NoSuchFileException e) { + findFirst = Files.find(logFile.path.getParent(), 3, (path, attr) -> path.getFileName().equals(outputFile.getFileName())).findFirst(); + if (findFirst.isPresent()) { + ignoreFiles.add(findFirst.get()); + checkResults.problems.addAll(applyDetectors(Token.OUTPUT_MISMATCH_FASTR, findFirst.get(), 0, new FileLineStreamReader(findFirst.get()))); } if (findFirst == null || !findFirst.isPresent()) { LOGGER.warning("Cannot read output file " + outputFile); @@ -198,8 +204,10 @@ public class LogFileParser { } checkResults.setSuccess(false); - } else { + } else if (laMatches(Token.END_CHECKING)) { break; + } else { + consumeLine(); } } @@ -305,10 +313,10 @@ public class LogFileParser { testing.problems.addAll(applyTestResultDetectors(diffResult)); diffResult.stream().forEach(chunk -> { if (!chunk.getLeft().isEmpty()) { - testing.problems.addAll(applyDetectors(Token.RUNNING_SPECIFIC_TESTS, chunk.getLeftFile(), chunk.getLeftStartLine(), chunk.getLeft())); + testing.problems.addAll(applyDetectors(Token.RUNNING_SPECIFIC_TESTS, chunk.getLeftFile(), chunk.getLeftStartLine(), new FileLineListReader(chunk.getLeft()))); } if (!chunk.getRight().isEmpty()) { - testing.problems.addAll(applyDetectors(Token.RUNNING_SPECIFIC_TESTS, chunk.getRightFile(), chunk.getRightStartLine(), chunk.getRight())); + testing.problems.addAll(applyDetectors(Token.RUNNING_SPECIFIC_TESTS, chunk.getRightFile(), chunk.getRightStartLine(), new FileLineListReader(chunk.getRight()))); } }); @@ -330,7 +338,6 @@ public class LogFileParser { if (laMatches("Running ")) { consumeLine(); } - // TODO anything more to parse ? testing.problems.addAll(applyDetectors(Token.RUNNING_VIGNETTES, logFile.path, collectBody(Token.END_TESTING))); } @@ -423,7 +430,7 @@ public class LogFileParser { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { if (endsWith(file, ".Rout", ".fail") && includeCheck.test(file)) { - outputCheck.problems.addAll(applyDetectors(Token.BEGIN_CHECKING, file, 0, Files.readAllLines(file))); + outputCheck.problems.addAll(applyDetectors(Token.BEGIN_CHECKING, file, 0, new FileLineStreamReader(file))); } return FileVisitResult.CONTINUE; } @@ -454,12 +461,12 @@ public class LogFileParser { if (!body.isEmpty()) { Line firstLine = body.get(0); List<String> strBody = body.stream().map(l -> l.text).collect(Collectors.toList()); - return applyDetectors(start, file, firstLine.lineNr, strBody); + return applyDetectors(start, file, firstLine.lineNr, new FileLineListReader(strBody)); } return new LinkedList<>(); } - private Collection<Problem> applyDetectors(Token start, Path file, int startLineNr, List<String> body) { + private Collection<Problem> applyDetectors(Token start, Path file, int startLineNr, FileLineReader body) { assert Files.isRegularFile(file); Location startLocation = null; if (!body.isEmpty()) { @@ -487,7 +494,9 @@ public class LogFileParser { } private Collection<Problem> applyTestResultDetectors(List<DiffChunk> diffChunk) { - return testResultDetectors.stream().map(detector -> detector.detect(pkg, null, diffChunk)).flatMap(l -> l.stream()).collect(Collectors.toList()); + return testResultDetectors.stream().map(detector -> { + return detector.detect(pkg, null, diffChunk); + }).flatMap(l -> l.stream()).collect(Collectors.toList()); } /** diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/test/RErrorDetectorTest.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/test/RErrorDetectorTest.java index 9e295bb54b43f612cd0829ff2e1cc3c27be58587..e404e94230451d3c976ce9abb22751a0e0c3ae75 100644 --- a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/test/RErrorDetectorTest.java +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/test/RErrorDetectorTest.java @@ -26,12 +26,12 @@ import java.nio.file.Paths; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.List; import java.util.Optional; import org.junit.Assert; import org.junit.Test; +import com.oracle.truffle.r.test.packages.analyzer.FileLineListReader; import com.oracle.truffle.r.test.packages.analyzer.Location; import com.oracle.truffle.r.test.packages.analyzer.Problem; import com.oracle.truffle.r.test.packages.analyzer.detectors.RErrorDetector; @@ -51,8 +51,8 @@ public class RErrorDetectorTest { @Test public void testMultiLine() { - List<String> lines = Arrays.asList(new String[]{"Error in check(options) : ", - "ERROR: installing Rd objects failed for package ‘RUnit’"}); + FileLineListReader lines = new FileLineListReader(Arrays.asList(new String[]{"Error in check(options) : ", + "ERROR: installing Rd objects failed for package ‘RUnit’"})); Collection<Problem> detect = RErrorDetector.INSTANCE.detect(pkgTestRun, loc(), lines); Assert.assertEquals(1, detect.size()); @@ -65,7 +65,7 @@ public class RErrorDetectorTest { @Test public void testSingleLine0() { - List<String> lines = Collections.singletonList("Error in check(options) : invalid value for 'label' "); + FileLineListReader lines = new FileLineListReader(Collections.singletonList("Error in check(options) : invalid value for 'label' ")); Collection<Problem> detect = RErrorDetector.INSTANCE.detect(pkgTestRun, loc(), lines); Assert.assertEquals(1, detect.size()); @@ -78,7 +78,7 @@ public class RErrorDetectorTest { @Test public void testSingleLine1() { - List<String> lines = Collections.singletonList("Error in check : invalid value for 'label' "); + FileLineListReader lines = new FileLineListReader(Collections.singletonList("Error in check : invalid value for 'label' ")); Collection<Problem> detect = RErrorDetector.INSTANCE.detect(pkgTestRun, loc(), lines); Assert.assertEquals(1, detect.size()); @@ -91,7 +91,7 @@ public class RErrorDetectorTest { @Test public void testSingleLineMultipleColon() { - List<String> lines = Collections.singletonList("Error in check(options) : invalid value for 'label' : "); + FileLineListReader lines = new FileLineListReader(Collections.singletonList("Error in check(options) : invalid value for 'label' : ")); Collection<Problem> detect = RErrorDetector.INSTANCE.detect(pkgTestRun, loc(), lines); Assert.assertEquals(1, detect.size()); @@ -104,7 +104,7 @@ public class RErrorDetectorTest { @Test public void testSingleLineWithoutCallstring0() { - List<String> lines = Collections.singletonList("Error: invalid value for 'label' "); + FileLineListReader lines = new FileLineListReader(Collections.singletonList("Error: invalid value for 'label' ")); Collection<Problem> detect = RErrorDetector.INSTANCE.detect(pkgTestRun, loc(), lines); Assert.assertEquals(1, detect.size()); @@ -117,7 +117,7 @@ public class RErrorDetectorTest { @Test public void testSingleLineWithoutCallstring1() { - List<String> lines = Collections.singletonList("Error: invalid value for 'label' : "); + FileLineListReader lines = new FileLineListReader(Collections.singletonList("Error: invalid value for 'label' : ")); Collection<Problem> detect = RErrorDetector.INSTANCE.detect(pkgTestRun, loc(), lines); Assert.assertEquals(1, detect.size()); @@ -129,7 +129,7 @@ public class RErrorDetectorTest { @Test public void testRInternalError0() { - List<String> lines = Collections.singletonList("RInternalError: invalid value for 'label'"); + FileLineListReader lines = new FileLineListReader(Collections.singletonList("RInternalError: invalid value for 'label'")); Collection<Problem> detect = RErrorDetector.INSTANCE.detect(pkgTestRun, loc(), lines); Assert.assertEquals(0, detect.size()); @@ -137,7 +137,7 @@ public class RErrorDetectorTest { @Test public void testRInternalError1() { - List<String> lines = Collections.singletonList("> RInternalError: invalid value for 'label'"); + FileLineListReader lines = new FileLineListReader(Collections.singletonList("> RInternalError: invalid value for 'label'")); Collection<Problem> detect = RErrorDetector.INSTANCE.detect(pkgTestRun, loc(), lines); Assert.assertEquals(0, detect.size()); @@ -145,7 +145,7 @@ public class RErrorDetectorTest { @Test public void testRInternalError2() { - List<String> lines = Collections.singletonList(" RInternalError: invalid value for 'label'"); + FileLineListReader lines = new FileLineListReader(Collections.singletonList(" RInternalError: invalid value for 'label'")); Collection<Problem> detect = RErrorDetector.INSTANCE.detect(pkgTestRun, loc(), lines); Assert.assertEquals(0, detect.size()); @@ -153,7 +153,7 @@ public class RErrorDetectorTest { @Test public void testWithLinePrefix() { - List<String> lines = Collections.singletonList("> Error: invalid value for 'label'"); + FileLineListReader lines = new FileLineListReader(Collections.singletonList("> Error: invalid value for 'label'")); Collection<Problem> detect = RErrorDetector.INSTANCE.detect(pkgTestRun, loc(), lines); Assert.assertEquals(1, detect.size()); @@ -165,8 +165,8 @@ public class RErrorDetectorTest { @Test public void testCallstringWithNamesAndValues0() { - List<String> lines = Arrays.asList(new String[]{"Error in grep(pattern, all.names, value = TRUE) : ", - " invalid regular expression '*': Dangling meta character '*' near index 0"}); + FileLineListReader lines = new FileLineListReader(Arrays.asList(new String[]{"Error in grep(pattern, all.names, value = TRUE) : ", + " invalid regular expression '*': Dangling meta character '*' near index 0"})); Collection<Problem> detect = RErrorDetector.INSTANCE.detect(pkgTestRun, loc(), lines); Assert.assertEquals(1, detect.size()); @@ -178,8 +178,8 @@ public class RErrorDetectorTest { @Test public void testCallstringWithNamesAndValues1() { - List<String> lines = Arrays.asList(new String[]{"Error in grep(pattern, all.names, value = \":\") : ", - " invalid regular expression '*': Dangling meta character '*' near index 0"}); + FileLineListReader lines = new FileLineListReader(Arrays.asList(new String[]{"Error in grep(pattern, all.names, value = \":\") : ", + " invalid regular expression '*': Dangling meta character '*' near index 0"})); Collection<Problem> detect = RErrorDetector.INSTANCE.detect(pkgTestRun, loc(), lines); Assert.assertEquals(1, detect.size()); diff --git a/com.oracle.truffle.r.test.packages/r/install.cache.R b/com.oracle.truffle.r.test.packages/r/install.cache.R index 44acb6c78892cef96158f0699daf6323e3a9c19d..cab215a510a3ca5a05007bad5c47e5470d063ed4 100644 --- a/com.oracle.truffle.r.test.packages/r/install.cache.R +++ b/com.oracle.truffle.r.test.packages/r/install.cache.R @@ -88,7 +88,7 @@ pkg.cache.insert <- function(pkg.cache.env, pkgname, lib) { # to produce a TAR with relative paths, we need to change the working dir prev.wd <- getwd() setwd(lib) - if(zip(toPath, pkgname) != 0L) { + if(zip(toPath, pkgname, flags="-r9Xq") != 0L) { log.message("could not compress package dir ", fromPath , " and store it to ", toPath, level=1) return (FALSE) } diff --git a/mx.fastr/mx_fastr_pkgs.py b/mx.fastr/mx_fastr_pkgs.py index abbe70e0d115b1104964fb4ac997ea5454967ceb..5baad996e5eea009e58eab2586eaf81a61b32957 100644 --- a/mx.fastr/mx_fastr_pkgs.py +++ b/mx.fastr/mx_fastr_pkgs.py @@ -495,6 +495,7 @@ def _set_test_status(fastr_test_info): with open(join(_pkg_testdir('fastr', pkg), 'testfile_status'), 'w') as f: f.write('# <file path> <tests passed> <tests skipped> <tests failed>\n') for fastr_relpath, fastr_testfile_status in fastr_outputs.iteritems(): + print "generating testfile_status for {0}".format(fastr_relpath) if fastr_testfile_status.status == "FAILED": relpath = fastr_relpath + ".fail" else: @@ -504,6 +505,8 @@ def _set_test_status(fastr_test_info): if os.path.exists(test_output_file): ok, skipped, failed = fastr_testfile_status.report f.write("{0} {1} {2} {3}\n".format(relpath, ok, skipped, failed)) + else: + print "File {0} does not exist".format(test_output_file) print 'END checking ' + pkg @@ -604,7 +607,8 @@ def _replace_engine_references(output): # ignore differences which come from test directory paths output[idx] = val.replace('fastr', '<engine>').replace('gnur', '<engine>') -def _fuzzy_compare(gnur_content, fastr_content, gnur_filename, fastr_filename): + +def _fuzzy_compare(gnur_content, fastr_content, gnur_filename, fastr_filename, verbose=False): ''' Compares the test output of GnuR and FastR by ignoring implementation-specific differences like header, error, and warning messages. @@ -636,14 +640,16 @@ def _fuzzy_compare(gnur_content, fastr_content, gnur_filename, fastr_filename): gnur_cur_statement_start = -1 fastr_cur_statement_start = -1 - while gnur_i < gnur_end: - gnur_line = gnur_content[gnur_i] - if fastr_i >= fastr_len: - overall_result = 1 + while True: + gnur_line, gnur_i = _get_next_line(gnur_prompt, gnur_content, gnur_end, gnur_i) + fastr_line, fastr_i = _get_next_line(fastr_prompt, fastr_content, fastr_len, fastr_i) + + if gnur_line is None or fastr_line is None: + # fail if FastR's output is shorter than GnuR's + if gnur_line is not None and fastr_line is None: + overall_result = 1 break - fastr_line = fastr_content[fastr_i] - # check if the current line starts a statement if _is_statement_begin(gnur_prompt, gnur_line) and gnur_cur_statement_start != gnur_i: gnur_cur_statement_start = gnur_i @@ -681,8 +687,6 @@ def _fuzzy_compare(gnur_content, fastr_content, gnur_filename, fastr_filename): to_match = 'Error' if 'Error' in gnur_line else 'Warning' if to_match not in fastr_line: result = 1 - # XXX do not break - # break else: # accept differences in the error/warning messages but we need to synchronize sync = True @@ -691,8 +695,6 @@ def _fuzzy_compare(gnur_content, fastr_content, gnur_filename, fastr_filename): # genuine difference (modulo whitespace) if not _ignore_whitespace(gnur_line, fastr_line): result = 1 - # XXX do not break, but we might need to synchronize indices - # break # report a mismatch or success @@ -704,6 +706,13 @@ def _fuzzy_compare(gnur_content, fastr_content, gnur_filename, fastr_filename): if fastr_cur_statement_start in statements_passed: statements_passed.remove(fastr_cur_statement_start) statements_failed.add(fastr_cur_statement_start) + + # for compatibility: print the first difference + if verbose: + print gnur_filename + ':%d' % (gnur_cur_statement_start+1) + ' vs. ' + fastr_filename + ':%d' % (fastr_cur_statement_start+1) + print gnur_line.strip() + print "vs." + print fastr_line.strip() else: assert result == 0 if fastr_cur_statement_start not in statements_failed: @@ -736,14 +745,19 @@ def _fuzzy_compare(gnur_content, fastr_content, gnur_filename, fastr_filename): gnur_i = gnur_i + 1 fastr_i = fastr_i + 1 - if overall_result == 1: - print gnur_filename + ':%d' % gnur_i + ' vs. ' + fastr_filename + ':%d' % fastr_i - print gnur_line.strip() - print "vs." - print fastr_line.strip() return overall_result, len(statements_passed), len(statements_failed) +def _get_next_line(prompt, content, content_len, line_idx): + i = line_idx + while i < content_len: + line = content[i] + if line.replace(prompt, "", 1).strip() is not "": + return line, i + i = i + 1 + return None, i + + def _ignore_whitespace(gnur_line, fastr_line): return gnur_line.translate(None, ' \t') == fastr_line.translate(None, ' \t')