1 16 package com.google.gwt.junit.server; 17 18 import com.google.gwt.junit.JUnitMessageQueue; 19 import com.google.gwt.junit.JUnitShell; 20 import com.google.gwt.junit.client.impl.ExceptionWrapper; 21 import com.google.gwt.junit.client.impl.JUnitHost; 22 import com.google.gwt.junit.client.impl.StackTraceWrapper; 23 import com.google.gwt.junit.client.TestResults; 24 import com.google.gwt.junit.client.Trial; 25 import com.google.gwt.user.client.rpc.InvocationException; 26 import com.google.gwt.user.server.rpc.RemoteServiceServlet; 27 28 import java.lang.reflect.Constructor ; 29 import java.lang.reflect.Field ; 30 import java.util.List ; 31 32 import javax.servlet.http.HttpServletRequest ; 33 34 39 public class JUnitHostImpl extends RemoteServiceServlet implements JUnitHost { 40 41 46 private static final int TIME_TO_WAIT_FOR_TESTNAME = 300000; 47 48 52 55 private static JUnitMessageQueue sHost = null; 56 57 61 private static synchronized JUnitMessageQueue getHost() { 62 if (sHost == null) { 63 sHost = JUnitShell.getMessageQueue(); 64 if (sHost == null) { 65 throw new InvocationException( 66 "Unable to find JUnitShell; is this servlet running under GWTTestCase?"); 67 } 68 } 69 return sHost; 70 } 71 72 75 private static void setField(Class cls, String fieldName, Object obj, 76 Object value) throws SecurityException , NoSuchFieldException , 77 IllegalArgumentException , IllegalAccessException { 78 Field fld = cls.getDeclaredField(fieldName); 79 fld.setAccessible(true); 80 fld.set(obj, value); 81 } 82 83 public String getFirstMethod(String testClassName) { 84 return getHost().getNextTestName(getClientId(), testClassName, 85 TIME_TO_WAIT_FOR_TESTNAME); 86 } 87 88 public String reportResultsAndGetNextMethod(String testClassName, 89 TestResults results) { 90 JUnitMessageQueue host = getHost(); 91 HttpServletRequest request = getThreadLocalRequest(); 92 String agent = request.getHeader("User-Agent"); 93 results.setAgent(agent); 94 String machine = request.getRemoteHost(); 95 results.setHost(machine); 96 List trials = results.getTrials(); 97 for (int i = 0; i < trials.size(); ++i) { 98 Trial trial = (Trial) trials.get(i); 99 ExceptionWrapper ew = trial.getExceptionWrapper(); 100 trial.setException(deserialize(ew)); 101 } 102 host.reportResults(testClassName, results); 103 return host.getNextTestName(getClientId(), testClassName, 104 TIME_TO_WAIT_FOR_TESTNAME); 105 } 106 107 110 private Throwable deserialize(ExceptionWrapper ew) { 111 if (ew == null) { 112 return null; 113 } 114 115 Throwable ex = null; 116 Throwable cause = deserialize(ew.cause); 117 try { 118 Class exClass = Class.forName(ew.typeName); 119 try { 120 Constructor ctor = exClass.getDeclaredConstructor(new Class []{ 122 String .class, Throwable .class}); 123 ctor.setAccessible(true); 124 ex = (Throwable ) ctor.newInstance(new Object []{ew.message, cause}); 125 } catch (Throwable e) { 126 try { 128 Constructor ctor = exClass 129 .getDeclaredConstructor(new Class []{String .class}); 130 ctor.setAccessible(true); 131 ex = (Throwable ) ctor.newInstance(new Object []{ew.message}); 132 ex.initCause(cause); 133 } catch (Throwable e2) { 134 try { 136 Constructor ctor = exClass 137 .getDeclaredConstructor(new Class []{Throwable .class}); 138 ctor.setAccessible(true); 139 ex = (Throwable ) ctor.newInstance(new Object []{cause}); 140 setField(exClass, "detailMessage", ex, ew.message); 141 } catch (Throwable e3) { 142 try { 144 Constructor ctor = exClass.getDeclaredConstructor(null); 145 ctor.setAccessible(true); 146 ex = (Throwable ) ctor.newInstance(null); 147 ex.initCause(cause); 148 setField(exClass, "detailMessage", ex, ew.message); 149 } catch (Throwable e4) { 150 this.log("Failed to deserialize getException of type '" 152 + ew.typeName + "'; no available constructor", e4); 153 154 } 156 } 157 } 158 } 159 160 } catch (Throwable e) { 161 this.log( 162 "Failed to deserialize getException of type '" + ew.typeName + "'", 163 e); 164 } 165 166 if (ex == null) { 167 ex = new RuntimeException (ew.typeName + ": " + ew.message, cause); 168 } 169 170 ex.setStackTrace(deserialize(ew.stackTrace)); 171 return ex; 172 } 173 174 177 private StackTraceElement deserialize(StackTraceWrapper stw) { 178 StackTraceElement ste = null; 179 Object [] args = new Object []{ 180 stw.className, stw.methodName, stw.fileName, 181 new Integer (stw.lineNumber)}; 182 try { 183 try { 184 Constructor ctor = StackTraceElement .class 186 .getDeclaredConstructor(new Class []{ 187 String .class, String .class, String .class, int.class}); 188 ctor.setAccessible(true); 189 ste = (StackTraceElement ) ctor.newInstance(args); 190 } catch (NoSuchMethodException e) { 191 Constructor ctor = StackTraceElement .class.getDeclaredConstructor(null); 193 ctor.setAccessible(true); 194 ste = (StackTraceElement ) ctor.newInstance(null); 195 setField(StackTraceElement .class, "declaringClass", ste, args[0]); 196 setField(StackTraceElement .class, "methodName", ste, args[1]); 197 setField(StackTraceElement .class, "fileName", ste, args[2]); 198 setField(StackTraceElement .class, "lineNumber", ste, args[3]); 199 } 200 } catch (Throwable e) { 201 this.log("Error creating stack trace", e); 202 } 203 return ste; 204 } 205 206 209 private StackTraceElement [] deserialize(StackTraceWrapper[] stackTrace) { 210 int len = stackTrace.length; 211 StackTraceElement [] result = new StackTraceElement [len]; 212 for (int i = 0; i < len; ++i) { 213 result[i] = deserialize(stackTrace[i]); 214 } 215 return result; 216 } 217 218 221 private String getClientId() { 222 HttpServletRequest request = getThreadLocalRequest(); 223 String agent = request.getHeader("User-Agent"); 224 String machine = request.getRemoteHost(); 225 return machine + " / " + agent; 226 } 227 } 228 | Popular Tags |