Mercurial > hg > thermostat-ng > web-gateway
changeset 152:428032cdc6fc
Add base infrastructure for integration tests
Reviewed-by: jerboaa
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-May/023104.html
author | Jie Kang <jkang@redhat.com> |
---|---|
date | Tue, 16 May 2017 11:52:33 -0400 |
parents | c8192ee541b9 |
children | de6a3c5c2321 |
files | pom.xml tests/integration-tests/pom.xml tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/tests/integration/IntegrationTest.java tests/pom.xml tests/test-utils/pom.xml tests/test-utils/src/main/java/com/redhat/thermostat/gateway/tests/utils/MongodTestUtil.java tests/test-utils/src/main/java/com/redhat/thermostat/gateway/tests/utils/ProcessTestUtil.java |
diffstat | 8 files changed, 692 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/pom.xml Thu May 11 02:35:17 2017 -0400 +++ b/pom.xml Tue May 16 11:52:33 2017 -0400 @@ -53,10 +53,13 @@ <module>distribution</module> <module>common</module> <module>services</module> + + <module>tests</module> </modules> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.7</java.version> <jersey.version>2.25</jersey.version> <jetty.version>9.2.19.v20160908</jetty.version>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/integration-tests/pom.xml Tue May 16 11:52:33 2017 -0400 @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Copyright 2012-2017 Red Hat, Inc. + + This file is part of Thermostat. + + Thermostat is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + Thermostat is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Thermostat; see the file COPYING. If not see + <http://www.gnu.org/licenses/>. + + Linking this code with other modules is making a combined work + based on this code. Thus, the terms and conditions of the GNU + General Public License cover the whole combination. + + As a special exception, the copyright holders of this code give + you permission to link this code with independent modules to + produce an executable, regardless of the license terms of these + independent modules, and to copy and distribute the resulting + executable under terms of your choice, provided that you also + meet, for each linked independent module, the terms and conditions + of the license of that module. An independent module is a module + which is not derived from or based on this code. If you modify + this code, you may extend this exception to your version of the + library, but you are not obligated to do so. If you do not wish + to do so, delete this exception statement from your version. + +--> +<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/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-web-gateway-tests</artifactId> + <version>1.99.12-SNAPSHOT</version> + </parent> + + <artifactId>thermostat-web-gateway-tests-integration</artifactId> + + <packaging>jar</packaging> + + <name>Thermostat Web Gateway Integration Tests</name> + + <build> + <plugins> + <plugin> + <artifactId>maven-failsafe-plugin</artifactId> + <version>2.19.1</version> + <executions> + <execution> + <configuration> + <redirectTestOutputToFile>true</redirectTestOutputToFile> + <skip>${maven.itest.skip}</skip> + </configuration> + <goals> + <goal>integration-test</goal> + <goal>verify</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <version>3.0.2</version> + <configuration> + <skipIfEmpty>true</skipIfEmpty> + </configuration> + <executions> + <execution> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <dependencies> + <!-- Thermostat Web Gateway dependencies --> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-web-gateway-distribution</artifactId> + <version>${project.version}</version> + <type>pom</type> + </dependency> + + <!-- Test dependencies --> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-web-gateway-tests-utils</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>${junit.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-client</artifactId> + <version>${jetty.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + +</project> +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java Tue May 16 11:52:33 2017 -0400 @@ -0,0 +1,69 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + + +package com.redhat.thermostat.gateway.service.jvm.gc; + +import static org.junit.Assert.assertEquals; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.http.HttpMethod; +import org.junit.Before; +import org.junit.Test; + +import com.redhat.thermostat.gateway.tests.integration.IntegrationTest; + +public class JvmGcServiceIntegrationTest extends IntegrationTest { + + private final String collectionName = "jvm-gc"; + private final String gcUrl = baseUrl + "/jvm-gc/0.0.2"; + + @Before + public void beforeIntegrationTest() { + mongodTestUtil.dropCollection(collectionName); + } + + @Test + public void testGet() throws InterruptedException, TimeoutException, ExecutionException { + ContentResponse response = client.newRequest(gcUrl).method(HttpMethod.GET).send(); + assertEquals(200, response.getStatus()); + String expected = "{ \"response\" : [] }"; + assertEquals(expected, response.getContentAsString()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/tests/integration/IntegrationTest.java Tue May 16 11:52:33 2017 -0400 @@ -0,0 +1,127 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.gateway.tests.integration; + +import static org.junit.Assert.fail; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.eclipse.jetty.client.HttpClient; +import org.junit.AfterClass; +import org.junit.BeforeClass; + +import com.redhat.thermostat.gateway.tests.utils.MongodTestUtil; +import com.redhat.thermostat.gateway.tests.utils.ProcessTestUtil; + +public class IntegrationTest { + protected static HttpClient client; + protected static String baseUrl = "http://127.0.0.1:30000"; + + protected static final MongodTestUtil mongodTestUtil = new MongodTestUtil(); + private static final Path distributionImage = Paths.get("../../distribution/target/image"); + private static final String WEB_GATEWAY_SCRIPT = "thermostat-web-gateway.sh"; + + private static Process serverProcess; + + @BeforeClass + public static void beforeClassIntegrationTest() throws Exception { + mongodTestUtil.startMongod(); + setupMongoCredentials(); + + client = new HttpClient(); + client.start(); + + startServer(); + } + + private static void setupMongoCredentials() throws IOException, InterruptedException { + Path mongoSetup = distributionImage.resolve("etc/mongo-dev-setup.js"); + + ProcessBuilder processBuilder = new ProcessBuilder().command("mongo", mongodTestUtil.listenAddress, mongoSetup.toAbsolutePath().toString()).inheritIO(); + Process mongoProcess = processBuilder.start(); + mongoProcess.waitFor(); + } + + private static void startServer() throws IOException, InterruptedException { + String command = distributionImage.resolve("bin").resolve(WEB_GATEWAY_SCRIPT).toAbsolutePath().toString(); + + ProcessBuilder processBuilder = new ProcessBuilder().command(command).inheritIO().redirectError(ProcessBuilder.Redirect.PIPE); + + serverProcess = processBuilder.start(); + final BufferedReader reader = new BufferedReader(new InputStreamReader(serverProcess.getErrorStream())); + + Future<Boolean> f = Executors.newFixedThreadPool(1).submit(new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + String line; + while ((line = reader.readLine()) != null && !line.contains("Server:main: Started")) { + System.out.println(line); + } + return true; + } + }); + + try { + f.get(5000L, TimeUnit.MILLISECONDS); + } catch (ExecutionException | TimeoutException e) { + fail(); + } + } + + + + private static void stopServer() throws Exception { + ProcessTestUtil.killRecursively(serverProcess); + } + + @AfterClass + public static void afterClassIntegrationTest() throws Exception { + mongodTestUtil.stopMongod(); + client.stop(); + stopServer(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/pom.xml Tue May 16 11:52:33 2017 -0400 @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Copyright 2012-2017 Red Hat, Inc. + + This file is part of Thermostat. + + Thermostat is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + Thermostat is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Thermostat; see the file COPYING. If not see + <http://www.gnu.org/licenses/>. + + Linking this code with other modules is making a combined work + based on this code. Thus, the terms and conditions of the GNU + General Public License cover the whole combination. + + As a special exception, the copyright holders of this code give + you permission to link this code with independent modules to + produce an executable, regardless of the license terms of these + independent modules, and to copy and distribute the resulting + executable under terms of your choice, provided that you also + meet, for each linked independent module, the terms and conditions + of the license of that module. An independent module is a module + which is not derived from or based on this code. If you modify + this code, you may extend this exception to your version of the + library, but you are not obligated to do so. If you do not wish + to do so, delete this exception statement from your version. + +--> +<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/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-web-gateway</artifactId> + <version>1.99.12-SNAPSHOT</version> + </parent> + + <artifactId>thermostat-web-gateway-tests</artifactId> + <packaging>pom</packaging> + + <name>Thermostat Web Gateway Tests</name> + + <modules> + <module>integration-tests</module> + <module>test-utils</module> + </modules> +</project> +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-utils/pom.xml Tue May 16 11:52:33 2017 -0400 @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Copyright 2012-2017 Red Hat, Inc. + + This file is part of Thermostat. + + Thermostat is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + Thermostat is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Thermostat; see the file COPYING. If not see + <http://www.gnu.org/licenses/>. + + Linking this code with other modules is making a combined work + based on this code. Thus, the terms and conditions of the GNU + General Public License cover the whole combination. + + As a special exception, the copyright holders of this code give + you permission to link this code with independent modules to + produce an executable, regardless of the license terms of these + independent modules, and to copy and distribute the resulting + executable under terms of your choice, provided that you also + meet, for each linked independent module, the terms and conditions + of the license of that module. An independent module is a module + which is not derived from or based on this code. If you modify + this code, you may extend this exception to your version of the + library, but you are not obligated to do so. If you do not wish + to do so, delete this exception statement from your version. + +--> +<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/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>thermostat-web-gateway-tests</artifactId> + <groupId>com.redhat.thermostat</groupId> + <version>1.99.12-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>thermostat-web-gateway-tests-utils</artifactId> + <name>Thermostat Web Gateway Test Utilities</name> + <packaging>jar</packaging> + + <dependencies> + <!-- Thermostat Web Gateway dependencies --> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-web-gateway-common-mongodb</artifactId> + <version>${project.version}</version> + </dependency> + <!-- MongoDB dependencies --> + <dependency> + <groupId>org.mongodb</groupId> + <artifactId>mongo-java-driver</artifactId> + <version>${mongo-java-driver.version}</version> + </dependency> + </dependencies> +</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-utils/src/main/java/com/redhat/thermostat/gateway/tests/utils/MongodTestUtil.java Tue May 16 11:52:33 2017 -0400 @@ -0,0 +1,133 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.gateway.tests.utils; + +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; + +import org.bson.Document; + +import com.mongodb.MongoClient; +import com.mongodb.ServerAddress; + +public class MongodTestUtil { + private final String databaseName = "thermostat"; + private final String host = "127.0.0.1"; + private final int port = 27518; + public final String listenAddress = host + ":" + port; + + private MongoClient mongoClient; + private Path tempDbDir; + private Path tempLogFile; + public Process process; + + + + public void startMongod() throws IOException, InterruptedException { + tempDbDir = Files.createTempDirectory("tms-mongo"); + tempDbDir.toFile().deleteOnExit(); + Files.createDirectories(tempDbDir.resolve("data/db")); + tempLogFile = tempDbDir.resolve("mongod.log"); + tempLogFile.toFile().deleteOnExit(); + + String[] command = {"mongod", "--dbpath", tempDbDir.resolve("data/db").toAbsolutePath().toString(), "--port", String.valueOf(port), "--fork", "--logpath", tempLogFile.toAbsolutePath().toString()}; + ProcessBuilder builder = new ProcessBuilder(command); + process = builder.start(); + + mongoClient = new MongoClient(new ServerAddress(host, port)); + + waitForMongodStart(); + } + + public void stopMongod() throws IOException, InterruptedException { + try { + mongoClient.getDatabase("admin").runCommand(new Document("shutdown", 1)); + } catch (Exception ignored) { + } + mongoClient.close(); + mongoClient = null; + waitForMongodStop(); + finish(); + } + + public void dropCollection(String collectionName) { + mongoClient.getDatabase(databaseName).getCollection(collectionName).drop(); + } + + private void finish() throws IOException { + Files.walkFileTree(tempDbDir, new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + + }); + } + + private boolean waitForMongodStart() throws IOException, InterruptedException { + return waitFor("waiting for connections on port"); + } + + private boolean waitForMongodStop() throws IOException, InterruptedException { + return waitFor("dbexit: rc: 0"); + } + + private boolean waitFor(String match) throws IOException, InterruptedException { + final String[] s = new String[]{""}; + + for (int i = 0; i < 100; i++) { + if (Files.exists(tempLogFile) && !s[0].contains(match)) { + s[0] = new String(Files.readAllBytes(tempLogFile)); + } else if (s[0].contains(match)) { + return true; + } + Thread.sleep(100L); + } + return false; + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-utils/src/main/java/com/redhat/thermostat/gateway/tests/utils/ProcessTestUtil.java Tue May 16 11:52:33 2017 -0400 @@ -0,0 +1,115 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.gateway.tests.utils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +public class ProcessTestUtil { + /** + * Kill the process and all its children, recursively. Sends SIGTERM. + */ + public static void killRecursively(Process process) throws Exception { + killRecursively(getPid(process)); + } + + private static void killRecursively(int pid) throws Exception { + List<Integer> childPids = findChildPids(pid); + for (Integer childPid : childPids) { + killRecursively(childPid); + } + killProcess(pid); + } + + private static void killProcess(int processId) throws Exception { + System.err.println("Killing process with pid: " + processId); + Runtime.getRuntime().exec("kill " + processId).waitFor(); + + while (1 != Runtime.getRuntime().exec("kill -s 0 " + processId).waitFor()) { + // Repeatedly send kill signal until it fails meaning process doesn't exist + Thread.sleep(50l); + } + } + + private static List<Integer> findChildPids(int processId) throws IOException { + String children = new String(readAll(Runtime.getRuntime().exec("ps --ppid " + processId + " -o pid=").getInputStream())); + String[] childPids = children.split("\n"); + List<Integer> result = new ArrayList<>(); + for (String childPid : childPids) { + String pidString = childPid.trim(); + if (pidString.length() == 0) { + continue; + } + try { + result.add(Integer.parseInt(pidString)); + } catch (NumberFormatException nfe) { + System.err.println(nfe); + } + } + return result; + } + + private static int getPid(Process process) throws Exception { + final String UNIX_PROCESS_CLASS = "java.lang.UNIXProcess"; + // JDK 9 renamed this class to ProcessImpl + final String PROCESS_IMPL_CLASS = "java.lang.ProcessImpl"; + if (!(process.getClass().getName().equals(UNIX_PROCESS_CLASS) || process.getClass().getName().equals(PROCESS_IMPL_CLASS))) { + throw new IllegalArgumentException("can only kill " + UNIX_PROCESS_CLASS + " or " + PROCESS_IMPL_CLASS + "; input is a " + process.getClass()); + } + + Class<?> processClass = process.getClass(); + Field pidField = processClass.getDeclaredField("pid"); + pidField.setAccessible(true); + return (int) pidField.get(process); + } + + private static byte[] readAll(InputStream in) throws IOException { + final int TEMPORARY_BUFFER_SIZE = 1024; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[TEMPORARY_BUFFER_SIZE]; + int read; + while ((read = in.read(buffer)) != -1) { + baos.write(buffer, 0, read); + } + + return baos.toByteArray(); + } +}