1d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann/*******************************************************************************
2d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors
3d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann * All rights reserved. This program and the accompanying materials
4d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann * are made available under the terms of the Eclipse Public License v1.0
5d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann * which accompanies this distribution, and is available at
6d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann * http://www.eclipse.org/legal/epl-v10.html
7d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann *
8d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann * Contributors:
9d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann *    Marc R. Hoffmann - initial API and implementation
10d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann *
11d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann *******************************************************************************/
12d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannpackage org.jacoco.cli.internal.commands;
13d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
14d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport static org.junit.Assert.assertTrue;
15d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport static org.junit.Assert.fail;
16d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
17d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport java.io.File;
18d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport java.io.IOException;
19d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport java.net.InetAddress;
20d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport java.net.ServerSocket;
21d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport java.net.Socket;
22d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
23d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport org.jacoco.cli.internal.CommandTestBase;
24d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport org.jacoco.core.runtime.IRemoteCommandVisitor;
25d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport org.jacoco.core.runtime.RemoteControlReader;
26d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport org.jacoco.core.runtime.RemoteControlWriter;
27e8b2588d0403c5dd3115ffcba210fd175ef87d78Marc R. Hoffmannimport org.junit.After;
28d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport org.junit.Rule;
29d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport org.junit.Test;
30d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport org.junit.rules.TemporaryFolder;
31d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
32d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann/**
33d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann * Unit tests for {@link Dump}.
34d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann */
35d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannpublic class DumpTest extends CommandTestBase {
36d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
37d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	@Rule
38d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	public TemporaryFolder tmp = new TemporaryFolder();
39d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
40e8b2588d0403c5dd3115ffcba210fd175ef87d78Marc R. Hoffmann	private ServerSocket serverSocket;
41e8b2588d0403c5dd3115ffcba210fd175ef87d78Marc R. Hoffmann
42e8b2588d0403c5dd3115ffcba210fd175ef87d78Marc R. Hoffmann	@After
43e8b2588d0403c5dd3115ffcba210fd175ef87d78Marc R. Hoffmann	public void after() throws IOException {
44e8b2588d0403c5dd3115ffcba210fd175ef87d78Marc R. Hoffmann		if (serverSocket != null) {
45e8b2588d0403c5dd3115ffcba210fd175ef87d78Marc R. Hoffmann			serverSocket.close();
46e8b2588d0403c5dd3115ffcba210fd175ef87d78Marc R. Hoffmann		}
47e8b2588d0403c5dd3115ffcba210fd175ef87d78Marc R. Hoffmann	}
48e8b2588d0403c5dd3115ffcba210fd175ef87d78Marc R. Hoffmann
49d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	@Test
5094ed743f66d67ddff24ccf9b83f120d3edd1f9d2Marc R. Hoffmann	public void should_print_usage_when_no_argument_is_given()
5194ed743f66d67ddff24ccf9b83f120d3edd1f9d2Marc R. Hoffmann			throws Exception {
52d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		execute("dump");
53d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		assertFailure();
54d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		assertContains("Option \"-destfile\" is required", err);
55d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		assertContains("java -jar jacococli.jar dump [-address <address>]",
56d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				err);
57d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	}
58d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
59d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	@Test
6094ed743f66d67ddff24ccf9b83f120d3edd1f9d2Marc R. Hoffmann	public void should_write_dump() throws Exception {
61d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
62d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		File execfile = new File(tmp.getRoot(), "jacoco.exec");
63d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		int port = startMockServer();
64d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
65d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		execute("dump", "-destfile", execfile.getAbsolutePath(), "-port",
66d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				String.valueOf(port));
67d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
68d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		assertOk();
69d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		assertContains("[INFO] Connecting to ", out);
70d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		assertContains("[INFO] Writing execution data to "
71d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				+ execfile.getAbsolutePath(), out);
72d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		assertTrue(execfile.exists());
73d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	}
74d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
75d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	@Test
7694ed743f66d67ddff24ccf9b83f120d3edd1f9d2Marc R. Hoffmann	public void should_log_connection_error_when_retry_is_specified()
7794ed743f66d67ddff24ccf9b83f120d3edd1f9d2Marc R. Hoffmann			throws Exception {
78d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
79d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		File execfile = new File(tmp.getRoot(), "jacoco.exec");
80d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		int port = unusedPort();
81d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
82d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		try {
83d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			execute("dump", "-destfile", execfile.getAbsolutePath(), "-port",
84d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann					String.valueOf(port), "-retry", "1");
85d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			fail("IOException expected");
86d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		} catch (IOException ignore) {
87d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		}
88d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
89d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		assertContains("[WARN] Connection refused", err);
90d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	}
91d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
92d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	private int startMockServer() throws IOException {
93e8b2588d0403c5dd3115ffcba210fd175ef87d78Marc R. Hoffmann		serverSocket = new ServerSocket(0, 0, InetAddress.getByName(null));
94d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		new Thread() {
95d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			@Override
96d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			public void run() {
97d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				try {
98d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann					serveRequest(serverSocket.accept());
99d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				} catch (IOException e) {
100d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann					throw new RuntimeException(e);
101d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				}
102d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			}
103d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		}.start();
104d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		return serverSocket.getLocalPort();
105d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	}
106d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
107d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	private void serveRequest(Socket socket) throws IOException {
108d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		final RemoteControlWriter writer = new RemoteControlWriter(
109d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				socket.getOutputStream());
110d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		final RemoteControlReader reader = new RemoteControlReader(
111d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				socket.getInputStream());
112d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		reader.setRemoteCommandVisitor(new IRemoteCommandVisitor() {
113d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
114d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			public void visitDumpCommand(boolean dump, boolean reset)
115d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann					throws IOException {
116d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				writer.sendCmdOk();
117d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			}
118d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		});
119d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		while (reader.read()) {
120d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		}
121d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	}
122d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
123d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	private int unusedPort() throws IOException {
124d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		final ServerSocket serverSocket = new ServerSocket(0, 0,
125d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				InetAddress.getByName(null));
126d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		final int port = serverSocket.getLocalPort();
127d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		serverSocket.close();
128d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		return port;
129d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	}
130d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
131d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann}
132