This is an automated email from the ASF dual-hosted git repository. pkarwasz pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit f29e900edced22ea900af87b15d9d558dc2eb568 Author: Gary Gregory <[email protected]> AuthorDate: Sat Feb 5 15:12:09 2022 -0500 Add ThrowableInformationTest. --- .../apache/log4j/spi/ThrowableInformationTest.java | 338 +++++++++++++++++++++ 1 file changed, 338 insertions(+) diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/spi/ThrowableInformationTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/spi/ThrowableInformationTest.java new file mode 100644 index 0000000..e032bd7 --- /dev/null +++ b/log4j-1.2-api/src/test/java/org/apache/log4j/spi/ThrowableInformationTest.java @@ -0,0 +1,338 @@ +/* + * 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.log4j.spi; + +import java.io.PrintWriter; + +import junit.framework.TestCase; + +/** + * Tests {@link ThrowableInformation}. + */ +public class ThrowableInformationTest extends TestCase { + + /** + * Create ThrowableInformationTest. + * + * @param name test name. + */ + public ThrowableInformationTest(final String name) { + super(name); + } + + /** + * Custom throwable that only calls methods overridden by VectorWriter in log4j 1.2.14 and earlier. + */ + private static final class OverriddenThrowable extends Throwable { + private static final long serialVersionUID = 1L; + + /** + * Create new instance. + */ + public OverriddenThrowable() { + } + + /** + * Print stack trace. + * + * @param s print writer. + */ + public void printStackTrace(final PrintWriter s) { + s.print((Object) "print(Object)"); + s.print("print(char[])".toCharArray()); + s.print("print(String)"); + s.println((Object) "println(Object)"); + s.println("println(char[])".toCharArray()); + s.println("println(String)"); + s.write("write(char[])".toCharArray()); + s.write("write(char[], int, int)".toCharArray(), 2, 8); + s.write("write(String, int, int)", 2, 8); + } + } + + /** + * Test capturing stack trace from a throwable that only uses the PrintWriter methods overridden in log4j 1.2.14 and + * earlier. + */ + public void testOverriddenBehavior() { + ThrowableInformation ti = new ThrowableInformation(new OverriddenThrowable()); + String[] rep = ti.getThrowableStrRep(); + assertEquals(4, rep.length); + assertEquals("print(Object)print(char[])print(String)println(Object)", rep[0]); + assertEquals("println(char[])", rep[1]); + assertEquals("println(String)", rep[2]); + assertEquals("write(char[])ite(charite(Stri", rep[3]); + } + + /** + * Custom throwable that calls methods not overridden by VectorWriter in log4j 1.2.14 and earlier. + */ + private static final class NotOverriddenThrowable extends Throwable { + private static final long serialVersionUID = 1L; + + /** + * Create new instance. + */ + public NotOverriddenThrowable() { + } + + /** + * Print stack trace. + * + * @param s print writer. + */ + public void printStackTrace(final PrintWriter s) { + s.print(true); + s.print('a'); + s.print(1); + s.print(2L); + s.print(Float.MAX_VALUE); + s.print(Double.MIN_VALUE); + s.println(true); + s.println('a'); + s.println(1); + s.println(2L); + s.println(Float.MAX_VALUE); + s.println(Double.MIN_VALUE); + s.write('C'); + } + } + + /** + * Test capturing stack trace from a throwable that uses the PrintWriter methods not overridden in log4j 1.2.14 and + * earlier. + */ + public void testNotOverriddenBehavior() { + ThrowableInformation ti = new ThrowableInformation(new NotOverriddenThrowable()); + String[] rep = ti.getThrowableStrRep(); + assertEquals(7, rep.length); + StringBuffer buf = new StringBuffer(String.valueOf(true)); + buf.append('a'); + buf.append(String.valueOf(1)); + buf.append(String.valueOf(2L)); + buf.append(String.valueOf(Float.MAX_VALUE)); + buf.append(String.valueOf(Double.MIN_VALUE)); + buf.append(String.valueOf(true)); + assertEquals(buf.toString(), rep[0]); + assertEquals("a", rep[1]); + assertEquals(String.valueOf(1), rep[2]); + assertEquals(String.valueOf(2L), rep[3]); + assertEquals(String.valueOf(Float.MAX_VALUE), rep[4]); + assertEquals(String.valueOf(Double.MIN_VALUE), rep[5]); + assertEquals("C", rep[6]); + } + + /** + * Custom throwable that calls methods of VectorWriter with null. + */ + private static final class NullThrowable extends Throwable { + private static final long serialVersionUID = 1L; + + /** + * Create new instance. + */ + public NullThrowable() { + } + + /** + * Print stack trace. + * + * @param s print writer. + */ + public void printStackTrace(final PrintWriter s) { + s.print((Object) null); + s.print((String) null); + s.println((Object) null); + s.println((String) null); + } + } + + /** + * Test capturing stack trace from a throwable that passes null to PrintWriter methods. + */ + + public void testNull() { + ThrowableInformation ti = new ThrowableInformation(new NullThrowable()); + String[] rep = ti.getThrowableStrRep(); + assertEquals(2, rep.length); + String nullStr = String.valueOf((Object) null); + assertEquals(nullStr + nullStr + nullStr, rep[0]); + assertEquals(nullStr, rep[1]); + } + + /** + * Custom throwable that does nothing in printStackTrace. + */ + private static final class EmptyThrowable extends Throwable { + private static final long serialVersionUID = 1L; + + /** + * Create new instance. + */ + public EmptyThrowable() { + } + + /** + * Print stack trace. + * + * @param s print writer. + */ + public void printStackTrace(final PrintWriter s) { + } + } + + /** + * Test capturing stack trace from a throwable that does nothing on a call to printStackTrace. + */ + + public void testEmpty() { + ThrowableInformation ti = new ThrowableInformation(new EmptyThrowable()); + String[] rep = ti.getThrowableStrRep(); + assertEquals(0, rep.length); + } + + /** + * Custom throwable that emits a specified string in printStackTrace. + */ + private static final class StringThrowable extends Throwable { + private static final long serialVersionUID = 1L; + /** + * Stack trace. + */ + private final String stackTrace; + + /** + * Create new instance. + * + * @param trace stack trace. + */ + public StringThrowable(final String trace) { + stackTrace = trace; + } + + /** + * Print stack trace. + * + * @param s print writer. + */ + public void printStackTrace(final PrintWriter s) { + s.print(stackTrace); + } + } + + /** + * Test capturing stack trace from throwable that just has a line feed. + */ + public void testLineFeed() { + ThrowableInformation ti = new ThrowableInformation(new StringThrowable("\n")); + String[] rep = ti.getThrowableStrRep(); + assertEquals(1, rep.length); + assertEquals("", rep[0]); + } + + /** + * Test capturing stack trace from throwable that just has a carriage return. + */ + public void testCarriageReturn() { + ThrowableInformation ti = new ThrowableInformation(new StringThrowable("\r")); + String[] rep = ti.getThrowableStrRep(); + assertEquals(1, rep.length); + assertEquals("", rep[0]); + } + + /** + * Test parsing of line breaks. + */ + public void testParsing() { + ThrowableInformation ti = new ThrowableInformation(new StringThrowable("Line1\rLine2\nLine3\r\nLine4\n\rLine6")); + String[] rep = ti.getThrowableStrRep(); + assertEquals(6, rep.length); + assertEquals("Line1", rep[0]); + assertEquals("Line2", rep[1]); + assertEquals("Line3", rep[2]); + assertEquals("Line4", rep[3]); + assertEquals("", rep[4]); + assertEquals("Line6", rep[5]); + } + + /** + * Test capturing stack trace from throwable that a line feed followed by blank. + */ + public void testLineFeedBlank() { + ThrowableInformation ti = new ThrowableInformation(new StringThrowable("\n ")); + String[] rep = ti.getThrowableStrRep(); + assertEquals(2, rep.length); + assertEquals("", rep[0]); + assertEquals(" ", rep[1]); + } + + /** + * Test that getThrowable returns the throwable provided to the constructor. + */ + public void testGetThrowable() { + Throwable t = new StringThrowable("Hello, World"); + ThrowableInformation ti = new ThrowableInformation(t); + assertSame(t, ti.getThrowable()); + } + + /** + * Tests isolation of returned string representation from internal state of ThrowableInformation. log4j 1.2.15 and + * earlier did not isolate initial call. See bug 44032. + */ + public void testIsolation() { + ThrowableInformation ti = new ThrowableInformation(new StringThrowable("Hello, World")); + String[] rep = ti.getThrowableStrRep(); + assertEquals("Hello, World", rep[0]); + rep[0] = "Bonjour, Monde"; + String[] rep2 = ti.getThrowableStrRep(); + assertEquals("Hello, World", rep2[0]); + } + + /** + * Custom throwable that throws a runtime exception when printStackTrace is called. + */ + private static final class NastyThrowable extends Throwable { + private static final long serialVersionUID = 1L; + + /** + * Create new instance. + */ + public NastyThrowable() { + } + + /** + * Print stack trace. + * + * @param s print writer. + */ + public void printStackTrace(final PrintWriter s) { + s.print("NastyException"); + throw new RuntimeException("Intentional exception"); + } + } + + /** + * Tests that a failure in printStackTrace does not percolate out of getThrowableStrRep(). + * + */ + public void testNastyException() { + ThrowableInformation ti = new ThrowableInformation(new NastyThrowable()); + String[] rep = ti.getThrowableStrRep(); + assertEquals("NastyException", rep[0]); + } + +}
