/*
* 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));
}
}