/* * RHQ Management Platform * Copyright (C) 2012 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation, and/or the GNU Lesser * General Public License, version 2.1, also as published by the Free * Software Foundation. * * This program 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 and the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU General Public License * and the GNU Lesser General Public License along with this program; * if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.rhq.modules.plugins.wildfly10; import java.io.File; import java.io.InputStreamReader; import java.util.Arrays; import java.util.List; import java.util.Map; import org.testng.Assert; import org.testng.annotations.Test; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.exporter.ZipExporter; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.rhq.core.system.ProcessInfo; import org.rhq.core.system.SystemInfo; import org.rhq.core.system.SystemInfoFactory; import org.rhq.core.util.PropertiesFileUpdate; import org.rhq.core.util.stream.StreamUtil; /** * A unit test for {@link AS7CommandLine}. */ public class AS7CommandLineTest { private static final File FAKE_JBOSS_HOME = new File("."); private static final String FILE_URL_PREFIX = (File.separatorChar == '/') ? "file://" : "file:///"; private interface CommandLineProducer { AS7CommandLine get(); } public static class FakeServerProcess { ProcessInfo processInfo; File fakeJBossModulesJar; void cleanUp() throws Exception { processInfo.kill("KILL"); fakeJBossModulesJar.delete(); } //this used as a main class of the process that fakes a running AS7 server //It just sits idle until killed (a featureful application server, indeed :) ). public static synchronized void main(String[] args) throws Exception { FakeServerProcess.class.wait(); } } @Test public void testSysPropsWithAbsolutePathAndFileProtocolWithoutProcess() throws Exception { File propsFile1 = File.createTempFile("jboss1-", ".properties"); File propsFile2 = File.createTempFile("jboss2-", ".properties"); String propsFile1Path = FILE_URL_PREFIX + propsFile1; String propsFile2Path = FILE_URL_PREFIX + propsFile2; try { testSysProps(propsFile1, propsFile2, FAKE_JBOSS_HOME, getAs7CommandLine(propsFile1Path, propsFile2Path, FAKE_JBOSS_HOME)); } finally { propsFile1.delete(); propsFile2.delete(); } } @Test public void testSysPropsWithRelativePathAndFileProtocolWithoutProcess() throws Exception { File propsFile1 = File.createTempFile("jboss1-", ".properties", new File(".")); File propsFile2 = File.createTempFile("jboss2-", ".properties", new File(".")); //create the bin subdirectory so that the path deduced by AS7CommandLine can be traversed new File("bin").mkdir(); //without the process, the AS7CommandLine tries to figure out the path as relative to $JBOSS_HOME/bin //since we're assigning jboss home to "." and creating the file in ".", too, we need to prepend the //path with a ".." to jump out of the assumed "bin". String propsFile1Path = "file:../" + propsFile1.getName(); String propsFile2Path = "file:../" + propsFile2.getName(); try { testSysProps(propsFile1, propsFile2, FAKE_JBOSS_HOME, getAs7CommandLine(propsFile1Path, propsFile2Path, FAKE_JBOSS_HOME)); } finally { propsFile1.delete(); propsFile2.delete(); new File("bin").delete(); } } @Test public void testSysPropsWithAbsolutePathWithoutProcess() throws Exception { File propsFile1 = File.createTempFile("jboss1-", ".properties"); File propsFile2 = File.createTempFile("jboss2-", ".properties"); String propsFile1Path = propsFile1.getAbsolutePath(); String propsFile2Path = propsFile2.getAbsolutePath(); try { testSysProps(propsFile1, propsFile2, FAKE_JBOSS_HOME, getAs7CommandLine(propsFile1Path, propsFile2Path, FAKE_JBOSS_HOME)); } finally { propsFile1.delete(); propsFile2.delete(); } } @Test public void testSysPropsWithRelativePathWithoutProcess() throws Exception { File propsFile1 = File.createTempFile("jboss1-", ".properties", new File(".")); File propsFile2 = File.createTempFile("jboss2-", ".properties", new File(".")); //create the bin subdirectory so that the path deduced by AS7CommandLine can be traversed new File("bin").mkdir(); //without the process, the AS7CommandLine tries to figure out the path as relative to $JBOSS_HOME/bin //since we're assigning jboss home to "." and creating the file in ".", too, we need to prepend the //path with a ".." to jump out of the assumed "bin". String propsFile1Path = "../" + propsFile1.getName(); String propsFile2Path = "../" + propsFile2.getName(); try { testSysProps(propsFile1, propsFile2, FAKE_JBOSS_HOME, getAs7CommandLine(propsFile1Path, propsFile2Path, FAKE_JBOSS_HOME)); } finally { propsFile1.delete(); propsFile2.delete(); new File("bin").delete(); } } @Test public void testSysPropsWithAbsolutePathWithProcess() throws Exception { File propsFile1 = File.createTempFile("jboss1-", ".properties"); File propsFile2 = File.createTempFile("jboss2-", ".properties"); String propsFile1Path = propsFile1.getAbsolutePath(); String propsFile2Path = propsFile2.getAbsolutePath(); FakeServerProcess fakeServer = startFakeServer(FAKE_JBOSS_HOME, FAKE_JBOSS_HOME, propsFile1Path, propsFile2Path); Assert.assertNotNull(fakeServer, "Failed to start or find the fake server process."); try { testSysProps(propsFile1, propsFile2, FAKE_JBOSS_HOME, getAs7CommandLine(fakeServer)); } finally { propsFile1.delete(); propsFile2.delete(); fakeServer.cleanUp(); } } @Test public void testSysPropsWithAbsolutePathWithProcessFromDifferentDirectory() throws Exception { File propsFile1 = File.createTempFile("jboss1-", ".properties"); File propsFile2 = File.createTempFile("jboss2-", ".properties"); String propsFile1Path = propsFile1.getAbsolutePath(); String propsFile2Path = propsFile2.getAbsolutePath(); FakeServerProcess fakeServer = startFakeServer(new File(".."), FAKE_JBOSS_HOME, propsFile1Path, propsFile2Path); Assert.assertNotNull(fakeServer, "Failed to start or find the fake server process."); try { testSysProps(propsFile1, propsFile2, FAKE_JBOSS_HOME, getAs7CommandLine(fakeServer)); } finally { propsFile1.delete(); propsFile2.delete(); fakeServer.cleanUp(); } } @Test public void testSysPropsWithAbsolutePathAndFileProtocolWithProcess() throws Exception { File propsFile1 = File.createTempFile("jboss1-", ".properties"); File propsFile2 = File.createTempFile("jboss2-", ".properties"); String propsFile1Path = FILE_URL_PREFIX + propsFile1; String propsFile2Path = FILE_URL_PREFIX + propsFile2; FakeServerProcess fakeServer = startFakeServer(FAKE_JBOSS_HOME, FAKE_JBOSS_HOME, propsFile1Path, propsFile2Path); Assert.assertNotNull(fakeServer, "Failed to start or find the fake server process."); try { testSysProps(propsFile1, propsFile2, FAKE_JBOSS_HOME, getAs7CommandLine(fakeServer)); } finally { propsFile1.delete(); propsFile2.delete(); fakeServer.cleanUp(); } } @Test public void testSysPropsWithAbsolutePathAndFileProtocolWithProcessFromDifferentDirectory() throws Exception { File propsFile1 = File.createTempFile("jboss1-", ".properties"); File propsFile2 = File.createTempFile("jboss2-", ".properties"); String propsFile1Path = FILE_URL_PREFIX + propsFile1; String propsFile2Path = FILE_URL_PREFIX + propsFile2; FakeServerProcess fakeServer = startFakeServer(new File(".."), FAKE_JBOSS_HOME, propsFile1Path, propsFile2Path); Assert.assertNotNull(fakeServer, "Failed to start or find the fake server process."); try { testSysProps(propsFile1, propsFile2, FAKE_JBOSS_HOME, getAs7CommandLine(fakeServer)); } finally { propsFile1.delete(); propsFile2.delete(); fakeServer.cleanUp(); } } @Test public void testSysPropsWithRelativePathAndFileProtocolWithProcess() throws Exception { File propsFile1 = File.createTempFile("jboss1-", ".properties", FAKE_JBOSS_HOME); File propsFile2 = File.createTempFile("jboss2-", ".properties", FAKE_JBOSS_HOME); String propsFile1Path = "file:./" + propsFile1.getName(); String propsFile2Path = "file:./" + propsFile2.getName(); FakeServerProcess fakeServer = startFakeServer(FAKE_JBOSS_HOME, FAKE_JBOSS_HOME, propsFile1Path, propsFile2Path); Assert.assertNotNull(fakeServer, "Failed to start or find the fake server process."); try { testSysProps(propsFile1, propsFile2, FAKE_JBOSS_HOME, getAs7CommandLine(fakeServer)); } finally { propsFile1.delete(); propsFile2.delete(); fakeServer.cleanUp(); } } @Test public void testSysPropsWithRelativePathAndFileProtocolWithProcessFromDifferentDirectory() throws Exception { File cwd = new File(".."); File propsFile1 = File.createTempFile("jboss1-", ".properties", cwd); File propsFile2 = File.createTempFile("jboss2-", ".properties", cwd); String propsFile1Path = "file:./" + propsFile1.getName(); String propsFile2Path = "file:./" + propsFile2.getName(); FakeServerProcess fakeServer = startFakeServer(cwd, FAKE_JBOSS_HOME, propsFile1Path, propsFile2Path); Assert.assertNotNull(fakeServer, "Failed to start or find the fake server process."); try { testSysProps(propsFile1, propsFile2, FAKE_JBOSS_HOME, getAs7CommandLine(fakeServer)); } finally { propsFile1.delete(); propsFile2.delete(); fakeServer.cleanUp(); } } @Test public void testSysPropsWithRelativePathWithProcess() throws Exception { File propsFile1 = File.createTempFile("jboss1-", ".properties", FAKE_JBOSS_HOME); File propsFile2 = File.createTempFile("jboss2-", ".properties", FAKE_JBOSS_HOME); String propsFile1Path = propsFile1.getName(); String propsFile2Path = propsFile2.getName(); FakeServerProcess fakeServer = startFakeServer(FAKE_JBOSS_HOME, FAKE_JBOSS_HOME, propsFile1Path, propsFile2Path); Assert.assertNotNull(fakeServer, "Failed to start or find the fake server process."); try { testSysProps(propsFile1, propsFile2, FAKE_JBOSS_HOME, getAs7CommandLine(fakeServer)); } finally { propsFile1.delete(); propsFile2.delete(); fakeServer.cleanUp(); } } @Test public void testSysPropsWithRelativePathWithProcessFromDifferentDirectory() throws Exception { File cwd = new File(".."); File propsFile1 = File.createTempFile("jboss1-", ".properties", cwd); File propsFile2 = File.createTempFile("jboss2-", ".properties", cwd); String propsFile1Path = propsFile1.getName(); String propsFile2Path = propsFile2.getName(); FakeServerProcess fakeServer = startFakeServer(cwd, FAKE_JBOSS_HOME, propsFile1Path, propsFile2Path); Assert.assertNotNull(fakeServer, "Failed to start or find the fake server process."); try { testSysProps(propsFile1, propsFile2, FAKE_JBOSS_HOME, getAs7CommandLine(fakeServer)); } finally { propsFile1.delete(); propsFile2.delete(); fakeServer.cleanUp(); } } private CommandLineProducer getAs7CommandLine(final String propsFile1Path, final String propsFile2Path, final File jbossHome) { return new CommandLineProducer() { @Override public AS7CommandLine get() { return new AS7CommandLine(getCommandLine(jbossHome, propsFile1Path, propsFile2Path)); } }; } private CommandLineProducer getAs7CommandLine(final FakeServerProcess serverProcess) { return new CommandLineProducer() { @Override public AS7CommandLine get() { return new AS7CommandLine(serverProcess.processInfo); } }; } private void testSysProps(File propsFile1, File propsFile2, File jbossHome, CommandLineProducer commandLine) throws Exception { PropertiesFileUpdate propsFile1Updater = new PropertiesFileUpdate(propsFile1.getPath()); propsFile1Updater.update("prop1", "delta"); propsFile1Updater.update("prop4", "epsilon"); PropertiesFileUpdate propsFile2Updater = new PropertiesFileUpdate(propsFile1.getPath()); propsFile2Updater.update("prop2", "zeta"); propsFile2Updater.update("prop5", "eta"); Map<String, String> sysprops = commandLine.get().getSystemProperties(); Assert.assertNotNull(sysprops); Assert.assertEquals(sysprops.size(), 8); Assert.assertEquals(sysprops.get("[Standalone]"), ""); Assert.assertEquals(sysprops.get("prop1"), "delta"); Assert.assertEquals(sysprops.get("prop2"), "zeta"); Assert.assertEquals(sysprops.get("prop3"), "gamma"); Assert.assertEquals(sysprops.get("prop4"), "epsilon"); Assert.assertEquals(sysprops.get("prop5"), "eta"); Assert.assertEquals(sysprops.get("jboss.home.dir"), jbossHome.getAbsolutePath()); Assert.assertEquals(sysprops.get("jboss.server.base.dir"), new File(jbossHome, "standalone").getAbsolutePath()); } private FakeServerProcess startFakeServer(File cwd, File jbossHome, String propsFile1Path, String propsFile2Path) throws Exception { //prepare the fake jboss-modules.jar Class<?> mainClass = FakeServerProcess.class; File jbossModulesJar = File.createTempFile("jboss-modules-fake", ".jar"); ShrinkWrap.create(JavaArchive.class).addClass(mainClass) .setManifest(new StringAsset("Main-Class: " + mainClass.getName() + "\n")).as(ZipExporter.class) .exportTo(jbossModulesJar, true); String[] commandLine = getCommandLine(jbossModulesJar, jbossHome, propsFile1Path, propsFile2Path); ProcessBuilder pb = new ProcessBuilder(commandLine); Process process = pb.directory(cwd).start(); try { int exitValue = process.exitValue(); String stdout = StreamUtil.slurp(new InputStreamReader(process.getInputStream())); String stderr = StreamUtil.slurp(new InputStreamReader(process.getErrorStream())); Assert .fail("The fake jboss as server process has finished even though it should keep running. The exit value was " + exitValue + ". Stdout was:\n" + stdout + "\n\nStderr was:\n" + stderr); } catch (IllegalThreadStateException e) { //expected } SystemInfo sysInfo = SystemInfoFactory.createSystemInfo(); List<ProcessInfo> processes = sysInfo.getAllProcesses(); for (ProcessInfo pi : processes) { String[] cl = pi.getCommandLine(); if (Arrays.equals(cl, commandLine)) { FakeServerProcess ret = new FakeServerProcess(); ret.fakeJBossModulesJar = jbossModulesJar; ret.processInfo = pi; return ret; } } return null; } private String[] getCommandLine(File jbossHome, String propsFile1Path, String propsFile2Path) { return getCommandLine(new File(jbossHome, "jboss-modules.jar"), jbossHome, propsFile1Path, propsFile2Path); } private String[] getCommandLine(File jbossModules, File jbossHome, String propsFile1Path, String propsFile2Path) { return new String[] { // "java", // "-D[Standalone]", // "-server", // "-Dprop1=alpha", // "-Dprop2=beta", // "-Dprop3=gamma", // "-jar", jbossModules.getAbsolutePath(), // "-mp", new File(jbossHome, "modules").getAbsolutePath(), // "-jaxpmodule", "javax.xml.jaxp-provider", // "org.jboss.as.standalone", // "-Djboss.home.dir=" + jbossHome.getAbsolutePath(), // "-Djboss.server.base.dir=" + new File(jbossHome, "standalone").getAbsolutePath(), // "-P", propsFile1Path, // "--properties=" + propsFile2Path }; } public static synchronized void main(String[] args) throws Exception { AS7CommandLineTest.class.wait(); } }