package hudson.plugins.cobertura; import junit.framework.Test; import junit.framework.TestSuite; import junit.framework.TestCase; import hudson.plugins.cobertura.targets.CoverageResult; import hudson.plugins.cobertura.targets.CoverageMetric; import java.io.InputStream; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import java.util.HashSet; import java.util.Map.Entry; import java.util.concurrent.Callable; /** * Unit tests for {@link CoberturaCoverageParser}. * * @author Stephen Connolly * @version 1.0 * @author davidmc24 */ public class CoberturaCoverageParserTest extends TestCase { public CoberturaCoverageParserTest(String name) { super(name); } public void setUp() throws Exception { super.setUp(); } public void tearDown() throws Exception { super.tearDown(); } public void testFailureMode1() throws Exception { try { CoberturaCoverageParser.parse((InputStream)null, null); } catch (NullPointerException e) { assertTrue("Expected exception thrown", true); } } public void print(CoverageResult r, int d) { System.out.print(" ".substring(0, d*2)); System.out.print(r.getElement() + "[" + r.getName() + "]"); for (CoverageMetric m : r.getMetrics()) { System.out.print(" " + m + "=" + r.getCoverage(m)); } System.out.println(); for (String child: r.getChildren()) { print(r.getChild(child), d + 1); } } public void testParse() throws Exception { Set<String> paths = new HashSet<String>(); CoverageResult result = CoberturaCoverageParser.parse(getClass().getResourceAsStream("coverage.xml"), null, paths); result.setOwner(null); print(result, 0); assertNotNull(result); assertEquals(CoverageResult.class, result.getClass()); assertEquals(Messages.CoberturaCoverageParser_name(), result.getName()); // assertEquals(10, result.getMethods()); assertEquals(2, result.getChildren().size()); CoverageResult subResult = result.getChild("<default>"); assertEquals("<default>", subResult.getName()); assertEquals(1, subResult.getChildren().size()); assertEquals(Ratio.create(0, 3), subResult.getCoverage(CoverageMetric.METHOD)); assertEquals(Ratio.create(0, 11), subResult.getCoverage(CoverageMetric.LINE)); subResult = result.getChild("search"); assertEquals("search", subResult.getName()); assertEquals(3, subResult.getChildren().size()); assertEquals(Ratio.create(0, 19), subResult.getCoverage(CoverageMetric.LINE)); assertEquals(Ratio.create(0, 12), subResult.getCoverage(CoverageMetric.CONDITIONAL)); assertEquals(Ratio.create(0, 4), subResult.getCoverage(CoverageMetric.METHOD)); assertEquals(1, paths.size()); } public void atestParse2() throws Exception { CoverageResult result = CoberturaCoverageParser.parse(getClass().getResourceAsStream("coverage-with-data.xml"), null); result.setOwner(null); print(result, 0); assertNotNull(result); assertEquals(CoverageResult.class, result.getClass()); assertEquals(Messages.CoberturaCoverageParser_name(), result.getName()); // assertEquals(10, result.getMethods()); assertEquals(2, result.getChildren().size()); CoverageResult subResult = result.getChild("<default>"); assertEquals("<default>", subResult.getName()); assertEquals(1, subResult.getChildren().size()); assertEquals(Ratio.create(3, 3), subResult.getCoverage(CoverageMetric.METHOD)); assertEquals(Ratio.create(11, 11), subResult.getCoverage(CoverageMetric.LINE)); subResult = result.getChild("search"); assertEquals("search", subResult.getName()); assertEquals(3, subResult.getChildren().size()); assertEquals(Ratio.create(16, 19), subResult.getCoverage(CoverageMetric.LINE)); assertEquals(Ratio.create(9, 12), subResult.getCoverage(CoverageMetric.CONDITIONAL)); assertEquals(Ratio.create(4, 4), subResult.getCoverage(CoverageMetric.METHOD)); } public void atestParseMultiPackage() throws Exception { // ProjectCoverage result = CoberturaCoverageParser.parse(getClass().getResourceAsStream("coverage-two-packages.xml")); // result = CoberturaCoverageParser.trimPaths(result, "C:\\local\\maven\\helpers\\hudson\\cobertura\\"); // assertNotNull(result); // assertEquals(ProjectCoverage.class, result.getClass()); // assertEquals("Maven Cloverreport", result.getName()); //// assertEquals(40, result.getMethods()); // assertEquals(2, result.getPackageCoverages().size()); //// assertEquals(14, result.findClassCoverage("hudson.plugins.cobertura.results.AbstractCloverMetrics").getCoveredmethods()); } /** * Tests the memory usage of * {@link CoberturaCoverageParser#parse(InputStream, CoverageResult, Set)}. * * @since 28-Apr-2009 */ public void atestParseMemoryUsage() throws Exception { Map<String, Long> files = new LinkedHashMap<String, Long>(); files.put("coverage.xml", 100000L); files.put("coverage-with-data.xml", 100000L); files.put("coverage-with-lots-of-data.xml", 2500000L); for(Entry<String, Long> e : files.entrySet()) { final String fileName = e.getKey(); long maxMemory = e.getValue(); Callable<CoverageResult> callable = new Callable<CoverageResult>() { public CoverageResult call() throws Exception { InputStream in = getClass().getResourceAsStream(fileName); CoverageResult result = CoberturaCoverageParser.parse(in, null, null); result.setOwner(null); return result; } }; assertMaxMemoryUsage(fileName + " results", callable, maxMemory); } } /** * Tests the memory usage of a specified Callable. The Callable should * return the object that it is generating, so that it is not garbage * collected until the proper point in the test. The callable will be * called 6 times. The results of the first call are be ignored, to avoid * pollution of the results by class initialization. The amount of memory * used in the other runs are averaged to produce the average memory usage * for the Callable. This number is then compared with the specified * maximum desired memory usage. If the average memory usage is greater * than the specified number, it will be reported as a failed assertion. * * @param description a plain-text description of the Callable, to be used * in diagnostic messages * @param callable the callable for which to run a memory usage test * @param maxMemoryUsage the maximum desired memory usage for the Callable, * in bytes */ private static void assertMaxMemoryUsage(String description, Callable<? extends Object> callable, long maxMemoryUsage) throws Exception { Runtime rt = Runtime.getRuntime(); final int iterations = 5; long sum = 0; for(int i=0; i<iterations+1; i++) { rt.gc(); long startMemUsed = rt.totalMemory() - rt.freeMemory(); @SuppressWarnings("unused") Object result = callable.call(); rt.gc(); long endMemUsed = rt.totalMemory() - rt.freeMemory(); long deltaMemUsed = endMemUsed - startMemUsed; if(deltaMemUsed < 0) { deltaMemUsed = 0; } if(i != 0) { //Ignore the first iteration, due to class initialization sum += deltaMemUsed; } } long averageMemoryUsage = sum / iterations; String message = description + " consume " + averageMemoryUsage + " bytes of memory on average, " + (averageMemoryUsage - maxMemoryUsage) + " bytes more than the specified limit of " + maxMemoryUsage + " bytes"; assertTrue(message, averageMemoryUsage < maxMemoryUsage); System.out.println(description + " consume " + averageMemoryUsage + "/" + maxMemoryUsage + " bytes of memory"); } public static Test suite() { return new TestSuite(CoberturaCoverageParserTest.class); } }