/*
* JBoss, Home of Professional Open Source.
* Copyright 2012, 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.runner;
import static java.lang.String.format;
import static java.util.Arrays.asList;
import static org.jboss.as.patching.HashUtils.bytesToHexString;
import static org.jboss.as.patching.HashUtils.hashFile;
import static org.jboss.as.patching.metadata.Patch.PatchType.CUMULATIVE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import org.jboss.as.patching.ContentConflictsException;
import org.jboss.as.patching.DirectoryStructure;
import org.jboss.as.patching.IoUtils;
import org.jboss.as.patching.PatchInfo;
import org.jboss.as.patching.installation.Identity;
import org.jboss.as.patching.installation.PatchableTarget;
import org.jboss.as.patching.metadata.ContentItem;
import org.jboss.as.patching.metadata.Patch;
import org.jboss.as.patching.tool.PatchingResult;
import org.junit.Assert;
/**
* @author <a href="http://jmesnil.net/">Jeff Mesnil</a> (c) 2012, Red Hat Inc
*/
public class PatchingAssert {
public static void assertContains(File f, File... files) {
List<File> set = Arrays.asList(files);
assertTrue(f + " not found in " + set, set.contains(f));
}
public static File assertDirExists(File rootDir, String... segments) {
return assertFileExists(true, rootDir, segments);
}
public static void assertDirDoesNotExist(File rootDir, String... segments) {
assertFileDoesNotExist(rootDir, segments);
}
public static File assertFileExists(File rootDir, String... segments) {
return assertFileExists(false, rootDir, segments);
}
private static File assertFileExists(boolean isDir, File rootFile, String... segments) {
assertTrue(rootFile + " does not exist", rootFile.exists());
File f = rootFile;
for (String segment : segments) {
f = new File(f, segment);
assertTrue(f + " does not exist", f.exists());
}
assertEquals(f + " is " + (isDir? "not":"") + " a directory", isDir, f.isDirectory());
return f;
}
public static void assertFileDoesNotExist(File rootFile, String... segments) {
File f = IoUtils.newFile(rootFile, segments);
assertFalse(f + " exists", f.exists());
}
public static void assertFileContent(byte[] expected, File f) throws Exception {
assertFileContent(null, expected, f);
}
public static void assertFileContent(String message, byte[] expected, File f) throws Exception {
assertEquals(message, bytesToHexString(expected), bytesToHexString(hashFile(f)));
}
public static void assertDefinedModule(File[] modulesPath, String moduleName, byte[] expectedHash) throws Exception {
for (File path : modulesPath) {
final File modulePath = PatchContentLoader.getModulePath(path, moduleName, "main");
final File moduleXml = new File(modulePath, "module.xml");
if (moduleXml.exists()) {
assertDefinedModuleWithRootElement(moduleXml, moduleName, "<module");
if (expectedHash != null) {
byte[] actualHash = hashFile(modulePath);
assertTrue("content of module differs", Arrays.equals(expectedHash, actualHash));
}
return;
}
}
fail("count not find module for " + moduleName + " in " + asList(modulesPath));
}
public static void assertDefinedModule(File moduleRoot, String moduleName, byte[] expectedHash) throws Exception {
final File modulePath = PatchContentLoader.getModulePath(moduleRoot, moduleName, "main");
final File moduleXml = new File(modulePath, "module.xml");
if (moduleXml.exists()) {
assertDefinedModuleWithRootElement(moduleXml, moduleName, "<module");
if (expectedHash != null) {
byte[] actualHash = hashFile(modulePath);
assertTrue("content of module differs", Arrays.equals(expectedHash, actualHash));
}
return;
}
fail("count not find module for " + moduleName + " in " + moduleRoot);
}
static void assertDefinedBundle(File[] bundlesPath, String moduleName, byte[] expectedHash) throws Exception {
for (File path : bundlesPath) {
final File bundlePath = PatchContentLoader.getModulePath(path, moduleName, "main");
if(bundlePath.exists()) {
if(expectedHash != null) {
byte[] actualHash = hashFile(bundlePath);
assertTrue("content of bundle differs", Arrays.equals(expectedHash, actualHash));
}
return;
}
}
fail("content not found bundle for " + moduleName + " in " + asList(bundlesPath));
}
static void assertDefinedBundle(File bundlesDir, String moduleName, byte[] expectedHash) throws Exception {
final File bundlePath = PatchContentLoader.getModulePath(bundlesDir, moduleName, "main");
if(bundlePath.exists()) {
if(expectedHash != null) {
byte[] actualHash = hashFile(bundlePath);
assertTrue("content of bundle differs", Arrays.equals(expectedHash, actualHash));
}
} else {
fail("content not found bundle for " + moduleName + " in " + bundlesDir);
}
}
static void assertDefinedAbsentBundle(File[] bundlesPath, String moduleName) throws Exception {
for (File path : bundlesPath) {
final File bundlePath = PatchContentLoader.getModulePath(path, moduleName, "main");
if(bundlePath.exists()) {
final File[] children = bundlePath.listFiles();
if(children.length == 0) {
return;
}
}
}
fail("content not found bundle for " + moduleName + " in " + asList(bundlesPath));
}
static void assertDefinedAbsentBundle(File bundlesDir, String bundleName) throws Exception {
final File bundlePath = PatchContentLoader.getModulePath(bundlesDir, bundleName, "main");
if(bundlePath.exists()) {
final File[] children = bundlePath.listFiles();
if(children.length == 0) {
return;
}
}
fail("content found for " + bundleName + " in " + bundlesDir);
}
static void assertDefinedAbsentModule(File[] modulesPath, String moduleName) throws Exception {
for (File path : modulesPath) {
final File modulePath = PatchContentLoader.getModulePath(path, moduleName, "main");
final File moduleXml = new File(modulePath, "module.xml");
if (moduleXml.exists()) {
assertDefinedModuleWithRootElement(moduleXml, moduleName, "<module-absent ");
return;
}
}
fail("count not found module for " + moduleName + " in " + asList(modulesPath));
}
public static void assertDefinedAbsentModule(File modulesDir, String moduleName) throws Exception {
final File modulePath = PatchContentLoader.getModulePath(modulesDir, moduleName, "main");
final File moduleXml = new File(modulePath, "module.xml");
if (moduleXml.exists()) {
assertDefinedModuleWithRootElement(moduleXml, moduleName, "<module-absent ");
} else {
fail("count not found module for " + moduleName + " in " + modulesDir);
}
}
private static void assertDefinedModuleWithRootElement(File moduleXMLFile, String moduleName, String rootElement) throws Exception {
assertFileExists(moduleXMLFile);
assertFileContains(moduleXMLFile,rootElement);
assertFileContains(moduleXMLFile, format("name=\"%s\"", moduleName));
}
private static void assertFileContains(File f, String string) throws Exception {
try (Scanner scanner = new Scanner(f, "UTF-8").useDelimiter("\\Z")) {
String content = scanner.next();
assertTrue(string + " not found in " + f + " with content=" + content, content.contains(string));
}
}
public static void assertPatchHasBeenApplied(PatchingResult result, Patch patch) {
if (CUMULATIVE == patch.getIdentity().getPatchType()) {
assertEquals(patch.getPatchId(), result.getPatchInfo().getCumulativePatchID());
assertTrue(result.getPatchInfo().getPatchIDs().isEmpty());
assertEquals(patch.getIdentity().forType(CUMULATIVE, org.jboss.as.patching.metadata.Identity.IdentityUpgrade.class).getResultingVersion(), result.getPatchInfo().getVersion());
} else {
assertTrue(result.getPatchInfo().getPatchIDs().contains(patch.getPatchId()));
// applied one-off patch is at the top of the patchIDs
assertEquals(patch.getPatchId(), result.getPatchInfo().getPatchIDs().get(0));
}
}
static void assertPatchHasNotBeenApplied(ContentConflictsException result, Patch patch, ContentItem problematicItem, DirectoryStructure structure) {
assertFalse("patch should have failed", result.getConflicts().isEmpty());
assertTrue(problematicItem + " is not reported in the problems " + result.getConflicts(), result.getConflicts().contains(problematicItem));
assertDirDoesNotExist(structure.getInstalledImage().getPatchHistoryDir(patch.getPatchId()));
}
public static void assertPatchHasBeenRolledBack(PatchingResult result, Patch patch, PatchInfo expectedPatchInfo) {
assertEquals(expectedPatchInfo.getVersion(), result.getPatchInfo().getVersion());
assertEquals(expectedPatchInfo.getCumulativePatchID(), result.getPatchInfo().getCumulativePatchID());
assertEquals(expectedPatchInfo.getPatchIDs(), result.getPatchInfo().getPatchIDs());
// assertNoResourcesForPatch(result.getPatchInfo(), patch);
}
public static void assertPatchHasBeenRolledBack(PatchingResult result, Patch patch, PatchableTarget.TargetInfo expectedPatchInfo) {
assertEquals(expectedPatchInfo.getCumulativePatchID(), result.getPatchInfo().getCumulativePatchID());
assertEquals(expectedPatchInfo.getPatchIDs(), result.getPatchInfo().getPatchIDs());
// assertNoResourcesForPatch(result.getPatchInfo(), patch);
}
public static void assertPatchHasBeenRolledBack(PatchingResult result, Identity expectedIdentity) throws IOException {
assertEquals(expectedIdentity.getVersion(), result.getPatchInfo().getVersion());
assertEquals(expectedIdentity.loadTargetInfo().getCumulativePatchID(), result.getPatchInfo().getCumulativePatchID());
assertEquals(expectedIdentity.loadTargetInfo().getPatchIDs(), result.getPatchInfo().getPatchIDs());
}
static void assertNoResourcesForPatch(DirectoryStructure structure, Patch patch) {
assertDirDoesNotExist(structure.getModulePatchDirectory(patch.getPatchId()));
assertDirDoesNotExist(structure.getBundlesPatchDirectory(patch.getPatchId()));
assertDirDoesNotExist(structure.getInstalledImage().getPatchHistoryDir(patch.getPatchId()));
}
public static void assertInstallationIsPatched(Patch patch, PatchableTarget.TargetInfo targetInfo) {
if (CUMULATIVE == patch.getIdentity().getPatchType()) {
assertEquals(patch.getPatchId(), targetInfo.getCumulativePatchID());
} else {
Assert.assertTrue(targetInfo.getPatchIDs().contains(patch.getPatchId()));
// applied one-off patch is at the top of the patchIDs
assertEquals(patch.getPatchId(), targetInfo.getPatchIDs().get(0));
}
}
}