mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

boli
21.18.2006 367d26919e0cfe9a315f6dbea606798ec516d91d
Adds a tool to show svn diff output annotated with EMMA coverage information. To use the tool, just pipe the unified diff output from 'svn diff' to build-tools/bin/coveragediff.

Fix for issue 680
1 files modified
2 files added
504 ■■■■■ changed files
opendj-sdk/opends/build-tools/bin/coveragediff 61 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/build-tools/src/org/opends/build/tools/CoverageDiff.java 439 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/build.xml 4 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/build-tools/bin/coveragediff
New file
@@ -0,0 +1,61 @@
#!/bin/sh
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (the "License").  You may not use this file except in compliance
# with the License.
#
# You can obtain a copy of the license at
# trunk/opends/resource/legal-notices/OpenDS.LICENSE
# or https://OpenDS.dev.java.net/OpenDS.LICENSE.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at
# trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
# add the following below this CDDL HEADER, with the fields enclosed
# by brackets "[]" replaced with your own identifying * information:
#      Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
#      Portions Copyright 2006 Sun Microsystems, Inc.
# Capture this script's directory
ROOT_DIR=`dirname $0`/../../
# See if JAVA_HOME is set.  If not, then see if there is a java executable in
# the path and try to figure it out.
if test -z "${JAVA_BIN}"
then
  if test -z "${JAVA_HOME}"
  then
    JAVA_BIN=`which java 2> /dev/null`
    if test ${?} -eq 0
    then
      export JAVA_BIN
    else
      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
      exit 1
    fi
  else
    JAVA_BIN=${JAVA_HOME}/bin/java
    export JAVA_BIN
  fi
fi
CLASSPATH=${ROOT_DIR}/ext/build-tools.jar:${ROOT_DIR}/ext/emma/lib/emma.jar
export CLASSPATH
EMMADATAPATH=${ROOT_DIR}/build/coverage/gathereddata/
cd `pwd`
echo ${CLASSPATH}
# Launch the setup process.
"${JAVA_BIN}" ${JAVA_ARGS} org.opends.build.tools.CoverageDiff ${EMMADATAPATH}
opendj-sdk/opends/build-tools/src/org/opends/build/tools/CoverageDiff.java
New file
@@ -0,0 +1,439 @@
package org.opends.build.tools;
import com.vladium.emma.*;
import com.vladium.emma.report.*;
import com.vladium.emma.data.*;
import com.vladium.util.IntObjectMap;
import java.io.*;
import java.util.Iterator;
import java.util.ArrayList;
public class CoverageDiff {
  private static boolean verbose = false;
  public static void main(String[] args) {
    if(args.length < 1 || args[0] == null)
    {
      System.out.println("Please specify emma data location");
      return;
    }
    IReportDataView emmaDataView = null;
    try
    {
      emmaDataView = loadEmmaData(new File(args[0].trim()));
    }
    catch(IOException ie)
    {
      System.out.println("An error occured while loading EMMA data: " + ie.toString());
    }
    if(emmaDataView == null)
    {
      System.out.println(System.in);
    }
    else
    {
      try
      {
        processDiffOutput(new BufferedReader(new InputStreamReader(System.in)), emmaDataView);
      }
      catch(IOException ie)
      {
        System.out.println("An error occured while processing diff output: " + ie.toString());
      }
    }
  }
  private static IReportDataView loadEmmaData(File emmaCoverageDataDir) throws IOException {
    File[] emmaCoverageDataFiles = emmaCoverageDataDir.listFiles();
    int emmaCoverageDataFileCount = 0;
    IReportDataView m_view = null;
    IMetaData mdata = null;
    ICoverageData cdata = null;
    if(emmaCoverageDataFiles == null || emmaCoverageDataFiles.length <= 0)
    {
      throw new IOException("No EMMA data files found");
    }
    if (verbose) System.out.println("processing input files ...");
    final long start = verbose ? System.currentTimeMillis() : 0;
    // merge all data files:
    for (int f = 0; f < emmaCoverageDataFiles.length; ++f) {
      final File dataFile = emmaCoverageDataFiles[f];
      if (verbose)
        System.out.println("processing input file [" + dataFile.getAbsolutePath() + "] ...");
      final IMergeable[] fileData = DataFactory.load(dataFile);
      final IMetaData _mdata = (IMetaData) fileData[DataFactory.TYPE_METADATA];
      if (_mdata != null) {
        if (verbose)
          System.out.println("  loaded " + _mdata.size() + " metadata entries");
        if (mdata == null)
          mdata = _mdata;
        else
          mdata = (IMetaData) mdata.merge(_mdata); // note: later datapath entries override earlier ones
      }
      final ICoverageData _cdata = (ICoverageData) fileData[DataFactory.TYPE_COVERAGEDATA];
      if (_cdata != null) {
        if (verbose)
          System.out.println("  loaded " + _cdata.size() + " coverage data entries");
        if (cdata == null)
          cdata = _cdata;
        else
          cdata = (ICoverageData) cdata.merge(_cdata); // note: later datapath entries override earlier ones
      }
      ++emmaCoverageDataFileCount;
    }
    if (verbose) {
      final long end = System.currentTimeMillis();
      System.out.println(emmaCoverageDataFileCount + " file(s) read and merged in " + (end - start) + " ms");
    }
    if ((mdata == null) || mdata.isEmpty()) {
      System.out.println("nothing to do: no metadata found in any of the data files");
      return null;
    }
    if (cdata == null) {
      System.out.println("nothing to do: no runtime coverage data found in any of the data files");
      return null;
    }
    if (cdata.isEmpty()) {
      System.out.println("no collected coverage data found in any of the data files [Diff output will not include coverage data]");
      return null;
    }
    if (!mdata.hasLineNumberData() || !mdata.hasSrcFileData()) {
      System.out.println("no collected line coverage data found in any of the data files [Diff output will not include coverage data]");
      return null;
    }
    final IReportDataModel model = IReportDataModel.Factory.create (mdata, cdata);
    m_view = model.getView (IReportDataView.HIER_SRC_VIEW);
    if (verbose) {
      if (mdata != null) {
        System.out.println("  merged metadata contains " + mdata.size() + " entries");
      }
      if (cdata != null) {
        System.out.println("  merged coverage data contains " + cdata.size() + " entries");
      }
    }
    return m_view;
  }
  private static BufferedReader getDiffOutputReader() throws IOException {
    Process child = Runtime.getRuntime().exec("svn diff");
    InputStream diffOutputStream = child.getInputStream();
    BufferedReader diffOutput = new BufferedReader(
        new InputStreamReader(diffOutputStream));
    return diffOutput;
  }
  private static void processDiffOutput(BufferedReader diffOutput,
                                        IReportDataView emmaDataView)
      throws IOException {
    String line = diffOutput.readLine();
    ArrayList<String> diffOutputFile = new ArrayList<String>();
    while(line != null)
    {
      //Diffed file
      if(line.length() >6 && line.substring(0, 6).equals("Index:"))
      {
        processDiffOutputFile(diffOutputFile, emmaDataView);
        diffOutputFile = new ArrayList<String>();
        diffOutputFile.add(line);
      }
      else
      {
        diffOutputFile.add(line);
      }
      line = diffOutput.readLine();
    }
    processDiffOutputFile(diffOutputFile, emmaDataView);
  }
  private static void processDiffOutputFile(ArrayList<String> diffFile,
                                            IReportDataView emmaDataView)
      throws IOException
  {
    if(diffFile.size() <= 0)
    {
      return;
    }
    String fileHeader = diffFile.get(0);
    File srcFilePath = new File(fileHeader.substring(7));
    FileInputStream srcFile = new FileInputStream(srcFilePath);
    String srcFilePackage = parseJavaPackage(srcFile);
    SrcFileItem emmaSourceItem = getEmmaSrcItem(emmaDataView.getRoot(),
                  srcFilePackage, srcFilePath.getName());
    if(emmaSourceItem == null)
    {
      System.out.println(fileHeader);
      System.out.println("Coverage: Not Available");
      for(int i = 1; i < diffFile.size(); i++)
      {
        System.out.println(diffFile.get(i));
      }
    }
    else
    {
      System.out.println(fileHeader);
      System.out.print("Coverage: ");
      String name;
      StringBuffer buf = new StringBuffer();
      for(int i = 1; i <= 4; i++)
      {
        buf.setLength(0);
        emmaSourceItem.getAttribute(i, 0).format(emmaSourceItem, buf);
        name = emmaSourceItem.getAttribute(i, 0).getName();
        System.out.print(name);
        for(int j = 0; j < buf.length() - name.length() + 1; j++)
        {
          System.out.print(" ");
        }
      }
      System.out.print("\n          ");
      for(int i = 1; i <= 4; i++)
      {
        buf.setLength(0);
        emmaSourceItem.getAttribute(i, 0).format(emmaSourceItem, buf);
        System.out.print(buf + " ");
      }
      System.out.println("");
      System.out.println(diffFile.get(1));
      //Figure out the flag for the working copy.
      String workingCopyFlag = null;
      String otherCopyFlag = null;
      String firstFileLine = diffFile.get(2);
      String secondFileLine = diffFile.get(3);
      System.out.println(firstFileLine);
      System.out.println(secondFileLine);
      if(firstFileLine.endsWith("(working copy)"))
      {
        workingCopyFlag = firstFileLine.substring(0, 1);
      }
      else
      {
        otherCopyFlag = firstFileLine.substring(0, 1);
      }
      if(secondFileLine.endsWith("(working copy)"))
      {
        workingCopyFlag = secondFileLine.substring(0, 1);
      }
      else
      {
        otherCopyFlag = secondFileLine.substring(0, 1);
      }
      if(firstFileLine.endsWith("(revision 0)") &&
          secondFileLine.endsWith("(revision 0)"))
      {
        workingCopyFlag = "+";
        otherCopyFlag = "-";
      }
      if(workingCopyFlag == null || otherCopyFlag == null ||
          srcFilePackage == null)
      {
        for(int i = 4; i < diffFile.size(); i++)
        {
          System.out.println(diffFile.get(i));
        }
      }
      else
      {
        ArrayList<String> diffOutputChunk = new ArrayList<String>();
        for(int i = 4; i < diffFile.size(); i++)
        {
          //Found a chunk indicator.
          if(diffFile.get(i).startsWith("@@"))
          {
            processDiffOutputFileChunk(diffOutputChunk, workingCopyFlag,
                otherCopyFlag, emmaSourceItem);
            diffOutputChunk = new ArrayList<String>();
            diffOutputChunk.add(diffFile.get(i));
          }
          //Not any of the above so this line must be diffed text
          else
          {
            diffOutputChunk.add(diffFile.get(i));
          }
        }
        //Finishing process whatever we have queued up
        processDiffOutputFileChunk(diffOutputChunk, workingCopyFlag,
            otherCopyFlag, emmaSourceItem);
      }
    }
  }
  private static void processDiffOutputFileChunk(ArrayList<String> diffChunk,
                                                 String workingCopyFlag,
                                                 String otherCopyFlag,
                                                 SrcFileItem emmaSrcItem)
  {
    if(diffChunk.size() <= 0)
    {
      return;
    }
    int workingCopyBegin;
    int workingCopyRange;
    int otherCopyBegin;
    int otherCopyRange;
    IntObjectMap lineCoverageMap = null;
    if(emmaSrcItem != null)
    {
      lineCoverageMap = emmaSrcItem.getLineCoverage ();
    }
    String chunkHeader = diffChunk.get(0);
    System.out.println(chunkHeader);
    int workingCopyBeginIdx = chunkHeader.indexOf(workingCopyFlag);
    int workingCopyCommaIdx = chunkHeader.indexOf(",", workingCopyBeginIdx);
    int workingCopyEndIdx = chunkHeader.indexOf(" ", workingCopyCommaIdx);
    int otherCopyBeginIdx = chunkHeader.indexOf(otherCopyFlag);
    int otherCopyCommaIdx = chunkHeader.indexOf(",", otherCopyBeginIdx);
    int otherCopyEndIdx = chunkHeader.indexOf(" ", otherCopyCommaIdx);
    workingCopyBegin = Integer.parseInt(
        chunkHeader.substring(workingCopyBeginIdx + 1, workingCopyCommaIdx));
    workingCopyRange = Integer.parseInt(
        chunkHeader.substring(workingCopyCommaIdx + 1, workingCopyEndIdx));
    otherCopyBegin = Integer.parseInt(
        chunkHeader.substring(otherCopyBeginIdx + 1, otherCopyCommaIdx));
    otherCopyRange = Integer.parseInt(
        chunkHeader.substring(otherCopyCommaIdx + 1, otherCopyEndIdx));
    String chunkLine;
    SrcFileItem.LineCoverageData lCoverageData = null;
    int workingCopyLineIncrement = 0;
    int otherCopyLineIncrement = 0;
    for(int i = 1; i < diffChunk.size(); i++)
    {
      chunkLine = diffChunk.get(i);
      //System.out.print(workingCopyBegin + workingCopyLineIncrement + " ");
      if(lineCoverageMap != null)
      {
        lCoverageData = (SrcFileItem.LineCoverageData) lineCoverageMap.get (workingCopyBegin + workingCopyLineIncrement);
      }
      if(!chunkLine.startsWith(otherCopyFlag) && lCoverageData != null)
      {
        switch(lCoverageData.m_coverageStatus)
        {
          case SrcFileItem.LineCoverageData.LINE_COVERAGE_ZERO:
            System.out.println(chunkLine.charAt(0) + "N" + chunkLine.substring(1));
            break;
          case SrcFileItem.LineCoverageData.LINE_COVERAGE_PARTIAL:
            System.out.println(chunkLine.charAt(0) + "P" + chunkLine.substring(1));
            break;
          case SrcFileItem.LineCoverageData.LINE_COVERAGE_COMPLETE:
            System.out.println(chunkLine.charAt(0) + "C" + chunkLine.substring(1));
            break;
          default:
            System.out.println(chunkLine.charAt(0) + "U" + chunkLine.substring(1));
        }
      }
      else
      {
        System.out.println(chunkLine.charAt(0) + " " + chunkLine.substring(1));
      }
      if(!chunkLine.startsWith(otherCopyFlag))
      {
        workingCopyLineIncrement++;
      }
      if(!chunkLine.startsWith(workingCopyFlag))
      {
        otherCopyLineIncrement++;
      }
    }
  }
  private static String parseJavaPackage(FileInputStream srcFile)
      throws IOException {
    BufferedReader srcFileReader = new BufferedReader(
        new InputStreamReader(srcFile));
    String line = srcFileReader.readLine();
    while(line != null)
    {
      int beginIdx = line.indexOf("package");
      if(beginIdx > -1)
      {
        int endIdx = line.indexOf(";", beginIdx);
        if(endIdx > -1)
        {
          return  line.substring(beginIdx + 7, endIdx).trim();
        }
      }
      line = srcFileReader.readLine();
    }
    return null;
  }
  private static SrcFileItem getEmmaSrcItem(IItem rootItem,
                                      String srcPackageName,
                                      String srcFileName)
  {
    for(Iterator packages = rootItem.getChildren(); packages.hasNext();)
    {
      IItem packageItem = (IItem)packages.next();
      if(packageItem.getName().equals(srcPackageName))
      {
        for(Iterator sources = packageItem.getChildren(); sources.hasNext();)
        {
          SrcFileItem sourceItem = (SrcFileItem)sources.next();
          if(sourceItem.getName().equals(srcFileName))
          {
            return sourceItem;
          }
        }
      }
    }
    return null;
  }
}
opendj-sdk/opends/build.xml
@@ -854,6 +854,10 @@
        <fileset dir="${ant.lib.dir}">
          <include name="*.jar" />
        </fileset>
        <fileset dir="${emma.dir}">
          <include name="*.jar" />
        </fileset>
        <path refid="run.classpath" />
      </classpath>
    </javac>