/*
* 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.logging;
import java.io.IOException;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.client.helpers.Operations.CompositeOperationBuilder;
import org.jboss.as.controller.services.path.PathResourceDefinition;
import org.jboss.as.logging.logmanager.ConfigurationPersistence;
import org.jboss.as.subsystem.test.KernelServices;
import org.jboss.as.subsystem.test.SubsystemOperations;
import org.jboss.byteman.contrib.bmunit.BMRule;
import org.jboss.byteman.contrib.bmunit.BMRules;
import org.jboss.byteman.contrib.bmunit.BMUnitRunner;
import org.jboss.dmr.ModelNode;
import org.jboss.logmanager.LogContext;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* @author <a href="jperkins@redhat.com">James R. Perkins</a>
*/
@RunWith(BMUnitRunner.class)
public class LoggingSubsystemRollbackTestCase extends AbstractLoggingSubsystemTest {
private static final String PROFILE_NAME = "test-profile";
@Override
protected String getSubsystemXml() throws IOException {
return readResource("/rollback-logging.xml");
}
@Override
protected void standardSubsystemTest(final String configId) throws Exception {
// do nothing as this is not a subsystem parsing test
}
@After
@Override
public void clearLogContext() {
super.clearLogContext();
final LoggingProfileContextSelector contextSelector = LoggingProfileContextSelector.getInstance();
if (contextSelector.exists(PROFILE_NAME)) {
clearLogContext(contextSelector.get(PROFILE_NAME));
contextSelector.remove(PROFILE_NAME);
}
}
@Test
@BMRule(name = "Test logger rollback handler",
targetClass = "org.jboss.as.logging.LoggerOperations$LoggerAddOperationStepHandler",
targetMethod = "performRuntime",
targetLocation = "AT EXIT",
condition = "$4.equals(\"org.jboss.as.logging.test\")",
action = "$1.setRollbackOnly()"
)
public void testRollbackLogger() throws Exception {
final KernelServices kernelServices = boot();
// Save the current model
final ModelNode validSubsystemModel = getSubsystemModel(kernelServices);
// The logger address
final PathAddress address = createLoggerAddress("org.jboss.as.logging.test");
// Operation should fail based on byteman script
ModelNode op = SubsystemOperations.createAddOperation(address.toModelNode());
ModelNode result = kernelServices.executeOperation(op);
Assert.assertFalse("The add operation should have failed, but was successful: " + result, SubsystemOperations.isSuccessfulOutcome(result));
// Verify the loggers are not there - operation should fail on missing resource
op = SubsystemOperations.createReadResourceOperation(address.toModelNode());
result = kernelServices.executeOperation(op);
Assert.assertFalse("The operation should have failed, but was successful: " + result, SubsystemOperations.isSuccessfulOutcome(result));
// verify the subsystem model matches the old model
final ModelNode currentModel = getSubsystemModel(kernelServices);
compare(validSubsystemModel, currentModel);
final ConfigurationPersistence config = ConfigurationPersistence.getConfigurationPersistence(LogContext.getLogContext());
compare(currentModel, config);
}
@Test
@BMRule(name = "Test handler rollback handler",
targetClass = "org.jboss.as.logging.HandlerOperations$HandlerAddOperationStepHandler",
targetMethod = "performRuntime",
targetLocation = "AT EXIT",
condition = "$4.equals(\"CONSOLE2\")",
action = "$1.setRollbackOnly()")
public void testRollbackHandler() throws Exception {
final KernelServices kernelServices = boot();
// Save the current model
final ModelNode validSubsystemModel = getSubsystemModel(kernelServices);
// Handler address
final PathAddress address = createConsoleHandlerAddress("CONSOLE2");
// Operation should fail based on byteman script
ModelNode op = SubsystemOperations.createAddOperation(address.toModelNode());
op.get(CommonAttributes.LEVEL.getName()).set("INFO");
op.get(AbstractHandlerDefinition.FORMATTER.getName()).set("%d{HH:mm:ss,SSS} %-5p [%c] (%t) CONSOLE2: %s%e%n");
ModelNode result = kernelServices.executeOperation(op);
Assert.assertFalse("The add operation should have failed, but was successful: " + result, SubsystemOperations.isSuccessfulOutcome(result));
// Verify the loggers are not there - operation should fail on missing resource
op = SubsystemOperations.createReadResourceOperation(address.toModelNode());
result = kernelServices.executeOperation(op);
Assert.assertFalse("The operation should have failed, but was successful: " + result, SubsystemOperations.isSuccessfulOutcome(result));
// verify the subsystem model matches the old model
final ModelNode currentModel = getSubsystemModel(kernelServices);
compare(validSubsystemModel, currentModel);
final ConfigurationPersistence config = ConfigurationPersistence.getConfigurationPersistence(LogContext.getLogContext());
compare(currentModel, config);
}
@Test
@BMRule(name = "Test handler rollback handler",
targetClass = "org.jboss.as.logging.LoggerOperations$LoggerWriteAttributeHandler",
targetMethod = "applyUpdate",
targetLocation = "AT EXIT",
condition = "$3.equals(\"org.jboss.as.logging\")",
action = "$1.setRollbackOnly()")
public void testRollbackComposite() throws Exception {
final KernelServices kernelServices = boot();
// Add a handler to be removed
final PathAddress consoleHandler = createConsoleHandlerAddress("CONSOLE2");
// Create a new handler
ModelNode op = SubsystemOperations.createAddOperation(consoleHandler.toModelNode());
op.get(CommonAttributes.LEVEL.getName()).set("INFO");
op.get(AbstractHandlerDefinition.FORMATTER.getName()).set("%d{HH:mm:ss,SSS} %-5p [%c] (%t) CONSOLE2: %s%e%n");
ModelNode result = kernelServices.executeOperation(op);
Assert.assertTrue(SubsystemOperations.getFailureDescriptionAsString(result), SubsystemOperations.isSuccessfulOutcome(result));
// Add the handler to a logger
final PathAddress loggerAddress = createLoggerAddress("org.jboss.as.logging");
op = SubsystemOperations.createOperation(CommonAttributes.ADD_HANDLER_OPERATION_NAME, loggerAddress.toModelNode());
op.get(CommonAttributes.HANDLER_NAME.getName()).set(consoleHandler.getLastElement().getValue());
result = kernelServices.executeOperation(op);
Assert.assertTrue(SubsystemOperations.getFailureDescriptionAsString(result), SubsystemOperations.isSuccessfulOutcome(result));
// Save the current model
final ModelNode validSubsystemModel = getSubsystemModel(kernelServices);
final CompositeOperationBuilder operationBuilder = CompositeOperationBuilder.create();
// create a new handler
final PathAddress fileHandlerAddress = createFileHandlerAddress("fail-fh");
final ModelNode fileHandlerOp = SubsystemOperations.createAddOperation(fileHandlerAddress.toModelNode());
fileHandlerOp.get(CommonAttributes.FILE.getName(), PathResourceDefinition.RELATIVE_TO.getName()).set("jboss.server.log.dir");
fileHandlerOp.get(CommonAttributes.FILE.getName(), PathResourceDefinition.PATH.getName()).set("fail-fh.log");
fileHandlerOp.get(CommonAttributes.AUTOFLUSH.getName()).set(true);
operationBuilder.addStep(fileHandlerOp);
// create a new logger
final PathAddress testLoggerAddress = createLoggerAddress("test");
final ModelNode testLoggerOp = SubsystemOperations.createAddOperation(testLoggerAddress.toModelNode());
operationBuilder.addStep(testLoggerOp);
// add handler to logger
operationBuilder.addStep(SubsystemOperations.createWriteAttributeOperation(testLoggerAddress.toModelNode(), CommonAttributes.HANDLERS, new ModelNode().setEmptyList().add("fail-fh")));
// remove the console handler
operationBuilder.addStep(SubsystemOperations.createRemoveOperation(consoleHandler.toModelNode()));
// add handler to existing logger - should force fail on this one
operationBuilder.addStep(SubsystemOperations.createWriteAttributeOperation(loggerAddress.toModelNode(), CommonAttributes.HANDLERS, new ModelNode().setEmptyList().add("fail-fh")));
// verify the operation failed
result = kernelServices.executeOperation(operationBuilder.build().getOperation());
Assert.assertFalse("The add operation should have failed, but was successful: " + result, SubsystemOperations.isSuccessfulOutcome(result));
// verify the subsystem model matches the old model
final ModelNode currentModel = getSubsystemModel(kernelServices);
compare(validSubsystemModel, currentModel);
final ConfigurationPersistence config = ConfigurationPersistence.getConfigurationPersistence(LogContext.getLogContext());
compare(currentModel, config);
}
@Test
@BMRule(name = "Test handler rollback handler",
targetClass = "org.jboss.as.logging.LoggerOperations$LoggerWriteAttributeHandler",
targetMethod = "applyUpdate",
targetLocation = "AT EXIT",
condition = "$3.equals(\"org.jboss.as.logging\")",
action = "$1.setRollbackOnly()")
public void testRollbackCompositeLoggingProfile() throws Exception {
final KernelServices kernelServices = boot();
// Add a handler to be removed
final PathAddress consoleHandler = createConsoleHandlerAddress("CONSOLE2");
// Create a new handler
ModelNode op = SubsystemOperations.createAddOperation(consoleHandler.toModelNode());
op.get(CommonAttributes.LEVEL.getName()).set("INFO");
op.get(AbstractHandlerDefinition.FORMATTER.getName()).set("%d{HH:mm:ss,SSS} %-5p [%c] (%t) CONSOLE2: %s%e%n");
ModelNode result = kernelServices.executeOperation(op);
Assert.assertTrue(SubsystemOperations.getFailureDescriptionAsString(result), SubsystemOperations.isSuccessfulOutcome(result));
// Add the handler to a logger
final PathAddress loggerAddress = createLoggerAddress("org.jboss.as.logging");
op = SubsystemOperations.createOperation(CommonAttributes.ADD_HANDLER_OPERATION_NAME, loggerAddress.toModelNode());
op.get(CommonAttributes.HANDLER_NAME.getName()).set(consoleHandler.getLastElement().getValue());
result = kernelServices.executeOperation(op);
Assert.assertTrue(SubsystemOperations.getFailureDescriptionAsString(result), SubsystemOperations.isSuccessfulOutcome(result));
// Save the current model
final ModelNode validSubsystemModel = getSubsystemModel(kernelServices);
final CompositeOperationBuilder operationBuilder = CompositeOperationBuilder.create();
// create a new handler
final PathAddress fileHandlerAddress = createFileHandlerAddress("fail-fh");
final ModelNode fileHandlerOp = SubsystemOperations.createAddOperation(fileHandlerAddress.toModelNode());
fileHandlerOp.get(CommonAttributes.FILE.getName(), PathResourceDefinition.RELATIVE_TO.getName()).set("jboss.server.log.dir");
fileHandlerOp.get(CommonAttributes.FILE.getName(), PathResourceDefinition.PATH.getName()).set("fail-fh.log");
fileHandlerOp.get(CommonAttributes.AUTOFLUSH.getName()).set(true);
operationBuilder.addStep(fileHandlerOp);
// create a new logger
final PathAddress testLoggerAddress = createLoggerAddress(PROFILE_NAME, "test");
final ModelNode testLoggerOp = SubsystemOperations.createAddOperation(testLoggerAddress.toModelNode());
operationBuilder.addStep(testLoggerOp);
// remove the console handler
operationBuilder.addStep(SubsystemOperations.createRemoveOperation(consoleHandler.toModelNode()));
// add handler to existing logger - should force fail on this one
operationBuilder.addStep(SubsystemOperations.createWriteAttributeOperation(loggerAddress.toModelNode(), CommonAttributes.HANDLERS, new ModelNode().setEmptyList().add("fail-fh")));
// verify the operation failed
result = kernelServices.executeOperation(operationBuilder.build().getOperation());
Assert.assertFalse("The add operation should have failed, but was successful: " + result, SubsystemOperations.isSuccessfulOutcome(result));
// verify the subsystem model matches the old model
final ModelNode currentModel = getSubsystemModel(kernelServices);
compare(validSubsystemModel, currentModel);
final ConfigurationPersistence config = ConfigurationPersistence.getConfigurationPersistence(LogContext.getLogContext());
compare(currentModel, config);
}
@Test
@BMRules(rules = {
@BMRule(name = "Test handler rollback handler",
targetClass = "org.jboss.as.logging.HandlerOperations$HandlerAddOperationStepHandler",
targetMethod = "performRuntime",
targetLocation = "AT EXIT",
condition = "$4.equals(\"CONSOLE2\")",
action = "$1.setRollbackOnly()"),
@BMRule(name = "Test logger rollback handler",
targetClass = "org.jboss.as.logging.LoggerOperations$LoggerAddOperationStepHandler",
targetMethod = "performRuntime",
targetLocation = "AT EXIT",
condition = "$4.equals(\"org.jboss.as.logging.test\")",
action = "$1.setRollbackOnly()")
})
public void testRollbackAdd() throws Exception {
rollbackAdd(null);
rollbackAdd(PROFILE_NAME);
}
@Test
@BMRules(rules = {
@BMRule(name = "Test handler write-attribute rollback handler",
targetClass = "org.jboss.as.logging.HandlerOperations$LogHandlerWriteAttributeHandler",
targetMethod = "applyUpdate",
targetLocation = "AT EXIT",
condition = "$3.equals(\"CONSOLE\")",
action = "$1.setRollbackOnly()"),
@BMRule(name = "Test logger write-attribute rollback handler",
targetClass = "org.jboss.as.logging.LoggerOperations$LoggerWriteAttributeHandler",
targetMethod = "applyUpdate",
targetLocation = "AT EXIT",
condition = "$3.equals(\"ROOT\")",
action = "$1.setRollbackOnly()")
})
public void testRollbackWriteAttribute() throws Exception {
rollbackWriteAttribute(null);
rollbackWriteAttribute(PROFILE_NAME);
}
@Test
@BMRules(rules = {
@BMRule(name = "Test handler rollback handler",
targetClass = "org.jboss.as.logging.HandlerOperations$HandlerUpdateOperationStepHandler",
targetMethod = "performRuntime",
targetLocation = "AT EXIT",
condition = "$4.equals(\"CONSOLE\")",
action = "$1.setRollbackOnly()"),
@BMRule(name = "Test logger rollback handler",
targetClass = "org.jboss.as.logging.LoggerOperations$LoggerUpdateOperationStepHandler",
targetMethod = "performRuntime",
targetLocation = "AT EXIT",
condition = "$4.equals(\"ROOT\")",
action = "$1.setRollbackOnly()")
})
public void testRollbackUpdateAttribute() throws Exception {
rollbackUpdateAttribute(null);
rollbackUpdateAttribute(PROFILE_NAME);
}
@Test
@BMRules(rules = {
@BMRule(name = "Test handler write-attribute rollback handler",
targetClass = "org.jboss.as.logging.LoggerOperations$LoggerWriteAttributeHandler",
targetMethod = "applyUpdate",
targetLocation = "AT EXIT",
condition = "$3.equals(\"ROOT\")",
action = "$1.setRollbackOnly()")
})
public void testRollbackRemove() throws Exception {
rollbackRemove(null);
rollbackRemove(PROFILE_NAME);
}
@Test
@BMRules(rules = {
@BMRule(name = "Test handler write-attribute rollback handler",
targetClass = "org.jboss.as.logging.LoggerOperations$LoggerWriteAttributeHandler",
targetMethod = "applyUpdate",
targetLocation = "AT EXIT",
condition = "$3.equals(\"ROOT\")",
action = "$1.setRollbackOnly()")
})
public void testRollbackRemoveProfile() throws Exception {
final KernelServices kernelServices = boot();
// Save the current model
final ModelNode validSubsystemModel = getSubsystemModel(kernelServices);
final CompositeOperationBuilder compositeOperationBuilder = CompositeOperationBuilder.create();
// The handler address to remove
final PathAddress profileAddress = createAddress(CommonAttributes.LOGGING_PROFILE, PROFILE_NAME);
// Remove the handler
compositeOperationBuilder.addStep(SubsystemOperations.createRemoveOperation(profileAddress.toModelNode(), true));
// Add a step to fail
final ModelNode rootLoggerAddress = createRootLoggerAddress().toModelNode();
compositeOperationBuilder.addStep(SubsystemOperations.createWriteAttributeOperation(rootLoggerAddress, CommonAttributes.LEVEL, "INFO"));
ModelNode result = kernelServices.executeOperation(compositeOperationBuilder.build().getOperation());
Assert.assertFalse("The update operation should have failed, but was successful: " + result, SubsystemOperations.isSuccessfulOutcome(result));
// verify the subsystem model matches the old model
final ModelNode currentModel = getSubsystemModel(kernelServices);
compare(validSubsystemModel, currentModel);
ConfigurationPersistence config = ConfigurationPersistence.getConfigurationPersistence(LogContext.getLogContext());
compare(currentModel, config);
// Check the profile was rolled back
config = ConfigurationPersistence.getConfigurationPersistence(LoggingProfileContextSelector.getInstance().get(PROFILE_NAME));
compare(PROFILE_NAME, currentModel, config);
}
public void rollbackAdd(final String profileName) throws Exception {
final KernelServices kernelServices = boot();
// Save the current model
final ModelNode validSubsystemModel = getSubsystemModel(kernelServices);
// Add a handler to be removed
final PathAddress consoleHandler = createConsoleHandlerAddress(profileName, "CONSOLE2");
// Create a new handler
ModelNode op = SubsystemOperations.createAddOperation(consoleHandler.toModelNode());
op.get(CommonAttributes.LEVEL.getName()).set("INFO");
op.get(AbstractHandlerDefinition.FORMATTER.getName()).set("%d{HH:mm:ss,SSS} %-5p [%c] (%t) CONSOLE2: %s%e%n");
ModelNode result = kernelServices.executeOperation(op);
Assert.assertFalse("The add operation should have failed, but was successful: " + result, SubsystemOperations.isSuccessfulOutcome(result));
// verify the subsystem model matches the old model
ModelNode currentModel = getSubsystemModel(kernelServices);
compare(profileName, validSubsystemModel, currentModel);
final LogContext logContext = (profileName == null ? LogContext.getLogContext() : LoggingProfileContextSelector.getInstance().get(profileName));
ConfigurationPersistence config = ConfigurationPersistence.getConfigurationPersistence(logContext);
compare(profileName, currentModel, config);
// Fail on a logger write attribute
final PathAddress loggerAddress = createLoggerAddress(profileName, "org.jboss.as.logging.test");
op = SubsystemOperations.createAddOperation(loggerAddress.toModelNode());
result = kernelServices.executeOperation(op);
Assert.assertFalse("The add operation should have failed, but was successful: " + result, SubsystemOperations.isSuccessfulOutcome(result));
// verify the subsystem model matches the old model
currentModel = getSubsystemModel(kernelServices);
compare(profileName, validSubsystemModel, currentModel);
config = ConfigurationPersistence.getConfigurationPersistence(logContext);
compare(profileName, currentModel, config);
}
public void rollbackWriteAttribute(final String profileName) throws Exception {
final KernelServices kernelServices = boot();
// Save the current model
final ModelNode validSubsystemModel = getSubsystemModel(kernelServices);
// Add a handler to be removed
final PathAddress consoleHandler = createConsoleHandlerAddress(profileName, "CONSOLE");
// Create a new handler
ModelNode op = SubsystemOperations.createWriteAttributeOperation(consoleHandler.toModelNode(), ConsoleHandlerResourceDefinition.TARGET, "System.err");
ModelNode result = kernelServices.executeOperation(op);
Assert.assertFalse("The write operation should have failed, but was successful: " + result, SubsystemOperations.isSuccessfulOutcome(result));
// verify the subsystem model matches the old model
ModelNode currentModel = getSubsystemModel(kernelServices);
compare(profileName, validSubsystemModel, currentModel);
final LogContext logContext = (profileName == null ? LogContext.getLogContext() : LoggingProfileContextSelector.getInstance().get(profileName));
ConfigurationPersistence config = ConfigurationPersistence.getConfigurationPersistence(logContext);
compare(profileName, currentModel, config);
// Fail on a logger write attribute
final PathAddress rootLoggerAddress = createRootLoggerAddress(profileName);
op = SubsystemOperations.createWriteAttributeOperation(rootLoggerAddress.toModelNode(), CommonAttributes.LEVEL, "TRACE");
result = kernelServices.executeOperation(op);
Assert.assertFalse("The write operation should have failed, but was successful: " + result, SubsystemOperations.isSuccessfulOutcome(result));
// verify the subsystem model matches the old model
currentModel = getSubsystemModel(kernelServices);
compare(profileName, validSubsystemModel, currentModel);
config = ConfigurationPersistence.getConfigurationPersistence(logContext);
compare(profileName, currentModel, config);
}
public void rollbackUpdateAttribute(final String profileName) throws Exception {
final KernelServices kernelServices = boot();
// Save the current model
final ModelNode validSubsystemModel = getSubsystemModel(kernelServices);
// Add a handler to be removed
final PathAddress consoleHandler = createConsoleHandlerAddress(profileName, "CONSOLE");
// Create a new handler
ModelNode op = SubsystemOperations.createOperation(AbstractHandlerDefinition.CHANGE_LEVEL_OPERATION_NAME, consoleHandler.toModelNode());
op.get(CommonAttributes.LEVEL.getName()).set("DEBUG");
ModelNode result = kernelServices.executeOperation(op);
Assert.assertFalse("The update operation should have failed, but was successful: " + result, SubsystemOperations.isSuccessfulOutcome(result));
// verify the subsystem model matches the old model
ModelNode currentModel = getSubsystemModel(kernelServices);
compare(profileName, validSubsystemModel, currentModel);
final LogContext logContext = (profileName == null ? LogContext.getLogContext() : LoggingProfileContextSelector.getInstance().get(profileName));
ConfigurationPersistence config = ConfigurationPersistence.getConfigurationPersistence(logContext);
compare(profileName, currentModel, config);
// Fail on a logger write attribute
final PathAddress rootLoggerAddress = createRootLoggerAddress(profileName);
op = SubsystemOperations.createOperation(RootLoggerResourceDefinition.ROOT_LOGGER_CHANGE_LEVEL_OPERATION_NAME, rootLoggerAddress.toModelNode());
op.get(CommonAttributes.LEVEL.getName()).set("TRACE");
result = kernelServices.executeOperation(op);
Assert.assertFalse("The update operation should have failed, but was successful: " + result, SubsystemOperations.isSuccessfulOutcome(result));
// verify the subsystem model matches the old model
currentModel = getSubsystemModel(kernelServices);
compare(profileName, validSubsystemModel, currentModel);
config = ConfigurationPersistence.getConfigurationPersistence(logContext);
compare(profileName, currentModel, config);
}
public void rollbackRemove(final String profileName) throws Exception {
final KernelServices kernelServices = boot();
// Save the current model
final ModelNode validSubsystemModel = getSubsystemModel(kernelServices);
final CompositeOperationBuilder compositeOperationBuilder = CompositeOperationBuilder.create();
// The handler address to remove
final PathAddress consoleHandler = createConsoleHandlerAddress(profileName, "CONSOLE");
// Remove the handler
compositeOperationBuilder.addStep(SubsystemOperations.createRemoveOperation(consoleHandler.toModelNode()));
// The logger to remove
final PathAddress loggerAddress = createLoggerAddress(profileName, "org.jboss.as.logging");
compositeOperationBuilder.addStep(SubsystemOperations.createRemoveOperation(loggerAddress.toModelNode()));
// Add a step to fail
final ModelNode rootLoggerAddress = createRootLoggerAddress(profileName).toModelNode();
compositeOperationBuilder.addStep(SubsystemOperations.createWriteAttributeOperation(rootLoggerAddress, CommonAttributes.LEVEL, "INFO"));
ModelNode result = kernelServices.executeOperation(compositeOperationBuilder.build().getOperation());
Assert.assertFalse("The update operation should have failed, but was successful: " + result, SubsystemOperations.isSuccessfulOutcome(result));
// verify the subsystem model matches the old model
ModelNode currentModel = getSubsystemModel(kernelServices);
compare(profileName, validSubsystemModel, currentModel);
final LogContext logContext = (profileName == null ? LogContext.getLogContext() : LoggingProfileContextSelector.getInstance().get(profileName));
ConfigurationPersistence config = ConfigurationPersistence.getConfigurationPersistence(logContext);
compare(profileName, currentModel, config);
}
}