/* * JBoss, Home of Professional Open Source. * Copyright 2013, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.as.patching.tests; import java.io.File; import java.io.IOException; import java.util.Collection; import org.jboss.as.patching.DirectoryStructure; import org.jboss.as.patching.IoUtils; import org.jboss.as.patching.PatchingException; import org.jboss.as.patching.installation.InstallationManager; import org.jboss.as.patching.installation.InstalledIdentity; import org.jboss.as.patching.installation.PatchableTarget; import org.jboss.as.patching.metadata.ContentItem; import org.jboss.as.patching.metadata.ContentModification; import org.jboss.as.patching.metadata.ContentType; import org.jboss.as.patching.metadata.MiscContentItem; import org.jboss.as.patching.metadata.ModificationCondition; import org.jboss.as.patching.metadata.ModificationType; import org.jboss.as.patching.metadata.ModuleItem; import org.jboss.as.patching.metadata.Patch; import org.jboss.as.patching.metadata.PatchElement; import org.jboss.as.patching.metadata.PatchElementProvider; import org.jboss.as.patching.runner.PatchContentLoader; import org.jboss.as.patching.runner.TestUtils; import org.junit.Assert; /** * @author Emanuel Muckenhuber */ abstract class PatchStepAssertions { protected abstract void before(File installation, Patch patch, InstallationManager manager) throws IOException; protected abstract void after(File installation, Patch patch, InstallationManager manager) throws IOException; protected static final PatchStepAssertions APPLY = new PatchStepAssertions() { @Override protected void before(final File installation, final Patch patch, final InstallationManager manager) throws IOException { assertNotApplied(patch, manager); } @Override protected void after(File installation, Patch patch, InstallationManager manager) throws IOException { assertApplied(patch, manager); } }; protected static final PatchStepAssertions ROLLBACK = new PatchStepAssertions() { @Override protected void before(File installation, Patch patch, InstallationManager manager) throws IOException { assertApplied(patch, manager); } @Override protected void after(File installation, Patch patch, InstallationManager manager) throws IOException { assertNotApplied(patch, manager); } }; protected static final PatchStepAssertions NONE = new PatchStepAssertions() { @Override protected void before(File installation, Patch patch, InstallationManager manager) throws IOException { } @Override protected void after(File installation, Patch patch, InstallationManager manager) throws IOException { } }; static void assertApplied(final Patch patch, InstallationManager manager) throws IOException { final String patchID = patch.getPatchId(); InstalledIdentity installedIdentity = null; try { installedIdentity = manager.getInstalledIdentity(patch.getIdentity().getName(), null); } catch (PatchingException e) { Assert.fail(e.getLocalizedMessage()); } final PatchableTarget target = installedIdentity.getIdentity(); final PatchableTarget.TargetInfo identity = target.loadTargetInfo(); assertIsApplied(patch.getIdentity().getPatchType(), patchID, identity); assertExists(identity.getDirectoryStructure().getInstalledImage().getPatchHistoryDir(patchID)); assertContentItems(patchID, target, patch.getModifications()); for (final PatchElement element : patch.getElements()) { final PatchElementProvider provider = element.getProvider(); final PatchableTarget targetElement = provider.isAddOn() ? installedIdentity.getAddOn(provider.getName()) : installedIdentity.getLayer(provider.getName()); assertIsApplied(provider.getPatchType(), element.getId(), targetElement.loadTargetInfo()); assertContentItems(element.getId(), targetElement, element.getModifications()); } } static void assertNotApplied(final Patch patch, InstallationManager manager) throws IOException { InstalledIdentity installedIdentity = null; try { installedIdentity = manager.getInstalledIdentity(patch.getIdentity().getName(), patch.getIdentity().getVersion()); } catch (PatchingException e) { Assert.fail(e.getLocalizedMessage()); } final PatchableTarget.TargetInfo identity = installedIdentity.getIdentity().loadTargetInfo(); assertNotApplied(patch.getIdentity().getPatchType(), patch.getPatchId(), identity); assertDoesNotExists(identity.getDirectoryStructure().getInstalledImage().getPatchHistoryDir(patch.getPatchId())); for (final PatchElement element : patch.getElements()) { final PatchElementProvider provider = element.getProvider(); final PatchableTarget target = provider.isAddOn() ? installedIdentity.getAddOn(provider.getName()) : installedIdentity.getLayer(provider.getName()); Assert.assertNotNull(target); assertNotApplied(provider.getPatchType(), element.getId(), target.loadTargetInfo()); } } static void assertNotApplied(final Patch.PatchType patchType, final String patchId, final PatchableTarget.TargetInfo targetInfo) { if (patchType == Patch.PatchType.CUMULATIVE) { Assert.assertNotEquals(patchId, targetInfo.getCumulativePatchID()); } else { Assert.assertFalse(targetInfo.getPatchIDs().contains(patchId)); } final DirectoryStructure structure = targetInfo.getDirectoryStructure(); assertDoesNotExists(structure.getBundlesPatchDirectory(patchId)); assertDoesNotExists(structure.getModulePatchDirectory(patchId)); } static void assertIsApplied(final Patch.PatchType patchType, final String patchId, final PatchableTarget.TargetInfo targetInfo) { if (patchType == Patch.PatchType.CUMULATIVE) { Assert.assertEquals(patchId, targetInfo.getCumulativePatchID()); Assert.assertTrue(targetInfo.getPatchIDs().isEmpty()); } else { Assert.assertTrue(targetInfo.getPatchIDs().contains(patchId)); } final DirectoryStructure structure = targetInfo.getDirectoryStructure(); assertExists(structure.getBundlesPatchDirectory(patchId)); assertExists(structure.getModulePatchDirectory(patchId)); } static void assertContentItems(final String patchID, final PatchableTarget target, final Collection<ContentModification> modifications) throws IOException { for (final ContentModification modification : modifications) { assertContentModification(patchID, target, modification); } } static void assertExists(final File file) { if (file != null) { Assert.assertTrue(file.getAbsolutePath(), file.exists()); } } static void assertDoesNotExists(final File file) { if (file != null) { Assert.assertFalse(file.getAbsolutePath(), file.exists()); } } static void assertContentModification(final String patchID, final PatchableTarget target, final ContentModification modification) { final ContentItem item = modification.getItem(); final ContentType contentType = item.getContentType(); switch (contentType) { case MODULE: assertModule(patchID, target, (ModuleItem) item); break; case BUNDLE: break; case MISC: final File home = target.getDirectoryStructure().getInstalledImage().getJbossHome(); final ModificationCondition condition = modification.getCondition(); if(condition != null) { if(condition instanceof ModificationCondition.ExistsCondition) { final ContentItem requiredItem = ((ModificationCondition.ExistsCondition)condition).getContentItem(); File requiredFile; switch(requiredItem.getContentType()) { case MISC: requiredFile = PatchContentLoader.getMiscPath(home, (MiscContentItem)requiredItem); break; case MODULE: case BUNDLE: default: throw new IllegalStateException("Unsupported content type"); } if(!requiredFile.exists()) { final File file = PatchContentLoader.getMiscPath(home, (MiscContentItem)item); Assert.assertFalse(file.exists()); return; } } } assertMisc(home, modification.getType(), (MiscContentItem) item); break; default: Assert.fail(); } } static void assertMisc(final File root, final ModificationType modification, final MiscContentItem item) { final File file = PatchContentLoader.getMiscPath(root, item); Assert.assertTrue(item.getRelativePath(), file.exists() == (modification != ModificationType.REMOVE)); } static void assertModule(final String patchID, final PatchableTarget target, final String moduleName, final String slot) { assertModule(patchID, target, new ModuleItem(moduleName, slot, IoUtils.NO_CONTENT)); } static void assertModule(final String patchID, final PatchableTarget target, final ModuleItem item) { final File[] mp = TestUtils.getModuleRoot(target); final File currentPatch = target.getDirectoryStructure().getModulePatchDirectory(patchID); final File module = PatchContentLoader.getModulePath(currentPatch, item); assertModulePath(mp, item, module); } static void assertModulePath(final File[] mp, final ModuleItem item, final File reference) { File resolved = null; for (final File root : mp) { final File moduleRoot = PatchContentLoader.getModulePath(root, item); final File moduleXml = new File(moduleRoot, "module.xml"); if (moduleXml.exists()) { resolved = moduleRoot; break; } } Assert.assertEquals(item.toString(), reference, resolved); } }