You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by pk...@apache.org on 2022/03/29 14:05:31 UTC

[logging-log4j2] 11/25: Add ThrowableInformationTest.

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 <ga...@gmail.com>
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]);
+    }
+
+}