aboutsummaryrefslogtreecommitdiff
path: root/org.jacoco.cli.test
diff options
context:
space:
mode:
authorMarc R. Hoffmann <hoffmann@mountainminds.com>2017-05-25 00:53:18 +0200
committerEvgeny Mandrikov <Godin@users.noreply.github.com>2017-05-25 00:53:18 +0200
commit13f12d39db0b3c0ddc60124572e5d4f984be0255 (patch)
tree2e1ea16bf0675dfd83730f48ad48edf2e880df89 /org.jacoco.cli.test
parent10f3ff0dd010d647625ef5937f301126250267d0 (diff)
downloadjacoco-13f12d39db0b3c0ddc60124572e5d4f984be0255.tar.gz
Add Command Line Interface (#525)
Diffstat (limited to 'org.jacoco.cli.test')
-rw-r--r--org.jacoco.cli.test/.classpath20
-rw-r--r--org.jacoco.cli.test/.project30
-rw-r--r--org.jacoco.cli.test/about.html27
-rw-r--r--org.jacoco.cli.test/pom.xml41
-rw-r--r--org.jacoco.cli.test/src/org/jacoco/cli/internal/CommandTestBase.java73
-rw-r--r--org.jacoco.cli.test/src/org/jacoco/cli/internal/MainTest.java80
-rw-r--r--org.jacoco.cli.test/src/org/jacoco/cli/internal/XmlDocumentationTest.java130
-rw-r--r--org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ClassInfoTest.java54
-rw-r--r--org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/DumpTest.java131
-rw-r--r--org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ExecInfoTest.java79
-rw-r--r--org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/InstrumentTest.java132
-rw-r--r--org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/MergeTest.java97
-rw-r--r--org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ReportTest.java151
-rw-r--r--org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/VersionTest.java31
14 files changed, 1076 insertions, 0 deletions
diff --git a/org.jacoco.cli.test/.classpath b/org.jacoco.cli.test/.classpath
new file mode 100644
index 00000000..0ed344a5
--- /dev/null
+++ b/org.jacoco.cli.test/.classpath
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry including="**/*.java" kind="src" output="target/classes" path="src">
+ <attributes>
+ <attribute name="optional" value="true"/>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/org.jacoco.cli.test/.project b/org.jacoco.cli.test/.project
new file mode 100644
index 00000000..fbd366b0
--- /dev/null
+++ b/org.jacoco.cli.test/.project
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.jacoco.cli.test</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+ <linkedResources>
+ <link>
+ <name>.settings</name>
+ <type>2</type>
+ <locationURI>PARENT-1-PROJECT_LOC/org.jacoco.core.test/.settings</locationURI>
+ </link>
+ </linkedResources>
+</projectDescription>
diff --git a/org.jacoco.cli.test/about.html b/org.jacoco.cli.test/about.html
new file mode 100644
index 00000000..d31112db
--- /dev/null
+++ b/org.jacoco.cli.test/about.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>
+ @build.date@
+</p>
+
+<h3>License</h3>
+
+<p>
+ All Content in this plug-in is made available by Mountainminds GmbH &amp; Co.
+ KG, Munich. Unless otherwise indicated below, the Content is provided to you
+ under the terms and conditions of the Eclipse Public License Version 1.0
+ (&quot;EPL&quot;). A copy of the EPL is available at
+ <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+ For purposes of the EPL, "Program" will mean the Content.
+</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/org.jacoco.cli.test/pom.xml b/org.jacoco.cli.test/pom.xml
new file mode 100644
index 00000000..bc3c6b7d
--- /dev/null
+++ b/org.jacoco.cli.test/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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:
+ Evgeny Mandrikov - initial API and implementation
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jacoco</groupId>
+ <artifactId>org.jacoco.tests</artifactId>
+ <version>0.7.10-SNAPSHOT</version>
+ <relativePath>../org.jacoco.tests</relativePath>
+ </parent>
+
+ <artifactId>org.jacoco.cli.test</artifactId>
+
+ <name>JaCoCo :: Test :: Command Line Interface</name>
+
+ <properties>
+ <jacoco.includes>org.jacoco.cli.*</jacoco.includes>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>org.jacoco.cli</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/org.jacoco.cli.test/src/org/jacoco/cli/internal/CommandTestBase.java b/org.jacoco.cli.test/src/org/jacoco/cli/internal/CommandTestBase.java
new file mode 100644
index 00000000..4d12a373
--- /dev/null
+++ b/org.jacoco.cli.test/src/org/jacoco/cli/internal/CommandTestBase.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * 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.cli.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+
+import org.junit.Before;
+
+/**
+ * Base class for command tests.
+ */
+public abstract class CommandTestBase {
+
+ protected StringWriter out;
+ protected StringWriter err;
+ protected int result;
+
+ @Before
+ public void before() {
+ out = new StringWriter();
+ err = new StringWriter();
+ }
+
+ protected int execute(String... args) throws Exception {
+ result = new Main(args).execute(new PrintWriter(out),
+ new PrintWriter(err));
+ return result;
+ }
+
+ protected void assertOk() {
+ assertEquals(err.toString(), 0, result);
+ }
+
+ protected void assertFailure() {
+ assertEquals(-1, result);
+ }
+
+ protected void assertNoOutput(StringWriter buffer) {
+ assertEquals("", buffer.toString());
+ }
+
+ protected void assertContains(String expected, StringWriter buffer) {
+ final String content = buffer.toString();
+ assertTrue(content, content.contains(expected));
+ }
+
+ protected String getClassPath() {
+ final String name = getClass().getName();
+ final String res = "/" + name.replace('.', '/') + ".class";
+ String loc = getClass().getResource(res).getFile();
+ try {
+ loc = URLDecoder.decode(loc, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ }
+ return loc.substring(0, loc.length() - res.length());
+ }
+
+}
diff --git a/org.jacoco.cli.test/src/org/jacoco/cli/internal/MainTest.java b/org.jacoco.cli.test/src/org/jacoco/cli/internal/MainTest.java
new file mode 100644
index 00000000..5a0d7424
--- /dev/null
+++ b/org.jacoco.cli.test/src/org/jacoco/cli/internal/MainTest.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * 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.cli.internal;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link Main}.
+ */
+public class MainTest extends CommandTestBase {
+
+ @Test
+ public void should_print_usage_when_no_arguments_given() throws Exception {
+ execute();
+
+ assertFailure();
+ assertNoOutput(out);
+ assertContains("Argument \"<command>\" is required", err);
+ assertContains("Usage: java -jar jacococli.jar --help | <command>",
+ err);
+ assertContains("Command line interface for JaCoCo.", err);
+ }
+
+ @Test
+ public void should_print_error_message_when_invalid_command_is_given()
+ throws Exception {
+ execute("foo");
+
+ assertFailure();
+ assertNoOutput(out);
+ assertContains("\"foo\" is not a valid value for \"<command>\"", err);
+ assertContains("Usage: java -jar jacococli.jar --help | <command>",
+ err);
+ }
+
+ @Test
+ public void should_print_general_usage_when_help_option_is_given()
+ throws Exception {
+ execute("--help");
+
+ assertOk();
+ assertNoOutput(err);
+ assertContains("Usage: java -jar jacococli.jar --help | <command>",
+ out);
+ assertContains("<command> : dump|instrument|merge|report", out);
+ }
+
+ @Test
+ public void should_print_command_usage_when_command_and_help_option_is_given()
+ throws Exception {
+ execute("dump", "--help");
+
+ assertOk();
+ assertNoOutput(err);
+ assertContains("Usage: java -jar jacococli.jar dump", out);
+ assertContains(
+ "Request execution data from a JaCoCo agent running in 'tcpserver' output mode.",
+ out);
+ }
+
+ @Test
+ public void should_not_print_any_output_when_quiet_option_is_given()
+ throws Exception {
+ execute("version", "--quiet");
+
+ assertOk();
+ assertNoOutput(out);
+ assertNoOutput(err);
+ }
+
+}
diff --git a/org.jacoco.cli.test/src/org/jacoco/cli/internal/XmlDocumentationTest.java b/org.jacoco.cli.test/src/org/jacoco/cli/internal/XmlDocumentationTest.java
new file mode 100644
index 00000000..83f79bc9
--- /dev/null
+++ b/org.jacoco.cli.test/src/org/jacoco/cli/internal/XmlDocumentationTest.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * 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.cli.internal;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.w3c.dom.Document;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+/**
+ * Unit tests for {@link XmlDocumentation}.
+ */
+public class XmlDocumentationTest {
+
+ @Rule
+ public TemporaryFolder tmp = new TemporaryFolder();
+
+ private DocumentBuilder builder;
+ private XPath xpath;
+
+ @Before
+ public void before() throws Exception {
+ final DocumentBuilderFactory builderFactory = DocumentBuilderFactory
+ .newInstance();
+ builder = builderFactory.newDocumentBuilder();
+ builder.setErrorHandler(new ErrorHandler() {
+ public void error(SAXParseException exception) throws SAXException {
+ fail(exception.getMessage());
+ }
+
+ public void fatalError(SAXParseException exception)
+ throws SAXException {
+ fail(exception.getMessage());
+ }
+
+ public void warning(SAXParseException exception)
+ throws SAXException {
+ fail(exception.getMessage());
+ }
+ });
+
+ xpath = XPathFactory.newInstance().newXPath();
+ }
+
+ @Test
+ public void should_create_documentation() throws Exception {
+ File file = new File(tmp.getRoot(), "doc.xml");
+
+ XmlDocumentation.main(file.getAbsolutePath());
+
+ Document doc = parse(file);
+
+ assertContains("java -jar jacococli.jar report",
+ "/documentation/command[@name='report']/usage/text()", doc);
+
+ assertContains("Generate reports",
+ "/documentation/command[@name='report']/description/text()",
+ doc);
+
+ assertContains("<execfiles>",
+ "/documentation/command[@name='report']/option[1]/usage/text()",
+ doc);
+
+ assertContains("false",
+ "/documentation/command[@name='report']/option[1]/@required",
+ doc);
+
+ assertContains("true",
+ "/documentation/command[@name='report']/option[1]/@multiple",
+ doc);
+
+ assertContains("-classfiles <path>",
+ "/documentation/command[@name='report']/option[2]/usage/text()",
+ doc);
+
+ assertContains("true",
+ "/documentation/command[@name='report']/option[2]/@multiple",
+ doc);
+
+ }
+
+ private Document parse(File file) throws Exception {
+ InputStream in = new FileInputStream(file);
+ try {
+ return builder.parse(new InputSource(in));
+ } finally {
+ in.close();
+ }
+ }
+
+ private void assertContains(String expected, String query, Document doc)
+ throws XPathExpressionException {
+ final String actual = eval(query, doc);
+ assertTrue(actual, actual.contains(expected));
+ }
+
+ private String eval(String query, Document doc)
+ throws XPathExpressionException {
+ return (String) xpath.evaluate(query, doc, XPathConstants.STRING);
+ }
+
+}
diff --git a/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ClassInfoTest.java b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ClassInfoTest.java
new file mode 100644
index 00000000..62934e28
--- /dev/null
+++ b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ClassInfoTest.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.cli.internal.commands;
+
+import org.jacoco.cli.internal.CommandTestBase;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link ClassInfo}.
+ */
+public class ClassInfoTest extends CommandTestBase {
+
+ @Test
+ public void should_print_usage_when_invalid_option_is_given()
+ throws Exception {
+ execute("classinfo", "--invalid");
+
+ assertFailure();
+ assertContains("\"--invalid\" is not a valid option", err);
+ assertContains(
+ "java -jar jacococli.jar classinfo [<classlocations> ...]",
+ err);
+ }
+
+ @Test
+ public void should_print_warning_when_no_class_files_are_provided()
+ throws Exception {
+ execute("classinfo");
+
+ assertOk();
+ assertContains("[WARN] No class files provided.", out);
+ }
+
+ @Test
+ public void should_print_class_info() throws Exception {
+ execute("classinfo", getClassPath());
+
+ assertOk();
+ assertContains(
+ "class name: org/jacoco/cli/internal/commands/ClassInfoTest",
+ out);
+ assertContains("methods: 4", out);
+ }
+
+}
diff --git a/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/DumpTest.java b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/DumpTest.java
new file mode 100644
index 00000000..3a859f52
--- /dev/null
+++ b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/DumpTest.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * 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.cli.internal.commands;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import org.jacoco.cli.internal.CommandTestBase;
+import org.jacoco.core.runtime.IRemoteCommandVisitor;
+import org.jacoco.core.runtime.RemoteControlReader;
+import org.jacoco.core.runtime.RemoteControlWriter;
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * Unit tests for {@link Dump}.
+ */
+public class DumpTest extends CommandTestBase {
+
+ @Rule
+ public TemporaryFolder tmp = new TemporaryFolder();
+
+ private ServerSocket serverSocket;
+
+ @After
+ public void after() throws IOException {
+ if (serverSocket != null) {
+ serverSocket.close();
+ }
+ }
+
+ @Test
+ public void should_print_usage_when_no_argument_is_given()
+ throws Exception {
+ execute("dump");
+ assertFailure();
+ assertContains("Option \"--destfile\" is required", err);
+ assertContains("java -jar jacococli.jar dump [--address <address>]",
+ err);
+ }
+
+ @Test
+ public void should_write_dump() throws Exception {
+
+ File execfile = new File(tmp.getRoot(), "jacoco.exec");
+ int port = startMockServer();
+
+ execute("dump", "--destfile", execfile.getAbsolutePath(), "--port",
+ String.valueOf(port));
+
+ assertOk();
+ assertContains("[INFO] Connecting to ", out);
+ assertContains("[INFO] Writing execution data to "
+ + execfile.getAbsolutePath(), out);
+ assertTrue(execfile.exists());
+ }
+
+ @Test
+ public void should_log_connection_error_when_retry_is_specified()
+ throws Exception {
+
+ File execfile = new File(tmp.getRoot(), "jacoco.exec");
+ int port = unusedPort();
+
+ try {
+ execute("dump", "--destfile", execfile.getAbsolutePath(), "--port",
+ String.valueOf(port), "--retry", "1");
+ fail("IOException expected");
+ } catch (IOException ignore) {
+ }
+
+ assertContains("[WARN] Connection refused", err);
+ }
+
+ private int startMockServer() throws IOException {
+ serverSocket = new ServerSocket(0, 0, InetAddress.getByName(null));
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ serveRequest(serverSocket.accept());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }.start();
+ return serverSocket.getLocalPort();
+ }
+
+ private void serveRequest(Socket socket) throws IOException {
+ final RemoteControlWriter writer = new RemoteControlWriter(
+ socket.getOutputStream());
+ final RemoteControlReader reader = new RemoteControlReader(
+ socket.getInputStream());
+ reader.setRemoteCommandVisitor(new IRemoteCommandVisitor() {
+
+ public void visitDumpCommand(boolean dump, boolean reset)
+ throws IOException {
+ writer.sendCmdOk();
+ }
+ });
+ while (reader.read()) {
+ }
+ }
+
+ private int unusedPort() throws IOException {
+ final ServerSocket serverSocket = new ServerSocket(0, 0,
+ InetAddress.getByName(null));
+ final int port = serverSocket.getLocalPort();
+ serverSocket.close();
+ return port;
+ }
+
+}
diff --git a/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ExecInfoTest.java b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ExecInfoTest.java
new file mode 100644
index 00000000..54540865
--- /dev/null
+++ b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ExecInfoTest.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * 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.cli.internal.commands;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.jacoco.cli.internal.CommandTestBase;
+import org.jacoco.core.data.ExecutionData;
+import org.jacoco.core.data.ExecutionDataWriter;
+import org.jacoco.core.data.SessionInfo;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * Unit tests for {@link ExecInfo}.
+ */
+public class ExecInfoTest extends CommandTestBase {
+
+ @Rule
+ public TemporaryFolder tmp = new TemporaryFolder();
+
+ @Test
+ public void should_print_usage_when_invalid_argument_is_given()
+ throws Exception {
+ execute("execinfo", "--invalid");
+
+ assertFailure();
+ assertContains("\"--invalid\" is not a valid option", err);
+ assertContains("java -jar jacococli.jar execinfo [<execfiles> ...]",
+ err);
+ }
+
+ @Test
+ public void should_print_warning_when_no_exec_files_are_provided()
+ throws Exception {
+ execute("execinfo");
+
+ assertOk();
+ assertContains("[WARN] No execution data files provided.", out);
+ }
+
+ @Test
+ public void should_print_execution_data_info() throws Exception {
+ File execfile = createExecFile();
+
+ execute("execinfo", execfile.getAbsolutePath());
+
+ assertOk();
+ assertContains("[INFO] Loading exec file " + execfile.getAbsolutePath(),
+ out);
+ assertContains("CLASS ID HITS/PROBES CLASS NAME", out);
+ assertContains("Session \"testid\":", out);
+ assertContains("0000000000001234 2 of 3 foo/MyClass", out);
+ }
+
+ private File createExecFile() throws IOException {
+ File f = new File(tmp.getRoot(), "test.exec");
+ final FileOutputStream out = new FileOutputStream(f);
+ final ExecutionDataWriter writer = new ExecutionDataWriter(out);
+ writer.visitSessionInfo(new SessionInfo("testid", 1, 2));
+ writer.visitClassExecution(new ExecutionData(0x1234, "foo/MyClass",
+ new boolean[] { false, true, true }));
+ out.close();
+ return f;
+ }
+
+}
diff --git a/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/InstrumentTest.java b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/InstrumentTest.java
new file mode 100644
index 00000000..5d70b48c
--- /dev/null
+++ b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/InstrumentTest.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * 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.cli.internal.commands;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.jacoco.cli.internal.CommandTestBase;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * Unit tests for {@link Instrument}.
+ */
+public class InstrumentTest extends CommandTestBase {
+
+ @Rule
+ public TemporaryFolder tmp = new TemporaryFolder();
+
+ @Test
+ public void should_print_usage_when_no_options_are_given()
+ throws Exception {
+ execute("instrument");
+ assertFailure();
+ assertContains("Option \"--dest\" is required", err);
+ assertContains(
+ "Usage: java -jar jacococli.jar instrument [<sourcefiles> ...]",
+ err);
+ }
+
+ @Test
+ public void should_instrument_class_files_and_copy_resources()
+ throws Exception {
+ File destdir = tmp.getRoot();
+
+ execute("instrument", "--dest", destdir.getAbsolutePath(),
+ getClassPath());
+
+ assertOk();
+ assertContains("[INFO] 14 classes instrumented to "
+ + destdir.getAbsolutePath(), out);
+
+ // non class-file resources are copied:
+ assertTrue(new File(destdir, "about.html").isFile());
+
+ assertInstrumented(new File(destdir,
+ "org/jacoco/cli/internal/commands/InstrumentTest.class"));
+ }
+
+ @Test
+ public void should_not_instrument_anything_when_no_source_is_given()
+ throws Exception {
+ File destdir = tmp.getRoot();
+
+ execute("instrument", "--dest", destdir.getAbsolutePath());
+
+ assertOk();
+ assertArrayEquals(new String[0], destdir.list());
+ }
+
+ @Test
+ public void should_not_create_dest_file_when_source_class_is_broken()
+ throws Exception {
+ File srcdir = new File(tmp.getRoot(), "src");
+ srcdir.mkdir();
+ File destdir = new File(tmp.getRoot(), "dest");
+ destdir.mkdir();
+
+ OutputStream out = new FileOutputStream(
+ new File(srcdir, "Broken.class"));
+ out.write((byte) 0xca);
+ out.write((byte) 0xfe);
+ out.write((byte) 0xba);
+ out.write((byte) 0xbe);
+ out.write((byte) 0x00);
+ out.write((byte) 0x00);
+ out.write((byte) 0x00);
+ out.write((byte) 50);
+ out.close();
+
+ try {
+ execute("instrument", "--dest", destdir.getAbsolutePath(),
+ srcdir.getAbsolutePath());
+ fail("exception expected");
+ } catch (IOException expected) {
+ }
+
+ assertFalse(new File(destdir, "Broken.class").exists());
+ }
+
+ private void assertInstrumented(File classfile) throws IOException {
+ InputStream in = new FileInputStream(classfile);
+ ClassReader reader = new ClassReader(in);
+ in.close();
+ final Set<String> fields = new HashSet<String>();
+ reader.accept(new ClassVisitor(Opcodes.ASM5) {
+ @Override
+ public FieldVisitor visitField(int access, String name, String desc,
+ String signature, Object value) {
+ fields.add(name);
+ return null;
+ }
+ }, 0);
+ assertTrue(fields.contains("$jacocoData"));
+ }
+
+}
diff --git a/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/MergeTest.java b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/MergeTest.java
new file mode 100644
index 00000000..ea534751
--- /dev/null
+++ b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/MergeTest.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * 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.cli.internal.commands;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.jacoco.cli.internal.CommandTestBase;
+import org.jacoco.core.data.ExecutionData;
+import org.jacoco.core.data.ExecutionDataWriter;
+import org.jacoco.core.tools.ExecFileLoader;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * Unit tests for {@link Merge}.
+ */
+public class MergeTest extends CommandTestBase {
+
+ @Rule
+ public TemporaryFolder tmp = new TemporaryFolder();
+
+ @Test
+ public void should_print_usage_when_no_options_are_given()
+ throws Exception {
+ execute("merge");
+
+ assertFailure();
+ assertContains("Option \"--destfile\" is required", err);
+ assertContains("java -jar jacococli.jar merge [<execfiles> ...]", err);
+ }
+
+ @Test
+ public void should_print_warning_when_no_exec_files_are_provided()
+ throws Exception {
+ File dest = new File(tmp.getRoot(), "merged.exec");
+ execute("merge", "--destfile", dest.getAbsolutePath());
+
+ assertOk();
+ assertContains("[WARN] No execution data files provided.", out);
+ Set<String> names = loadExecFile(dest);
+ assertEquals(Collections.emptySet(), names);
+ }
+
+ @Test
+ public void should_merge_exec_files() throws Exception {
+ File a = createExecFile("a");
+ File b = createExecFile("b");
+ File c = createExecFile("c");
+ File dest = new File(tmp.getRoot(), "merged.exec");
+
+ execute("merge", "--destfile", dest.getAbsolutePath(),
+ a.getAbsolutePath(), b.getAbsolutePath(), c.getAbsolutePath());
+
+ assertOk();
+ Set<String> names = loadExecFile(dest);
+ assertEquals(new HashSet<String>(Arrays.asList("a", "b", "c")), names);
+ }
+
+ private File createExecFile(String name) throws IOException {
+ File file = new File(tmp.getRoot(), name + ".exec");
+ final FileOutputStream execout = new FileOutputStream(file);
+ ExecutionDataWriter writer = new ExecutionDataWriter(execout);
+ writer.visitClassExecution(new ExecutionData(name.hashCode(), name,
+ new boolean[] { true }));
+ execout.close();
+ return file;
+ }
+
+ private Set<String> loadExecFile(File file) throws IOException {
+ ExecFileLoader loader = new ExecFileLoader();
+ loader.load(file);
+ Set<String> names = new HashSet<String>();
+ for (ExecutionData d : loader.getExecutionDataStore().getContents()) {
+ names.add(d.getName());
+ }
+ return names;
+ }
+
+}
diff --git a/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ReportTest.java b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ReportTest.java
new file mode 100644
index 00000000..77564c8f
--- /dev/null
+++ b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/ReportTest.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * 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.cli.internal.commands;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+import org.jacoco.cli.internal.CommandTestBase;
+import org.jacoco.core.data.ExecutionData;
+import org.jacoco.core.data.ExecutionDataWriter;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * Unit tests for {@link Report}.
+ */
+public class ReportTest extends CommandTestBase {
+
+ @Rule
+ public TemporaryFolder tmp = new TemporaryFolder();
+
+ @Test
+ public void should_print_usage_when_no_options_are_given()
+ throws Exception {
+ execute("report");
+
+ assertFailure();
+ assertContains("Option \"--classfiles\" is required", err);
+ assertContains(
+ "Usage: java -jar jacococli.jar report [<execfiles> ...]", err);
+ }
+
+ @Test
+ public void should_print_warning_when_no_exec_files_are_provided()
+ throws Exception {
+ execute("report", "--classfiles", getClassPath());
+
+ assertOk();
+ assertContains("[WARN] No execution data files provided.", out);
+ }
+
+ @Test
+ public void should_print_number_of_analyzed_classes() throws Exception {
+ execute("report", "--classfiles", getClassPath());
+
+ assertOk();
+ assertContains("[INFO] Analyzing 14 classes.", out);
+ }
+
+ @Test
+ public void should_print_warning_when_exec_data_does_not_match()
+ throws Exception {
+ File exec = new File(tmp.getRoot(), "jacoco.exec");
+ final FileOutputStream execout = new FileOutputStream(exec);
+ ExecutionDataWriter writer = new ExecutionDataWriter(execout);
+ // Add probably invalid id for this test class:
+ writer.visitClassExecution(
+ new ExecutionData(0x123, getClass().getName().replace('.', '/'),
+ new boolean[] { true }));
+ execout.close();
+
+ execute("report", exec.getAbsolutePath(), "--classfiles",
+ getClassPath());
+
+ assertOk();
+ assertContains("[WARN] Some classes do not match with execution data.",
+ out);
+ assertContains(
+ "[WARN] For report generation the same class files must be used as at runtime.",
+ out);
+ assertContains(
+ "[WARN] Execution data for class org/jacoco/cli/internal/commands/ReportTest does not match.",
+ out);
+ }
+
+ @Test
+ public void should_create_xml_report_when_xml_option_is_provided()
+ throws Exception {
+ File xml = new File(tmp.getRoot(), "coverage.xml");
+
+ execute("report", "--classfiles", getClassPath(), "--xml",
+ xml.getAbsolutePath());
+
+ assertOk();
+ assertTrue(xml.isFile());
+ }
+
+ @Test
+ public void should_create_csv_report_when_csv_option_is_provided()
+ throws Exception {
+ File csv = new File(tmp.getRoot(), "coverage.csv");
+
+ execute("report", "--classfiles", getClassPath(), "--csv",
+ csv.getAbsolutePath());
+
+ assertOk();
+ assertTrue(csv.isFile());
+ }
+
+ @Test
+ public void should_create_html_report_when_html_option_is_provided()
+ throws Exception {
+ File html = new File(tmp.getRoot(), "coverage");
+
+ execute("report", "--classfiles", getClassPath(), "--sourcefiles",
+ "./src", "--html", html.getAbsolutePath());
+
+ assertOk();
+ assertTrue(html.isDirectory());
+ assertTrue(new File(html,
+ "org.jacoco.cli.internal.commands/ReportTest.html").isFile());
+ assertTrue(new File(html,
+ "org.jacoco.cli.internal.commands/ReportTest.java.html")
+ .isFile());
+ }
+
+ @Test
+ public void should_use_all_values_when_multiple_classfiles_options_are_provided()
+ throws Exception {
+ File html = new File(tmp.getRoot(), "coverage");
+
+ final String c1 = getClassPath()
+ + "/org/jacoco/cli/internal/commands/ReportTest.class";
+ final String c2 = getClassPath()
+ + "/org/jacoco/cli/internal/commands/DumpTest.class";
+
+ execute("report", "--classfiles", c1, "--classfiles", c2, "--html",
+ html.getAbsolutePath());
+
+ assertOk();
+ assertTrue(html.isDirectory());
+ assertTrue(new File(html,
+ "org.jacoco.cli.internal.commands/ReportTest.html").isFile());
+ assertTrue(
+ new File(html, "org.jacoco.cli.internal.commands/DumpTest.html")
+ .isFile());
+ }
+
+}
diff --git a/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/VersionTest.java b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/VersionTest.java
new file mode 100644
index 00000000..56b259a5
--- /dev/null
+++ b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/VersionTest.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * 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.cli.internal.commands;
+
+import org.jacoco.cli.internal.CommandTestBase;
+import org.jacoco.core.JaCoCo;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link Version}.
+ */
+public class VersionTest extends CommandTestBase {
+
+ @Test
+ public void should_print_version() throws Exception {
+ execute("version");
+
+ assertOk();
+ assertContains(JaCoCo.VERSION, out);
+ }
+
+}