Skip to content
This repository has been archived by the owner on Oct 1, 2020. It is now read-only.

Commit

Permalink
Use TCP/IP connection for communication with agent.
Browse files Browse the repository at this point in the history
  • Loading branch information
marchof committed Feb 10, 2012
1 parent 07e849a commit 7b00da9
Show file tree
Hide file tree
Showing 14 changed files with 401 additions and 80 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*******************************************************************************
* Copyright (c) 2006, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc R. Hoffmann - initial API and implementation
*
******************************************************************************/
package com.mountainminds.eclemma.internal.core;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.jacoco.core.data.ExecutionData;
import org.jacoco.core.data.ExecutionDataReader;
import org.jacoco.core.data.ExecutionDataStore;
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.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

/**
* Unit tests for {@link ExecutionDataDumper}.
*/
public class ExecutionDataDumperTest {

@Rule
public TemporaryFolder folder = new TemporaryFolder();
private ExecutionDataDumper dumper;

private PipedOutputStream out;
private RemoteControlWriter writer;

@Before
public void setup() throws IOException {
final IPath path = Path.fromOSString(folder.getRoot().getAbsolutePath());
out = new PipedOutputStream();
final PipedInputStream in = new PipedInputStream();
out.connect(in);
writer = new RemoteControlWriter(out);
dumper = new ExecutionDataDumper(new RemoteControlReader(in),
new ExecutionDataFiles(path));
}

@Test
public void testEmpty() throws Exception {
out.close();
assertNull(dumper.dump());
}

@Test
public void testTwoSessions() throws Exception {
writer.visitSessionInfo(new SessionInfo("Session", 10, 20));
writer.visitClassExecution(new ExecutionData(11, "Clazz1", new boolean[8]));
writer.sendCmdOk();
verifyExecContent(dumper.dump(), "Clazz1");

writer.visitSessionInfo(new SessionInfo("Session", 10, 20));
writer.visitClassExecution(new ExecutionData(11, "Clazz2", new boolean[8]));
writer.sendCmdOk();
out.close();
verifyExecContent(dumper.dump(), "Clazz2");
assertNull(dumper.dump());
}

private void verifyExecContent(IPath path, String... classnames)
throws Exception {
final FileInputStream in = new FileInputStream(path.toFile());
final ExecutionDataReader reader = new ExecutionDataReader(in);
reader.setSessionInfoVisitor(new SessionInfoStore());
final ExecutionDataStore store = new ExecutionDataStore();
reader.setExecutionDataVisitor(store);
while (reader.read()) {
}
in.close();
final Set<String> actual = new HashSet<String>();
for (ExecutionData data : store.getContents()) {
actual.add(data.getName());
}
assertEquals(new HashSet<String>(Arrays.asList(classnames)), actual);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import java.io.File;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.junit.Before;
Expand Down Expand Up @@ -56,19 +55,19 @@ public void testGetAgentFile() throws CoreException {

@Test
public void testGetArgument() throws CoreException {
final String arg = support.getArgument(new Path("here/jacoco.exec"));
final String arg = support.getArgument(12345);
assertTrue(arg, arg.startsWith("-javaagent:"));
assertTrue(
arg,
arg.endsWith("jacocoagent.jar=destfile=here/jacoco.exec,includes=*,excludes=,exclclassloader=sun.reflect.DelegatingClassLoader"));
arg.endsWith("jacocoagent.jar=includes=*,excludes=,exclclassloader=sun.reflect.DelegatingClassLoader,output=tcpclient,port=12345"));
}

@Test
public void testAddArgument() throws CoreException {
ConfigurationMock mock = new ConfigurationMock();
mock.pushResult("OTHER");
final ILaunchConfiguration config = support.addArgument(new Path(
"here/jacoco.exec"), mock.getMock());
final ILaunchConfiguration config = support.addArgument(12345,
mock.getMock());
final String arg = config.getAttribute(
IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, "");
assertTrue(arg, arg.startsWith("OTHER -javaagent:"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2011 Mountainminds GmbH & Co. KG and Contributors
* Copyright (c) 2006, 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
Expand Down Expand Up @@ -110,6 +110,30 @@ public IStatus getStatus(Object param1) {
public static final EclEmmaStatus MERGE_ERROR = new EclEmmaStatus(5010,
IStatus.ERROR, CoreMessages.StatusMERGE_ERROR_message);

/**
* Error while starting the agent server.
*/
public static final EclEmmaStatus AGENTSERVER_START_ERROR = new EclEmmaStatus(
5011, IStatus.ERROR, CoreMessages.StatusAGENTSERVER_START_ERROR_message);

/**
* Error while stopping the agent server.
*/
public static final EclEmmaStatus AGENTSERVER_STOP_ERROR = new EclEmmaStatus(
5012, IStatus.ERROR, CoreMessages.StatusAGENTSERVER_STOP_ERROR_message);

/**
* Error while dumping coverage data.
*/
public static final EclEmmaStatus EXECDATA_DUMP_ERROR = new EclEmmaStatus(
5013, IStatus.ERROR, CoreMessages.StatusEXECDATA_DUMP_ERROR_message);

/**
* Error while requesting an execution data dump.
*/
public static final EclEmmaStatus DUMP_REQUEST_ERROR = new EclEmmaStatus(
5014, IStatus.ERROR, CoreMessages.StatusDUMP_REQUEST_ERROR_message);

/**
* No coverage data file has been created during a coverage launch. This
* status is used to issue an error prompt.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@
package com.mountainminds.eclemma.core.launching;

import java.util.Collections;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.debug.core.DebugPlugin;
Expand All @@ -27,14 +25,13 @@
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.osgi.util.NLS;

import com.mountainminds.eclemma.core.EclEmmaStatus;
import com.mountainminds.eclemma.core.ScopeUtils;
import com.mountainminds.eclemma.internal.core.CoreMessages;
import com.mountainminds.eclemma.internal.core.EclEmmaCorePlugin;
import com.mountainminds.eclemma.internal.core.launching.AgentArgumentSupport;
import com.mountainminds.eclemma.internal.core.launching.AgentServer;
import com.mountainminds.eclemma.internal.core.launching.CoverageLaunch;

/**
Expand All @@ -48,8 +45,6 @@ public abstract class CoverageLauncher implements ICoverageLauncher,
/** Launch mode for the launch delegates used internally. */
public static final String DELEGATELAUNCHMODE = ILaunchManager.RUN_MODE;

protected String launchtype;

protected ILaunchConfigurationDelegate launchdelegate;

protected ILaunchConfigurationDelegate2 launchdelegate2;
Expand All @@ -58,7 +53,7 @@ public abstract class CoverageLauncher implements ICoverageLauncher,

public void setInitializationData(IConfigurationElement config,
String propertyName, Object data) throws CoreException {
launchtype = config.getAttribute("type"); //$NON-NLS-1$
final String launchtype = config.getAttribute("type"); //$NON-NLS-1$
launchdelegate = getLaunchDelegate(launchtype);
if (launchdelegate instanceof ILaunchConfigurationDelegate2) {
launchdelegate2 = (ILaunchConfigurationDelegate2) launchdelegate;
Expand Down Expand Up @@ -87,11 +82,15 @@ public void launch(ILaunchConfiguration configuration, String mode,
return;
}

// Start agent server
final CoverageLaunch coverageLaunch = (CoverageLaunch) launch;
final AgentServer server = coverageLaunch.getAgentServer();
server.start();

// Delegate to run mode launcher
final AgentArgumentSupport argSupport = new AgentArgumentSupport();
final ICoverageLaunch coverageLaunch = (ICoverageLaunch) launch;
final ILaunchConfiguration adjusted = argSupport.addArgument(
coverageLaunch.getExecutionDataFile(), configuration);

server.getPort(), configuration);
launchdelegate.launch(adjusted, DELEGATELAUNCHMODE, launch,
new SubProgressMonitor(monitor, 1));

Expand All @@ -102,11 +101,8 @@ public void launch(ILaunchConfiguration configuration, String mode,

public ILaunch getLaunch(ILaunchConfiguration configuration, String mode)
throws CoreException {
final IPath execfile = EclEmmaCorePlugin.getInstance()
.getExecutionDataFiles().newFile();
final Set<IPackageFragmentRoot> scope = ScopeUtils
.getConfiguredScope(configuration);
return new CoverageLaunch(configuration, execfile, scope);
return new CoverageLaunch(configuration,
ScopeUtils.getConfiguredScope(configuration));
}

public boolean buildForLaunch(ILaunchConfiguration configuration,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2011 Mountainminds GmbH & Co. KG and Contributors
* Copyright (c) 2006, 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
Expand All @@ -13,7 +13,7 @@

import java.util.Set;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.jdt.core.IPackageFragmentRoot;

Expand All @@ -23,13 +23,6 @@
*/
public interface ICoverageLaunch extends ILaunch {

/**
* Returns the location of the execution data file for this launch.
*
* @return absolute path of the coverage data file
*/
public IPath getExecutionDataFile();

/**
* Returns the collection of {@link IPackageFragmentRoot} considered as the
* scope for this launch.
Expand All @@ -38,4 +31,12 @@ public interface ICoverageLaunch extends ILaunch {
*/
public Set<IPackageFragmentRoot> getScope();

/**
* Requests a new for this launch resulting in a new coverage session.
*
* @param reset
* if <code>true</code> execution data is reset for this launch
*/
public void requestDump(boolean reset) throws CoreException;

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2011 Mountainminds GmbH & Co. KG and Contributors
* Copyright (c) 2006, 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
Expand Down Expand Up @@ -37,6 +37,11 @@ public class CoreMessages extends NLS {
public static String StatusEXPORT_ERROR_message;
public static String StatusIMPORT_ERROR_message;
public static String StatusMERGE_ERROR_message;
public static String StatusAGENTSERVER_START_ERROR_message;
public static String StatusAGENTSERVER_STOP_ERROR_message;
public static String StatusEXECDATA_DUMP_ERROR_message;
public static String StatusDUMP_REQUEST_ERROR_message;

public static String StatusNO_COVERAGE_DATA_ERROR_message;

public static String ExportFormatHTML_value;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2011 Mountainminds GmbH & Co. KG and Contributors
* Copyright (c) 2006, 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
Expand All @@ -11,12 +11,7 @@
******************************************************************************/
package com.mountainminds.eclemma.internal.core;

import java.io.File;
import java.text.MessageFormat;
import java.util.Date;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
Expand All @@ -31,9 +26,8 @@

import com.mountainminds.eclemma.core.EclEmmaStatus;
import com.mountainminds.eclemma.core.ICorePreferences;
import com.mountainminds.eclemma.core.ICoverageSession;
import com.mountainminds.eclemma.core.ISessionManager;
import com.mountainminds.eclemma.core.launching.ICoverageLaunch;
import com.mountainminds.eclemma.internal.core.launching.CoverageLaunch;

/**
* Bundle activator for the EclEmma core.
Expand Down Expand Up @@ -77,36 +71,23 @@ public void handleDebugEvents(DebugEvent[] events) {
&& e.getKind() == DebugEvent.TERMINATE) {
final IProcess proc = (IProcess) e.getSource();
final ILaunch launch = proc.getLaunch();
if (launch instanceof ICoverageLaunch) {
final ICoverageLaunch coverage = (ICoverageLaunch) launch;
IPath coveragedatafile = coverage.getExecutionDataFile();
if (checkCoverageDataFile(coveragedatafile)) {
Object[] args = new Object[] {
launch.getLaunchConfiguration().getName(), new Date() };
String description = MessageFormat.format(
CoreMessages.LaunchSessionDescription_value, args);
ICoverageSession session = new CoverageSession(description,
coverage.getScope(), coveragedatafile,
launch.getLaunchConfiguration());
sessionManager.addSession(session,
preferences.getActivateNewSessions(), launch);
}
if (launch instanceof CoverageLaunch) {
final CoverageLaunch coverageLaunch = (CoverageLaunch) launch;
coverageLaunch.getAgentServer().stop();
checkExecutionData(coverageLaunch);
}
}
}
}

private boolean checkCoverageDataFile(IPath path) {
final File file = path.toFile();
final boolean ok = file.exists() && file.length() > 0;
if (!ok) {
private void checkExecutionData(CoverageLaunch launch) {
if (!launch.getAgentServer().hasDataReceived()) {
try {
showPrompt(EclEmmaStatus.NO_COVERAGE_DATA_ERROR.getStatus(), path);
showPrompt(EclEmmaStatus.NO_COVERAGE_DATA_ERROR.getStatus(), launch);
} catch (CoreException e) {
getLog().log(e.getStatus());
}
}
return ok;
}
};

Expand Down Expand Up @@ -160,7 +141,7 @@ public ExecutionDataFiles getExecutionDataFiles() {
}

/**
* Issues an user prompt using the statis handler registered for the given
* Issues an user prompt using the status handler registered for the given
* status.
*
* @param status
Expand Down
Loading

0 comments on commit 7b00da9

Please sign in to comment.