/* * 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 static org.jboss.as.patching.HashUtils.hashFile; import static org.jboss.as.patching.runner.TestUtils.createModule0; 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 java.util.Arrays; import org.jboss.as.patching.PatchingException; import org.jboss.as.patching.installation.InstalledIdentity; import org.jboss.as.patching.tool.ContentVerificationPolicy; import org.junit.Assert; import org.junit.Test; /** * @author Emanuel Muckenhuber */ public class BasicHistoryUnitTestCase extends AbstractPatchingTest { static final String[] FILE_ONE = {"bin", "standalone.sh"}; static final String[] FILE_TWO = {"bin", "standalone.conf"}; static final String[] FILE_EXISTING = {"bin", "test"}; @Test public void testBasicPatchHistory() throws IOException, PatchingException { final PatchingTestBuilder builder = createDefaultBuilder(); final byte[] standaloneHash = new byte[20]; final byte[] moduleHash = new byte[20]; // Create a file final File existing = builder.getFile(FILE_EXISTING); touch(existing); dump(existing, randomString()); final byte[] existingHash = hashFile(existing); final byte[] initialHash = Arrays.copyOf(existingHash, existingHash.length); final PatchingTestStepBuilder cp1 = builder.createStepBuilder(); cp1.setPatchId("CP1") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .upgradeElement("base-CP1", "base", false) .addModuleWithRandomContent("org.jboss.test", moduleHash) .getParent() .addFileWithRandomContent(standaloneHash, FILE_ONE) .updateFileWithRandomContent(initialHash, existingHash, FILE_EXISTING); // Apply CP1 apply(cp1); Assert.assertTrue(builder.hasFile(FILE_ONE)); Assert.assertTrue(builder.hasFile(FILE_EXISTING)); Assert.assertTrue(Arrays.equals(existingHash, hashFile(existing))); final PatchingTestStepBuilder oneOff1 = builder.createStepBuilder(); oneOff1.setPatchId("oneOff1") .oneOffPatchIdentity(PRODUCT_VERSION) .oneOffPatchElement("base-oneOff1", "base", false) .updateModuleWithRandomContent("org.jboss.test", moduleHash, null) .getParent() .updateFileWithRandomContent(standaloneHash, null, FILE_ONE) .updateFileWithRandomContent(Arrays.copyOf(existingHash, existingHash.length), existingHash, FILE_EXISTING); // Apply oneOff1 apply(oneOff1); Assert.assertTrue(builder.hasFile(FILE_ONE)); Assert.assertTrue(builder.hasFile(FILE_EXISTING)); Assert.assertTrue(Arrays.equals(existingHash, hashFile(existing))); final PatchingTestStepBuilder cp2 = builder.createStepBuilder(); cp2.setPatchId("CP2") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .upgradeElement("base-CP2", "base", false) .addModuleWithRandomContent("org.jboss.test", moduleHash) .getParent() .addFileWithRandomContent(standaloneHash, FILE_TWO) .updateFileWithRandomContent(Arrays.copyOf(existingHash, existingHash.length), existingHash, FILE_EXISTING); // Apply CP2 apply(cp2); // Builds upon CP1 and has to invalidate one-off1 Assert.assertTrue(builder.hasFile(FILE_TWO)); Assert.assertTrue(builder.hasFile(FILE_ONE)); Assert.assertTrue(builder.hasFile(FILE_EXISTING)); Assert.assertTrue(Arrays.equals(existingHash, hashFile(existing))); rollback(cp2); rollback(oneOff1); rollback(cp1); } @Test public void testAutoResolveConflicts() throws Exception { final PatchingTestBuilder builder = createDefaultBuilder(); // Create a file final File existing = builder.getFile(FILE_EXISTING); touch(existing); dump(existing, randomString()); final byte[] existingHash = hashFile(existing); final byte[] initialHash = Arrays.copyOf(existingHash, existingHash.length); final byte[] moduleHash = new byte[20]; final PatchingTestStepBuilder oo1 = builder.createStepBuilder(); oo1.setPatchId("one-off-one") .oneOffPatchIdentity(PRODUCT_VERSION) .updateFileWithRandomContent(initialHash, existingHash, FILE_EXISTING) .oneOffPatchElement("base-one-off", "base", false) .addModuleWithRandomContent("test.module", moduleHash) ; // Apply OO1 apply(oo1); final PatchingTestStepBuilder cp1 = builder.createStepBuilder(); cp1.setPatchId("CP1") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .updateFileWithRandomContent(initialHash, existingHash, FILE_EXISTING) .upgradeElement("base-cp1", "base", false) .addModuleWithRandomContent("test.module", moduleHash) ; // Apply CP1 apply(cp1); rollback(cp1); rollback(oo1); } @Test public void testLayersBasics() throws Exception { final PatchingTestBuilder builder = createDefaultBuilder("layer2", "layer1", "base"); final byte[] standaloneHash = new byte[20]; final byte[] moduleHash = new byte[20]; final PatchingTestStepBuilder cp1 = builder.createStepBuilder(); cp1.setPatchId("CP1") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .upgradeElement("base-CP1", "base", false) .addModuleWithRandomContent("org.jboss.test", moduleHash) .getParent() .addFileWithRandomContent(standaloneHash, FILE_ONE) ; // Apply CP1 apply(cp1); Assert.assertTrue(builder.hasFile(FILE_ONE)); final PatchingTestStepBuilder cp2 = builder.createStepBuilder(); cp2.setPatchId("CP2") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .upgradeElement("layer2-CP2", "layer2", false) .addModuleWithRandomContent("org.jboss.test", null) .getParent() .upgradeElement("layer1-CP2", "layer1", false) .addModuleWithRandomContent("org.jboss.test", null) .getParent() .updateFileWithRandomContent(Arrays.copyOf(standaloneHash, standaloneHash.length), standaloneHash, FILE_ONE) ; // Apply CP2 apply(cp2); Assert.assertTrue(builder.hasFile(FILE_ONE)); final PatchingTestStepBuilder cp3 = builder.createStepBuilder(); cp3.setPatchId("CP3") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .removeFile(Arrays.copyOf(standaloneHash, standaloneHash.length), FILE_ONE) ; // Apply CP3 apply(cp3); Assert.assertFalse(builder.hasFile(FILE_ONE)); // Rollback rollback(cp3); Assert.assertTrue(builder.hasFile(FILE_ONE)); rollback(cp2); Assert.assertTrue(builder.hasFile(FILE_ONE)); rollback(cp1); Assert.assertFalse(builder.hasFile(FILE_ONE)); } @Test public void testRemoveModule() throws Exception { final PatchingTestBuilder testBuilder = createDefaultBuilder(); final File root = testBuilder.getRoot(); final File installation = new File(root, JBOSS_INSTALLATION); final File moduleRoot = new File(installation, "modules/system/layers/base"); final File module0 = createModule0(moduleRoot, "test.module", randomString()); final byte[] existing = hashFile(module0); final PatchingTestStepBuilder step1 = testBuilder.createStepBuilder(); step1.setPatchId("step1") .oneOffPatchIdentity(PRODUCT_VERSION) .oneOffPatchElement("base-1", "base", false) .removeModule("test.module", "main", existing) ; apply(step1); rollback(step1); } @Test public void testBasicIncrementalPatch() throws Exception { final PatchingTestBuilder builder = createDefaultBuilder(); final byte[] moduleHashOne = new byte[20]; final byte[] moduleHashTwo = new byte[20]; final PatchingTestStepBuilder cp1 = builder.createStepBuilder(); cp1.setPatchId("CP1") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .upgradeElement("base-CP1", "base", false) .addModuleWithRandomContent("org.jboss.test", moduleHashOne) ; // Apply CP1 apply(cp1); final PatchingTestStepBuilder cp2 = builder.createStepBuilder(); cp2.setPatchId("CP2") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .upgradeElement("base-CP2", "base", false) .addModuleWithRandomContent("org.jboss.test.two", moduleHashTwo) ; // Apply CP2 apply(cp2); InstalledIdentity identity = loadInstallationManager().getDefaultIdentity(); PatchStepAssertions.assertModule("base-CP2", identity.getLayer("base"), "org.jboss.test", "main"); PatchStepAssertions.assertModule("base-CP2", identity.getLayer("base"), "org.jboss.test.two", "main"); final PatchingTestStepBuilder cp3 = builder.createStepBuilder(); cp3.setPatchId("CP3") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .upgradeElement("base-CP3", "base", false) .removeModule("org.jboss.test.two", "main", moduleHashTwo) ; // Apply CP2 apply(cp3); identity = loadInstallationManager().getDefaultIdentity(); PatchStepAssertions.assertModule("base-CP3", identity.getLayer("base"), "org.jboss.test", "main"); PatchStepAssertions.assertModule("base-CP3", identity.getLayer("base"), "org.jboss.test.two", "main"); rollback(cp3); identity = loadInstallationManager().getDefaultIdentity(); PatchStepAssertions.assertModule("base-CP2", identity.getLayer("base"), "org.jboss.test", "main"); PatchStepAssertions.assertModule("base-CP2", identity.getLayer("base"), "org.jboss.test.two", "main"); rollback(cp2); identity = loadInstallationManager().getDefaultIdentity(); PatchStepAssertions.assertModule("base-CP1", identity.getLayer("base"), "org.jboss.test", "main"); rollback(cp1); } @Test public void testIncrementalLayersPatch() throws Exception { final PatchingTestBuilder builder = createDefaultBuilder("layer-2", "layer-1", "base"); final byte[] moduleHashOne = new byte[20]; final byte[] moduleHashTwo = new byte[20]; final byte[] moduleHashThree = new byte[20]; final byte[] moduleHashFour = new byte[20]; final byte[] moduleHashFive = new byte[20]; final byte[] moduleHashSix = new byte[20]; final PatchingTestStepBuilder cp1 = builder.createStepBuilder(); cp1.setPatchId("CP1") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .upgradeElement("base-CP1", "base", false) .addModuleWithRandomContent("org.jboss.test", moduleHashOne) ; // Apply CP1 apply(cp1); final PatchingTestStepBuilder cp2 = builder.createStepBuilder(); cp2.setPatchId("CP2") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .upgradeElement("layer-1-CP1", "layer-1", false) .addModuleWithRandomContent("org.jboss.test.two", moduleHashTwo) ; // Apply CP2 apply(cp2); final PatchingTestStepBuilder cp3 = builder.createStepBuilder(); cp3.setPatchId("CP3") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .upgradeElement("layer-2-CP1", "layer-2", false) .removeModule("org.jboss.test.three", "main", moduleHashThree) ; // Apply CP2 apply(cp3); final PatchingTestStepBuilder cp4 = builder.createStepBuilder(); cp4.setPatchId("CP4") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .upgradeElement("base-CP2", "base", false) .addModuleWithRandomContent("org.jboss.test.four", moduleHashFour) ; // Apply CP4 apply(cp4); InstalledIdentity identity = loadInstallationManager().getDefaultIdentity(); PatchStepAssertions.assertModule("base-CP2", identity.getLayer("base"), "org.jboss.test", "main"); PatchStepAssertions.assertModule("base-CP2", identity.getLayer("base"), "org.jboss.test.four", "main"); final PatchingTestStepBuilder cp5 = builder.createStepBuilder(); cp5.setPatchId("CP5") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .upgradeElement("base-CP3", "base", false) .updateModuleWithRandomContent("org.jboss.test.four", moduleHashFour, null) .getParent() .upgradeElement("layer-1-CP2", "layer-1", false) .addModuleWithRandomContent("org.jboss.test.five", moduleHashFive) .getParent() .upgradeElement("layer-2-CP2", "layer-2", false) .addModuleWithRandomContent("org.jboss.test.six", moduleHashSix) ; // Apply CP5 apply(cp5); identity = loadInstallationManager().getDefaultIdentity(); PatchStepAssertions.assertModule("base-CP3", identity.getLayer("base"), "org.jboss.test", "main"); PatchStepAssertions.assertModule("base-CP3", identity.getLayer("base"), "org.jboss.test.four", "main"); PatchStepAssertions.assertModule("layer-1-CP2", identity.getLayer("layer-1"), "org.jboss.test.two", "main"); PatchStepAssertions.assertModule("layer-1-CP2", identity.getLayer("layer-1"), "org.jboss.test.five", "main"); PatchStepAssertions.assertModule("layer-2-CP2", identity.getLayer("layer-2"), "org.jboss.test.three", "main"); PatchStepAssertions.assertModule("layer-2-CP2", identity.getLayer("layer-2"), "org.jboss.test.six", "main"); rollback(cp5); rollback(cp4); rollback(cp3); rollback(cp2); rollback(cp1); } @Test public void testRollbackTo() throws Exception { final PatchingTestBuilder test = createDefaultBuilder(); final byte[] existingHash = new byte[20]; final byte[] resultingHash = Arrays.copyOf(existingHash, existingHash.length); final PatchingTestStepBuilder oop1 = test.createStepBuilder(); oop1.setPatchId("oop1") .oneOffPatchIdentity(PRODUCT_VERSION) .oneOffPatchElement("base-oop1", "base", false) .addModuleWithRandomContent("org.jboss.test", existingHash) ; apply(oop1); final PatchingTestStepBuilder oop2 = test.createStepBuilder(); oop2.setPatchId("oop2") .oneOffPatchIdentity(PRODUCT_VERSION) .oneOffPatchElement("base-oop2", "base", false) .updateModuleWithRandomContent("org.jboss.test", existingHash, resultingHash) ; apply(oop2); // RollbackTo rollback(oop1, ContentVerificationPolicy.STRICT, PatchStepAssertions.NONE, true); } @Test public void testUpdateNonExistingFile() throws Exception { final PatchingTestBuilder test = createDefaultBuilder(); final byte[] existingHash = new byte[20]; final byte[] resultingHash = Arrays.copyOf(existingHash, existingHash.length); final PatchingTestStepBuilder oop1 = test.createStepBuilder(); oop1.setPatchId("oop1") .oneOffPatchIdentity(PRODUCT_VERSION) .oneOffPatchElement("base-oop1", "base", false) .addModuleWithRandomContent("org.jboss.test", null) .getParent() .updateFileWithRandomContent(existingHash, resultingHash, "client.jar") ; apply(oop1, ContentVerificationPolicy.OVERRIDE_ALL); Assert.assertTrue(test.hasFile("client.jar")); final byte[] moduleHash = new byte[20]; final PatchingTestStepBuilder cp1 = test.createStepBuilder(); cp1.setPatchId("CP1") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .upgradeElement("base-CP1", "base", false) .addModuleWithRandomContent("org.jboss.test", moduleHash) .getParent() ; // Apply CP1 apply(cp1, ContentVerificationPolicy.OVERRIDE_ALL); Assert.assertFalse(test.hasFile("client.jar")); rollback(cp1); rollback(oop1); } @Test public void testAddExistingFile() throws Exception { final PatchingTestBuilder test = createDefaultBuilder(); // Create a file final File existing = test.getFile(FILE_EXISTING); touch(existing); dump(existing, randomString()); final byte[] existingHash = hashFile(existing); final byte[] resultingHash = Arrays.copyOf(existingHash, existingHash.length); final PatchingTestStepBuilder oop1 = test.createStepBuilder(); oop1.setPatchId("oop1") .oneOffPatchIdentity(PRODUCT_VERSION) .oneOffPatchElement("base-oop1", "base", false) .addModuleWithRandomContent("org.jboss.test", null) .getParent() .addFileWithRandomContent(resultingHash, FILE_EXISTING); apply(oop1, ContentVerificationPolicy.OVERRIDE_ALL); Assert.assertTrue(test.hasFile(FILE_EXISTING)); final byte[] moduleHash = new byte[20]; final PatchingTestStepBuilder cp1 = test.createStepBuilder(); cp1.setPatchId("CP1") .upgradeIdentity(PRODUCT_VERSION, PRODUCT_VERSION) .upgradeElement("base-CP1", "base", false) .addModuleWithRandomContent("org.jboss.test", moduleHash) .getParent() ; // Apply CP1 apply(cp1, ContentVerificationPolicy.OVERRIDE_ALL); Assert.assertTrue(test.hasFile(FILE_EXISTING)); rollback(cp1); rollback(oop1); Assert.assertTrue(test.hasFile(FILE_EXISTING)); } }