blob: 96078d766c22f4ee978a7ad4b18178ca4f5521c4 [file] [log] [blame]
/*
* 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;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.apache.qpid.server.logging.messages.ChannelMessages.IDLE_TXN_LOG_HIERARCHY;
import static org.apache.qpid.server.logging.messages.ChannelMessages.OPEN_TXN_LOG_HIERARCHY;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import org.apache.qpid.server.TransactionTimeoutHelper.CloseAction;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.logging.LogMessage;
import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.test.utils.QpidTestCase;
import org.hamcrest.Description;
import org.mockito.ArgumentMatcher;
public class TransactionTimeoutHelperTest extends QpidTestCase
{
private final LogActor _logActor = mock(LogActor.class);
private final LogSubject _logSubject = mock(LogSubject.class);
private final ServerTransaction _transaction = mock(ServerTransaction.class);
private final CloseAction _closeAction = mock(CloseAction.class);
private TransactionTimeoutHelper _transactionTimeoutHelper;
private long _now;
public void testNotTransactional() throws Exception
{
when(_transaction.isTransactional()).thenReturn(false);
_transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, 5, 10, 5, 10);
verifyZeroInteractions(_logActor, _closeAction);
}
public void testOpenTransactionProducesWarningOnly() throws Exception
{
final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61);
configureMockTransaction(sixtyOneSecondsAgo, sixtyOneSecondsAgo);
_transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, SECONDS.toMillis(30), 0, 0, 0);
verify(_logActor).message(same(_logSubject), isLogMessage(OPEN_TXN_LOG_HIERARCHY, "CHN-1007 : Open Transaction : 61,\\d{3} ms"));
verifyZeroInteractions(_closeAction);
}
public void testOpenTransactionProducesTimeoutActionOnly() throws Exception
{
final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61);
configureMockTransaction(sixtyOneSecondsAgo, sixtyOneSecondsAgo);
_transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, 0, SECONDS.toMillis(30), 0, 0);
verify(_closeAction).doTimeoutAction("Open transaction timed out");
verifyZeroInteractions(_logActor);
}
public void testOpenTransactionProducesWarningAndTimeoutAction() throws Exception
{
final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61);
configureMockTransaction(sixtyOneSecondsAgo, sixtyOneSecondsAgo);
_transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, SECONDS.toMillis(15), SECONDS.toMillis(30), 0, 0);
verify(_logActor).message(same(_logSubject), isLogMessage(OPEN_TXN_LOG_HIERARCHY, "CHN-1007 : Open Transaction : 61,\\d{3} ms"));
verify(_closeAction).doTimeoutAction("Open transaction timed out");
}
public void testIdleTransactionProducesWarningOnly() throws Exception
{
final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61);
final long thrityOneSecondsAgo = _now - SECONDS.toMillis(31);
configureMockTransaction(sixtyOneSecondsAgo, thrityOneSecondsAgo);
_transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, 0, 0, SECONDS.toMillis(30), 0);
verify(_logActor).message(same(_logSubject), isLogMessage(IDLE_TXN_LOG_HIERARCHY, "CHN-1008 : Idle Transaction : 31,\\d{3} ms"));
verifyZeroInteractions(_closeAction);
}
public void testIdleTransactionProducesTimeoutActionOnly() throws Exception
{
final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61);
final long thrityOneSecondsAgo = _now - SECONDS.toMillis(31);
configureMockTransaction(sixtyOneSecondsAgo, thrityOneSecondsAgo);
_transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, 0, 0, 0, SECONDS.toMillis(30));
verify(_closeAction).doTimeoutAction("Idle transaction timed out");
verifyZeroInteractions(_logActor);
}
public void testIdleTransactionProducesWarningAndTimeoutAction() throws Exception
{
final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61);
final long thrityOneSecondsAgo = _now - SECONDS.toMillis(31);
configureMockTransaction(sixtyOneSecondsAgo, thrityOneSecondsAgo);
_transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, 0, 0, SECONDS.toMillis(15), SECONDS.toMillis(30));
verify(_logActor).message(same(_logSubject), isLogMessage(IDLE_TXN_LOG_HIERARCHY, "CHN-1008 : Idle Transaction : 31,\\d{3} ms"));
verify(_closeAction).doTimeoutAction("Idle transaction timed out");
}
public void testIdleAndOpenWarnings() throws Exception
{
final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61);
final long thirtyOneSecondsAgo = _now - SECONDS.toMillis(31);
configureMockTransaction(sixtyOneSecondsAgo, thirtyOneSecondsAgo);
_transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, SECONDS.toMillis(60), 0, SECONDS.toMillis(30), 0);
verify(_logActor).message(same(_logSubject), isLogMessage(IDLE_TXN_LOG_HIERARCHY, "CHN-1008 : Idle Transaction : 31,\\d{3} ms"));
verify(_logActor).message(same(_logSubject), isLogMessage(OPEN_TXN_LOG_HIERARCHY, "CHN-1007 : Open Transaction : 61,\\d{3} ms"));
verifyZeroInteractions(_closeAction);
}
@Override
protected void setUp() throws Exception
{
super.setUp();
CurrentActor.set(_logActor);
_transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject, _closeAction);
_now = System.currentTimeMillis();
}
@Override
protected void tearDown() throws Exception
{
try
{
super.tearDown();
}
finally
{
CurrentActor.remove();
}
}
private void configureMockTransaction(final long startTime, final long updateTime)
{
when(_transaction.isTransactional()).thenReturn(true);
when(_transaction.getTransactionStartTime()).thenReturn(startTime);
when(_transaction.getTransactionUpdateTime()).thenReturn(updateTime);
}
private LogMessage isLogMessage(String expectedlogHierarchy, String expectedText)
{
return argThat(new IsLogMessage(expectedlogHierarchy, expectedText));
}
class IsLogMessage extends ArgumentMatcher<LogMessage>
{
private final String _expectedLogHierarchy;
private final String _expectedLogMessageMatches;
private String _hierarchyMatchesFailure;
private String _logMessageMatchesFailure;
public IsLogMessage(String expectedlogHierarchy, String expectedLogMessageMatches)
{
_expectedLogHierarchy = expectedlogHierarchy;
_expectedLogMessageMatches = expectedLogMessageMatches;
}
public boolean matches(Object arg)
{
LogMessage logMessage = (LogMessage)arg;
boolean hierarchyMatches = logMessage.getLogHierarchy().equals(_expectedLogHierarchy);
boolean logMessageMatches = logMessage.toString().matches(_expectedLogMessageMatches);
if (!hierarchyMatches)
{
_hierarchyMatchesFailure = "LogHierarchy does not match. Expected " + _expectedLogHierarchy + " actual " + logMessage.getLogHierarchy();
}
if (!logMessageMatches)
{
_logMessageMatchesFailure = "LogMessage does not match. Expected " + _expectedLogMessageMatches + " actual " + logMessage.toString();
}
return hierarchyMatches && logMessageMatches;
}
@Override
public void describeTo(Description description)
{
if (_hierarchyMatchesFailure != null)
{
description.appendText(_hierarchyMatchesFailure);
}
if (_logMessageMatchesFailure != null)
{
description.appendText(_logMessageMatchesFailure);
}
}
}
}