// Modified or written by Luca Marrocco for inclusion with hoptoad. // Copyright (c) 2009 Luca Marrocco. // Licensed under the Apache License, Version 2.0 (the "License") package hoptoad; import ch.qos.logback.classic.spi.ThrowableProxy; import org.apache.commons.lang.exception.ExceptionUtils; import org.junit.Test; import java.util.List; import java.util.regex.PatternSyntaxException; import static hoptoad.Exceptions.ERROR_MESSAGE; import static hoptoad.Exceptions.newException; import static hoptoad.Slurp.*; import static hoptoad.ValidBacktraces.isValidBacktrace; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.not; import static org.junit.Assert.*; public class BacktraceTest { public static final List<String> backtrace() { return strings(slurp(read("backtrace.txt"))); } private List<String> filteredBacktrace() { return strings(slurp(read("filteredBacktrace.txt"))); } @Test public void testExceptionToRubyBacktrace() { final Throwable EXCEPTION = newException(ERROR_MESSAGE); final Iterable<String> backtrace = new RubyBacktrace(new ThrowableProxy(EXCEPTION)); assertThat(backtrace, hasItem("at hoptoad.Exceptions.java:15:in `newException'")); } @Test public void testEscapesExceptionClassName() { try { new Backtrace(new ThrowableProxy(new Exception("com.banana.MyClass{junk}"))); } catch (PatternSyntaxException e) { fail("Throwing a pattern syntax exception means the class name might not have been escaped properly"); } } @Test public void testExceptionToRubyBacktrace$UsingNewRubyBacktraceEmptyInstanceAsFactoryOfRubyBacktrace() { final Throwable EXCEPTION = newException(ERROR_MESSAGE); final Iterable<String> backtrace = new RubyBacktrace().newBacktrace(new ThrowableProxy(EXCEPTION)); assertThat(backtrace, hasItem("at hoptoad.Exceptions.java:15:in `newException'")); } @Test public void testFilteredIgnoringMessage() { final Throwable EXCEPTION = newException(ERROR_MESSAGE); final Iterable<String> backtrace = new QuietRubyBacktrace(new ThrowableProxy(EXCEPTION)); assertThat(backtrace, not(hasItem("java.lang.RuntimeException: undefined method `password' for nil:NilClass"))); assertThat(backtrace, not(hasItem("java.lang.RuntimeException undefined method `password' for nilNilClass"))); } @Test public void testFilteredIgnoringMessage$UsingNewQuiteBacktraceEmptyInstanceAsFactoryOfQuietRubyBacktrace() { final Throwable EXCEPTION = newException(ERROR_MESSAGE); final Iterable<String> backtrace = new QuietRubyBacktrace().newBacktrace(new ThrowableProxy(EXCEPTION)); assertThat(backtrace, not(hasItem("java.lang.RuntimeException: undefined method `password' for nil:NilClass"))); assertThat(backtrace, not(hasItem("java.lang.RuntimeException undefined method `password' for nilNilClass"))); } @Test public void testFilteredSafeCausedByTest() { final Throwable EXCEPTION = newException(ERROR_MESSAGE); final Iterable<String> backtrace = new Backtrace(strings(ExceptionUtils.getStackTrace(EXCEPTION))); assertThat(backtrace, not(hasItem("Caused by: java.lang.NullPointerException"))); assertThat(backtrace, hasItem("Caused by java.lang.NullPointerException")); assertThat(backtrace, not(hasItem("java.lang.RuntimeException: undefined method `password' for nil:NilClass"))); assertThat(backtrace, hasItem("java.lang.RuntimeException undefined method `password' for nilNilClass")); } @Test public void testIgnoreCocoonBacktrace() { final Iterable<String> backtrace = new Backtrace(backtrace()) { @Override protected void ignore() { ignoreCocoon(); } }; assertThat(backtrace, not(hasItem("org.apache.cocoon.components.expression.jexl.JexlExpression.evaluate(JexlExpression.java:49)"))); assertThat(backtrace, not(hasItem("org.apache.cocoon.template.script.event.StartElement.execute(StartElement.java:115)"))); assertThat(backtrace, not(hasItem("org.apache.cocoon.template.instruction.Call.execute(Call.java:143)"))); assertThat(backtrace, not(hasItem("org.apache.cocoon.template.JXTemplateGenerator.performGeneration(JXTemplateGenerator.java:117)"))); assertThat(backtrace, not(hasItem("org.apache.cocoon.components.pipeline.AbstractProcessingPipeline.processXMLPipeline(AbstractProcessingPipeline.java:578)"))); assertThat(backtrace, not(hasItem("org.apache.cocoon.components.treeprocessor.sitemap.SerializeNode.invoke(SerializeNode.java:120)"))); assertThat(backtrace, not(hasItem("org.apache.cocoon.environment.ForwardRedirector.redirect(ForwardRedirector.java:59)"))); assertThat(backtrace, not(hasItem("org.apache.cocoon.components.flow.AbstractInterpreter.forwardTo(AbstractInterpreter.java:209)"))); assertThat(backtrace, not(hasItem("org.apache.cocoon.components.flow.javascript.fom.FOM_JavaScriptInterpreter.forwardTo(FOM_JavaScriptInterpreter.java:905)"))); assertThat(backtrace, not(hasItem("org.apache.cocoon.components.flow.javascript.fom.FOM_Cocoon.forwardTo(FOM_Cocoon.java:698)"))); assertThat(backtrace, not(hasItem("org.apache.commons.jexl.util.introspection.UberspectImpl$VelMethodImpl.invoke(UberspectImpl.java:268)"))); assertThat(backtrace, not(hasItem("org.apache.commons.jexl.parser.ASTMethod.execute(ASTMethod.java:61)"))); assertThat(backtrace, not(hasItem("org.apache.commons.jexl.parser.ASTReference.execute(ASTReference.java:68)"))); assertThat(backtrace, not(hasItem("org.apache.commons.jexl.parser.ASTReference.value(ASTReference.java:50)"))); assertThat(backtrace, not(hasItem("org.apache.commons.jexl.ExpressionImpl.evaluate(ExpressionImpl.java:86)"))); } @Test public void testIgnoreEclipseBacktrace() { final Iterable<String> backtrace = new Backtrace(backtrace()) { @Override protected void ignore() { ignoreEclipse(); } }; assertThat(backtrace, not(hasItem("org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)"))); assertThat(backtrace, not(hasItem("org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)"))); assertThat(backtrace, not(hasItem("org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)"))); } @Test public void testIgnoreExceptionGenerateInsideTest() { final Throwable EXCEPTION = newException(ERROR_MESSAGE); final Iterable<String> backtrace = new Backtrace(strings(ExceptionUtils.getStackTrace(EXCEPTION))) { @Override protected void ignore() { ignoreJunit(); ignoreEclipse(); ignoreNoise(); } }; assertThat(backtrace, not(hasItem(" at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)"))); assertThat(backtrace, not(hasItem(" at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)"))); assertThat(backtrace, not(hasItem(" at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)"))); assertThat(backtrace, not(hasItem(" at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)"))); assertThat(backtrace, not(hasItem(" at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)"))); assertThat(backtrace, not(hasItem(" at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)"))); assertThat(backtrace, not(hasItem(" at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)"))); assertThat(backtrace, not(hasItem(" at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)"))); assertThat(backtrace, not(hasItem(" at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)"))); assertThat(backtrace, not(hasItem(" at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)"))); assertThat(backtrace, not(hasItem(" at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)"))); assertThat(backtrace, not(hasItem(" at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)"))); assertThat(backtrace, not(hasItem(" at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)"))); assertThat(backtrace, not(hasItem(" at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)"))); } @Test public void testIgnoreIgnomreCommonsBacktrace() { final Iterable<String> backtrace = new QuietRubyBacktrace(backtrace()); final Iterable<String> filteredBacktrace = new QuietRubyBacktrace(filteredBacktrace()); assertEquals(filteredBacktrace.toString(), backtrace.toString()); } @Test public void testIgnoreJunitBacktrace() { final Iterable<String> backtrace = new Backtrace(backtrace()) { @Override protected void ignore() { ignoreJunit(); } }; assertThat(backtrace, not(hasItem("org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)"))); assertThat(backtrace, not(hasItem("org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)"))); assertThat(backtrace, not(hasItem("org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)"))); assertThat(backtrace, not(hasItem("org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)"))); assertThat(backtrace, not(hasItem("org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)"))); assertThat(backtrace, not(hasItem("org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)"))); assertThat(backtrace, not(hasItem("org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)"))); assertThat(backtrace, not(hasItem("org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)"))); } @Test public void testIgnoreMortbayJettyBacktrace() { final Iterable<String> backtrace = new Backtrace(backtrace()) { @Override protected void ignore() { ignoreMortbayJetty(); } }; assertThat(backtrace, not(hasItem("org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:206)"))); assertThat(backtrace, not(hasItem("org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)"))); assertThat(backtrace, not(hasItem("org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)"))); assertThat(backtrace, not(hasItem("org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)"))); assertThat(backtrace, not(hasItem("org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)"))); assertThat(backtrace, not(hasItem("org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)"))); assertThat(backtrace, not(hasItem("org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)"))); assertThat(backtrace, not(hasItem("org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)"))); assertThat(backtrace, not(hasItem("org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)"))); assertThat(backtrace, not(hasItem("org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)"))); assertThat(backtrace, not(hasItem("org.mortbay.jetty.Server.handle(Server.java:324)"))); assertThat(backtrace, not(hasItem("org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1,088)"))); assertThat(backtrace, not(hasItem("org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)"))); assertThat(backtrace, not(hasItem("org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)"))); assertThat(backtrace, not(hasItem("org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)"))); assertThat(backtrace, not(hasItem("org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)"))); assertThat(backtrace, not(hasItem("org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)"))); assertThat(backtrace, not(hasItem("org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)"))); } @Test public void testIgnoreMozillaBacktrace() { final Iterable<String> backtrace = new Backtrace(backtrace()) { @Override protected void ignore() { ignoreMozilla(); } }; assertThat(backtrace, not(hasItem("org.mozilla.javascript.FunctionObject.doInvoke(FunctionObject.java:523)"))); assertThat(backtrace, not(hasItem("org.mozilla.javascript.ScriptRuntime.call(ScriptRuntime.java:1,244)"))); assertThat(backtrace, not(hasItem("org.mozilla.javascript.continuations.ContinuationInterpreter.interpret(ContinuationInterpreter.java:1,134)"))); assertThat(backtrace, not(hasItem("org.mozilla.javascript.ScriptRuntime.call(ScriptRuntime.java:1,244)"))); assertThat(backtrace, not(hasItem("org.mozilla.javascript.ScriptableObject.callMethod(ScriptableObject.java:1,591)"))); assertThat(backtrace, not(hasItem("org.mozilla.javascript.FunctionObject.doInvoke(FunctionObject.java:523)"))); } @Test public void testIgnoreNoiseBacktrace() { final Iterable<String> backtrace = new Backtrace(backtrace()) { @Override protected void ignore() { ignoreNoise(); } }; assertThat(backtrace, not(hasItem("inv1.invoke(:-1)"))); assertThat(backtrace, not(hasItem("javax.servlet.http.HttpServlet.service(HttpServlet.java:820)"))); assertThat(backtrace, not(hasItem("sun.reflect.GeneratedMethodAccessor338.invoke(null:-1)"))); assertThat(backtrace, not(hasItem("sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)"))); assertThat(backtrace, not(hasItem("java.lang.reflect.Method.invoke(Method.java:597)"))); } @Test public void testIgnoreSpringBacktrace() { final Iterable<String> backtrace = new Backtrace(backtrace()) { @Override protected void ignore() { ignoreSpringSecurity(); } }; assertThat( backtrace, not(hasItem("org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)"))); assertThat(backtrace, not(hasItem("org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)"))); assertThat(backtrace, not(hasItem("org.springframework.security.providers.anonymous.AnonymousProcessingFilter.doFilterHttp(AnonymousProcessingFilter.java:105)"))); assertThat(backtrace, not(hasItem("org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:271)"))); assertThat(backtrace, not(hasItem("org.springframework.security.ui.basicauth.BasicProcessingFilter.doFilterHttp(BasicProcessingFilter.java:173)"))); assertThat(backtrace, not(hasItem("org.springframework.security.ui.ExceptionTranslationFilter.doFilterHttp(ExceptionTranslationFilter.java:101)"))); assertThat(backtrace, not(hasItem("org.springframework.security.ui.logout.LogoutFilter.doFilterHttp(LogoutFilter.java:89)"))); assertThat(backtrace, not(hasItem("org.springframework.security.ui.rememberme.RememberMeProcessingFilter.doFilterHttp(RememberMeProcessingFilter.java:116)"))); assertThat(backtrace, not(hasItem("org.springframework.security.ui.SessionFixationProtectionFilter.doFilterHttp(SessionFixationProtectionFilter.java:67)"))); assertThat(backtrace, not(hasItem("org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)"))); assertThat(backtrace, not(hasItem("org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:174)"))); assertThat( backtrace, not(hasItem("org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91)"))); assertThat(backtrace, not(hasItem("org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)"))); } @Test public void testJavaBacktrace() { final Throwable EXCEPTION = newException(ERROR_MESSAGE); final Iterable<String> backtrace = new Backtrace(new ThrowableProxy(EXCEPTION)); assertThat(backtrace, hasItem("at hoptoad.Exceptions.newException(Exceptions.java:15)")); } @Test public void testJavaBacktrace$UsingNewBacktraceEmptyInstanceAsFactoryOfBacktrace() { final Throwable EXCEPTION = newException(ERROR_MESSAGE); final Iterable<String> backtrace = new Backtrace().newBacktrace(new ThrowableProxy(EXCEPTION)); assertThat(backtrace, hasItem("at hoptoad.Exceptions.newException(Exceptions.java:15)")); } @Test public void testNotValidaBacktrace() { String string = "Caused by: java.lang.NullPointerException"; assertFalse(isValidBacktrace(string)); } @Test public void testValidaBacktrace() { assertTrue(isValidBacktrace("at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)")); assertTrue(isValidBacktrace("vendors/rails/actionpack/lib/action_controller/filter.rb:579:in `call_filters'")); } }