/* * RHQ Management Platform * Copyright (C) 2005-2014 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 as published by * the Free Software Foundation version 2 of the License. * * 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 for more details. * * You should have received a copy of the GNU 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.itest; import static org.rhq.modules.plugins.wildfly10.test.util.Constants.JBOSS_HOME; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; import java.io.File; import java.io.FileOutputStream; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.hyperic.sigar.SigarException; import org.testng.Assert; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.measurement.AvailabilityType; import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pc.inventory.InventoryManager; import org.rhq.core.pc.inventory.ResourceContainer; import org.rhq.core.pluginapi.configuration.ListPropertySimpleWrapper; import org.rhq.core.pluginapi.configuration.MapPropertySimpleWrapper; import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; import org.rhq.core.pluginapi.util.StartScriptConfiguration; import org.rhq.core.system.ProcessInfo; import org.rhq.core.system.SystemInfo; import org.rhq.core.system.SystemInfoFactory; import org.rhq.modules.plugins.wildfly10.JBossProductType; import org.rhq.modules.plugins.wildfly10.helper.ServerPluginConfiguration; /** * The base class for the integration tests for the two AS7 server types. * * @author Ian Springer */ public abstract class AbstractServerComponentTest extends AbstractJBossAS7PluginTest { private static final Map<String, String> EAP6_VERSION_TO_AS7_VERSION_MAP = new HashMap<String, String>(); static { EAP6_VERSION_TO_AS7_VERSION_MAP.put("6.0.0", "7.1.2.Final-redhat-1"); EAP6_VERSION_TO_AS7_VERSION_MAP.put("6.0.1", "7.1.3.Final-redhat-4"); EAP6_VERSION_TO_AS7_VERSION_MAP.put("6.1.0.Alpha", "7.2.0.Alpha1-redhat-4"); EAP6_VERSION_TO_AS7_VERSION_MAP.put("6.1.0", "7.2.0.Final-redhat-8"); } private static final String RELEASE_VERSION_TRAIT_NAME = "_skm:release-version"; private static final String SHUTDOWN_OPERATION_NAME = "shutdown"; private static final String START_OPERATION_NAME = "start"; protected abstract ResourceType getServerResourceType(); protected abstract String getServerResourceKey(); protected abstract Resource getServerResource(); public void testServerAttributeValidation() throws Exception { AvailabilityType avail = getAvailability(getServerResource()); assertEquals(avail, AvailabilityType.UP); Configuration pluginConfig = getServerResource().getPluginConfiguration(); ServerPluginConfiguration serverPluginConfig = new ServerPluginConfiguration(pluginConfig); // Change the baseDir prop. File originalBaseDir = serverPluginConfig.getBaseDir(); serverPluginConfig.setBaseDir(new File(System.getProperty("java.io.tmpdir"))); // Restart the server ResourceComponent so it picks up the changes we just made to the plugin config. InventoryManager inventoryManager = this.pluginContainer.getInventoryManager(); inventoryManager.deactivateResource(getServerResource()); ResourceContainer serverContainer = inventoryManager.getResourceContainer(getServerResource()); InvalidPluginConfigurationException ipce = null; try { inventoryManager.activateResource(getServerResource(), serverContainer, true); } catch (InvalidPluginConfigurationException e) { ipce = e; } // Set the baseDir back to the original value and restart the component before making any assertions, to ensure // things aren't left in a corrupt state for remaining test methods. serverPluginConfig.setBaseDir(originalBaseDir); inventoryManager.activateResource(getServerResource(), serverContainer, true); Assert.assertNotNull(ipce, "InvalidPluginConfigurationException was not thrown by server component's " + "start() method due to invalid baseDir."); // Change the expectedRuntimeProductName property String originalExpectedRuntimeProductName = pluginConfig.getSimpleValue("expectedRuntimeProductName"); if (originalExpectedRuntimeProductName.equals(JBossProductType.WILDFLY.PRODUCT_NAME)) { pluginConfig.setSimpleValue("expectedRuntimeProductName", JBossProductType.EAP.PRODUCT_NAME); } else { pluginConfig.setSimpleValue("expectedRuntimeProductName", JBossProductType.WILDFLY.PRODUCT_NAME); } // Restart the server ResourceComponent so it picks up the changes we just made to the plugin config. inventoryManager.deactivateResource(getServerResource()); ipce = null; try { inventoryManager.activateResource(getServerResource(), serverContainer, true); } catch (InvalidPluginConfigurationException e) { ipce = e; } // Set the expectedRuntimeProductName property back to the original value and restart the component before // making any assertions, to ensure things aren't left in a corrupt state for remaining test methods. pluginConfig.setSimpleValue("expectedRuntimeProductName", originalExpectedRuntimeProductName); inventoryManager.activateResource(getServerResource(), serverContainer, true); Assert.assertNotNull(ipce, "InvalidPluginConfigurationException was not thrown by server component's " + "start() method due to invalid productType."); } protected void validatePluginConfiguration(Configuration pluginConfig) { System.out.println("---------- " + pluginConfig.toString(true)); // "hostname" prop String hostname = pluginConfig.getSimpleValue("hostname", null); String expectedHostname = System.getProperty(getBindAddressSystemPropertyName()); assertEquals(hostname, expectedHostname, "Plugin config prop [hostname]."); // "port" prop String portString = pluginConfig.getSimpleValue("port", null); Integer port = (portString != null) ? Integer.valueOf(portString) : null; int portOffset = getPortOffset(); Integer expectedPort = portOffset + 9990; assertEquals(port, expectedPort, "Plugin config prop [port]."); // "startScript" prop String startScript = pluginConfig.getSimpleValue("startScript"); Assert.assertNotNull(startScript); File startScriptFile = new File(startScript); String expectedStartScriptFileName = getExpectedStartScriptFileName(); Assert.assertEquals(startScriptFile.getName(), expectedStartScriptFileName); if (!startScriptFile.isAbsolute()) { // If it's relative, e.g. "bin/standalone.sh", it will be resolved relative to the AS home dir. startScriptFile = new File(JBOSS_HOME, startScript); } Assert.assertTrue(startScriptFile.exists(), "Start script [" + startScriptFile + "] does not exist."); // "startScriptEnv" prop PropertySimple startScriptEnvProp = pluginConfig.getSimple("startScriptEnv"); MapPropertySimpleWrapper startScriptEnvPropWrapper = new MapPropertySimpleWrapper(startScriptEnvProp); Map<String, String> env = startScriptEnvPropWrapper.getValue(); validateStartScriptEnv(env); // "startScriptArgs" prop PropertySimple startScriptArgsProp = pluginConfig.getSimple("startScriptArgs"); ListPropertySimpleWrapper startScriptArgsPropWrapper = new ListPropertySimpleWrapper(startScriptArgsProp); List<String> args = startScriptArgsPropWrapper.getValue(); Assert.assertEquals(args, getExpectedStartScriptArgs(), "Plugin config prop [startScriptArgs]"); } protected int getPortOffset() { String portOffsetString = System.getProperty(getPortOffsetSystemPropertyName()); return (portOffsetString != null) ? Integer.valueOf(portOffsetString) : 0; } protected void validateStartScriptEnv(Map<String, String> env) { String javaHome = env.get("JAVA_HOME"); if (javaHome != null) { Assert.assertTrue(new File(javaHome).isDirectory()); } String path = env.get("PATH"); if (path != null) { String[] pathElements = path.split(File.pathSeparator); Assert.assertTrue(pathElements.length >= 1); Assert.assertTrue(new File(pathElements[0]).isDirectory()); } } protected abstract String getBindAddressSystemPropertyName(); protected abstract String getPortOffsetSystemPropertyName(); public void testReleaseVersionTrait() throws Exception { String releaseVersion = collectTrait(getServerResource(), RELEASE_VERSION_TRAIT_NAME); String as7Version = System.getProperty("as7.version"); String expectedReleaseVersion; if (as7Version.startsWith("6.")) { // EAP6 expectedReleaseVersion = EAP6_VERSION_TO_AS7_VERSION_MAP.get(as7Version); if (expectedReleaseVersion == null) { throw new Exception("No AS7 version mapping is defined for EAP6 version [" + as7Version + "]."); } } else { // AS7 expectedReleaseVersion = as7Version; } assertEquals(releaseVersion, expectedReleaseVersion, "Unexpected value for trait [" + RELEASE_VERSION_TRAIT_NAME + "]."); } public void testExecuteCliOperations() throws Exception { // First make sure the server is up. AvailabilityType avail = getAvailability(getServerResource()); assertEquals(avail, AvailabilityType.UP); Configuration c = new Configuration(); c.put(new PropertySimple("commands", "ls")); invokeOperationAndAssertSuccess(getServerResource(), "executeCommands", c); File script = null; try { c = new Configuration(); script = File.createTempFile("test", "script"); writeFile("ls", script); c.put(new PropertySimple("file", script.getAbsolutePath())); invokeOperationAndAssertSuccess(getServerResource(), "executeScript", c); } finally { script.delete(); } } private File writeFile(String content, File fileToOverwrite) throws Exception { FileOutputStream out = null; try { fileToOverwrite.getParentFile().mkdirs(); out = new FileOutputStream(fileToOverwrite); out.write(content.getBytes()); return fileToOverwrite; } finally { if (out != null) { out.close(); } } } public void testShutdownAndStartOperations() throws Exception { // First make sure the server is up. AvailabilityType avail = getAvailability(getServerResource()); assertEquals(avail, AvailabilityType.UP); // Now shut it down using the Shutdown op and make sure it has gone down. invokeOperationAndAssertSuccess(getServerResource(), SHUTDOWN_OPERATION_NAME, null); avail = getAvailability(getServerResource()); assertEquals(avail, AvailabilityType.DOWN); // Before restarting it, add some stuff to the 'startScriptEnv' and 'startScriptArgs' props so we can verify // they are used correctly by the Start op. Configuration pluginConfig = getServerResource().getPluginConfiguration(); StartScriptConfiguration startScriptConfig = new StartScriptConfiguration(pluginConfig); // Add a var to the start script env. Map<String, String> env = startScriptConfig.getStartScriptEnv(); env.put("FOO", "bar"); // uppercase env var name or Windows will do it for you startScriptConfig.setStartScriptEnv(env); // Add an arg to the start script args. List<String> args = startScriptConfig.getStartScriptArgs(); args.add("-Dfoo=bar"); startScriptConfig.setStartScriptArgs(args); // Restart the server ResourceComponent so it picks up the changes we just made to the plugin config. InventoryManager inventoryManager = this.pluginContainer.getInventoryManager(); inventoryManager.deactivateResource(getServerResource()); ResourceContainer serverContainer = inventoryManager.getResourceContainer(getServerResource()); inventoryManager.activateResource(getServerResource(), serverContainer, true); // Finally restart it using the Start op and make sure it has come back up. invokeOperationAndAssertSuccess(getServerResource(), START_OPERATION_NAME, null); avail = getAvailability(getServerResource()); assertEquals(avail, AvailabilityType.UP); List<ProcessInfo> processes = getServerProcesses(); //Assert.assertEquals(processes.size(), 1, getCommandLines(processes).toString()); ProcessInfo serverProcess = processes.get(0); Map<String, String> processEnv = serverProcess.getEnvironmentVariables(); assertEquals(processEnv.get("FOO"), "bar", processEnv.toString()); List<String> processArgs = Arrays.asList(serverProcess.getCommandLine()); assertTrue(processArgs.contains("-Dfoo=bar"), processArgs.toString()); } protected abstract String getExpectedStartScriptFileName(); protected abstract List<String> getExpectedStartScriptArgs(); protected void killServerProcesses() { List<ProcessInfo> processes = getServerProcesses(); System.out.println("\n=== Killing " + processes.size() + " " + getServerResourceType() + " processes..."); for (ProcessInfo process : processes) { System.out.println("====== Killing process with pid [" + process.getPid() + "] and command line [" + Arrays.toString(process.getCommandLine()) + "]..."); try { process.kill("KILL"); } catch (SigarException e) { System.err.println("Failed to kill " + process + ": " + e); } } processes = getServerProcesses(); Assert.assertEquals(processes.size(), 0, "Failed to kill " + processes.size() + " " + getServerResourceType() + " processes: " + processes); } private List<ProcessInfo> getServerProcesses() { SystemInfo systemInfo = SystemInfoFactory.createSystemInfo(); return systemInfo .getProcesses("arg|*|match=org\\.jboss\\.as\\..+,arg|-Djboss.socket.binding.port-offset|match=" + getPortOffset()); } }