1 package org.testng.remote.strprotocol; 2 3 import java.io.PrintWriter; 4 import java.io.StringWriter; 5 import java.util.List; 6 7 import org.testng.ITestContext; 8 import org.testng.ITestResult; 9 import org.testng.SkipException; 10 import org.testng.collections.Lists; 11 12 import static org.testng.internal.Utils.isStringEmpty; 13 14 15 /** 16 * An <code>IStringMessage</code> implementation for test results events. 17 * 18 * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a> 19 */ 20 public class TestResultMessage implements IStringMessage { 21 private static final long serialVersionUID = -4157150777889117479L; 22 protected int m_messageType; 23 protected String m_suiteName; 24 protected String m_testName; 25 protected String m_testClassName; 26 protected String m_testMethodName; 27 protected String m_stackTrace; 28 protected long m_startMillis; 29 protected long m_endMillis; 30 protected String[] m_parameters= new String[0]; 31 protected String[] m_paramTypes= new String[0]; 32 private String m_testDescription; 33 private int m_invocationCount; 34 private int m_currentInvocationCount; 35 private String m_instanceName; 36 37 /** 38 * This constructor is used by the Eclipse client to initialize a result message based 39 * on what was received over the network. 40 */ TestResultMessage(final int resultType, final String suiteName, final String testName, final String className, final String methodName, final String testDescriptor, String instanceName, final String[] params, final long startMillis, final long endMillis, final String stackTrace, int invocationCount, int currentInvocationCount)41 public TestResultMessage(final int resultType, 42 final String suiteName, 43 final String testName, 44 final String className, 45 final String methodName, 46 final String testDescriptor, 47 String instanceName, 48 final String[] params, 49 final long startMillis, 50 final long endMillis, 51 final String stackTrace, 52 int invocationCount, 53 int currentInvocationCount) 54 { 55 init(resultType, 56 suiteName, 57 testName, 58 className, 59 methodName, 60 stackTrace, 61 startMillis, 62 endMillis, 63 extractParams(params), 64 extractParamTypes(params), 65 testDescriptor, 66 instanceName, 67 invocationCount, 68 currentInvocationCount 69 ); 70 } 71 72 /** 73 * This constructor is used by RemoteTestNG to initialize a result message 74 * from an ITestResult. 75 */ TestResultMessage(final String suiteName, final String testName, final ITestResult result)76 public TestResultMessage(final String suiteName, 77 final String testName, 78 final ITestResult result) 79 { 80 Throwable throwable = result.getThrowable(); 81 String stackTrace = null; 82 83 if((ITestResult.FAILURE == result.getStatus()) 84 || (ITestResult.SUCCESS_PERCENTAGE_FAILURE == result.getStatus())) { 85 StringWriter sw = new StringWriter(); 86 PrintWriter pw = new PrintWriter(sw); 87 Throwable cause= throwable; 88 if (null != cause) { 89 cause.printStackTrace(pw); 90 stackTrace = sw.getBuffer().toString(); 91 } 92 else { 93 stackTrace= "unknown stack trace"; 94 } 95 } 96 else if(ITestResult.SKIP == result.getStatus() 97 && (throwable != null && SkipException.class.isAssignableFrom(throwable.getClass()))) { 98 stackTrace= throwable.getMessage(); 99 } else if (throwable != null) { 100 StringWriter sw = new StringWriter(); 101 PrintWriter pw = new PrintWriter(sw); 102 throwable.printStackTrace(pw); 103 stackTrace = sw.toString(); 104 } 105 106 init(MessageHelper.TEST_RESULT + result.getStatus(), 107 suiteName, 108 testName, 109 result.getTestClass().getName(), 110 result.getMethod().getMethod().getName(), 111 MessageHelper.replaceUnicodeCharactersWithAscii(stackTrace), 112 result.getStartMillis(), 113 result.getEndMillis(), 114 toString(result.getParameters(), result.getMethod().getMethod().getParameterTypes()), 115 toString(result.getMethod().getMethod().getParameterTypes()), 116 MessageHelper.replaceUnicodeCharactersWithAscii(result.getName()), 117 MessageHelper.replaceUnicodeCharactersWithAscii(result.getInstanceName()), 118 result.getMethod().getInvocationCount(), 119 result.getMethod().getCurrentInvocationCount() 120 ); 121 } 122 TestResultMessage(final ITestContext testCtx, final ITestResult result)123 public TestResultMessage(final ITestContext testCtx, final ITestResult result) { 124 this(testCtx.getSuite().getName(), testCtx.getCurrentXmlTest().getName(), result); 125 // this(testCtx.getSuite().getName(), 126 // result.getTestName() != null ? result.getTestName() : result.getName(), result); 127 } 128 init(final int resultType, final String suiteName, final String testName, final String className, final String methodName, final String stackTrace, final long startMillis, final long endMillis, final String[] parameters, final String[] types, final String testDescription, String instanceName, int invocationCount, int currentInvocationCount)129 private void init(final int resultType, 130 final String suiteName, 131 final String testName, 132 final String className, 133 final String methodName, 134 final String stackTrace, 135 final long startMillis, 136 final long endMillis, 137 final String[] parameters, 138 final String[] types, 139 final String testDescription, 140 String instanceName, 141 int invocationCount, 142 int currentInvocationCount) { 143 m_messageType = resultType; 144 m_suiteName = suiteName; 145 m_testName = testName; 146 m_testClassName = className; 147 m_testMethodName = methodName; 148 m_stackTrace = stackTrace; 149 m_startMillis= startMillis; 150 m_endMillis= endMillis; 151 m_parameters= parameters; 152 m_paramTypes= types; 153 m_testDescription= testDescription; 154 m_invocationCount = invocationCount; 155 m_currentInvocationCount = currentInvocationCount; 156 m_instanceName = instanceName; 157 } 158 getResult()159 public int getResult() { 160 return m_messageType; 161 } 162 163 @Override getMessageAsString()164 public String getMessageAsString() { 165 StringBuffer buf = new StringBuffer(); 166 StringBuffer parambuf = new StringBuffer(); 167 168 if(null != m_parameters && m_parameters.length > 0) { 169 for (int j = 0; j < m_parameters.length; j++) { 170 if (j > 0) { 171 parambuf.append(MessageHelper.PARAM_DELIMITER); 172 } 173 parambuf.append(m_paramTypes[j] + ":" + m_parameters[j]); 174 } 175 } 176 177 buf.append(m_messageType) 178 .append(MessageHelper.DELIMITER) 179 .append(m_suiteName) 180 .append(MessageHelper.DELIMITER) 181 .append(m_testName) 182 .append(MessageHelper.DELIMITER) 183 .append(m_testClassName) 184 .append(MessageHelper.DELIMITER) 185 .append(m_testMethodName) 186 .append(MessageHelper.DELIMITER) 187 .append(parambuf) 188 .append(MessageHelper.DELIMITER) 189 .append(m_startMillis) 190 .append(MessageHelper.DELIMITER) 191 .append(m_endMillis) 192 .append(MessageHelper.DELIMITER) 193 .append(MessageHelper.replaceNewLine(m_stackTrace)) 194 .append(MessageHelper.DELIMITER) 195 .append(MessageHelper.replaceNewLine(m_testDescription)) 196 ; 197 198 return buf.toString(); 199 } 200 getSuiteName()201 public String getSuiteName() { 202 return m_suiteName; 203 } 204 getTestClass()205 public String getTestClass() { 206 return m_testClassName; 207 } 208 getMethod()209 public String getMethod() { 210 return m_testMethodName; 211 } 212 getName()213 public String getName() { 214 return m_testName; 215 } 216 getStackTrace()217 public String getStackTrace() { 218 return m_stackTrace; 219 } 220 getEndMillis()221 public long getEndMillis() { 222 return m_endMillis; 223 } 224 getStartMillis()225 public long getStartMillis() { 226 return m_startMillis; 227 } 228 getParameters()229 public String[] getParameters() { 230 return m_parameters; 231 } 232 getParameterTypes()233 public String[] getParameterTypes() { 234 return m_paramTypes; 235 } 236 getTestDescription()237 public String getTestDescription() { 238 return m_testDescription; 239 } 240 toDisplayString()241 public String toDisplayString() { 242 StringBuffer buf= new StringBuffer(m_testName != null ? m_testName : m_testMethodName); 243 244 if(null != m_parameters && m_parameters.length > 0) { 245 buf.append("("); 246 for(int i= 0; i < m_parameters.length; i++) { 247 if(i > 0) { 248 buf.append(", "); 249 } 250 if("java.lang.String".equals(m_paramTypes[i]) && !("null".equals(m_parameters[i]) || "\"\"".equals(m_parameters[i]))) { 251 buf.append("\"").append(m_parameters[i]).append("\""); 252 } 253 else { 254 buf.append(m_parameters[i]); 255 } 256 257 } 258 buf.append(")"); 259 } 260 261 return buf.toString(); 262 } 263 264 @Override equals(Object o)265 public boolean equals(Object o) { 266 if(this == o) { 267 return true; 268 } 269 if(o == null || getClass() != o.getClass()) { 270 return false; 271 } 272 273 final TestResultMessage that = (TestResultMessage) o; 274 275 if(m_suiteName != null ? !m_suiteName.equals(that.m_suiteName) : that.m_suiteName != null) { 276 return false; 277 } 278 if(m_testName != null ? !m_testName.equals(that.m_testName) : that.m_testName != null) { 279 return false; 280 } 281 if(m_testClassName != null ? !m_testClassName.equals(that.m_testClassName) : that.m_testClassName != null) { 282 return false; 283 } 284 String toDisplayString= toDisplayString(); 285 if(toDisplayString != null ? !toDisplayString.equals(that.toDisplayString()) : that.toDisplayString() != null) { 286 return false; 287 } 288 289 return true; 290 } 291 292 @Override hashCode()293 public int hashCode() { 294 int result = (m_suiteName != null ? m_suiteName.hashCode() : 0); 295 result = 29 * result + (m_testName != null ? m_testName.hashCode() : 0); 296 result = 29 * result + m_testClassName.hashCode(); 297 result = 29 * result + toDisplayString().hashCode(); 298 return result; 299 } 300 toString(Object[] objects, Class<?>[] objectClasses)301 String[] toString(Object[] objects, Class<?>[] objectClasses) { 302 if(null == objects) { 303 return new String[0]; 304 } 305 List<String> result= Lists.newArrayList(objects.length); 306 for(Object o: objects) { 307 if(null == o) { 308 result.add("null"); 309 } 310 else if (o.getClass().isArray()) { 311 String[] strArray; 312 if (o.getClass().getComponentType().isPrimitive()){ 313 strArray = primitiveArrayToString(o); 314 } else { 315 strArray = toString((Object[]) o, null); 316 } 317 StringBuilder sb = new StringBuilder("["); 318 for (int i = 0; i < strArray.length; i++) 319 { 320 sb.append(strArray[i]); 321 if (i + 1 < strArray.length) 322 { 323 sb.append(","); 324 } 325 } 326 sb.append("]"); 327 result.add(sb.toString()); 328 } 329 else { 330 String tostring= o.toString(); 331 if(isStringEmpty(tostring)) { 332 result.add("\"\""); 333 } 334 else { 335 result.add(MessageHelper.replaceNewLine(tostring)); 336 } 337 } 338 } 339 340 return result.toArray(new String[result.size()]); 341 } 342 primitiveArrayToString(Object o)343 private String[] primitiveArrayToString(Object o) { 344 List<String> results = Lists.newArrayList(); 345 if (o instanceof byte[]) { 346 byte[] array = (byte[]) o; 347 for (byte anArray : array) { 348 results.add(String.valueOf(anArray)); 349 } 350 } else if (o instanceof boolean[]) { 351 boolean[] array = (boolean[]) o; 352 for (boolean anArray : array) { 353 results.add(String.valueOf(anArray)); 354 } 355 } else if (o instanceof char[]) { 356 char[] array = (char[]) o; 357 for (char anArray : array) { 358 results.add(String.valueOf(anArray)); 359 } 360 } else if (o instanceof double[]) { 361 double[] array = (double[]) o; 362 for (double anArray : array) { 363 results.add(String.valueOf(anArray)); 364 } 365 } else if (o instanceof float[]) { 366 float[] array = (float[]) o; 367 for (float anArray : array) { 368 results.add(String.valueOf(anArray)); 369 } 370 } else if (o instanceof short[]) { 371 short[] array = (short[]) o; 372 for (short anArray : array) { 373 results.add(String.valueOf(anArray)); 374 } 375 } else if (o instanceof int[]) { 376 int[] array = (int[]) o; 377 for (int anArray : array) { 378 results.add(String.valueOf(anArray)); 379 } 380 } else if (o instanceof long[]) { 381 long[] array = (long[]) o; 382 for (long anArray : array) { 383 results.add(String.valueOf(anArray)); 384 } 385 } 386 return results.toArray(new String[results.size()]); 387 } 388 toString(Class<?>[] classes)389 private String[] toString(Class<?>[] classes) { 390 if(null == classes) { 391 return new String[0]; 392 } 393 List<String> result= Lists.newArrayList(classes.length); 394 for(Class<?> cls: classes) { 395 result.add(cls.getName()); 396 } 397 398 return result.toArray(new String[result.size()]); 399 } 400 extractParamTypes(String[] params)401 private String[] extractParamTypes(String[] params) { 402 List<String> result= Lists.newArrayList(params.length); 403 for(String s: params) { 404 result.add(s.substring(0, s.indexOf(':'))); 405 } 406 407 return result.toArray(new String[result.size()]); 408 } 409 extractParams(String[] params)410 private String[] extractParams(String[] params) { 411 List<String> result= Lists.newArrayList(params.length); 412 for(String s: params) { 413 result.add(MessageHelper.replaceNewLineReplacer(s.substring(s.indexOf(':') + 1))); 414 } 415 416 return result.toArray(new String[result.size()]); 417 } 418 getInvocationCount()419 public int getInvocationCount() { 420 return m_invocationCount; 421 } 422 getCurrentInvocationCount()423 public int getCurrentInvocationCount() { 424 return m_currentInvocationCount; 425 } 426 427 @Override toString()428 public String toString() { 429 return "[TestResultMessage suite:" + m_suiteName + " test:" + m_testName 430 + " method:" + m_testMethodName 431 + "]"; 432 } 433 setParameters(String[] params)434 public void setParameters(String[] params) { 435 m_parameters = extractParams(params); 436 m_paramTypes = extractParamTypes(params); 437 } 438 getInstanceName()439 public String getInstanceName() { 440 return m_instanceName; 441 } 442 } 443