1 /*******************************************************************************
2  * Copyright (c) 2009, 2015 Mountainminds GmbH & Co. KG and Contributors
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *    Evgeny Mandrikov - initial API and implementation
10  *
11  *******************************************************************************/
12 package org.jacoco.agent.rt.internal;
13 
14 import static org.junit.Assert.assertEquals;
15 import static org.junit.Assert.assertFalse;
16 import static org.junit.Assert.assertNull;
17 import static org.junit.Assert.assertSame;
18 import static org.junit.Assert.assertTrue;
19 import static org.junit.Assert.fail;
20 
21 import java.io.ByteArrayInputStream;
22 import java.io.File;
23 import java.io.IOException;
24 import java.lang.management.ManagementFactory;
25 
26 import javax.management.InstanceNotFoundException;
27 import javax.management.MBeanServer;
28 import javax.management.ObjectName;
29 
30 import org.jacoco.agent.rt.internal.output.IAgentOutput;
31 import org.jacoco.agent.rt.internal.output.FileOutput;
32 import org.jacoco.agent.rt.internal.output.NoneOutput;
33 import org.jacoco.agent.rt.internal.output.TcpClientOutput;
34 import org.jacoco.agent.rt.internal.output.TcpServerOutput;
35 import org.jacoco.core.JaCoCo;
36 import org.jacoco.core.data.ExecutionDataReader;
37 import org.jacoco.core.data.ExecutionDataStore;
38 import org.jacoco.core.data.SessionInfoStore;
39 import org.jacoco.core.runtime.AgentOptions;
40 import org.jacoco.core.runtime.AgentOptions.OutputMode;
41 import org.jacoco.core.runtime.RuntimeData;
42 import org.junit.Before;
43 import org.junit.Rule;
44 import org.junit.Test;
45 import org.junit.rules.TemporaryFolder;
46 
47 /**
48  * Unit tests for {@link Agent}.
49  */
50 public class AgentTest implements IExceptionLogger {
51 
52 	@Rule
53 	public TemporaryFolder folder = new TemporaryFolder();
54 
55 	private AgentOptions options;
56 	private File execfile;
57 
58 	private Exception exception;
59 
60 	@Before
setup()61 	public void setup() {
62 		options = new AgentOptions();
63 		execfile = new File(folder.getRoot(), "jacoco.exec");
64 		options.setOutput(OutputMode.file);
65 		options.setDestfile(execfile.getAbsolutePath());
66 	}
67 
68 	@Test
testCreateController()69 	public void testCreateController() {
70 		Agent agent = new Agent(options, this);
71 
72 		options.setOutput(OutputMode.file);
73 		assertEquals(FileOutput.class, agent.createAgentOutput()
74 				.getClass());
75 
76 		options.setOutput(OutputMode.tcpserver);
77 		assertEquals(TcpServerOutput.class, agent.createAgentOutput()
78 				.getClass());
79 
80 		options.setOutput(OutputMode.tcpclient);
81 		assertEquals(TcpClientOutput.class, agent.createAgentOutput()
82 				.getClass());
83 
84 		options.setOutput(OutputMode.none);
85 		assertEquals(NoneOutput.class, agent.createAgentOutput()
86 				.getClass());
87 	}
88 
89 	@Test
testStartupShutdown()90 	public void testStartupShutdown() throws Exception {
91 		options.setSessionId("testsession");
92 		Agent agent = new Agent(options, this);
93 		agent.startup();
94 
95 		assertEquals("testsession", agent.getData().getSessionId());
96 
97 		agent.shutdown();
98 
99 		assertTrue(execfile.isFile());
100 		assertTrue(execfile.length() > 0);
101 		assertNull(exception);
102 	}
103 
104 	@Test
testShutdownWithException()105 	public void testShutdownWithException() throws Exception {
106 		final Exception expected = new Exception();
107 		Agent agent = new Agent(options, this) {
108 			@Override
109 			IAgentOutput createAgentOutput() {
110 				return new IAgentOutput() {
111 					public void startup(AgentOptions options, RuntimeData data) {
112 					}
113 
114 					public void shutdown() throws Exception {
115 						throw expected;
116 					}
117 
118 					public void writeExecutionData(boolean reset) {
119 					}
120 				};
121 			}
122 		};
123 		agent.startup();
124 
125 		agent.shutdown();
126 
127 		assertSame(expected, exception);
128 	}
129 
130 	@Test
testNoSessionId()131 	public void testNoSessionId() throws Exception {
132 		Agent agent = new Agent(options, this);
133 
134 		final String defaultId = agent.getData().getSessionId();
135 
136 		agent.startup();
137 
138 		assertFalse(defaultId.equals(agent.getData().getSessionId()));
139 		assertNull(exception);
140 	}
141 
142 	@Test
testNoDumpOnExit()143 	public void testNoDumpOnExit() throws Exception {
144 		options.setDumpOnExit(false);
145 		Agent agent = new Agent(options, this);
146 
147 		agent.startup();
148 		agent.shutdown();
149 
150 		assertEquals(0, execfile.length());
151 		assertNull(exception);
152 	}
153 
154 	@Test
testInvalidExecFile()155 	public void testInvalidExecFile() throws Exception {
156 		options.setDestfile(folder.getRoot().getAbsolutePath());
157 		Agent agent = new Agent(options, this);
158 
159 		agent.startup();
160 
161 		assertTrue(exception instanceof IOException);
162 	}
163 
164 	@Test
testGetVersion()165 	public void testGetVersion() {
166 		Agent agent = new Agent(options, this);
167 		assertEquals(JaCoCo.VERSION, agent.getVersion());
168 	}
169 
170 	@Test
testGetSetSessionId()171 	public void testGetSetSessionId() throws IOException {
172 		Agent agent = new Agent(options, this);
173 		agent.startup();
174 		agent.setSessionId("agenttestid");
175 		assertEquals("agenttestid", agent.getSessionId());
176 
177 		SessionInfoStore sessionStore = new SessionInfoStore();
178 		ExecutionDataReader reader = new ExecutionDataReader(
179 				new ByteArrayInputStream(agent.getExecutionData(false)));
180 		reader.setSessionInfoVisitor(sessionStore);
181 		reader.read();
182 		assertEquals("agenttestid", sessionStore.getInfos().get(0).getId());
183 	}
184 
185 	@Test
testReset()186 	public void testReset() {
187 		Agent agent = new Agent(options, this);
188 
189 		boolean[] probes = agent.getData()
190 				.getExecutionData(Long.valueOf(0x12345678), "Foo", 1)
191 				.getProbes();
192 		probes[0] = true;
193 
194 		agent.reset();
195 
196 		assertFalse(probes[0]);
197 	}
198 
199 	@Test
testGetExecutionData()200 	public void testGetExecutionData() throws IOException {
201 		options.setSessionId("agenttestid");
202 		Agent agent = new Agent(options, this);
203 		agent.startup();
204 
205 		boolean[] probes = agent.getData()
206 				.getExecutionData(Long.valueOf(0x12345678), "Foo", 1)
207 				.getProbes();
208 		probes[0] = true;
209 
210 		byte[] data = agent.getExecutionData(true);
211 
212 		// ensure reset has been executed
213 		assertFalse(probes[0]);
214 
215 		ExecutionDataStore execStore = new ExecutionDataStore();
216 		SessionInfoStore sessionStore = new SessionInfoStore();
217 
218 		ExecutionDataReader reader = new ExecutionDataReader(
219 				new ByteArrayInputStream(data));
220 		reader.setExecutionDataVisitor(execStore);
221 		reader.setSessionInfoVisitor(sessionStore);
222 		reader.read();
223 
224 		assertEquals("Foo", execStore.get(0x12345678).getName());
225 		assertEquals(1, sessionStore.getInfos().size());
226 		assertEquals("agenttestid", sessionStore.getInfos().get(0).getId());
227 	}
228 
229 	@Test
testDump()230 	public void testDump() throws Exception {
231 		final boolean[] called = new boolean[1];
232 		Agent agent = new Agent(options, this) {
233 			@Override
234 			IAgentOutput createAgentOutput() {
235 				return new IAgentOutput() {
236 					public void startup(AgentOptions options, RuntimeData data) {
237 					}
238 
239 					public void shutdown() throws Exception {
240 					}
241 
242 					public void writeExecutionData(boolean reset) {
243 						assertTrue(reset);
244 						called[0] = true;
245 					}
246 				};
247 			}
248 		};
249 		agent.startup();
250 
251 		agent.dump(true);
252 
253 		assertTrue(called[0]);
254 	}
255 
256 	@Test
testJmx()257 	public void testJmx() throws Exception {
258 		options.setJmx(true);
259 		Agent agent = new Agent(options, this);
260 
261 		agent.startup();
262 
263 		ObjectName objectName = new ObjectName("org.jacoco:type=Runtime");
264 		final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
265 		assertEquals(JaCoCo.VERSION, server.getAttribute(objectName, "Version"));
266 
267 		agent.shutdown();
268 
269 		try {
270 			server.getMBeanInfo(objectName);
271 			fail("InstanceNotFoundException expected");
272 		} catch (InstanceNotFoundException expected) {
273 		}
274 	}
275 
276 	@Test(expected = InstanceNotFoundException.class)
testNoJmx()277 	public void testNoJmx() throws Exception {
278 		Agent agent = new Agent(options, this);
279 		agent.startup();
280 
281 		ObjectName objectName = new ObjectName("org.jacoco:type=Runtime");
282 		ManagementFactory.getPlatformMBeanServer().getMBeanInfo(objectName);
283 	}
284 
285 	// === IExceptionLogger ===
286 
logExeption(Exception ex)287 	public void logExeption(Exception ex) {
288 		exception = ex;
289 	}
290 
291 }
292