1 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 private static final Logger logger = Logger.getLogger(Main.class); 48 49 final Perl5Matcher pm = new Perl5Matcher(); 50 51 final Perl5Compiler pc = new Perl5Compiler(); 52 53 56 CoverageRate minimumCoverageRate; 57 58 64 Map minimumCoverageRates = new HashMap (); 65 66 71 Map packageCoverageMap = new HashMap (); 72 73 double inRangeAndDivideByOneHundred(String coverageRateAsPercentage) 74 { 75 return inRangeAndDivideByOneHundred(Integer.valueOf( 76 coverageRateAsPercentage).intValue()); 77 } 78 79 double inRangeAndDivideByOneHundred(int coverageRateAsPercentage) 80 { 81 if ((coverageRateAsPercentage >= 0) 82 && (coverageRateAsPercentage <= 100)) 83 { 84 return (double)coverageRateAsPercentage / 100; 85 } 86 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 StringTokenizer tokenizer = new StringTokenizer (minimumCoverageRate, 95 ":"); 96 this.minimumCoverageRates.put(pc.compile(tokenizer.nextToken()), 97 new CoverageRate(inRangeAndDivideByOneHundred(tokenizer 98 .nextToken()), inRangeAndDivideByOneHundred(tokenizer 99 .nextToken()))); 100 } 101 102 109 CoverageRate findMinimumCoverageRate(String classname) 110 { 111 Iterator iter = this.minimumCoverageRates.entrySet().iterator(); 112 while (iter.hasNext()) 113 { 114 Map.Entry entry = (Map.Entry )iter.next(); 115 116 if (pm.matches(classname, (Pattern)entry.getKey())) 117 { 118 return (CoverageRate)entry.getValue(); 119 } 120 } 121 return this.minimumCoverageRate; 122 } 123 124 public Main(String [] args) throws MalformedPatternException 125 { 126 int exitStatus = 0; 127 128 Header.print(System.out); 129 130 File dataFile = CoverageDataFileHandler.getDefaultDataFile(); 131 double branchCoverageRate = 0.0; 132 double lineCoverageRate = 0.0; 133 double packageBranchCoverageRate = 0.0; 134 double packageLineCoverageRate = 0.0; 135 double totalBranchCoverageRate = 0.0; 136 double totalLineCoverageRate = 0.0; 137 138 for (int i = 0; i < args.length; i++) 139 { 140 if (args[i].equals("--branch")) 141 { 142 branchCoverageRate = inRangeAndDivideByOneHundred(args[++i]); 143 } 144 else if (args[i].equals("--datafile")) 145 { 146 dataFile = new File (args[++i]); 147 } 148 else if (args[i].equals("--line")) 149 { 150 lineCoverageRate = inRangeAndDivideByOneHundred(args[++i]); 151 } 152 else if (args[i].equals("--regex")) 153 { 154 setMinimumCoverageRate(args[++i]); 155 } 156 else if (args[i].equals("--packagebranch")) 157 { 158 packageBranchCoverageRate = inRangeAndDivideByOneHundred(args[++i]); 159 } 160 else if (args[i].equals("--packageline")) 161 { 162 packageLineCoverageRate = inRangeAndDivideByOneHundred(args[++i]); 163 } 164 else if (args[i].equals("--totalbranch")) 165 { 166 totalBranchCoverageRate = inRangeAndDivideByOneHundred(args[++i]); 167 } 168 else if (args[i].equals("--totalline")) 169 { 170 totalLineCoverageRate = inRangeAndDivideByOneHundred(args[++i]); 171 } 172 } 173 174 ProjectData projectData = CoverageDataFileHandler 175 .loadCoverageData(dataFile); 176 177 if (projectData == null) 178 { 179 System.err.println("Error: Unable to read from data file " 180 + dataFile.getAbsolutePath()); 181 System.exit(1); 182 } 183 184 if ((branchCoverageRate == 0) && (lineCoverageRate == 0) 186 && (packageLineCoverageRate == 0) 187 && (packageBranchCoverageRate == 0) 188 && (totalLineCoverageRate == 0) 189 && (totalBranchCoverageRate == 0) 190 && (this.minimumCoverageRates.size() == 0)) 191 { 192 branchCoverageRate = 0.5; 193 lineCoverageRate = 0.5; 194 packageBranchCoverageRate = 0.5; 195 packageLineCoverageRate = 0.5; 196 totalBranchCoverageRate = 0.5; 197 totalLineCoverageRate = 0.5; 198 } 199 200 this.minimumCoverageRate = new CoverageRate(lineCoverageRate, 201 branchCoverageRate); 202 203 double totalLines = 0; 204 double totalLinesCovered = 0; 205 double totalBranches = 0; 206 double totalBranchesCovered = 0; 207 208 Iterator iter = projectData.getClasses().iterator(); 209 while (iter.hasNext()) 210 { 211 ClassData classData = (ClassData)iter.next(); 212 CoverageRate coverageRate = findMinimumCoverageRate(classData 213 .getName()); 214 215 if (totalBranchCoverageRate > 0.0) 216 { 217 totalBranches += classData.getNumberOfValidBranches(); 218 totalBranchesCovered += classData.getNumberOfCoveredBranches(); 219 } 220 221 if (totalLineCoverageRate > 0.0) 222 { 223 totalLines += classData.getNumberOfValidLines(); 224 totalLinesCovered += classData.getNumberOfCoveredLines(); 225 } 226 227 PackageCoverage packageCoverage = getPackageCoverage(classData 228 .getPackageName()); 229 if (packageBranchCoverageRate > 0.0) 230 { 231 packageCoverage.addBranchCount(classData 232 .getNumberOfValidBranches()); 233 packageCoverage.addBranchCoverage(classData 234 .getNumberOfCoveredBranches()); 235 } 236 237 if (packageLineCoverageRate > 0.0) 238 { 239 packageCoverage.addLineCount(classData.getNumberOfValidLines()); 240 packageCoverage.addLineCoverage(classData 241 .getNumberOfCoveredLines()); 242 } 243 244 logger.debug("Class " + classData.getName() 245 + ", line coverage rate: " 246 + percentage(classData.getLineCoverageRate()) 247 + "%, branch coverage rate: " 248 + percentage(classData.getBranchCoverageRate()) + "%"); 249 250 if (classData.getBranchCoverageRate() < coverageRate 251 .getBranchCoverageRate()) 252 { 253 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 exitStatus |= 2; 260 } 261 262 if (classData.getLineCoverageRate() < coverageRate 263 .getLineCoverageRate()) 264 { 265 System.err.println(classData.getName() 266 + " failed check. Line coverage rate of " 267 + percentage(classData.getLineCoverageRate()) 268 + "% is below " 269 + percentage(coverageRate.getLineCoverageRate()) + "%"); 270 exitStatus |= 4; 271 } 272 } 273 274 exitStatus |= checkPackageCoverageLevels(packageBranchCoverageRate, 275 packageLineCoverageRate); 276 277 if ((totalBranches > 0) 279 && (totalBranchCoverageRate > (totalBranchesCovered / totalBranches))) 280 { 281 System.err 282 .println("Project failed check. " 283 + "Total branch coverage rate of " 284 + percentage(totalBranchesCovered / totalBranches) 285 + "% is below " 286 + percentage(totalBranchCoverageRate) + "%"); 287 exitStatus |= 8; 288 } 289 290 if ((totalLines > 0) 291 && (totalLineCoverageRate > (totalLinesCovered / totalLines))) 292 { 293 System.err.println("Project failed check. " 294 + "Total line coverage rate of " 295 + percentage(totalLinesCovered / totalLines) 296 + "% is below " + percentage(totalLineCoverageRate) + "%"); 297 exitStatus |= 16; 298 } 299 300 System.exit(exitStatus); 301 } 302 303 private PackageCoverage getPackageCoverage(String packageName) 304 { 305 PackageCoverage packageCoverage = (PackageCoverage)packageCoverageMap 306 .get(packageName); 307 if (packageCoverage == null) 308 { 309 packageCoverage = new PackageCoverage(); 310 packageCoverageMap.put(packageName, packageCoverage); 311 } 312 return packageCoverage; 313 } 314 315 private int checkPackageCoverageLevels(double packageBranchCoverageRate, 316 double packageLineCoverageRate) 317 { 318 int exitStatus = 0; 319 Iterator iter = packageCoverageMap.entrySet().iterator(); 320 while (iter.hasNext()) 321 { 322 Map.Entry entry = (Map.Entry )iter.next(); 323 String packageName = (String )entry.getKey(); 324 PackageCoverage packageCoverage = (PackageCoverage)entry.getValue(); 325 326 exitStatus |= checkPackageCoverage(packageBranchCoverageRate, 327 packageLineCoverageRate, packageName, packageCoverage); 328 } 329 return exitStatus; 330 } 331 332 private int checkPackageCoverage(double packageBranchCoverageRate, 333 double packageLineCoverageRate, String packageName, 334 PackageCoverage packageCoverage) 335 { 336 int exitStatus = 0; 337 double branchCoverage = packageCoverage.getBranchCoverage() 338 / packageCoverage.getBranchCount(); 339 if ((packageCoverage.getBranchCount() > 0) 340 && (packageBranchCoverageRate > branchCoverage)) 341 { 342 System.err.println("Package " + packageName 343 + " failed check. Package branch coverage rate of " 344 + percentage(branchCoverage) + "% is below " 345 + percentage(packageBranchCoverageRate) + "%"); 346 exitStatus |= 32; 347 } 348 349 double lineCoverage = packageCoverage.getLineCoverage() 350 / packageCoverage.getLineCount(); 351 if ((packageCoverage.getLineCount() > 0) 352 && (packageLineCoverageRate > lineCoverage)) 353 { 354 System.err.println("Package " + packageName 355 + " failed check. Package line coverage rate of " 356 + percentage(lineCoverage) + "% is below " 357 + percentage(packageLineCoverageRate) + "%"); 358 exitStatus |= 64; 359 } 360 361 return exitStatus; 362 } 363 364 private String percentage(double coverateRate) 365 { 366 BigDecimal decimal = new BigDecimal (coverateRate * 100); 367 return decimal.setScale(1, BigDecimal.ROUND_DOWN).toString(); 368 } 369 370 public static void main(String [] args) throws MalformedPatternException 371 { 372 new Main(args); 373 } 374 375 } 376 | Popular Tags |