blob: d713203d7e48ba4aa0a723ded24f10acc4593aae [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2017 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.internal.output;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import org.jacoco.core.data.ExecutionDataStore;
import org.jacoco.core.data.ExecutionDataWriter;
import org.jacoco.core.data.SessionInfo;
import org.jacoco.core.data.SessionInfoStore;
import org.jacoco.core.runtime.RemoteControlReader;
import org.jacoco.core.runtime.RemoteControlWriter;
import org.jacoco.core.runtime.RuntimeData;
import org.junit.Before;
import org.junit.Test;
/**
* Unit tests for {@link TcpConnection}.
*/
public class TcpConnectionTest extends ExecutorTestBase {
private MockSocketConnection mockConnection;
private RuntimeData data;
@Before
@Override
public void setup() throws Exception {
super.setup();
mockConnection = new MockSocketConnection();
data = new RuntimeData();
}
@Test(expected = IOException.class)
public void testInvalidHeader() throws Exception {
final OutputStream remoteOut = mockConnection.getSocketB()
.getOutputStream();
remoteOut.write(0x01);
remoteOut.write(0xC0);
remoteOut.write(0xCA);
final TcpConnection connection = new TcpConnection(
mockConnection.getSocketA(), data);
connection.init();
connection.run();
}
@Test(expected = IOException.class)
public void testInvalidContent() throws Exception {
final OutputStream remoteOut = mockConnection.getSocketB()
.getOutputStream();
new ExecutionDataWriter(remoteOut);
final TcpConnection con = new TcpConnection(
mockConnection.getSocketA(), data);
con.init();
remoteOut.write(123);
con.run();
}
/**
* Remote endpoint is closed after a valid header has been send.
*/
@Test
public void testRemoteClose() throws Exception {
final OutputStream remoteOut = mockConnection.getSocketB()
.getOutputStream();
new ExecutionDataWriter(remoteOut);
final TcpConnection con = new TcpConnection(
mockConnection.getSocketA(), data);
con.init();
final Future<Void> f = executor.submit(new Callable<Void>() {
public Void call() throws Exception {
con.run();
return null;
}
});
assertBlocks(f);
mockConnection.getSocketB().close();
f.get();
}
/**
* Remote endpoint is closed before even a valid header was send.
*/
public void testRemoteCloseWithoutHeader() throws Throwable {
final TcpConnection con = new TcpConnection(
mockConnection.getSocketA(), data);
final Future<Void> f = executor.submit(new Callable<Void>() {
public Void call() throws Exception {
con.init();
return null;
}
});
assertBlocks(f);
mockConnection.getSocketB().close();
f.get();
}
/**
* Local socket is closed while waiting for commands.
*
* @throws Exception
*/
@Test
public void testLocalClose() throws Exception {
final OutputStream remoteOut = mockConnection.getSocketB()
.getOutputStream();
new ExecutionDataWriter(remoteOut);
final TcpConnection con = new TcpConnection(
mockConnection.getSocketA(), data);
con.init();
final Future<Void> f = executor.submit(new Callable<Void>() {
public Void call() throws Exception {
con.run();
return null;
}
});
assertBlocks(f);
con.close();
f.get();
}
@Test
public void testRemoteDump() throws Exception {
data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42).getProbes()[0] = true;
data.setSessionId("stubid");
final RemoteControlWriter remoteWriter = new RemoteControlWriter(
mockConnection.getSocketB().getOutputStream());
final TcpConnection con = new TcpConnection(
mockConnection.getSocketA(), data);
con.init();
final Future<Void> f = executor.submit(new Callable<Void>() {
public Void call() throws Exception {
con.run();
return null;
}
});
assertBlocks(f);
remoteWriter.visitDumpCommand(true, false);
readAndAssertData();
con.close();
f.get();
}
@Test
public void testLocalDump() throws Exception {
data.getExecutionData(Long.valueOf(0x12345678), "Foo", 42).getProbes()[0] = true;
data.setSessionId("stubid");
new RemoteControlWriter(mockConnection.getSocketB().getOutputStream());
final TcpConnection con = new TcpConnection(
mockConnection.getSocketA(), data);
con.init();
final Future<Void> f = executor.submit(new Callable<Void>() {
public Void call() throws Exception {
con.run();
return null;
}
});
assertBlocks(f);
con.writeExecutionData(false);
readAndAssertData();
con.close();
f.get();
}
@Test
public void testLocalDumpWithoutInit() throws Exception {
final TcpConnection con = new TcpConnection(
mockConnection.getSocketA(), data);
// Must not write any data as we're not initialized:
con.writeExecutionData(false);
assertEquals(0, mockConnection.getSocketB().getInputStream()
.available());
}
private void readAndAssertData() throws IOException {
final RemoteControlReader remoteReader = new RemoteControlReader(
mockConnection.getSocketB().getInputStream());
final ExecutionDataStore execStore = new ExecutionDataStore();
remoteReader.setExecutionDataVisitor(execStore);
final SessionInfoStore infoStore = new SessionInfoStore();
remoteReader.setSessionInfoVisitor(infoStore);
assertTrue(remoteReader.read());
final List<SessionInfo> infos = infoStore.getInfos();
assertEquals(1, infos.size());
assertEquals("stubid", infos.get(0).getId());
assertEquals("Foo", execStore.get(0x12345678).getName());
}
@Test
public void testRemoteReset() throws Exception {
data.getExecutionData(Long.valueOf(123), "Foo", 1).getProbes()[0] = true;
final RemoteControlWriter remoteWriter = new RemoteControlWriter(
mockConnection.getSocketB().getOutputStream());
final TcpConnection con = new TcpConnection(
mockConnection.getSocketA(), data);
con.init();
final Future<Void> f = executor.submit(new Callable<Void>() {
public Void call() throws Exception {
con.run();
return null;
}
});
assertBlocks(f);
remoteWriter.visitDumpCommand(false, true);
final RemoteControlReader remoteReader = new RemoteControlReader(
mockConnection.getSocketB().getInputStream());
final ExecutionDataStore execStore = new ExecutionDataStore();
remoteReader.setExecutionDataVisitor(execStore);
final SessionInfoStore infoStore = new SessionInfoStore();
remoteReader.setSessionInfoVisitor(infoStore);
assertTrue(remoteReader.read());
assertTrue(infoStore.getInfos().isEmpty());
assertTrue(execStore.getContents().isEmpty());
assertFalse(data.getExecutionData(Long.valueOf(123), "Foo", 1)
.getProbes()[0]);
con.close();
f.get();
}
}