diff options
author | Marc R. Hoffmann <hoffmann@mountainminds.com> | 2012-12-28 13:54:23 +0100 |
---|---|---|
committer | Marc R. Hoffmann <hoffmann@mountainminds.com> | 2012-12-28 13:54:23 +0100 |
commit | 47990a4a02bb738eedd7dce6a2f2dd10d5f28cc4 (patch) | |
tree | 6413669212ce5c34c5c8068038e50b1481df6743 | |
parent | 9c1b63dafd9be7316d3661aaa18aa3815160d19c (diff) | |
download | jacoco-47990a4a02bb738eedd7dce6a2f2dd10d5f28cc4.tar.gz |
Additional way to provide configuration options via classpath resource.
9 files changed, 177 insertions, 27 deletions
diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/ConfigLoaderTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/ConfigLoaderTest.java new file mode 100644 index 00000000..4ca8afa6 --- /dev/null +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/ConfigLoaderTest.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2009, 2012 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc R. Hoffmann - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.agent.rt; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Properties; + +import org.junit.Test; + +/** + * Unit tests for {@link ConfigLoader}. + */ +public class ConfigLoaderTest { + + @Test + public void testResource() { + Properties system = new Properties(); + Properties config = ConfigLoader.load( + "/org/jacoco/agent/rt/agent-test.properties", system); + + assertEquals("tcpclient", config.get("output")); + } + + @Test + public void testNoResource() { + Properties system = new Properties(); + Properties config = ConfigLoader.load("does-not-exist.properties", + system); + + assertTrue(config.isEmpty()); + } + + @Test + public void testSystemProperties() { + Properties system = new Properties(); + system.setProperty("jacoco-agent.output", "mbean"); + system.setProperty("output", "tcpserver"); // no prefix + system.setProperty("jacoco-agent.sessionid", "testid"); + Properties config = ConfigLoader.load( + "/org/jacoco/agent/rt/agent-test.properties", system); + + assertEquals("mbean", config.get("output")); + assertEquals("testid", config.get("sessionid")); + } + +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/agent-test.properties b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/agent-test.properties new file mode 100644 index 00000000..d13081c8 --- /dev/null +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/agent-test.properties @@ -0,0 +1 @@ +output=tcpclient
\ No newline at end of file diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/ConfigLoader.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/ConfigLoader.java new file mode 100644 index 00000000..977aac2f --- /dev/null +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/ConfigLoader.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2009, 2012 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc R. Hoffmann - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.agent.rt; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.Properties; + +/** + * Internal utility to load runtime configuration from a classpath resource and + * from system properties. System property keys are prefixed with + * <code>jacoco.</code>. If the same property is defined twice the system + * property takes precedence. + */ +final class ConfigLoader { + + private static final String SYS_PREFIX = "jacoco-agent."; + + static Properties load(final String resource, final Properties system) { + final Properties result = new Properties(); + + // 1. Try to load resource + final InputStream file = RT.class.getResourceAsStream(resource); + if (file != null) { + try { + result.load(file); + } catch (final IOException e) { + throw new RuntimeException(e); + } + } + + // 2. Override with system properties + for (final Map.Entry<Object, Object> entry : system.entrySet()) { + final String keystr = entry.getKey().toString(); + if (keystr.startsWith(SYS_PREFIX)) { + result.put(keystr.substring(SYS_PREFIX.length()), + entry.getValue()); + } + } + + return result; + } + + private ConfigLoader() { + } + +} diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/RT.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/RT.java index c760b0e2..53bca947 100644 --- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/RT.java +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/RT.java @@ -11,6 +11,8 @@ *******************************************************************************/ package org.jacoco.agent.rt; +import java.util.Properties; + import org.jacoco.core.runtime.AgentOptions; import org.jacoco.core.runtime.RuntimeData; @@ -21,10 +23,12 @@ import org.jacoco.core.runtime.RuntimeData; public class RT { private static final RuntimeData data; + private static final String CONFIG_RESOURCE = "/jacoco-agent.properties"; static { - final AgentOptions options = new AgentOptions(System.getProperties()); - data = Agent.getInstance(options).getData(); + final Properties config = ConfigLoader.load( + CONFIG_RESOURCE, System.getProperties()); + data = Agent.getInstance(new AgentOptions(config)).getData(); } /** diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/InstrumentTaskTest.xml b/org.jacoco.ant.test/src/org/jacoco/ant/InstrumentTaskTest.xml index ba61b720..fd23caa7 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/InstrumentTaskTest.xml +++ b/org.jacoco.ant.test/src/org/jacoco/ant/InstrumentTaskTest.xml @@ -8,7 +8,7 @@ http://www.eclipse.org/legal/epl-v10.html Contributors: - Brock Janiczak - initial API and implementation + Marc R. Hoffmann - initial API and implementation $Id: $ --> @@ -49,15 +49,32 @@ </jacoco:instrument> </target> - <target name="testInstrumentAndRun"> + <target name="testInstrumentAndRunWithConfigFile"> <jacoco:instrument destdir="${temp.dir}"> <fileset dir="${org.jacoco.ant.instrumentTaskTest.classes.dir}" includes="**/*.class"/> </jacoco:instrument> <au:assertLogContains text="Instrumented 12 classes to ${temp.dir}"/> <au:assertFileExists file="${temp.dir}/org/jacoco/ant/InstrumentTaskTest.class" /> + <echo file="${temp.dir}/jacoco-agent.properties">destfile=${temp.dir}/test.exec</echo> <java classname="org.jacoco.ant.TestTarget" failonerror="true" fork="true"> - <sysproperty key="jacoco.destfile" file="${temp.dir}/test.exec"/> + <classpath> + <pathelement path="${org.jacoco.ant.instrumentTaskTest.agent.file}"/> + <pathelement path="${temp.dir}"/> + </classpath> + </java> + <au:assertFileExists file="${temp.dir}/test.exec" /> + </target> + + <target name="testInstrumentAndRunWithSystemProperties"> + <jacoco:instrument destdir="${temp.dir}"> + <fileset dir="${org.jacoco.ant.instrumentTaskTest.classes.dir}" includes="**/*.class"/> + </jacoco:instrument> + <au:assertLogContains text="Instrumented 12 classes to ${temp.dir}"/> + <au:assertFileExists file="${temp.dir}/org/jacoco/ant/InstrumentTaskTest.class" /> + + <java classname="org.jacoco.ant.TestTarget" failonerror="true" fork="true"> + <sysproperty key="jacoco-agent.destfile" file="${temp.dir}/test.exec"/> <classpath> <pathelement path="${org.jacoco.ant.instrumentTaskTest.agent.file}"/> <pathelement path="${temp.dir}"/> diff --git a/org.jacoco.core.test/src/org/jacoco/core/runtime/AgentOptionsTest.java b/org.jacoco.core.test/src/org/jacoco/core/runtime/AgentOptionsTest.java index 99a37100..5939c267 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/runtime/AgentOptionsTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/runtime/AgentOptionsTest.java @@ -68,17 +68,17 @@ public class AgentOptionsTest { @Test public void testPropertiesOptions() { Properties properties = new Properties(); - properties.put("jacoco.destfile", "/target/test/test.exec"); - properties.put("jacoco.append", "false"); - properties.put("jacoco.includes", "org.*:com.*"); - properties.put("jacoco.excludes", "*Test"); - properties.put("jacoco.exclclassloader", "org.jacoco.test.TestLoader"); - properties.put("jacoco.sessionid", "testsession"); - properties.put("jacoco.dumponexit", "false"); - properties.put("jacoco.output", "tcpserver"); - properties.put("jacoco.address", "remotehost"); - properties.put("jacoco.port", "1234"); - properties.put("jacoco.classdumpdir", "target/dump"); + properties.put("destfile", "/target/test/test.exec"); + properties.put("append", "false"); + properties.put("includes", "org.*:com.*"); + properties.put("excludes", "*Test"); + properties.put("exclclassloader", "org.jacoco.test.TestLoader"); + properties.put("sessionid", "testsession"); + properties.put("dumponexit", "false"); + properties.put("output", "tcpserver"); + properties.put("address", "remotehost"); + properties.put("port", "1234"); + properties.put("classdumpdir", "target/dump"); AgentOptions options = new AgentOptions(properties); diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java b/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java index 1b45cd30..e15e0730 100644 --- a/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java +++ b/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java @@ -199,8 +199,7 @@ public final class AgentOptions { } /** - * New instance read from the given {@link Properties} object. All keys are - * prefixed with <code>jacoco.</code>. + * New instance read from the given {@link Properties} object. * * @param properties * {@link Properties} object to read configuration options from @@ -208,7 +207,7 @@ public final class AgentOptions { public AgentOptions(final Properties properties) { this(); for (final String key : VALID_OPTIONS) { - final String value = properties.getProperty("jacoco." + key); + final String value = properties.getProperty(key); if (value != null) { setOption(key, value); } diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 102658e0..cf1545fb 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -21,6 +21,9 @@ <h2>Trunk Build @qualified.bundle.version@ (@build.date@)</h2> <h3>New Features</h3> +<ul> + <li>Support for offline instrumentation (GitHub #4).</li> +</ul> <h3>Fixed Bugs</h3> diff --git a/org.jacoco.doc/docroot/doc/offline.html b/org.jacoco.doc/docroot/doc/offline.html index ca737505..a6d31b67 100644 --- a/org.jacoco.doc/docroot/doc/offline.html +++ b/org.jacoco.doc/docroot/doc/offline.html @@ -41,14 +41,26 @@ <h2>Configuration</h2> <p> - In offline mode the JaCoCo runtime can be configured with Java System - properties. The same set of properties as for the - <a href="agent.html">agent</a> is available, but prefixed with - "<code>jacoco.</code>". For example the location of the <code>*.exec</code> - file can be configured with the system property - "<code>jacoco.destfile</code>". + In offline mode the JaCoCo runtime can be configured with the same set of + properties which are available for the <a href="agent.html">agent</a>, except + for the <code>includes</code>/<code>excludes</code> options as the class files + are already instrumented. There are two different ways to provide the + configuration: </p> +<ul> + <li><b>Configuration File:</b> If a file <code>jacoco-agent.properties</code> + is supplied on the classpath options are loaded from this file. The file + has to be formatted in the + <a href="http://docs.oracle.com/javase/7/docs/api/java/util/Properties.html#load%28java.io.Reader%29">Java + properties file format</a>.</li> + <li><b>System Properties:</b> Options can also be supplied as Java system + properties. In this case the options have to be prefixed with + "<code>jacoco-agent.</code>". For example the location of the + <code>*.exec</code> file can be configured with the system property + "<code>jacoco-agent.destfile</code>".</li> +</ul> + <h2>Class Loading and Initialization</h2> <p> Unlike with on-the-fly instrumentation offline instrumented classes get a @@ -65,8 +77,8 @@ It is possible to also use offline-instrumented classes with the JaCoCo Java agent. In this case the configuration is taken from the agent options. The agent must be configured in a way that pre-instrumented classes are excluded, - e.g. with <code>excludes=*</code>. Otherwise it will result in error messages - on the console if the agent instruments such classes again. + e.g. with "<code>excludes=*</code>". Otherwise it will result in error + messages on the console if the agent instruments such classes again. </p> <h2>Execution Data Collection</h2> |