001 /*
002 * Cobertura - http://cobertura.sourceforge.net/
003 *
004 * Copyright (C) 2003 jcoverage ltd.
005 * Copyright (C) 2005 Mark Doliner <thekingant@users.sourceforge.net>
006 *
007 * Cobertura is free software; you can redistribute it and/or modify
008 * it under the terms of the GNU General Public License as published
009 * by the Free Software Foundation; either version 2 of the License,
010 * or (at your option) any later version.
011 *
012 * Cobertura is distributed in the hope that it will be useful, but
013 * WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * General Public License for more details.
016 *
017 * You should have received a copy of the GNU General Public License
018 * along with Cobertura; if not, write to the Free Software
019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
020 * USA
021 */
022
023 package net.sourceforge.cobertura.check;
024
025 import gnu.getopt.Getopt;
026 import gnu.getopt.LongOpt;
027
028 import java.io.File;
029 import java.io.FileInputStream;
030 import java.io.IOException;
031 import java.math.BigDecimal;
032 import java.util.HashMap;
033 import java.util.Iterator;
034 import java.util.Map;
035 import java.util.StringTokenizer;
036 import java.util.regex.Pattern;
037
038 import net.sourceforge.cobertura.coverage.CoverageData;
039 import net.sourceforge.cobertura.coverage.InstrumentationPersistence;
040 import net.sourceforge.cobertura.util.Copyright;
041
042 import org.apache.log4j.Logger;
043
044 public class Main extends InstrumentationPersistence
045 {
046
047 private static final Logger logger = Logger.getLogger(Main.class);
048
049 Map minimumCoverageRates = new HashMap();
050 CoverageRate minimumCoverageRate;
051
052 File instrumentationDirectory = new File(System.getProperty("user.dir"));
053
054 void setInstrumentationDirectory(File instrumentationDirectory)
055 {
056 this.instrumentationDirectory = instrumentationDirectory;
057 }
058
059 double inRangeAndDivideByOneHundred(String coverageRateAsPercentage)
060 {
061 return inRangeAndDivideByOneHundred(Integer.valueOf(
062 coverageRateAsPercentage).intValue());
063 }
064
065 double inRangeAndDivideByOneHundred(int coverageRateAsPercentage)
066 {
067 if ((coverageRateAsPercentage >= 0)
068 && (coverageRateAsPercentage <= 100))
069 {
070 return (double)coverageRateAsPercentage / 100;
071 }
072 throw new IllegalArgumentException(
073 "Invalid value, valid range is [0 .. 100]");
074 }
075
076 void setMinimumCoverageRate(String minimumCoverageRate)
077 {
078 StringTokenizer tokenizer = new StringTokenizer(minimumCoverageRate,
079 ":");
080 minimumCoverageRates.put(Pattern.compile(tokenizer.nextToken()),
081 new CoverageRate(inRangeAndDivideByOneHundred(tokenizer
082 .nextToken()), inRangeAndDivideByOneHundred(tokenizer
083 .nextToken())));
084 }
085
086 CoverageRate findMinimumCoverageRate(String classname)
087 {
088 Iterator i = minimumCoverageRates.entrySet().iterator();
089 while (i.hasNext())
090 {
091 Map.Entry entry = (Map.Entry)i.next();
092
093 Pattern pattern = (Pattern)entry.getKey();
094 if (pattern.matcher(classname).matches())
095 {
096 return (CoverageRate)entry.getValue();
097 }
098 }
099 return minimumCoverageRate;
100 }
101
102 public Main(String[] args) throws IOException
103 {
104 Copyright.print(System.out);
105 System.out.println("Cobertura coverage check");
106
107 LongOpt[] longOpts = new LongOpt[4];
108 longOpts[0] = new LongOpt("branch", LongOpt.REQUIRED_ARGUMENT, null,
109 'b');
110 longOpts[1] = new LongOpt("line", LongOpt.REQUIRED_ARGUMENT, null,
111 'l');
112 longOpts[2] = new LongOpt("directory", LongOpt.REQUIRED_ARGUMENT,
113 null, 'd');
114 longOpts[3] = new LongOpt("regex", LongOpt.REQUIRED_ARGUMENT, null,
115 'r');
116
117 Getopt g = new Getopt(getClass().getName(), args, ":b:l:d:r:",
118 longOpts);
119 int c;
120
121 double branchCoverageRate = 0.8;
122 double lineCoverageRate = 0.7;
123
124 while ((c = g.getopt()) != -1)
125 {
126 switch (c)
127 {
128 case 'b':
129 branchCoverageRate = inRangeAndDivideByOneHundred(g
130 .getOptarg());
131 break;
132
133 case 'l':
134 lineCoverageRate = inRangeAndDivideByOneHundred(g
135 .getOptarg());
136 break;
137
138 case 'd':
139 setInstrumentationDirectory(new File(g.getOptarg()));
140 break;
141
142 case 'r':
143 setMinimumCoverageRate(g.getOptarg());
144 break;
145 }
146 }
147
148 minimumCoverageRate = new CoverageRate(lineCoverageRate,
149 branchCoverageRate);
150
151 if (logger.isInfoEnabled())
152 {
153 logger.info("instrumentation directory: "
154 + instrumentationDirectory);
155 }
156
157 merge(loadInstrumentation(new FileInputStream(new File(
158 instrumentationDirectory,
159 InstrumentationPersistence.FILE_NAME))));
160
161 if (logger.isInfoEnabled())
162 {
163 logger
164 .info("instrumentation has " + keySet().size()
165 + " entries");
166 }
167
168 Iterator i = keySet().iterator();
169 while (i.hasNext())
170 {
171 String key = (String)i.next();
172
173 CoverageRate coverageRate = findMinimumCoverageRate(key);
174 CoverageData instrumentation = getInstrumentation(key);
175
176 if (logger.isInfoEnabled())
177 {
178 StringBuffer sb = new StringBuffer();
179 sb.append(key);
180 sb.append(", line: ");
181 sb.append(percentage(instrumentation.getLineCoverageRate()));
182 sb.append("% (");
183 sb.append(percentage(coverageRate.getLineCoverageRate()));
184 sb.append("%), branch: ");
185 sb
186 .append(percentage(instrumentation
187 .getBranchCoverageRate()));
188 sb.append("% (");
189 sb.append(percentage(coverageRate.getBranchCoverageRate()));
190 sb.append("%)");
191 logger.info(sb.toString());
192 }
193
194 if (instrumentation.getLineCoverageRate() < coverageRate
195 .getLineCoverageRate())
196 {
197 StringBuffer sb = new StringBuffer();
198 sb.append(key);
199 sb.append(" line coverage rate of: ");
200 sb.append(percentage(instrumentation.getLineCoverageRate()));
201 sb.append("% (required: ");
202 sb.append(percentage(coverageRate.getLineCoverageRate()));
203 sb.append("%)");
204 System.out.println(sb.toString());
205 }
206
207 if (instrumentation.getBranchCoverageRate() < coverageRate
208 .getBranchCoverageRate())
209 {
210 StringBuffer sb = new StringBuffer();
211 sb.append(key);
212 sb.append(" branch coverage rate of: ");
213 sb
214 .append(percentage(instrumentation
215 .getBranchCoverageRate()));
216 sb.append("% (required: ");
217 sb.append(percentage(coverageRate.getBranchCoverageRate()));
218 sb.append("%)");
219 System.out.println(sb.toString());
220 }
221 }
222 }
223
224 private String percentage(double coverateRate)
225 {
226 BigDecimal decimal = new BigDecimal(coverateRate * 100);
227 return decimal.setScale(1, BigDecimal.ROUND_DOWN).toString();
228 }
229
230 public static void main(String[] args) throws IOException
231 {
232 new Main(args);
233 }
234
235 }