001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.classic.spi; 015 016import static org.junit.Assert.assertNotNull; 017import static org.junit.Assert.assertTrue; 018 019import java.net.MalformedURLException; 020import java.net.URL; 021import java.net.URLClassLoader; 022 023import org.junit.Ignore; 024import org.junit.Test; 025 026import ch.qos.logback.classic.util.TestHelper; 027import ch.qos.logback.core.util.SystemInfo; 028 029public class PackagingDataCalculatorTest { 030 031 public void verify(ThrowableProxy tp) { 032 for (StackTraceElementProxy step : tp.getStackTraceElementProxyArray()) { 033 if (step != null) { 034 assertNotNull(step.getClassPackagingData()); 035 } 036 } 037 } 038 039 @Test 040 public void smoke() throws Exception { 041 Throwable t = new Throwable("x"); 042 ThrowableProxy tp = new ThrowableProxy(t); 043 PackagingDataCalculator pdc = tp.getPackagingDataCalculator(); 044 pdc.calculate(tp); 045 verify(tp); 046 tp.fullDump(); 047 } 048 049 @Test 050 public void nested() throws Exception { 051 Throwable t = TestHelper.makeNestedException(3); 052 ThrowableProxy tp = new ThrowableProxy(t); 053 PackagingDataCalculator pdc = tp.getPackagingDataCalculator(); 054 pdc.calculate(tp); 055 verify(tp); 056 } 057 058 public void doCalculateClassPackagingData(boolean withClassPackagingCalculation) { 059 try { 060 throw new Exception("testing"); 061 } catch (Throwable e) { 062 ThrowableProxy tp = new ThrowableProxy(e); 063 if (withClassPackagingCalculation) { 064 PackagingDataCalculator pdc = tp.getPackagingDataCalculator(); 065 pdc.calculate(tp); 066 } 067 } 068 } 069 070 double loop(int len, boolean withClassPackagingCalculation) { 071 long start = System.nanoTime(); 072 for (int i = 0; i < len; i++) { 073 doCalculateClassPackagingData(withClassPackagingCalculation); 074 } 075 return (1.0 * System.nanoTime() - start) / len / 1000; 076 } 077 078 @Ignore 079 @Test 080 public void perfTest() { 081 int len = 1000; 082 loop(len, false); 083 loop(len, true); 084 085 double d0 = loop(len, false); 086 System.out.println("without packaging info " + d0 + " microseconds"); 087 088 double d1 = loop(len, true); 089 System.out.println("with packaging info " + d1 + " microseconds"); 090 091 int slackFactor = 8; 092 if (!SystemInfo.getJavaVendor().contains("Sun")) { 093 // be more lenient with other JDKs 094 slackFactor = 15; 095 } 096 assertTrue("computing class packaging data (" + d1 + ") should have been less than " + slackFactor 097 + " times the time it takes to process an exception " + (d0 * slackFactor), d0 * slackFactor > d1); 098 099 } 100 101 private ClassLoader makeBogusClassLoader() throws MalformedURLException { 102 ClassLoader currentClassLoader = this.getClass().getClassLoader(); 103 return new BogusClassLoader(new URL[] {}, currentClassLoader); 104 } 105 106 @Test 107 // Test http://jira.qos.ch/browse/LBCLASSIC-125 108 public void noClassDefFoundError_LBCLASSIC_125Test() throws MalformedURLException { 109 ClassLoader cl = (URLClassLoader) makeBogusClassLoader(); 110 Thread.currentThread().setContextClassLoader(cl); 111 Throwable t = new Throwable("x"); 112 ThrowableProxy tp = new ThrowableProxy(t); 113 StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray(); 114 StackTraceElement bogusSTE = new StackTraceElement("com.Bogus", "myMethod", "myFile", 12); 115 stepArray[0] = new StackTraceElementProxy(bogusSTE); 116 PackagingDataCalculator pdc = tp.getPackagingDataCalculator(); 117 // NoClassDefFoundError should be caught 118 pdc.calculate(tp); 119 120 } 121 122}