/* * 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.cli; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.jboss.as.patching.HashUtils.bytesToHexString; import static org.jboss.as.patching.HashUtils.hashFile; import static org.jboss.as.patching.IoUtils.mkdir; import static org.jboss.as.patching.runner.PatchingAssert.assertDirDoesNotExist; import static org.jboss.as.patching.runner.PatchingAssert.assertFileContent; import static org.jboss.as.patching.runner.PatchingAssert.assertFileExists; import static org.jboss.as.patching.runner.TestUtils.createInstalledImage; import static org.jboss.as.patching.runner.TestUtils.createPatchXMLFile; import static org.jboss.as.patching.runner.TestUtils.createZippedPatchFile; import static org.jboss.as.patching.runner.TestUtils.dump; import static org.jboss.as.patching.runner.TestUtils.randomString; import static org.jboss.as.patching.runner.TestUtils.touch; import java.io.File; import java.io.IOException; import org.jboss.as.cli.CommandContext; import org.jboss.as.cli.CommandContextFactory; import org.jboss.as.patching.metadata.ContentModification; import org.jboss.as.patching.metadata.Patch; import org.jboss.as.patching.metadata.PatchBuilder; import org.jboss.as.patching.runner.AbstractTaskTestCase; import org.jboss.as.patching.runner.ContentModificationUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * @author Alexey Loubyansky * */ public class ResetConfigurationUnitTestCase extends AbstractTaskTestCase { private byte[] originalAppClientHash; private byte[] originalStandaloneHash; private byte[] originalDomainHash; private File appClientXmlFile; private File standaloneXmlFile; private File domainXmlFile; @Before public void setUp() throws Exception { // with some files in the configuration directories appClientXmlFile = touch(env.getInstalledImage().getAppClientDir(), "configuration", "appclient.xml"); dump(appClientXmlFile, "<original content of appclient configuration>"); originalAppClientHash = hashFile(appClientXmlFile); standaloneXmlFile = touch(env.getInstalledImage().getStandaloneDir(), "configuration", "standalone.xml"); dump(standaloneXmlFile, "<original content of standalone configuration>"); originalStandaloneHash = hashFile(standaloneXmlFile); domainXmlFile = touch(env.getInstalledImage().getDomainDir(), "configuration", "domain.xml"); dump(domainXmlFile, "<original content of domain configuration>"); originalDomainHash = hashFile(domainXmlFile); } @After public void tearDown() { super.tearDown(); originalAppClientHash = null; originalStandaloneHash = null; originalDomainHash = null; standaloneXmlFile = null; appClientXmlFile = null; domainXmlFile = null; } /** * Applies a patch, modifies standalone, appclient and domain xml config and rolls back the patch * with --reset-configuration=false * The expected result is: * - the modified config files remain as-is; * - in each configuration dir a new restored-configuration dir is created with the original, * unmodified configuration files. * * * @throws Exception */ @Test public void testResetConfigurationFalse() throws Exception { final File binDir = createInstalledImage(env, "consoleSlot", productConfig.getProductName(), productConfig.getProductVersion()); // build a one-off patch for the base installation // with 1 updated file String patchID = randomString(); String patchElementId = randomString(); File patchDir = mkdir(tempDir, patchID); // create a file for the conflict String fileNoConflictName = "file-no-conflict.txt"; File noConflictFile = touch(binDir, fileNoConflictName); dump(noConflictFile, "original script to run standalone AS7"); // patch the file ContentModification fileNoConflictModified = ContentModificationUtils.modifyMisc(patchDir, patchID, "updated script", noConflictFile, "bin", fileNoConflictName); //TestUtils.tree(env.getInstalledImage().getJbossHome()); Patch patch = PatchBuilder.create() .setPatchId(patchID) .setDescription(randomString()) .upgradeIdentity(productConfig.getProductName(), productConfig.getProductVersion(), productConfig.getProductVersion() + "CP1") .getParent() .addContentModification(fileNoConflictModified) .upgradeElement(patchElementId, "base", false) .getParent() .build(); // create the patch createPatchXMLFile(patchDir, patch, false); File zippedPatch = createZippedPatchFile(patchDir, patch.getPatchId()); // apply the patch using the cli CommandContext ctx = CommandContextFactory.getInstance().newCommandContext(); try { ctx.handle("patch apply " + zippedPatch.getAbsolutePath() + " --distribution=" + env.getInstalledImage().getJbossHome()); } catch(Exception e) { ctx.terminateSession(); throw e; } // check the config files have been backed up File backupAppclientXmlFile = assertFileExists(env.getInstalledImage().getPatchHistoryDir(patch.getPatchId()), "configuration", "appclient", "appclient.xml"); assertFileContent(originalAppClientHash, backupAppclientXmlFile); File backupStandaloneXmlFile = assertFileExists(env.getInstalledImage().getPatchHistoryDir(patch.getPatchId()), "configuration", "standalone", "standalone.xml"); assertFileContent(originalStandaloneHash, backupStandaloneXmlFile); File backupDomainXmlFile = assertFileExists(env.getInstalledImage().getPatchHistoryDir(patch.getPatchId()), "configuration", "domain", "domain.xml"); assertFileContent(originalDomainHash, backupDomainXmlFile); // let's change the standalone.xml file dump(standaloneXmlFile, "<updated standalone configuration with changes from the added module>"); byte[] updatedStandaloneXmlHash = hashFile(standaloneXmlFile); dump(appClientXmlFile, "<updated app client configuration with changes from the added module>"); byte[] updatedAppClientXmlHash = hashFile(appClientXmlFile); dump(domainXmlFile, "<updated domain configuration with changes from the added module>"); byte[] updatedDomainXmlHash = hashFile(domainXmlFile); try { ctx.handle("patch rollback --reset-configuration=false --distribution=" + env.getInstalledImage().getJbossHome()); } finally { ctx.terminateSession(); } //TestUtils.tree(env.getInstalledImage().getJbossHome()); assertRestoredConfig(env.getInstalledImage().getStandaloneDir(), "standalone.xml", updatedStandaloneXmlHash, originalStandaloneHash); assertRestoredConfig(env.getInstalledImage().getAppClientDir(), "appclient.xml", updatedAppClientXmlHash, originalAppClientHash); assertRestoredConfig(env.getInstalledImage().getDomainDir(), "domain.xml", updatedDomainXmlHash, originalDomainHash); } protected void assertRestoredConfig(File baseDir, String xmlName, byte[] updatedHash, byte[] originalHash) throws IOException { File rolledBackXmlFile = assertFileExists(baseDir, "configuration", xmlName); assertEquals(bytesToHexString(updatedHash), bytesToHexString(hashFile(rolledBackXmlFile))); File restoredXmlFile = assertFileExists(baseDir, "configuration", "restored-configuration", xmlName); assertEquals(bytesToHexString(originalHash), bytesToHexString(hashFile(restoredXmlFile))); } /** * Applies a patch, modifies standalone, appclient and domain xml config and rolls back the patch * with --reset-configuration=true * The expected result is: * - the modified config files are replaced with the original configuration files; * - the restored-configuration dir is not created in any of the configuration dirs * . * @throws Exception */ @Test public void testResetConfigurationTrue() throws Exception { final File binDir = createInstalledImage(env, "consoleSlot", productConfig.getProductName(), productConfig.getProductVersion()); // build a one-off patch for the base installation // with 1 updated file String patchID = randomString(); String patchElementId = randomString(); File patchDir = mkdir(tempDir, patchID); // create a file for the conflict String fileNoConflictName = "file-no-conflict.txt"; File noConflictFile = touch(binDir, fileNoConflictName); dump(noConflictFile, "original script to run standalone AS7"); // patch the file ContentModification fileNoConflictModified = ContentModificationUtils.modifyMisc(patchDir, patchID, "updated script", noConflictFile, "bin", fileNoConflictName); //TestUtils.tree(env.getInstalledImage().getJbossHome()); Patch patch = PatchBuilder.create() .setPatchId(patchID) .setDescription(randomString()) .upgradeIdentity(productConfig.getProductName(), productConfig.getProductVersion(), productConfig.getProductVersion() + "CP1") .getParent() .addContentModification(fileNoConflictModified) .upgradeElement(patchElementId, "base", false) .getParent() .build(); // create the patch createPatchXMLFile(patchDir, patch, false); File zippedPatch = createZippedPatchFile(patchDir, patch.getPatchId()); // apply the patch using the cli CommandContext ctx = CommandContextFactory.getInstance().newCommandContext(); try { ctx.handle("patch apply " + zippedPatch.getAbsolutePath() + " --distribution=" + env.getInstalledImage().getJbossHome()); } catch(Exception e) { ctx.terminateSession(); throw e; } // check the config files have been backed up File backupAppclientXmlFile = assertFileExists(env.getInstalledImage().getPatchHistoryDir(patch.getPatchId()), "configuration", "appclient", "appclient.xml"); assertFileContent(originalAppClientHash, backupAppclientXmlFile); File backupStandaloneXmlFile = assertFileExists(env.getInstalledImage().getPatchHistoryDir(patch.getPatchId()), "configuration", "standalone", "standalone.xml"); assertFileContent(originalStandaloneHash, backupStandaloneXmlFile); File backupDomainXmlFile = assertFileExists(env.getInstalledImage().getPatchHistoryDir(patch.getPatchId()), "configuration", "domain", "domain.xml"); assertFileContent(originalDomainHash, backupDomainXmlFile); // let's change the standalone.xml file dump(standaloneXmlFile, "<updated standalone configuration with changes from the added module>"); byte[] updatedStandaloneXmlFile = hashFile(standaloneXmlFile); assertNotEquals(bytesToHexString(originalStandaloneHash), bytesToHexString(updatedStandaloneXmlFile)); dump(appClientXmlFile, "<updated app client configuration with changes from the added module>"); byte[] updatedAppClientXmlHash = hashFile(appClientXmlFile); assertNotEquals(bytesToHexString(originalAppClientHash), bytesToHexString(updatedAppClientXmlHash)); dump(domainXmlFile, "<updated domain configuration with changes from the added module>"); byte[] updatedDomainXmlHash = hashFile(domainXmlFile); assertNotEquals(bytesToHexString(originalDomainHash), bytesToHexString(updatedDomainXmlHash)); try { ctx.handle("patch rollback --reset-configuration=true --distribution=" + env.getInstalledImage().getJbossHome()); } finally { ctx.terminateSession(); } //TestUtils.tree(env.getInstalledImage().getJbossHome()); File rolledBackStandaloneXmlFile = assertFileExists(env.getInstalledImage().getStandaloneDir(), "configuration", "standalone.xml"); assertEquals(bytesToHexString(originalStandaloneHash), bytesToHexString(hashFile(rolledBackStandaloneXmlFile))); File rolledBackAppClientXmlFile = assertFileExists(env.getInstalledImage().getAppClientDir(), "configuration", "appclient.xml"); assertEquals(bytesToHexString(originalAppClientHash), bytesToHexString(hashFile(rolledBackAppClientXmlFile))); File rolledBackDomainXmlFile = assertFileExists(env.getInstalledImage().getDomainDir(), "configuration", "domain.xml"); assertEquals(bytesToHexString(originalDomainHash), bytesToHexString(hashFile(rolledBackDomainXmlFile))); assertDirDoesNotExist(env.getInstalledImage().getStandaloneDir(), "configuration", "restored-configuration"); assertDirDoesNotExist(env.getInstalledImage().getAppClientDir(), "configuration", "restored-configuration"); assertDirDoesNotExist(env.getInstalledImage().getDomainDir(), "configuration", "restored-configuration"); } }