Trac #88: API to specify the session identifier used by the agent.
diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/JacocoAgent.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/JacocoAgent.java
index 35c1956..d4dabe8 100644
--- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/JacocoAgent.java
+++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/JacocoAgent.java
@@ -18,6 +18,9 @@
import java.io.IOException;
import java.io.OutputStream;
import java.lang.instrument.Instrumentation;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Random;
import org.jacoco.core.data.ExecutionDataWriter;
import org.jacoco.core.runtime.AgentOptions;
@@ -66,10 +69,25 @@
*/
public void init(final Instrumentation inst) throws Exception {
runtime = createRuntime(inst);
+ String sessionId = options.getSessionId();
+ if (sessionId == null) {
+ sessionId = createSessionId();
+ }
+ runtime.setSessionId(sessionId);
runtime.startup();
inst.addTransformer(new CoverageTransformer(runtime, options));
}
+ private String createSessionId() {
+ String host;
+ try {
+ host = InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException e) {
+ host = "unknownhost";
+ }
+ return host + "-" + Integer.toHexString(new Random().nextInt());
+ }
+
/**
* Creates the specific coverage runtime implementation.
*
diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/AgentTaskTest.xml b/org.jacoco.ant.test/src/org/jacoco/ant/AgentTaskTest.xml
index 7bc630b..d5e9f34 100644
--- a/org.jacoco.ant.test/src/org/jacoco/ant/AgentTaskTest.xml
+++ b/org.jacoco.ant.test/src/org/jacoco/ant/AgentTaskTest.xml
@@ -18,7 +18,7 @@
<target name="testCoverageAgent">
<jacoco:agent property="jacocoagent" append="false" destfile="test.exec"
exclClassLoader="EvilClassLoader" includes="org.example.*"
- excludes="*Test" dumponexit="false"/>
+ excludes="*Test" sessionid="testid" dumponexit="false"/>
<au:assertPropertySet name="jacocoagent"/>
<au:assertPropertyContains name="jacocoagent" value="-javaagent:"/>
<au:assertPropertyContains name="jacocoagent" value="append=false"/>
@@ -27,6 +27,7 @@
<au:assertPropertyContains name="jacocoagent" value="exclclassloader=EvilClassLoader"/>
<au:assertPropertyContains name="jacocoagent" value="includes=org.example.*"/>
<au:assertPropertyContains name="jacocoagent" value="excludes=*Test"/>
+ <au:assertPropertyContains name="jacocoagent" value="sessionid=testid"/>
<au:assertPropertyContains name="jacocoagent" value="dumponexit=false"/>
</target>
diff --git a/org.jacoco.ant/src/org/jacoco/ant/AbstractCoverageTask.java b/org.jacoco.ant/src/org/jacoco/ant/AbstractCoverageTask.java
index 5b6f08f..f54f7ea 100644
--- a/org.jacoco.ant/src/org/jacoco/ant/AbstractCoverageTask.java
+++ b/org.jacoco.ant/src/org/jacoco/ant/AbstractCoverageTask.java
@@ -124,6 +124,18 @@
}
/**
+ * Sets the session identifier.
+ *
+ * @ant.not-required Default is a auto-generated id
+ *
+ * @param id
+ * session identifier
+ */
+ public void setSessionId(final String id) {
+ agentOptions.setSessionId(id);
+ }
+
+ /**
* Dump coverage data on VM termination
*
* @ant.not-required Default is <code>true</code>
diff --git a/org.jacoco.build/buildbundle.xml b/org.jacoco.build/buildbundle.xml
index 6afc163..8165f58 100644
--- a/org.jacoco.build/buildbundle.xml
+++ b/org.jacoco.build/buildbundle.xml
@@ -112,7 +112,8 @@
append="true"
destfile="${result.tmp.coverage.file}"
includes="${testscope}"
- exclClassLoader="sun.reflect.DelegatingClassLoader|org.jacoco.core.test.TargetLoader">
+ exclClassLoader="sun.reflect.DelegatingClassLoader|org.jacoco.core.test.TargetLoader"
+ sessionid="${manifest.Bundle-SymbolicName}">
<junit haltonfailure="true" fork="true" forkmode="once" dir="${source.bundle.dir}">
<jvmarg line="${verify.jvm.args}"/>
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 b034a4c..75817d5 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
@@ -14,6 +14,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
@@ -44,6 +45,7 @@
assertEquals("", options.getExcludes());
assertEquals("sun.reflect.DelegatingClassLoader", options
.getExclClassloader());
+ assertNull(options.getSessionId());
assertTrue(options.getDumpOnExit());
assertEquals("", options.toString());
}
@@ -141,6 +143,20 @@
}
@Test
+ public void testGetSessionId() {
+ AgentOptions options = new AgentOptions("sessionid=testsession");
+ assertEquals("testsession", options.getSessionId());
+ }
+
+ @Test
+ public void testSetSessionId() {
+ AgentOptions options = new AgentOptions();
+ options.setSessionId("testsession");
+ assertEquals("testsession", options.getSessionId());
+ assertEquals("sessionid=testsession", options.toString());
+ }
+
+ @Test
public void testGetDumpOnExit() {
AgentOptions options = new AgentOptions("dumponexit=false");
assertFalse(options.getDumpOnExit());
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 61aebb2..94b98bc 100644
--- a/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java
+++ b/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java
@@ -73,13 +73,20 @@
public static final String EXCLCLASSLOADER = "exclclassloader";
/**
+ * Specifies a session identifier that is written with the execution data.
+ * Without this parameter a random identifier is created by the agent.
+ */
+ public static final String SESSIONID = "sessionid";
+
+ /**
* Specifies whether the agent will automatically dump coverage data on VM
* exit. Default is <code>true</code>
*/
public static final String DUMPONEXIT = "dumponexit";
private static final Collection<String> VALID_OPTIONS = Arrays.asList(
- DESTFILE, APPEND, INCLUDES, EXCLUDES, EXCLCLASSLOADER, DUMPONEXIT);
+ DESTFILE, APPEND, INCLUDES, EXCLUDES, EXCLCLASSLOADER, SESSIONID,
+ DUMPONEXIT);
private final Map<String, String> options;
@@ -217,6 +224,25 @@
}
/**
+ * Returns the session identifier.
+ *
+ * @return session identifier
+ */
+ public String getSessionId() {
+ return getOption(SESSIONID, null);
+ }
+
+ /**
+ * Sets the session identifier.
+ *
+ * @param id
+ * session identifier
+ */
+ public void setSessionId(final String id) {
+ setOption(SESSIONID, id);
+ }
+
+ /**
* Returns whether coverage data should be dumped on exit
*
* @return <code>true</code> if coverage data will be written on VM exit
diff --git a/org.jacoco.doc/docroot/doc/agent.html b/org.jacoco.doc/docroot/doc/agent.html
index 56131d6..2a604ce 100644
--- a/org.jacoco.doc/docroot/doc/agent.html
+++ b/org.jacoco.doc/docroot/doc/agent.html
@@ -100,8 +100,17 @@
<td><code>sun.reflect.DelegatingClassLoader</code></td>
</tr>
<tr>
+ <td><code>sessionid</code></td>
+ <td>A session identifier that is written with the execution data. Without
+ this parameter a random identifier is created by the agent.
+ </td>
+ <td><i>auto-generated</i></td>
+ </tr>
+ <tr>
<td><code>dumponexit</code></td>
- <td>If set to <code>true</code> coverage data will be written on VM shutdown</td>
+ <td>If set to <code>true</code> coverage data will be written on VM
+ shutdown.
+ </td>
<td><code>true</code></td>
</tr>
</tbody>
diff --git a/org.jacoco.doc/docroot/doc/ant.html b/org.jacoco.doc/docroot/doc/ant.html
index ad08b4b..888099f 100644
--- a/org.jacoco.doc/docroot/doc/ant.html
+++ b/org.jacoco.doc/docroot/doc/ant.html
@@ -173,8 +173,17 @@
<td><code>sun.reflect.DelegatingClassLoader</code></td>
</tr>
<tr>
+ <td><code>sessionid</code></td>
+ <td>A session identifier that is written with the execution data. Without
+ this parameter a random identifier is created by the agent.
+ </td>
+ <td><i>auto-generated</i></td>
+ </tr>
+ <tr>
<td><code>dumponexit</code></td>
- <td>If set to <code>true</code> coverage data will be written on VM shutdown</td>
+ <td>If set to <code>true</code> coverage data will be written on VM
+ shutdown.
+ </td>
<td><code>true</code></td>
</tr>
</tbody>
diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html
index 8f03949..8210004 100644
--- a/org.jacoco.doc/docroot/doc/changes.html
+++ b/org.jacoco.doc/docroot/doc/changes.html
@@ -19,10 +19,17 @@
<h2>Trunk Build @qualified.bundle.version@ (@build.date@)</h2>
+<h3>New Features</h3>
+<ul>
+ <li>Execution data now includes session information: an arbitrary identifier,
+ the start time and dump time (Trac #88).</li>
+</ul>
+
<h3>API Changes</h3>
<ul>
<li>Execution data file header is written and read in any case (Trac #72).</li>
- <li>Added dumponexit to Agent Options. (Trac #82)</li>
+ <li>Added <code>dumponexit</code> to agent options (Trac #82).</li>
+ <li>Added <code>sessionid</code> to agent options (Trac #88).</li>
<li>Additional and modified methods in <code>IRuntime</code> to produce
session information (Trac #88).</li>
</ul>