/* * 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.logging; import static org.junit.Assert.*; import java.io.File; import java.io.IOException; import java.util.List; import org.jboss.as.subsystem.test.AdditionalInitialization; import org.jboss.as.subsystem.test.KernelServices; import org.jboss.as.subsystem.test.SubsystemOperations; import org.jboss.dmr.ModelNode; import org.jboss.logmanager.LogContext; import org.jboss.logmanager.Logger; import org.junit.Before; import org.junit.Test; /** * @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a> */ public class RootSubsystemOperationsTestCase extends AbstractOperationsTestCase { private final String msg = "Test message "; @Before public void clearLogDir() { final File dir = LoggingTestEnvironment.get().getLogDir(); deleteRecursively(dir); } @Override protected void standardSubsystemTest(final String configId) throws Exception { // do nothing as this is not a subsystem parsing test } @Override protected AdditionalInitialization createAdditionalInitialization() { return LoggingTestEnvironment.get(); } @Override protected String getSubsystemXml() throws IOException { return readResource("/simple-subsystem.xml"); } @Test public void testAttributes() throws Exception { final KernelServices kernelServices = boot(); final ModelNode address = SUBSYSTEM_ADDRESS.toModelNode(); testWrite(kernelServices, address, LoggingResourceDefinition.ADD_LOGGING_API_DEPENDENCIES, true); testWrite(kernelServices, address, LoggingResourceDefinition.USE_DEPLOYMENT_LOGGING_CONFIG, false); testUndefine(kernelServices, address, LoggingResourceDefinition.ADD_LOGGING_API_DEPENDENCIES); testUndefine(kernelServices, address, LoggingResourceDefinition.USE_DEPLOYMENT_LOGGING_CONFIG); } @Test public void testLogFileResource() throws Exception { final KernelServices kernelServices = boot(); // Subsystem address final ModelNode address = SUBSYSTEM_ADDRESS.append("log-file").toModelNode(); ModelNode op = SubsystemOperations.createReadResourceOperation(address); //op.get("include-runtime").set(true); ModelNode result = executeOperation(kernelServices, op); List<ModelNode> resources = SubsystemOperations.readResult(result).asList(); assertFalse("No Resources were found: " + result, resources.isEmpty()); int expectedSize = resources.size(); // Add a new file not in the jboss.server.log.dir directory final File logFile = new File(LoggingTestEnvironment.get().getLogDir(), "fh.log"); final ModelNode fhAddress = createFileHandlerAddress("fh").toModelNode(); op = SubsystemOperations.createAddOperation(fhAddress); op.get("file").set(createFileValue(null, logFile.getAbsolutePath())); executeOperation(kernelServices, op); // Re-read the log-file resource, the size should be the same result = executeOperation(kernelServices, SubsystemOperations.createReadResourceOperation(address)); resources = SubsystemOperations.readResult(result).asList(); assertEquals("Log file " + logFile.getAbsolutePath() + " should not be a resource", expectedSize, resources.size()); // Change the file path of the file handler which should make it a log-file resource op = SubsystemOperations.createWriteAttributeOperation(fhAddress, "file", createFileValue("jboss.server.log.dir", "fh-2.log")); executeOperation(kernelServices, op); // Should be an additional resource result = executeOperation(kernelServices, SubsystemOperations.createReadResourceOperation(address)); resources = SubsystemOperations.readResult(result).asList(); assertEquals("Additional log-file resource failed to dynamically get added", ++expectedSize, resources.size()); // Test the read-log-file on the final ModelNode simpleLogAddress = SUBSYSTEM_ADDRESS.append("log-file", "simple.log").toModelNode(); op = SubsystemOperations.createOperation("read-log-file", simpleLogAddress); testReadLogFile(kernelServices, op, getLogger()); // Test on the logging-profile final ModelNode profileAddress = SUBSYSTEM_ADDRESS.append("logging-profile", "testProfile").append("log-file", "profile-simple.log").toModelNode(); op = SubsystemOperations.createOperation("read-log-file", profileAddress); testReadLogFile(kernelServices, op, getLogger("testProfile")); // Test file in subdirectory final ModelNode subFhAddress = createFileHandlerAddress("sub-fh").toModelNode(); op = SubsystemOperations.createAddOperation(subFhAddress); op.get("file").set(createFileValue("jboss.server.log.dir", "subdir" + File.separator + "sub-fh.log")); executeOperation(kernelServices, op); result = executeOperation(kernelServices, SubsystemOperations.createReadResourceOperation(address)); resources = SubsystemOperations.readResult(result).asList(); assertEquals("Log file " + logFile.getAbsolutePath() + " should not be a resource", ++expectedSize, resources.size()); } @Test @Deprecated public void testListLogFiles() throws Exception { final KernelServices kernelServices = boot(); // Subsystem address final ModelNode address = SUBSYSTEM_ADDRESS.toModelNode(); final ModelNode op = SubsystemOperations.createOperation("list-log-files", address); ModelNode result = executeOperation(kernelServices, op); List<ModelNode> logFiles = SubsystemOperations.readResult(result).asList(); // Should only be one file // TODO (jrp) can be tested when LOGMGR-83 is committed and the logmanager is updated // assertEquals("Found: " + logFiles, 2, logFiles.size()); // Should contain simple.log and simple-profile.log boolean found = false; boolean foundProfile = false; for (ModelNode fileInfo : logFiles) { final String fileName = fileInfo.get("file-name").asString(); if ("simple.log".equals(fileName)) { found = true; } if ("profile-simple.log".equals(fileName)) { foundProfile = true; } if ("ignore.log".equals(fileName)) { fail("Found ignore.log, but the file should not be listed."); } if ("profile-ignore.log".equals(fileName)) { fail("Found profile-ignore.log, but the file should not be listed."); } } assertTrue("simple.log file was not found", found); assertTrue("profile-simple.log file was not found", foundProfile); // Change the permissions on the file so read is not allowed final File file = new File(LoggingTestEnvironment.get().getLogDir(), "simple.log"); // The file should exist assertTrue("File does not exist", file.exists()); // Only test if successfully set if (file.setReadable(false)) { result = executeOperation(kernelServices, op); logFiles = SubsystemOperations.readResult(result).asList(); // The simple.log should not be in the list assertEquals("Read permission was found to be true on the file.", 1, logFiles.size()); // Reset the file permissions assertTrue("Could not reset file permissions", file.setReadable(true)); } } @Test @Deprecated public void testReadLogFile() throws Exception { final KernelServices kernelServices = boot(); // Subsystem address final ModelNode address = SUBSYSTEM_ADDRESS.toModelNode(); final ModelNode op = SubsystemOperations.createOperation("read-log-file", address); op.get("name").set("simple.log"); testReadLogFile(kernelServices, op, getLogger()); // Change the permissions on the file so read is not allowed final File file = new File(LoggingTestEnvironment.get().getLogDir(), op.get("name").asString()); // The file should exist assertTrue("File does not exist", file.exists()); ModelNode result = null; // Only test if successfully set if (file.setReadable(false)) { result = kernelServices.executeOperation(op); assertFalse("Should have failed due to denial of read permissions on the file.", SubsystemOperations.isSuccessfulOutcome(result)); // Reset the file permissions assertTrue("Could not reset file permissions", file.setReadable(true)); } // Should be able to read profile-simple.log, but it should be empty op.get("name").set("profile-simple.log"); result = executeOperation(kernelServices, op); final List<String> logLines = SubsystemOperations.readResultAsList(result); assertEquals(0, logLines.size()); // Should not be able to read ignore.log even though the file exists op.get("name").set("ignore.log"); result = kernelServices.executeOperation(op); assertFalse("Should have failed due to file not be readable.", SubsystemOperations.isSuccessfulOutcome(result)); // Should not be able to read ignore.log even though the file exists op.get("name").set("profile-ignore.log"); result = kernelServices.executeOperation(op); assertFalse("Should have failed due to file not be readable.", SubsystemOperations.isSuccessfulOutcome(result)); // Test an invalid file op.get("name").set("invalid"); result = kernelServices.executeOperation(op); assertFalse("Should have failed due to invalid file.", SubsystemOperations.isSuccessfulOutcome(result)); } private void testReadLogFile(final KernelServices kernelServices, final ModelNode op, final Logger logger) { // Log some messages for (int i = 0; i < 50; i++) { logger.info(msg + i); } ModelNode result = executeOperation(kernelServices, op); List<String> logLines = SubsystemOperations.readResultAsList(result); assertEquals(10, logLines.size()); checkLogLines(logLines, 40); // Read from top op.get("tail").set(false); result = executeOperation(kernelServices, op); logLines = SubsystemOperations.readResultAsList(result); assertEquals(10, logLines.size()); checkLogLines(logLines, 0); // Read more lines from top op.get("lines").set(20); result = executeOperation(kernelServices, op); logLines = SubsystemOperations.readResultAsList(result); assertEquals(20, logLines.size()); checkLogLines(logLines, 0); // Read from bottom op.get("tail").set(true); result = executeOperation(kernelServices, op); logLines = SubsystemOperations.readResultAsList(result); assertEquals(20, logLines.size()); checkLogLines(logLines, 30); // Skip lines from bottom op.get("tail").set(true); op.get("skip").set(5); result = executeOperation(kernelServices, op); logLines = SubsystemOperations.readResultAsList(result); assertEquals(20, logLines.size()); checkLogLines(logLines, 25); // Skip lines from top op.get("tail").set(false); op.get("skip").set(5); result = executeOperation(kernelServices, op); logLines = SubsystemOperations.readResultAsList(result); assertEquals(20, logLines.size()); checkLogLines(logLines, 5); // Read all lines op.get("tail").set(false); op.get("lines").set(-1); op.remove("skip"); result = executeOperation(kernelServices, op); logLines = SubsystemOperations.readResultAsList(result); assertEquals(50, logLines.size()); checkLogLines(logLines, 0); // Read all lines, but 5 lines op.get("tail").set(false); op.get("lines").set(-1); op.get("skip").set(5); result = executeOperation(kernelServices, op); logLines = SubsystemOperations.readResultAsList(result); assertEquals(45, logLines.size()); checkLogLines(logLines, 5); } private void checkLogLines(final List<String> logLines, final int start) { int index = start; for (String line : logLines) { final String lineMsg = msg + index; assertTrue(String.format("Expected line containing '%s', found '%s", lineMsg, line), line.contains(msg + index)); index++; } } private Logger getLogger() { return LogContext.getSystemLogContext().getLogger("org.jboss.as.logging.test"); } private Logger getLogger(final String loggingProfile) { return LoggingProfileContextSelector.getInstance().get(loggingProfile).getLogger("org.jboss.as.logging.test"); } static void deleteRecursively(final File dir) { if (dir.isDirectory()) { final File[] files = dir.listFiles(); for (File file : files) { if (file.isDirectory()) { deleteRecursively(file); } file.delete(); } } } }