summaryrefslogtreecommitdiff
path: root/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AbstractTestLogging.java
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AbstractTestLogging.java')
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AbstractTestLogging.java448
1 files changed, 448 insertions, 0 deletions
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AbstractTestLogging.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AbstractTestLogging.java
new file mode 100644
index 0000000000..f56f428f0b
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AbstractTestLogging.java
@@ -0,0 +1,448 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.logging.subjects.AbstractTestLogSubject;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.util.LogMonitor;
+
+/**
+ * Abstract superclass for logging test set up and utility methods.
+ *
+ * So named to prevent it being selected itself as a test to run by the test suite.
+ */
+public class AbstractTestLogging extends QpidBrokerTestCase
+{
+ public static final long DEFAULT_LOG_WAIT = 2000;
+ public static final String TEST_LOG_PREFIX = "MESSAGE";
+ protected LogMonitor _monitor;
+
+ InternalBrokerBaseCase _configLoader;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ setLogMessagePrefix();
+
+ super.setUp();
+ _monitor = new LogMonitor(_outputFile);
+ }
+
+ protected ServerConfiguration getServerConfig() throws ConfigurationException
+ {
+ ServerConfiguration _serverConfiguration;
+ if (isExternalBroker())
+ {
+ _serverConfiguration = new ServerConfiguration(_configFile)
+ {
+ @Override
+ public void initialise() throws ConfigurationException
+ {
+ //Overriding initialise to only setup the vhosts and not
+ //perform the ConfigurationPlugin setup, removing need for
+ //an ApplicationRegistry to be loaded.
+ setupVirtualHosts(getConfig());
+ }
+ };
+ _serverConfiguration.initialise();
+ }
+ else
+ {
+ _serverConfiguration = ApplicationRegistry.getInstance().getConfiguration();
+ }
+
+ return _serverConfiguration;
+ }
+
+ protected void setLogMessagePrefix()
+ {
+ //set the message prefix to facilitate scraping from the munged test output.
+ setSystemProperty("qpid.logging.prefix", TEST_LOG_PREFIX);
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ _monitor.close();
+ if (isExternalBroker() && _configLoader != null)
+ {
+ _configLoader.tearDown();
+ }
+ super.tearDown();
+ }
+
+ /**
+ * assert that the requested log message has not occured
+ *
+ * @param log
+ *
+ * @throws IOException
+ */
+ public void assertLoggingNotYetOccured(String log) throws IOException
+ {
+ // Ensure the alert has not occured yet
+ assertEquals("Message has already occured:" + log, 0,
+ findMatches(log).size());
+ }
+
+ protected void validateMessageID(String id, String log)
+ {
+ assertEquals("Incorrect message", id, getMessageID(log));
+ }
+
+ protected String getMessageID(String log)
+ {
+ String message = fromMessage(log);
+
+ return message.substring(0, message.indexOf(" "));
+ }
+
+ /**
+ * Return the first channel id from the log string
+ * ' ch;X' if there is no channel id return -1.
+ *
+ * @param log the log string to search.
+ *
+ * @return channel id or -1 if no channel id exists.
+ */
+ protected int getChannelID(String log)
+ {
+ int start = log.indexOf("ch:") + 3;
+
+ // If we do a check for ] as the boundary we will get cases where log
+ // is presented with the bounding. If we don't match a ] then we can use
+ // the end of the string as the boundary.
+ int end = log.indexOf("]", start);
+ if (end == -1)
+ {
+ end = log.length();
+ }
+
+ try
+ {
+ return Integer.parseInt(log.substring(start, end));
+ }
+ catch (Exception e)
+ {
+ return -1;
+ }
+ }
+
+ protected String fromMessage(String log)
+ {
+ int startSubject = log.indexOf("]") + 1;
+ int start = log.indexOf("]", startSubject) + 1;
+
+ // If we don't have a subject then the second indexOf will return 0
+ // in which case we can use the end of the actor as the index.
+ if (start == 0)
+ {
+ start = startSubject;
+ }
+
+ return log.substring(start).trim();
+ }
+
+ /**
+ * Extract the Subject from the Log Message.
+ *
+ * The subject is the second block inclosed in brackets '[ ]'.
+ *
+ * If there is no Subject or the second block of brackets '[ ]' cannot be
+ * identified then an empty String ("") is returned.
+ *
+ * The brackets '[ ]' are not included in the returned String.
+ *
+ * @param log The log message to process
+ *
+ * @return the Subject string or the empty string ("") if the subject can't be identified.
+ */
+ protected String fromSubject(String log)
+ {
+ int start = log.indexOf("[") + 1;
+ // Take the second index
+ start = log.indexOf("[", start) + 1;
+
+ // There may not be a subject so in that case return nothing.
+ if (start == 0)
+ {
+ return "";
+ }
+
+ int end = log.indexOf("]", start);
+ try
+ {
+ return log.substring(start, end);
+ }
+ catch (IndexOutOfBoundsException iobe)
+ {
+ return "";
+ }
+ }
+
+ /**
+ * Extract the actor segment from the log message.
+ * The Actor segment is the first section enclosed in '[ ]'.
+ *
+ * No analysis is performed to ensure that the first '[ ]' section of the
+ * given log is really an Actor segment.
+ *
+ * The brackets '[ ]' are not included in the returned String.
+ *
+ * @param log the Log Message
+ *
+ * @return the Actor segment or "" if unable to locate '[ ]' section
+ */
+ protected String fromActor(String log)
+ {
+ int start = log.indexOf("[") + 1;
+ int end = log.indexOf("]", start);
+ try
+ {
+ return log.substring(start, end).trim();
+ }
+ catch (IndexOutOfBoundsException iobe)
+ {
+ return "";
+ }
+ }
+
+ /**
+ * Return the message String from the given message section
+ *
+ * @param log the Message Section
+ *
+ * @return the Message String.
+ */
+ protected String getMessageString(String log)
+ {
+ // Remove the Log ID from the returned String
+ int start = log.indexOf(":") + 1;
+
+ return log.substring(start).trim();
+ }
+
+ /**
+ * Given our log message extract the connection ID:
+ *
+ * The log string will contain the connectionID identified by 'con:'
+ *
+ * So extract the value shown here by X:
+ *
+ * 'con:X('
+ *
+ * Extract the value between the ':' and '(' and process it as an Integer
+ *
+ * If we are unable to find the right index or process the substring as an
+ * Integer then return -1.
+ *
+ * @param log the log String to process
+ *
+ * @return the connection ID or -1.
+ */
+ protected int getConnectionID(String log)
+ {
+ int conIDStart = log.indexOf("con:") + 4;
+ int conIDEnd = log.indexOf("(", conIDStart);
+ try
+ {
+ return Integer.parseInt(log.substring(conIDStart, conIDEnd));
+ }
+ catch (Exception e)
+ {
+ return -1;
+ }
+ }
+
+ /**
+ * Extract the log entry from the raw log line which will contain other
+ * log4j formatting.
+ *
+ * This formatting may impead our testing process so extract the log message
+ * as we know it to be formatted.
+ *
+ * This starts with the string MESSAGE
+ *
+ * @param rawLog the raw log
+ *
+ * @return the log we are expecting to be printed without the log4j prefixes
+ */
+ protected String getLog(String rawLog)
+ {
+ int start = rawLog.indexOf(TEST_LOG_PREFIX);
+ return rawLog.substring(start);
+ }
+
+ /**
+ * Extract the log entry from the result set. Positions are 0-based.
+ *
+ * @param results list of log message results to extract from
+ * @param position position in the list of the message to extract
+ * @return the message string
+ */
+ protected String getLogMessage(List<String> results, int position)
+ {
+ return getLog(results.get(position));
+ }
+
+ /**
+ * Extract the nth-from-last log entry from the result set.
+ *
+ * @param results list of log message results to extract from
+ * @param positionFromEnd position from end of the message list to extract (eg 0 for last)
+ * @return the message string
+ */
+ protected String getLogMessageFromEnd(List<String> results, int positionFromEnd)
+ {
+ int resultSize = results.size();
+ return getLogMessage(results, resultSize - 1 - positionFromEnd);
+ }
+
+ protected List<String> findMatches(String toFind) throws IOException
+ {
+ return _monitor.findMatches(toFind);
+ }
+
+ protected List<String> waitAndFindMatches(String toFind) throws IOException
+ {
+ return waitAndFindMatches(toFind, DEFAULT_LOG_WAIT);
+ }
+
+ protected List<String> waitAndFindMatches(String toFind, long wait) throws IOException
+ {
+ return _monitor.waitAndFindMatches(toFind, wait);
+ }
+
+ public boolean waitForMessage(String message) throws FileNotFoundException, IOException
+ {
+ return waitForMessage(message, DEFAULT_LOG_WAIT);
+ }
+
+ public boolean waitForMessage(String message, long wait) throws FileNotFoundException, IOException
+ {
+ return _monitor.waitForMessage(message, wait, true);
+ }
+
+ /**
+ * Given a list of messages that have been pulled out of a log file
+ * Process the results splitting the log statements in to lists based on the
+ * actor's connection ID.
+ *
+ * So for each log entry extract the Connecition ID from the Actor of the log
+ *
+ * Then use that as a key to a HashMap storing the list of log messages for
+ * that connection.
+ *
+ * @param logMessages The list of mixed connection log messages
+ *
+ * @return Map indexed by connection id to a list of log messages just for that connection.
+ */
+ protected HashMap<Integer, List<String>> splitResultsOnConnectionID(List<String> logMessages)
+ {
+ HashMap<Integer, List<String>> connectionSplitList = new HashMap<Integer, List<String>>();
+
+ for (String log : logMessages)
+ {
+ // Get the connectionID from the Actor in the Message Log.
+ int cID = getConnectionID(fromActor(getLog(log)));
+
+ List<String> connectionData = connectionSplitList.get(cID);
+
+ // Create the initial List if we don't have one already
+ if (connectionData == null)
+ {
+ connectionData = new LinkedList<String>();
+ connectionSplitList.put(cID, connectionData);
+ }
+
+ // Store the log
+ connectionData.add(log);
+ }
+
+ return connectionSplitList;
+ }
+
+ /**
+ * Filter the give result set by the specficifed virtualhost.
+ * This is done using the getSlice to identify the virtualhost (vh) in the
+ * log message
+ *
+ * @param results full list of logs
+ * @param virtualHostName the virtualhostName to filter on
+ *
+ * @return the list of messages only for that virtualhost
+ */
+ protected List<String> filterResultsByVirtualHost(List<String> results, String virtualHostName)
+ {
+ List<String> filteredResults = new LinkedList<String>();
+ Iterator<String> iterator = results.iterator();
+
+ while (iterator.hasNext())
+ {
+ String log = iterator.next();
+
+ if (AbstractTestLogSubject.getSlice("vh", log).equals(virtualHostName))
+ {
+ filteredResults.add(log);
+ }
+ }
+
+ return filteredResults;
+ }
+
+ /**
+ * Dump the log results.
+ */
+ protected void dumpLogs(List<String> results) throws IOException
+ {
+ dumpLogs(results, null);
+ }
+
+ /**
+ * Dump the log results or if there are none, the contents of the
+ * monitored log file if the monitor is non-null.
+ */
+ protected void dumpLogs(List<String> results, LogMonitor monitor) throws IOException
+ {
+ System.err.println("Log Dump:");
+ for (String log : results)
+ {
+ System.err.println(log);
+ }
+
+ if (results.isEmpty() && monitor != null)
+ {
+ System.err.println("Monitored file contents:");
+ System.err.println(monitor.readFile());
+ }
+ }
+}