Coverage Report - net.sourceforge.cobertura.check.Main
 
Classes in this File Line Coverage Branch Coverage Complexity
Main
0%
0/131
0%
0/76
4
 
 1  
 /*
 2  
  * Cobertura - http://cobertura.sourceforge.net/
 3  
  *
 4  
  * Copyright (C) 2003 jcoverage ltd.
 5  
  * Copyright (C) 2005 Mark Doliner
 6  
  * Copyright (C) 2005 Nathan Wilson
 7  
  *
 8  
  * Cobertura is free software; you can redistribute it and/or modify
 9  
  * it under the terms of the GNU General Public License as published
 10  
  * by the Free Software Foundation; either version 2 of the License,
 11  
  * or (at your option) any later version.
 12  
  *
 13  
  * Cobertura is distributed in the hope that it will be useful, but
 14  
  * WITHOUT ANY WARRANTY; without even the implied warranty of
 15  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 16  
  * General Public License for more details.
 17  
  *
 18  
  * You should have received a copy of the GNU General Public License
 19  
  * along with Cobertura; if not, write to the Free Software
 20  
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 21  
  * USA
 22  
  */
 23  
 
 24  
 package net.sourceforge.cobertura.check;
 25  
 
 26  
 import java.io.File;
 27  
 import java.math.BigDecimal;
 28  
 import java.util.HashMap;
 29  
 import java.util.Iterator;
 30  
 import java.util.Map;
 31  
 import java.util.StringTokenizer;
 32  
 
 33  
 import net.sourceforge.cobertura.coveragedata.ClassData;
 34  
 import net.sourceforge.cobertura.coveragedata.CoverageDataFileHandler;
 35  
 import net.sourceforge.cobertura.coveragedata.ProjectData;
 36  
 import net.sourceforge.cobertura.util.Header;
 37  
 
 38  
 import org.apache.log4j.Logger;
 39  
 import org.apache.oro.text.regex.MalformedPatternException;
 40  
 import org.apache.oro.text.regex.Pattern;
 41  
 import org.apache.oro.text.regex.Perl5Compiler;
 42  
 import org.apache.oro.text.regex.Perl5Matcher;
 43  
 
 44  
 public class Main
 45  
 {
 46  
 
 47  0
         private static final Logger logger = Logger.getLogger(Main.class);
 48  
 
 49  0
         final Perl5Matcher pm = new Perl5Matcher();
 50  
 
 51  0
         final Perl5Compiler pc = new Perl5Compiler();
 52  
 
 53  
         /**
 54  
          * The default CoverageRate needed for a class to pass the check.
 55  
          */
 56  
         CoverageRate minimumCoverageRate;
 57  
 
 58  
         /**
 59  
          * The keys of this map contain regular expression Patterns that
 60  
          * match against classes.  The values of this map contain
 61  
          * CoverageRate objects that specify the minimum coverage rates
 62  
          * needed for a class that matches the pattern.
 63  
          */
 64  0
         Map minimumCoverageRates = new HashMap();
 65  
 
 66  
         /**
 67  
          * The keys of this map contain package names. The values of this 
 68  
          * map contain PackageCoverage objects that track the line and
 69  
          * branch coverage values for a package.
 70  
          */
 71  0
         Map packageCoverageMap = new HashMap();
 72  
 
 73  
         double inRangeAndDivideByOneHundred(String coverageRateAsPercentage)
 74  
         {
 75  0
                 return inRangeAndDivideByOneHundred(Integer.valueOf(
 76  
                                 coverageRateAsPercentage).intValue());
 77  
         }
 78  
 
 79  
         double inRangeAndDivideByOneHundred(int coverageRateAsPercentage)
 80  
         {
 81  0
                 if ((coverageRateAsPercentage >= 0)
 82  
                                 && (coverageRateAsPercentage <= 100))
 83  
                 {
 84  0
                         return (double)coverageRateAsPercentage / 100;
 85  
                 }
 86  0
                 throw new IllegalArgumentException("The value "
 87  
                                 + coverageRateAsPercentage
 88  
                                 + "% is invalid.  Percentages must be between 0 and 100.");
 89  
         }
 90  
 
 91  
         void setMinimumCoverageRate(String minimumCoverageRate)
 92  
                         throws MalformedPatternException
 93  
         {
 94  0
                 StringTokenizer tokenizer = new StringTokenizer(minimumCoverageRate,
 95  
                                 ":");
 96  0
                 this.minimumCoverageRates.put(pc.compile(tokenizer.nextToken()),
 97  
                                 new CoverageRate(inRangeAndDivideByOneHundred(tokenizer
 98  
                                                 .nextToken()), inRangeAndDivideByOneHundred(tokenizer
 99  
                                                 .nextToken())));
 100  0
         }
 101  
 
 102  
         /**
 103  
          * This method returns the CoverageRate object that
 104  
          * applies to the given class.  If checks if there is a
 105  
          * pattern that matches the class name, and returns that
 106  
          * if it finds one.  Otherwise it uses the global minimum
 107  
          * rates that were passed in.
 108  
          */
 109  
         CoverageRate findMinimumCoverageRate(String classname)
 110  
         {
 111  0
                 Iterator iter = this.minimumCoverageRates.entrySet().iterator();
 112  0
                 while (iter.hasNext())
 113  
                 {
 114  0
                         Map.Entry entry = (Map.Entry)iter.next();
 115  
 
 116  0
                         if (pm.matches(classname, (Pattern)entry.getKey()))
 117  
                         {
 118  0
                                 return (CoverageRate)entry.getValue();
 119  
                         }
 120  0
                 }
 121  0
                 return this.minimumCoverageRate;
 122  
         }
 123  
 
 124  
         public Main(String[] args) throws MalformedPatternException
 125  0
         {
 126  0
                 int exitStatus = 0;
 127  
 
 128  0
                 Header.print(System.out);
 129  
 
 130  0
                 File dataFile = CoverageDataFileHandler.getDefaultDataFile();
 131  0
                 double branchCoverageRate = 0.0;
 132  0
                 double lineCoverageRate = 0.0;
 133  0
                 double packageBranchCoverageRate = 0.0;
 134  0
                 double packageLineCoverageRate = 0.0;
 135  0
                 double totalBranchCoverageRate = 0.0;
 136  0
                 double totalLineCoverageRate = 0.0;
 137  
 
 138  0
                 for (int i = 0; i < args.length; i++)
 139  
                 {
 140  0
                         if (args[i].equals("--branch"))
 141  
                         {
 142  0
                                 branchCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
 143  0
                         }
 144  0
                         else if (args[i].equals("--datafile"))
 145  
                         {
 146  0
                                 dataFile = new File(args[++i]);
 147  0
                         }
 148  0
                         else if (args[i].equals("--line"))
 149  
                         {
 150  0
                                 lineCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
 151  0
                         }
 152  0
                         else if (args[i].equals("--regex"))
 153  
                         {
 154  0
                                 setMinimumCoverageRate(args[++i]);
 155  0
                         }
 156  0
                         else if (args[i].equals("--packagebranch"))
 157  
                         {
 158  0
                                 packageBranchCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
 159  0
                         }
 160  0
                         else if (args[i].equals("--packageline"))
 161  
                         {
 162  0
                                 packageLineCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
 163  0
                         }
 164  0
                         else if (args[i].equals("--totalbranch"))
 165  
                         {
 166  0
                                 totalBranchCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
 167  0
                         }
 168  0
                         else if (args[i].equals("--totalline"))
 169  
                         {
 170  0
                                 totalLineCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
 171  
                         }
 172  
                 }
 173  
 
 174  0
                 ProjectData projectData = CoverageDataFileHandler
 175  
                                 .loadCoverageData(dataFile);
 176  
 
 177  0
                 if (projectData == null)
 178  
                 {
 179  0
                         System.err.println("Error: Unable to read from data file "
 180  
                                         + dataFile.getAbsolutePath());
 181  0
                         System.exit(1);
 182  
                 }
 183  
 
 184  
                 // If they didn't specify any thresholds, then use some defaults
 185  0
                 if ((branchCoverageRate == 0) && (lineCoverageRate == 0)
 186  
                                 && (packageLineCoverageRate == 0)
 187  
                                 && (packageBranchCoverageRate == 0)
 188  
                                 && (totalLineCoverageRate == 0)
 189  
                                 && (totalBranchCoverageRate == 0)
 190  
                                 && (this.minimumCoverageRates.size() == 0))
 191  
                 {
 192  0
                         branchCoverageRate = 0.5;
 193  0
                         lineCoverageRate = 0.5;
 194  0
                         packageBranchCoverageRate = 0.5;
 195  0
                         packageLineCoverageRate = 0.5;
 196  0
                         totalBranchCoverageRate = 0.5;
 197  0
                         totalLineCoverageRate = 0.5;
 198  
                 }
 199  
 
 200  0
                 this.minimumCoverageRate = new CoverageRate(lineCoverageRate,
 201  
                                 branchCoverageRate);
 202  
 
 203  0
                 double totalLines = 0;
 204  0
                 double totalLinesCovered = 0;
 205  0
                 double totalBranches = 0;
 206  0
                 double totalBranchesCovered = 0;
 207  
 
 208  0
                 Iterator iter = projectData.getClasses().iterator();
 209  0
                 while (iter.hasNext())
 210  
                 {
 211  0
                         ClassData classData = (ClassData)iter.next();
 212  0
                         CoverageRate coverageRate = findMinimumCoverageRate(classData
 213  
                                         .getName());
 214  
 
 215  0
                         if (totalBranchCoverageRate > 0.0)
 216  
                         {
 217  0
                                 totalBranches += classData.getNumberOfValidBranches();
 218  0
                                 totalBranchesCovered += classData.getNumberOfCoveredBranches();
 219  
                         }
 220  
 
 221  0
                         if (totalLineCoverageRate > 0.0)
 222  
                         {
 223  0
                                 totalLines += classData.getNumberOfValidLines();
 224  0
                                 totalLinesCovered += classData.getNumberOfCoveredLines();
 225  
                         }
 226  
 
 227  0
                         PackageCoverage packageCoverage = getPackageCoverage(classData
 228  
                                         .getPackageName());
 229  0
                         if (packageBranchCoverageRate > 0.0)
 230  
                         {
 231  0
                                 packageCoverage.addBranchCount(classData
 232  
                                                 .getNumberOfValidBranches());
 233  0
                                 packageCoverage.addBranchCoverage(classData
 234  
                                                 .getNumberOfCoveredBranches());
 235  
                         }
 236  
 
 237  0
                         if (packageLineCoverageRate > 0.0)
 238  
                         {
 239  0
                                 packageCoverage.addLineCount(classData.getNumberOfValidLines());
 240  0
                                 packageCoverage.addLineCoverage(classData
 241  
                                                 .getNumberOfCoveredLines());
 242  
                         }
 243  
 
 244  0
                         logger.debug("Class " + classData.getName()
 245  
                                         + ", line coverage rate: "
 246  
                                         + percentage(classData.getLineCoverageRate())
 247  
                                         + "%, branch coverage rate: "
 248  
                                         + percentage(classData.getBranchCoverageRate()) + "%");
 249  
 
 250  0
                         if (classData.getBranchCoverageRate() < coverageRate
 251  
                                         .getBranchCoverageRate())
 252  
                         {
 253  0
                                 System.err.println(classData.getName()
 254  
                                                 + " failed check. Branch coverage rate of "
 255  
                                                 + percentage(classData.getBranchCoverageRate())
 256  
                                                 + "% is below "
 257  
                                                 + percentage(coverageRate.getBranchCoverageRate())
 258  
                                                 + "%");
 259  0
                                 exitStatus |= 2;
 260  
                         }
 261  
 
 262  0
                         if (classData.getLineCoverageRate() < coverageRate
 263  
                                         .getLineCoverageRate())
 264  
                         {
 265  0
                                 System.err.println(classData.getName()
 266  
                                                 + " failed check. Line coverage rate of "
 267  
                                                 + percentage(classData.getLineCoverageRate())
 268  
                                                 + "% is below "
 269  
                                                 + percentage(coverageRate.getLineCoverageRate()) + "%");
 270  0
                                 exitStatus |= 4;
 271  
                         }
 272  0
                 }
 273  
 
 274  0
                 exitStatus |= checkPackageCoverageLevels(packageBranchCoverageRate,
 275  
                                 packageLineCoverageRate);
 276  
 
 277  
                 // Check the rates for the overal project
 278  0
                 if ((totalBranches > 0)
 279  
                                 && (totalBranchCoverageRate > (totalBranchesCovered / totalBranches)))
 280  
                 {
 281  0
                         System.err
 282  
                                         .println("Project failed check. "
 283  
                                                         + "Total branch coverage rate of "
 284  
                                                         + percentage(totalBranchesCovered / totalBranches)
 285  
                                                         + "% is below "
 286  
                                                         + percentage(totalBranchCoverageRate) + "%");
 287  0
                         exitStatus |= 8;
 288  
                 }
 289  
 
 290  0
                 if ((totalLines > 0)
 291  
                                 && (totalLineCoverageRate > (totalLinesCovered / totalLines)))
 292  
                 {
 293  0
                         System.err.println("Project failed check. "
 294  
                                         + "Total line coverage rate of "
 295  
                                         + percentage(totalLinesCovered / totalLines)
 296  
                                         + "% is below " + percentage(totalLineCoverageRate) + "%");
 297  0
                         exitStatus |= 16;
 298  
                 }
 299  
 
 300  0
                 System.exit(exitStatus);
 301  0
         }
 302  
 
 303  
         private PackageCoverage getPackageCoverage(String packageName)
 304  
         {
 305  0
                 PackageCoverage packageCoverage = (PackageCoverage)packageCoverageMap
 306  
                                 .get(packageName);
 307  0
                 if (packageCoverage == null)
 308  
                 {
 309  0
                         packageCoverage = new PackageCoverage();
 310  0
                         packageCoverageMap.put(packageName, packageCoverage);
 311  
                 }
 312  0
                 return packageCoverage;
 313  
         }
 314  
 
 315  
         private int checkPackageCoverageLevels(double packageBranchCoverageRate,
 316  
                         double packageLineCoverageRate)
 317  
         {
 318  0
                 int exitStatus = 0;
 319  0
                 Iterator iter = packageCoverageMap.entrySet().iterator();
 320  0
                 while (iter.hasNext())
 321  
                 {
 322  0
                         Map.Entry entry = (Map.Entry)iter.next();
 323  0
                         String packageName = (String)entry.getKey();
 324  0
                         PackageCoverage packageCoverage = (PackageCoverage)entry.getValue();
 325  
 
 326  0
                         exitStatus |= checkPackageCoverage(packageBranchCoverageRate,
 327  
                                         packageLineCoverageRate, packageName, packageCoverage);
 328  0
                 }
 329  0
                 return exitStatus;
 330  
         }
 331  
 
 332  
         private int checkPackageCoverage(double packageBranchCoverageRate,
 333  
                         double packageLineCoverageRate, String packageName,
 334  
                         PackageCoverage packageCoverage)
 335  
         {
 336  0
                 int exitStatus = 0;
 337  0
                 double branchCoverage = packageCoverage.getBranchCoverage()
 338  
                                 / packageCoverage.getBranchCount();
 339  0
                 if ((packageCoverage.getBranchCount() > 0)
 340  
                                 && (packageBranchCoverageRate > branchCoverage))
 341  
                 {
 342  0
                         System.err.println("Package " + packageName
 343  
                                         + " failed check. Package branch coverage rate of "
 344  
                                         + percentage(branchCoverage) + "% is below "
 345  
                                         + percentage(packageBranchCoverageRate) + "%");
 346  0
                         exitStatus |= 32;
 347  
                 }
 348  
 
 349  0
                 double lineCoverage = packageCoverage.getLineCoverage()
 350  
                                 / packageCoverage.getLineCount();
 351  0
                 if ((packageCoverage.getLineCount() > 0)
 352  
                                 && (packageLineCoverageRate > lineCoverage))
 353  
                 {
 354  0
                         System.err.println("Package " + packageName
 355  
                                         + " failed check. Package line coverage rate of "
 356  
                                         + percentage(lineCoverage) + "% is below "
 357  
                                         + percentage(packageLineCoverageRate) + "%");
 358  0
                         exitStatus |= 64;
 359  
                 }
 360  
 
 361  0
                 return exitStatus;
 362  
         }
 363  
 
 364  
         private String percentage(double coverateRate)
 365  
         {
 366  0
                 BigDecimal decimal = new BigDecimal(coverateRate * 100);
 367  0
                 return decimal.setScale(1, BigDecimal.ROUND_DOWN).toString();
 368  
         }
 369  
 
 370  
         public static void main(String[] args) throws MalformedPatternException
 371  
         {
 372  0
                 new Main(args);
 373  0
         }
 374  
 
 375  
 }