#region License
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed 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.
*/
#endregion
#region Imports
using System;
using System.Collections;
using System.Collections.Specialized;
using Common.Logging;
using Common.Logging.Simple;
using NUnit.Framework;
using Spring.Aop.Framework;
using Spring.Aspects.Exceptions;
using Spring.Expressions;
using Spring.Objects;
using Spring.Util;
#endregion
namespace Spring.Aspects.Exceptions{
/// <summary>
/// This class contains tests for ExceptionHandlerAdvice
/// </summary>
/// <author>Mark Pollack</author>
[TestFixture]
public class ExceptionHandlerAspectIntegrationTests
{
private ExceptionHandlerAdvice exceptionHandlerAdvice;
private CaptureOutputLoggerFactoryAdapter loggerFactoryAdapter;
private ILoggerFactoryAdapter originalAdapter;
private static bool spelActionExecuted = false;
[SetUp]
public void Setup()
{
originalAdapter = LogManager.Adapter;
loggerFactoryAdapter = new CaptureOutputLoggerFactoryAdapter();
LogManager.Adapter = loggerFactoryAdapter;
exceptionHandlerAdvice = new ExceptionHandlerAdvice();
}
[TearDown]
public void TearDown()
{
// loggerFactoryAdapter.LogMessages.Clear();
//reset so other tests can produce some output if needed.
loggerFactoryAdapter.Dispose();
LogManager.Adapter = originalAdapter;
}
[Test]
public void ExecuteSpelAction()
{
string executeHandlerText =
"on exception name ArithmeticException execute Spring.Aspects.Exceptions.ExceptionHandlerAspectIntegrationTests.Executed(true)";
ITestObject to = CreateTestObjectProxy(executeHandlerText);
try
{
to.Exceptional(new ArithmeticException());
}
catch (ArithmeticException)
{
Assert.IsTrue(spelActionExecuted);
}
}
public static void Executed(bool val)
{
spelActionExecuted = val;
}
[Test]
public void LoggingTest()
{
LogExceptionHandler logHandler = new LogExceptionHandler();
logHandler.LogName = "adviceHandler";
string testText =
@"'Hello World, exception message = ' + #e.Message + ', target method = ' + #method.Name";
logHandler.SourceExceptionNames.Add("ArithmeticException");
logHandler.ActionExpressionText = testText;
exceptionHandlerAdvice.ExceptionHandlers.Add(logHandler);
exceptionHandlerAdvice.AfterPropertiesSet();
ProxyFactory pf = new ProxyFactory(new TestObject());
pf.AddAdvice(exceptionHandlerAdvice);
ITestObject to = (ITestObject)pf.GetProxy();
try
{
to.Exceptional(new ArithmeticException());
Assert.Fail("Should have thrown exception when only logging");
}
catch (ArithmeticException)
{
bool found = false;
foreach (string message in loggerFactoryAdapter.LogMessages)
{
if (message.IndexOf("Hello World") >= 0)
{
found = true;
}
}
Assert.IsTrue(found, "did not find logging output");
}
}
[Test]
public void LoggingTestWithString()
{
string logHandlerText = "on exception name ArithmeticException log 'My Message, Method Name ' + #method.Name";
ExecuteLoggingHandler(logHandlerText, "My Message");
}
[Test]
public void LoggingTestWithStringExplicitHandler()
{
string logHandlerText = "on exception name ArithmeticException log 'My Message, Method Name ' + #method.Name";
ExecuteLoggingHandler(logHandlerText, "My Message");
}
[Test]
public void LoggingTestWithConstraintExpression()
{
string logHandlerText = "on exception (#e is T(System.ArithmeticException)) log 'My Message, Method Name ' + #method.Name";
ExecuteLoggingHandler(logHandlerText, "My Message");
}
[Test]
public void LoggingTestWithConstraintExpressionWithExceptionHandlerInList()
{
LogExceptionHandler exHandler = new LogExceptionHandler();
exHandler.ConstraintExpressionText = "#e is T(System.ArithmeticException)";
exHandler.LogName = "adviceHandler";
exHandler.ActionExpressionText = "#log.Fatal('Request Timeout occured', #e)";
ExecuteLoggingHandlerInList(exHandler, "Request Timeout");
}
[Test]
public void LoggingTestWithConstraintExpressionWithKeyedExceptionHandler()
{
LogExceptionHandler exHandler = new LogExceptionHandler();
ExecuteLoggingHandlerWithKeyedLogHandler(exHandler,
@"on exception (#e is T(System.ArithmeticException)) log 'Request Timeout occured'", "Request Timeout");
}
[Test]
[ExpectedException(typeof(ArgumentException))]
public void LoggingTestWithBadString()
{
string logHandlerText = "on foobar name ArithmeticException log 'My Message, Method Name ' + #method.Name";
ExecuteLoggingHandler(logHandlerText, "My Message");
}
[Test]
public void LoggingTestWithInvalidConstraintExpression()
{
string logHandlerText = "on exception (#e is System.FooBar) log 'My Message, Method Name ' + #method.Name";
ExecuteLoggingHandler(logHandlerText, "[WARN] Was not able to evaluate constraint expression [#e is System.FooBar]");
}
[Test]
public void LoggingTestWithNonBooleanConstraintExpression()
{
string logHandlerText = "on exception (1+1) log 'My Message, Method Name ' + #method.Name";
ExecuteLoggingHandler(logHandlerText, "[WARN] Was not able to unbox constraint expression to boolean [1+1]");
}
private void ExecuteLoggingHandler(string logHandlerText, string searchString)
{
ITestObject to = CreateTestObjectProxy(logHandlerText);
try
{
to.Exceptional(new ArithmeticException());
}
catch (ArithmeticException)
{
AssertSearchString(searchString);
}
}
private void ExecuteLoggingHandlerInList(IExceptionHandler handler, string searchString)
{
ITestObject to = CreateTestObjectProxyInList(handler);
try
{
to.Exceptional(new ArithmeticException());
}
catch (ArithmeticException)
{
AssertSearchString(searchString);
}
}
private void ExecuteLoggingHandlerWithKeyedLogHandler(IExceptionHandler handler, string handlerText, string searchString)
{
ITestObject to = CreateTestObjectProxyWithKeyedHandler(handler, handlerText);
try
{
to.Exceptional(new ArithmeticException());
}
catch (ArithmeticException)
{
AssertSearchString(searchString);
}
}
[Test]
public void TranslationWithString()
{
string translationHandlerText =
"on exception name ArithmeticException translate new System.InvalidOperationException('My Message, Method Name ' + #method.Name, #e)";
ITestObject to = CreateTestObjectProxy(translationHandlerText);
AssertTranslation(to);
}
[Test]
public void TranslateWithExceptionHandlerInstance()
{
TranslationExceptionHandler exHandler = new TranslationExceptionHandler();
IList exceptionNames = new ArrayList();
exceptionNames.Add("ArithmeticException");
exHandler.SourceExceptionNames = exceptionNames;
exHandler.ActionExpressionText =
"new System.InvalidOperationException('My Message, Method Name ' + #method.Name, #e)";
ITestObject to = CreateTestObjectProxy(exHandler);
AssertTranslation(to);
}
private static void AssertTranslation(ITestObject to)
{
try
{
to.Exceptional(new ArithmeticException("Bad Math"));
Assert.Fail("Should have thrown exception");
}
catch (InvalidOperationException e)
{
Assert.That(e.InnerException, Is.InstanceOf(typeof(ArithmeticException)), "Inner exception.");
Assert.AreEqual("My Message, Method Name Exceptional", e.Message);
}
catch (Exception e)
{
Assert.That(e, Is.InstanceOf(typeof (InvalidOperationException)), "wrong exception type thrown.");
}
}
[Test]
public void WrapWithString()
{
string translationHandlerText =
"on exception name ArithmeticException wrap System.InvalidOperationException 'My Message'";
ITestObject to = CreateTestObjectProxy(translationHandlerText);
try
{
to.Exceptional(new ArithmeticException("Bad Math"));
Assert.Fail("Should have thrown exception");
}
catch (InvalidOperationException e)
{
Assert.That(e.InnerException, Is.InstanceOf(typeof(ArithmeticException)));
Assert.AreEqual("My Message", e.Message);
}
catch (Exception e)
{
Assert.That(e, Is.InstanceOf(typeof(InvalidOperationException)));
}
}
[Test]
public void WrapWithStringDefaultMessage()
{
string translationHandlerText =
"on exception name ArithmeticException wrap System.InvalidOperationException";
ITestObject to = CreateTestObjectProxy(translationHandlerText);
try
{
to.Exceptional(new ArithmeticException("Bad Math"));
Assert.Fail("Should have thrown exception");
}
catch (InvalidOperationException e)
{
Assert.AreEqual("Wrapped ArithmeticException", e.Message);
}
catch (Exception e)
{
Assert.That(e, Is.InstanceOf(typeof(InvalidOperationException)));
}
}
[Test]
public void ReplaceWithString()
{
string translationHandlerText =
"on exception name ArithmeticException replace System.InvalidOperationException 'My Message'";
ITestObject to = CreateTestObjectProxy(translationHandlerText);
try
{
to.Exceptional(new ArithmeticException("Bad Math"));
Assert.Fail("Should have thrown exception");
}
catch (InvalidOperationException e)
{
Assert.IsNull(e.InnerException);
Assert.AreEqual("My Message", e.Message);
}
catch (Exception e)
{
Assert.That(e, Is.InstanceOf(typeof(InvalidOperationException)));
}
}
[Test]
public void ReplaceWithStringDefaultMessage()
{
string translationHandlerText =
"on exception name ArithmeticException replace System.InvalidOperationException";
ITestObject to = CreateTestObjectProxy(translationHandlerText);
try
{
to.Exceptional(new ArithmeticException("Bad Math"));
Assert.Fail("Should have thrown exception");
}
catch (InvalidOperationException e)
{
Assert.IsNull(e.InnerException);
Assert.AreEqual("Replaced ArithmeticException", e.Message);
}
catch (Exception e)
{
Assert.That(e, Is.InstanceOf(typeof(InvalidOperationException)));
}
}
[Test]
public void SwallowWithString()
{
string returnHandlerText = "on exception name ArithmeticException swallow";
ITestObject to = CreateTestObjectProxy(returnHandlerText);
try
{
to.Exceptional(new ArithmeticException("Bad Math"));
}
catch (Exception e)
{
Assert.Fail("Should not have thrown exception" + e);
}
}
[Test]
public void SwallowReturnTypeIsValueType()
{
string returnHandlerText = "on exception name ArithmeticException swallow";
ITestObject to = CreateTestObjectProxy(returnHandlerText);
try
{
to.ExceptionalWithReturnValue(new ArithmeticException("Bad Math"));
}
catch (Exception e)
{
Assert.Fail("Should not have thrown exception. Exception type = " + e.GetType());
}
}
[Test]
public void ReturnWithString()
{
string returnHandlerText = "on exception name ArithmeticException return 12";
ITestObject to = CreateTestObjectProxy(returnHandlerText);
try
{
int retVal = to.ExceptionalWithReturnValue(new ArithmeticException("Bad Math"));
Assert.AreEqual(12, retVal);
}
catch (Exception)
{
Assert.Fail("Should not have thrown exception");
}
}
[Test]
public void ChainLogAndWrap()
{
string logHandlerText = "on exception name ArithmeticException log 'My Message, Method Name ' + #method.Name";
string translationHandlerText = "on exception name ArithmeticException wrap System.InvalidOperationException 'My Message'";
exceptionHandlerAdvice.ExceptionHandlers.Add(logHandlerText);
exceptionHandlerAdvice.ExceptionHandlers.Add(translationHandlerText);
exceptionHandlerAdvice.AfterPropertiesSet();
ProxyFactory pf = new ProxyFactory(new TestObject());
pf.AddAdvice(exceptionHandlerAdvice);
ITestObject to = (ITestObject)pf.GetProxy();
try
{
to.Exceptional(new ArithmeticException("Bad Math"));
Assert.Fail("Should have thrown exception");
}
catch (InvalidOperationException e)
{
Assert.IsNotNull(e.InnerException);
Exception innerEx = e.InnerException;
Assert.AreEqual("My Message", e.Message);
Assert.AreEqual("Bad Math", innerEx.Message);
}
catch (Exception e)
{
Assert.That(e, Is.InstanceOf(typeof(InvalidOperationException)));
}
}
private ITestObject CreateTestObjectProxy(string logHandlerText)
{
exceptionHandlerAdvice.ExceptionHandlers.Add(logHandlerText);
return CreateProxy();
}
private ITestObject CreateTestObjectProxy(IExceptionHandler exceptionHander)
{
exceptionHandlerAdvice.ExceptionHandlers.Add(exceptionHander);
return CreateProxy();
}
private ITestObject CreateTestObjectProxyInList(IExceptionHandler exceptionHander)
{
exceptionHandlerAdvice.ExceptionHandlers.Add(exceptionHander);
return CreateProxy();
}
private ITestObject CreateTestObjectProxyWithKeyedHandler(IExceptionHandler exceptionHander, string handlerText)
{
exceptionHandlerAdvice.ExceptionHandlerDictionary.Add("log", exceptionHander);
exceptionHandlerAdvice.ExceptionHandlers.Add(handlerText);
return CreateProxy();
}
private ITestObject CreateProxy()
{
exceptionHandlerAdvice.AfterPropertiesSet();
ProxyFactory pf = new ProxyFactory(new TestObject());
pf.AddAdvice(exceptionHandlerAdvice);
return (ITestObject)pf.GetProxy();
}
private void AssertSearchString(string searchString)
{
bool found = false;
foreach (string message in loggerFactoryAdapter.LogMessages)
{
if (message.IndexOf(searchString) >= 0)
{
found = true;
}
}
Assert.IsTrue(found, "did not find logging output [" + searchString + "] Logging values = "
+ StringUtils.CollectionToCommaDelimitedString(loggerFactoryAdapter.LogMessages));
}
}
}
|