/* * RHQ Management Platform * Copyright (C) 2005-2011 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.plugins.apache.upgrade; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import java.io.StringReader; import java.net.InetAddress; import java.net.URI; import java.net.UnknownHostException; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.testng.annotations.BeforeClass; import org.rhq.core.clientapi.agent.metadata.PluginMetadataParser; import org.rhq.core.clientapi.descriptor.AgentPluginDescriptorUtil; import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor; import org.rhq.core.domain.resource.InventoryStatus; import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.ResourceCategory; import org.rhq.core.domain.resource.ResourceError; import org.rhq.core.domain.resource.ResourceErrorType; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; import org.rhq.core.pluginapi.inventory.PluginContainerDeployment; import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent; import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; import org.rhq.core.system.SystemInfoFactory; import org.rhq.core.util.stream.StreamUtil; import org.rhq.plugins.apache.ApacheServerComponent; import org.rhq.plugins.apache.ApacheServerDiscoveryComponent; import org.rhq.plugins.apache.ApacheVirtualHostServiceComponent; import org.rhq.plugins.apache.ApacheVirtualHostServiceDiscoveryComponent; import org.rhq.plugins.apache.PluginLocation; import org.rhq.plugins.apache.parser.ApacheDirectiveTree; import org.rhq.plugins.apache.setup.ApacheTestConfiguration; import org.rhq.plugins.apache.setup.ApacheTestSetup; import org.rhq.plugins.apache.util.ApacheDeploymentUtil.DeploymentConfig; import org.rhq.plugins.apache.util.ResourceTypes; import org.rhq.plugins.apache.util.VHostSpec; import org.rhq.plugins.apache.util.VirtualHostLegacyResourceKeyUtil; import org.rhq.core.util.TokenReplacingReader; import org.rhq.test.pc.PluginContainerTest; /** * Base class for the upgrade test classes. * * @author Lukas Krejci */ public class UpgradeTestBase extends PluginContainerTest { private static final Log LOG = LogFactory.getLog(UpgradeTestBase.class); public enum ResourceKeyFormat { SNMP, RHQ3, RHQ4 }; protected static final String DEPLOYMENT_SIMPLE_WITH_RESOLVABLE_SERVERNAMES = "simpleWithResolvableServerNames"; protected static final String DEPLOYMENT_SIMPLE_WITH_UNRESOLVABLE_SERVER_NAMES = "simpleWithUnresolvableServerNames"; protected static final String DEPLOYMENT_SIMPLE_WITH_WILDCARD_LISTENS = "simpleWithWildcardListens"; private ResourceTypes apacheResourceTypes; protected Resource platform; @BeforeClass public void parseResourceTypesFromApachePlugin() throws Exception { apacheResourceTypes = new ResourceTypes(PluginLocation.APACHE_PLUGIN); platform = discoverPlatform(); } protected void testUpgrade(String testMethod, ApacheTestConfiguration testConfiguration) throws Throwable { String testId = this.getClass().getSimpleName() + "#" + testMethod; final ApacheTestSetup setup = new ApacheTestSetup(testId, testConfiguration.configurationName, context, apacheResourceTypes); boolean testFailed = false; try { String[] configFiles = Arrays.copyOf(testConfiguration.apacheConfigurationFiles, testConfiguration.apacheConfigurationFiles.length + 1); configFiles[testConfiguration.apacheConfigurationFiles.length] = "/snmpd.conf"; setup.withInventoryFrom(testConfiguration.inventoryFile) .withPlatformResource(platform).withDefaultExpectations().withDefaultOverrides(testConfiguration.defaultOverrides) .withApacheSetup().withConfigurationFiles(configFiles) .withServerRoot(testConfiguration.serverRoot).withExePath(testConfiguration.binPath); testConfiguration.beforeTestSetup(setup); LOG.debug("---------------------------------------------------------- Starting the upgrade test for: " + testId); LOG.debug("Deployment configuration: " + setup.getDeploymentConfig()); setup.setup(); testConfiguration.beforePluginContainerStart(setup); startConfiguredPluginContainer(); testConfiguration.beforeTests(setup); //ok, now we should see the resources upgraded in the fake server inventory. ResourceType serverResourceType = apacheResourceTypes.findByName("Apache HTTP Server"); ResourceType vhostResourceType = apacheResourceTypes.findByName("Apache Virtual Host"); Set<Resource> servers = setup.getFakeInventory().findResourcesByTypeAndStatus(serverResourceType, InventoryStatus.COMMITTED); assertEquals(servers.size(), 1, "There should be exactly one apache server discovered."); Resource server = servers.iterator().next(); String expectedResourceKey = ApacheServerDiscoveryComponent.formatResourceKey(testConfiguration.serverRoot, testConfiguration.serverRoot + "/conf/httpd.conf"); assertEquals(server.getResourceKey(), expectedResourceKey, "The server resource key doesn't seem to be upgraded."); Set<Resource> vhosts = setup.getFakeInventory().findResourcesByTypeAndStatus(vhostResourceType, InventoryStatus.COMMITTED); String[] expectedRKs = testConfiguration.getExpectedResourceKeysAfterUpgrade(setup); assertEquals(vhosts.size(), expectedRKs.length, "Unexpected number of vhosts discovered found"); List<String> expectedResourceKeys = Arrays.asList(expectedRKs); for (Resource vhost : vhosts) { assertTrue(expectedResourceKeys.contains(vhost.getResourceKey()), "Unexpected virtual host resource key: '" + vhost.getResourceKey() + "'. Only expecting " + expectedResourceKeys); } String[] expectedFailureRKs = testConfiguration.getExpectedResourceKeysWithFailures(setup); if (expectedFailureRKs != null && expectedFailureRKs.length > 0) { Set<Resource> failingResources = new HashSet<Resource>(); for(String rk : expectedFailureRKs) { for(Resource r : vhosts) { if (rk.equals(r.getResourceKey())) { failingResources.add(r); break; } } } assertEquals(failingResources.size(), expectedFailureRKs.length, "Couldn't find all the resources that should have failed."); for(Resource failingResource : failingResources) { List<ResourceError> errors = failingResource.getResourceErrors(ResourceErrorType.UPGRADE); assertNotNull(errors, "The main vhost doesn't have any upgrade errors."); assertEquals(errors.size(), 1, "There should be exactly one upgrade error on the main vhost."); } //check that all other vhosts were not upgraded but have no errors for(Resource r : vhosts) { if (failingResources.contains(r)) { continue; } assertEquals(r.getResourceErrors(ResourceErrorType.UPGRADE).size(), 0, "Unexpected number of resource upgrade errors on vhost " + r); } } else { for(Resource r : vhosts) { assertEquals(r.getResourceErrors(ResourceErrorType.UPGRADE).size(), 0, "Unexpected number of resource upgrade errors on vhost " + r); } } } catch (AssertionError e) { throw e; } catch (Throwable t) { testFailed = true; LOG.error("Error during test upgrade execution.", t); throw t; } finally { try { setup.withApacheSetup().stopApache(); } catch (Exception e) { if (testFailed) { LOG.error("Failed to stop apache.", e); } else { throw e; } } LOG.debug("---------------------------------------------------------- Finished the upgrade test for: " + testId); } } protected void defineRHQ3ResourceKeys(ApacheTestConfiguration testConfig, ApacheTestSetup setup) throws Exception { setup.withApacheSetup().init(); ApacheServerComponent component = setup.withApacheSetup().getServerComponent(); ApacheDirectiveTree config = component.parseRuntimeConfiguration(false); DeploymentConfig deployConfig = setup.getDeploymentConfig(); VirtualHostLegacyResourceKeyUtil keyUtil = new VirtualHostLegacyResourceKeyUtil(component, config); Map<String, String> replacements = deployConfig.getTokenReplacements(); testConfig.defaultOverrides.put("main.rhq3.resource.key", keyUtil.getRHQ3NonSNMPLegacyMainServerResourceKey()); if (deployConfig.vhost1 != null) { testConfig.defaultOverrides.put("vhost1.rhq3.resource.key", keyUtil.getRHQ3NonSNMPLegacyVirtualHostResourceKey(deployConfig.vhost1.getVHostSpec(replacements))); } if (deployConfig.vhost2 != null) { testConfig.defaultOverrides.put("vhost2.rhq3.resource.key", keyUtil.getRHQ3NonSNMPLegacyVirtualHostResourceKey(deployConfig.vhost2.getVHostSpec(replacements))); } if (deployConfig.vhost3 != null) { testConfig.defaultOverrides.put("vhost3.rhq3.resource.key", keyUtil.getRHQ3NonSNMPLegacyVirtualHostResourceKey(deployConfig.vhost3.getVHostSpec(replacements))); } if (deployConfig.vhost4 != null) { testConfig.defaultOverrides.put("vhost4.rhq3.resource.key", keyUtil.getRHQ3NonSNMPLegacyVirtualHostResourceKey(deployConfig.vhost4.getVHostSpec(replacements))); } setup.withDefaultOverrides(testConfig.defaultOverrides); } protected String interpret(String string, Map<String, String> variables) { return StreamUtil.slurp(new TokenReplacingReader(new StringReader(string), variables)); } protected static String[] getVHostRKs(ApacheTestSetup setup, int[] successfulUpgrades, int[] failedUpgrades, ResourceKeyFormat rkFormat) { int sucLen = successfulUpgrades == null ? 0 : successfulUpgrades.length; int failLen = failedUpgrades == null ? 0 : failedUpgrades.length; String[] ret = new String[sucLen + failLen]; int retIdx = 0; Map<String, String> replacements = setup.getInventoryFileReplacements(); for(int i = 0; i < sucLen; ++i, ++retIdx) { int vhostNum = successfulUpgrades[i]; if (vhostNum == 0) { ret[retIdx] = ApacheVirtualHostServiceComponent.MAIN_SERVER_RESOURCE_KEY; } else { VHostSpec vhost = setup.getDeploymentConfig().getVHost(vhostNum).getVHostSpec(replacements); ret[retIdx] = ApacheVirtualHostServiceDiscoveryComponent.createResourceKey(vhost.serverName, vhost.hosts); } } for(int i = 0; i < failLen; ++i, ++retIdx) { String variableName = null; if (failedUpgrades[i] == 0) { if (rkFormat == ResourceKeyFormat.SNMP) { variableName = ""; } else { variableName = "main.rhq"; } } else { if (rkFormat == ResourceKeyFormat.SNMP) { variableName += "vhost" + failedUpgrades[i] + "."; } else { variableName = "vhost" + failedUpgrades[i] + ".rhq"; } } switch (rkFormat) { case RHQ3: variableName += "3.resource.key"; break; case RHQ4: variableName += "4.resource.key"; break; case SNMP: variableName += "snmp.identifier"; break; } ret[retIdx] = replacements.get(variableName); } return ret; } @SuppressWarnings({ "rawtypes", "unchecked" }) public static Resource discoverPlatform() throws Exception { PluginDescriptor descriptor = AgentPluginDescriptorUtil.loadPluginDescriptorFromUrl(new URI(PluginLocation.PLATFORM_PLUGIN) .toURL()); PluginMetadataParser parser = new PluginMetadataParser(descriptor, Collections.<String, PluginMetadataParser> emptyMap()); List<ResourceType> platformTypes = parser.getAllTypes(); //this is the default container name in case of no plugin explicit plugin configuration, which we don't have. String containerName = InetAddress.getLocalHost().getCanonicalHostName(); for (ResourceType rt : platformTypes) { if (rt.getCategory() != ResourceCategory.PLATFORM) { continue; } Class discoveryClass = Class.forName(parser.getDiscoveryComponentClass(rt)); ResourceDiscoveryComponent discoveryComponent = (ResourceDiscoveryComponent) discoveryClass.newInstance(); ResourceDiscoveryContext context = new ResourceDiscoveryContext(rt, null, null, SystemInfoFactory.createSystemInfo(), Collections.emptyList(), Collections.emptyList(), containerName, PluginContainerDeployment.AGENT); Set<DiscoveredResourceDetails> results = discoveryComponent.discoverResources(context); if (!results.isEmpty()) { DiscoveredResourceDetails details = results.iterator().next(); Resource platform = new Resource(); platform.setDescription(details.getResourceDescription()); platform.setResourceKey(details.getResourceKey()); platform.setName(details.getResourceName()); platform.setVersion(details.getResourceVersion()); platform.setPluginConfiguration(details.getPluginConfiguration()); platform.setResourceType(rt); platform.setUuid(UUID.randomUUID().toString()); platform.setId(1); return platform; } } return null; } protected static String variableName(String prefix, String name) { StringBuilder bld = new StringBuilder(); if (prefix != null && !prefix.isEmpty()) { bld.append(prefix).append("."); } bld.append(name); return bld.toString(); } protected static InetAddress determineLocalhost() { try { return InetAddress.getLocalHost(); } catch (UnknownHostException e) { try { return InetAddress.getByName("127.0.0.1"); } catch (UnknownHostException ee) { //doesn't happen return null; } } } }