/******************************************************************************* * Copyright (c) 2005, 2007 Oracle. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0, which accompanies this distribution * and is available at http://www.eclipse.org/legal/epl-v10.html. * * Contributors: * Oracle - initial API and implementation ******************************************************************************/ package org.eclipse.jpt.utility.tests.internal; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import junit.framework.TestCase; import junit.framework.TestFailure; import junit.framework.TestResult; /** * various tools that can be used by test cases */ public final class TestTools { /** * test an object's implementation of Serializable by serializing the * specified object to a byte array; then de-serializing the byte array and * returning the resultant object */ public static T serialize(T o) throws IOException, ClassNotFoundException { ByteArrayOutputStream baOutStream = new ByteArrayOutputStream(2000); ObjectOutputStream outStream = new ObjectOutputStream(baOutStream); outStream.writeObject(o); outStream.close(); ByteArrayInputStream baInStream = new ByteArrayInputStream(baOutStream.toByteArray()); ObjectInputStream inStream = new ObjectInputStream(baInStream); T o2 = readObject(inStream); inStream.close(); return o2; } @SuppressWarnings("unchecked") private static T readObject(ObjectInput objectInput) throws IOException, ClassNotFoundException { return (T) objectInput.readObject(); } /** * redirect std out and std err to the specified stream */ public static void redirectSystemStreamsTo(OutputStream outputStream) { redirectSystemStreamsTo(new PrintStream(outputStream)); } /** * redirect std out and std err to the specified stream */ public static void redirectSystemStreamsTo(PrintStream printStream) { System.setOut(printStream); System.setErr(printStream); } /** * execute the specified test and dump the results to the console */ public static String execute(TestCase testCase) { long start = System.currentTimeMillis(); TestResult result = testCase.run(); long end = System.currentTimeMillis(); StringWriter stringWriter = new StringWriter(); PrintWriter writer = new PrintWriter(stringWriter); writer.print(testCase.getName()); writer.print(": "); if (result.wasSuccessful()) { writer.println("OK"); } else { TestFailure failure = null; if (result.failures().hasMoreElements()) { failure = (TestFailure) result.failures().nextElement(); } else { failure = (TestFailure) result.errors().nextElement(); } failure.thrownException().printStackTrace(writer); } writer.print("elapsed time: "); long elapsed = end - start; writer.print(elapsed / 1000L); writer.println(" sec."); return stringWriter.toString(); } private static final Class TestCase_class = TestCase.class; /** * Clear out all the instance variable of the specified test case, allowing * the various test fixtures to be garbage-collected. Typically this is * called in the #tearDown() method. */ public static void clear(TestCase testCase) throws IllegalAccessException { for (Class tempClass = testCase.getClass(); tempClass != TestCase_class; tempClass = tempClass.getSuperclass()) { Field[] fields = tempClass.getDeclaredFields(); for (int i = fields.length; i-- > 0;) { Field field = fields[i]; // leave primitives alone - they don't get garbage-collected, and we can't set them to null... if (field.getType().isPrimitive()) { continue; } // leave static fields alone (?) if (Modifier.isStatic(field.getModifiers())) { continue; } field.setAccessible(true); field.set(testCase, null); } } } /** * Workaround for a JUnit bug: JUnit does not configure the testing Thread * with a context class loader. This should probably happen in * TestRunner.doRunTest(Test), just before starting the thread. */ public static void setUpJUnitThreadContextClassLoader() { Thread.currentThread().setContextClassLoader(TestTools.class.getClassLoader()); } private TestTools() { super(); throw new UnsupportedOperationException(); } }