Repository: flex-utilities Updated Branches: refs/heads/develop 95416e61d -> dcb771fb8
FLEX-34902,FLEX-34903,FLEX-34904: Code coverage fixes FLEX-34902: Fix undercounting of line and method coverage at the package and overall level. File level counting was correct. FLEX-34903: Remove AS interface files from code coverage. FLEX-34904: Remove all files in the code coverage data directory when the server starts unless the -append option is used. Project: http://git-wip-us.apache.org/repos/asf/flex-utilities/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-utilities/commit/dcb771fb Tree: http://git-wip-us.apache.org/repos/asf/flex-utilities/tree/dcb771fb Diff: http://git-wip-us.apache.org/repos/asf/flex-utilities/diff/dcb771fb Branch: refs/heads/develop Commit: dcb771fb8ef8190fafe968d796dc553ff8153dd9 Parents: 95416e6 Author: dloverin <darrell.love...@gmail.com> Authored: Wed Jul 8 22:04:06 2015 -0400 Committer: dloverin <darrell.love...@gmail.com> Committed: Wed Jul 8 22:11:49 2015 -0400 ---------------------------------------------------------------------- CodeCoverage/JavaServer/java/build.xml | 2 +- .../reporter/AggregateSummaryInfo.java | 90 ++++++++++++++++++ .../reporter/CodeCoverageReporter.java | 2 +- .../codecoverage/reporter/CoverageSummary.java | 2 +- .../reporter/PackageSummaryInfo.java | 2 +- .../codecoverage/reporter/SummaryInfo.java | 8 +- .../reporter/reports/XMLReportWriter.java | 1 - .../reporter/swf/DebugLineVisitor.java | 69 +++++++++++++- .../codecoverage/server/CodeCoverageServer.java | 98 ++++++++++++++++++-- .../codecoverage/server/DataSocketAccepter.java | 5 +- 10 files changed, 256 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/dcb771fb/CodeCoverage/JavaServer/java/build.xml ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/java/build.xml b/CodeCoverage/JavaServer/java/build.xml index a631529..d58e4fb 100755 --- a/CodeCoverage/JavaServer/java/build.xml +++ b/CodeCoverage/JavaServer/java/build.xml @@ -75,7 +75,7 @@ <attribute name="Implementation-Version" value="${manifest.Implementation-Version}"/> <attribute name="Implementation-Vendor" value="${manifest.Implementation-Vendor}"/> <attribute name="Main-Class" value="org.apache.flex.tools.codecoverage.server.CodeCoverageServer"/> - <attribute name="Class-Path" value="."/> + <attribute name="Class-Path" value=". external/commons-io.jar"/> </manifest> </jar> </target> http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/dcb771fb/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/AggregateSummaryInfo.java ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/AggregateSummaryInfo.java b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/AggregateSummaryInfo.java new file mode 100644 index 0000000..7e61334 --- /dev/null +++ b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/AggregateSummaryInfo.java @@ -0,0 +1,90 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.flex.tools.codecoverage.reporter; + +import java.util.Collections; +import java.util.Set; + +/** + * Class to total the individual SummaryInfo objects for package and overall + * coverage reported. Do not use to track summary info at the file and method + * level. + */ +public class AggregateSummaryInfo extends SummaryInfo +{ + + private int totalLineCount; + private int executedLineCount; + private int totalMethodCount; + private int executedMethodCount; + + @Override + public int getExecutedLineCount() + { + return executedLineCount; + } + + @Override + public int getTotalLineCount() + { + return totalLineCount; + } + + @Override + public int getExecutedMethodCount() + { + return executedMethodCount; + } + + @Override + public int getTotalMethodCount() + { + return totalMethodCount; + } + + @Override + public Set<Integer> getUnexecutedLines() + { + return Collections.emptySet(); + } + + @Override + public Set<String> getUnexecutedMethods() + { + return Collections.emptySet(); + } + + @Override + public void setLineExecutionStatus(int lineNumber, String methodName, + Boolean executed) + { + throw new UnsupportedOperationException(); + } + + @Override + public void add(SummaryInfo summaryInfo) + { + executedLineCount += summaryInfo.getExecutedLineCount(); + totalLineCount += summaryInfo.getTotalLineCount(); + executedMethodCount += summaryInfo.getExecutedMethodCount(); + totalMethodCount += summaryInfo.getTotalMethodCount(); + } + +} http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/dcb771fb/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/CodeCoverageReporter.java ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/CodeCoverageReporter.java b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/CodeCoverageReporter.java index 7c0d868..875b52a 100755 --- a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/CodeCoverageReporter.java +++ b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/CodeCoverageReporter.java @@ -52,7 +52,7 @@ public class CodeCoverageReporter private static final String DEFAULT_REPORT_NAME = "ccreport.xml"; private static final String DEFAULT_DATA_DIRECTORY = "ccdata"; - private static final String CCREPORTER_VERSION = "0.9"; + private static final String CCREPORTER_VERSION = "0.9.1"; /** * CodeCovergeReporter will read code code coverage result files and http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/dcb771fb/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/CoverageSummary.java ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/CoverageSummary.java b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/CoverageSummary.java index ddf01a6..04e0c47 100755 --- a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/CoverageSummary.java +++ b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/CoverageSummary.java @@ -91,7 +91,7 @@ public class CoverageSummary /** * Summary information for all packages being reported. */ - private final SummaryInfo overall = new SummaryInfo(); + private final SummaryInfo overall = new AggregateSummaryInfo(); /** * Association of methods in a file. http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/dcb771fb/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/PackageSummaryInfo.java ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/PackageSummaryInfo.java b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/PackageSummaryInfo.java index 6e1fcdc..99347e4 100755 --- a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/PackageSummaryInfo.java +++ b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/PackageSummaryInfo.java @@ -29,7 +29,7 @@ import java.util.TreeSet; public class PackageSummaryInfo { private Set<String> filesInPackage = new TreeSet<String>(); - private SummaryInfo summaryInfo = new SummaryInfo(); + private SummaryInfo summaryInfo = new AggregateSummaryInfo(); /** * Set of files in a package. http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/dcb771fb/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/SummaryInfo.java ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/SummaryInfo.java b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/SummaryInfo.java index 08e490a..89a88db 100755 --- a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/SummaryInfo.java +++ b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/SummaryInfo.java @@ -27,7 +27,7 @@ import java.util.TreeSet; * Simple value class to record summary information on the lines executed vs the * total number of lines. * - * This information can be used for reporting at the package, file, and method + * This information can be used for reporting at the file and method * level. * * 1. total executed lines @@ -143,10 +143,6 @@ public class SummaryInfo if (executedLineSet.contains(lineNumber)) return; - // fixup method name that were not executed. - if (methodName == null) - methodName = ""; - if (executed) { unexecutedLineSet.remove(lineNumber); @@ -166,7 +162,7 @@ public class SummaryInfo // ignore empty method names. // these are cinit and script init methods. - if (!methodName.isEmpty()) + if (!methodName.isEmpty() && !executedMethodSet.contains(methodName)) unexecutedMethodSet.add(methodName); } } http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/dcb771fb/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/reports/XMLReportWriter.java ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/reports/XMLReportWriter.java b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/reports/XMLReportWriter.java index aeeec72..ddc0e52 100755 --- a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/reports/XMLReportWriter.java +++ b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/reports/XMLReportWriter.java @@ -167,7 +167,6 @@ public class XMLReportWriter implements IReportWriter xmlWriter.writeAttribute("name", summaryInfo.getName()); outputLineCoverage(xmlWriter, summaryInfo, false); - outputMethodCoverage(xmlWriter, summaryInfo, false); xmlWriter.writeEndElement(); } http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/dcb771fb/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/swf/DebugLineVisitor.java ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/swf/DebugLineVisitor.java b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/swf/DebugLineVisitor.java index 648e19b..5012112 100755 --- a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/swf/DebugLineVisitor.java +++ b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/reporter/swf/DebugLineVisitor.java @@ -22,16 +22,20 @@ package org.apache.flex.tools.codecoverage.reporter.swf; import org.apache.flex.abc.ABCConstants; import org.apache.flex.abc.Pool; import org.apache.flex.abc.instructionlist.InstructionList; +import org.apache.flex.abc.semantics.ClassInfo; import org.apache.flex.abc.semantics.ExceptionInfo; +import org.apache.flex.abc.semantics.InstanceInfo; import org.apache.flex.abc.semantics.Instruction; import org.apache.flex.abc.semantics.Label; import org.apache.flex.abc.semantics.MethodBodyInfo; import org.apache.flex.abc.semantics.MethodInfo; import org.apache.flex.abc.semantics.Name; +import org.apache.flex.abc.visitors.IClassVisitor; import org.apache.flex.abc.visitors.IMethodBodyVisitor; import org.apache.flex.abc.visitors.IMethodVisitor; import org.apache.flex.abc.visitors.ITraitsVisitor; import org.apache.flex.abc.visitors.NilABCVisitor; +import org.apache.flex.abc.visitors.NilMethodBodyVisitor; import org.apache.flex.abc.visitors.NilVisitors; import org.apache.flex.tools.codecoverage.reporter.CoverageData; @@ -46,7 +50,11 @@ public class DebugLineVisitor extends NilABCVisitor private final Pool<String> stringPool = new Pool<String>(Pool.DefaultType.HasDefaultZero); private final CoverageData coverageData; - + + // The current class information + private String currentCtorName; + private boolean currentClassIsInterface; + /** * Constructor * @@ -60,6 +68,19 @@ public class DebugLineVisitor extends NilABCVisitor } @Override + public IClassVisitor visitClass(InstanceInfo iinfo, ClassInfo cinfo) + { + currentClassIsInterface = (iinfo.flags & ABCConstants.CONSTANT_ClassInterface) != 0; + + if (currentClassIsInterface) + currentCtorName = null; + else + currentCtorName = "/" + iinfo.name.getBaseName(); + + return NilVisitors.NIL_CLASS_VISITOR; + } + + @Override public IMethodVisitor visitMethod(MethodInfo minfo) { return new MethodVisitor(); @@ -89,7 +110,51 @@ public class DebugLineVisitor extends NilABCVisitor @Override public IMethodBodyVisitor visitBody(MethodBodyInfo mbInfo) { - return new MethodBodyVisitor(mbInfo); + MethodInfo methodInfo = mbInfo.getMethodInfo(); + String methodName = methodInfo.getMethodName(); + + // ignore class inits, scripts inits, interfaces, and + // constructors. + if (ignoreMethod(methodName)) + { + return new MyNilMethodBodyVisitor(mbInfo); + } + else + { + return new MethodBodyVisitor(mbInfo); + } + } + + /** + * Ignore class inits, script inits, interfaces, and constructors. + * @param methodName The name of the method. + * @return true to ignore the method, false otherwise. + */ + private boolean ignoreMethod(String methodName) + { + return methodName == null || + methodName.length() == 0 || + currentClassIsInterface || + (currentCtorName != null && + methodName.endsWith(currentCtorName)); + } + } + + private class MyNilMethodBodyVisitor extends NilMethodBodyVisitor + { + private final MethodBodyInfo mbInfo; + + public MyNilMethodBodyVisitor(MethodBodyInfo mbInfo) + { + this.mbInfo = mbInfo; + } + + @Override + public int visitException(Label from, Label to, Label target, + Name exception_type, Name catch_var) + { + return mbInfo.addExceptionInfo(new ExceptionInfo(from, to, target, + exception_type, catch_var)); } } http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/dcb771fb/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/server/CodeCoverageServer.java ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/server/CodeCoverageServer.java b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/server/CodeCoverageServer.java index faea9c3..c55fb77 100755 --- a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/server/CodeCoverageServer.java +++ b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/server/CodeCoverageServer.java @@ -40,6 +40,10 @@ import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.io.FileUtils; /** * Main class of the Code Coverage Server. @@ -85,6 +89,16 @@ public class CodeCoverageServer public static final String ERROR_RESPONSE = "-1"; /** + * Command line options + */ + + /** + * Controls whether the server removes all existing data files on startup + * or appends to the existing data files. + */ + public static final String OPTION_APPEND = "-append"; + + /** * Default configuration values */ private static final String DEFAULT_HOST = "localhost"; @@ -107,11 +121,12 @@ public class CodeCoverageServer private static final boolean ADD_PRELOADSWF_KEY = true; private static final boolean REMOVE_PRELOADSWF_KEY = false; - private static final String CCSERVER_VERSION = "0.9"; + private static final String CCSERVER_VERSION = "0.9.1"; private static boolean start; private static boolean stop; - + private static boolean append = false; + /** * @param args */ @@ -137,20 +152,23 @@ public class CodeCoverageServer if (args.length == 0 || args.length == 1 && "-help".equals(args[0])) { - System.out.println("Usage: ccserver [start | stop]"); + System.out.println("Usage: ccserver [-append] [start | stop]"); return ExitCode.HELP.getExitCode(); } try { - if (!initializeProperties()) + if (!initializeProperties() || + !processArgs(args)) + { return ExitCode.INVALID_OPTIONS.getExitCode(); + } - processArgs(args); if (start) start(); else if (stop) stop(); + } catch (IOException e) { @@ -181,12 +199,22 @@ public class CodeCoverageServer { } - private void processArgs(final String[] args) + /** + * Process commmand line args. + * @param args + * @return true if the args are correct, false if there were errors. + */ + private boolean processArgs(final String[] args) { for (final String arg : args) { switch (arg) { + case OPTION_APPEND: + { + append = true; + break; + } case START_COMMAND: { start = true; @@ -199,10 +227,17 @@ public class CodeCoverageServer } default: { - System.err.println("unexpected argument " + arg); + System.err.println("unexpected argument: " + arg); + return false; } } } + + // start is the default action. + if (!start && !stop) + start = true; + + return true; } /** @@ -238,12 +273,14 @@ public class CodeCoverageServer } } + int fileCount = initDataDirectory(dataDirectory); + // modify mm.cfg file updateMMCFG(ADD_PRELOADSWF_KEY); // create thread to listen for connections on the data port final DataSocketAccepter dataSocketAccepter = - new DataSocketAccepter(host, dataPort, dataDirectory); + new DataSocketAccepter(host, dataPort, dataDirectory, fileCount); final Thread dataThread = new Thread(dataSocketAccepter); dataThread.start(); @@ -290,6 +327,51 @@ public class CodeCoverageServer } /** + * Either remove all files or if -append is set then figure out + * which number to start incrementing at. + * + * @param dataDirectory + * @throws IOException + */ + private int initDataDirectory(File dataDirectory) throws IOException + { + int maxFileIndex = 0; + Pattern filenamePattern = Pattern.compile("ccdata_(\\d+)\\.txt"); + + if (append) + { + + String[] filenames = dataDirectory.list(); + for (String filename : filenames) + { + Matcher matcher = filenamePattern.matcher(filename); + boolean matches = matcher.matches(); + if (matches) + { + try + { + String indexString = matcher.group(1); + int value = Integer.parseInt(indexString); + if (value >= maxFileIndex) + maxFileIndex = value + 1; + } + catch (Exception e) + { + // ignore + } + } + } + + } + else + { + FileUtils.cleanDirectory(dataDirectory); + } + + return maxFileIndex; + } + + /** * Process a server command. * * @param reader The socket reader. http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/dcb771fb/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/server/DataSocketAccepter.java ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/server/DataSocketAccepter.java b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/server/DataSocketAccepter.java index 1de9992..879c1b2 100755 --- a/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/server/DataSocketAccepter.java +++ b/CodeCoverage/JavaServer/java/src/org/apache/flex/tools/codecoverage/server/DataSocketAccepter.java @@ -42,7 +42,7 @@ public class DataSocketAccepter implements Runnable private Thread dataSocketReader; private volatile boolean listening = true; private final File dataDirectory; - private int fileCount = 0; + private int fileCount; private Socket currentSocket; private final String host; private final int dataPort; @@ -56,7 +56,7 @@ public class DataSocketAccepter implements Runnable * Each new connection results in a new file created in this directory. */ public DataSocketAccepter(final String host, final int dataPort, - final File dataDirectory) + final File dataDirectory, final int fileCount) { if (dataDirectory == null) @@ -65,6 +65,7 @@ public class DataSocketAccepter implements Runnable this.host = host; this.dataPort = dataPort; this.dataDirectory = dataDirectory; + this.fileCount = fileCount; } /**