package com.ibm.tck.client; /* * Licensed Materials - Property of IBM, * (c) Copyright IBM Corp. 2003 All Rights Reserved */ import java.io.*; import java.util.*; /** * The main entry point for all tests. * TestRunner has the following sequence.<br> * <UL> * <LI>invoked with main(), if the first arg is -noserver, simply run tests and write to stdout (useful for debugging)</LI> * <LI>load 'testres' resource file (In DataOutputStream format)</LI> * <LI>load client communication class name</LI> * <LI>load test server URL for results</LI> * <LI>load test server URL for interactive tests</LI> * <LI>load number of tests</LI> * <LI>load each test name and store</LI> * <LI>load number of excludes</LI> * <LI>load each exclude test name and store</LI> * <LI>load all options set for this test run</LI> * <LI>close resource file</LI> * <LI>for each test name * <UL> * <LI>lookup class and instantiate</LI> * <LI>call runTests()</LI> * <LI>runTests() runs each test in a test checking first to see if it excluded</LI> * <LI>results are sent back to the server (if not -noserver)</LI> * </UL> * <LI>done</LI> * </UL> * One difference is that if the TestRunner is invoked by the TCKMidlet, an object * representing the MIDlet is set in the runner. Any <code>TestCase</code> can * cast the result of <code>getMidlet()</code> to a MIDlet if they know they * are running on MIDP. * */ public final class TestRunner { private Object midlet; private String serverURL; private String interactiveURL; private String clientClass; private Vector excludes; private Hashtable options = new Hashtable(); private Vector testClasses; private Vector filters; static private boolean noserver = false; private ByteArrayOutputStream testResults; private ByteArrayOutputStream output; private ClientConnection clientConnection; private int _passed, _failed, _excluded; /** * main() should be invoded with no arguments. If -noserver is passed as the first argument, no attempt * is made to send the results back to a server. This is useful for testing individual * tests. * * @param args string array of args but only supported option is -noserver indicating whether or not to send results back to server. */ public static void main(String[] args) { if (args.length > 0) { if (args[0].toLowerCase().equals("-noserver")) noserver = true; else { System.out.println("Only option is [-noserver]"); } } new TestRunner(); } /** * Constructor for TestRunner. */ public TestRunner() { excludes = new Vector(1); testClasses = new Vector(1); filters = new Vector(1); testResults = new ByteArrayOutputStream(); output = new ByteArrayOutputStream(); run(); } /** * Constructor for TestRunner. * * @param midlet An object representing the MIDlet the TestRunner is running on. */ public TestRunner(Object midlet) { excludes = new Vector(1); testClasses = new Vector(1); filters = new Vector(1); testResults = new ByteArrayOutputStream(); output = new ByteArrayOutputStream(); this.midlet = midlet; run(); } /** * Answer a boolean if testName, comprised of a full class name and test description, * is excluded. * * @param testName the fully qualified name * @return a boolean indicating whether or not a testName is excluded */ public boolean isExcluded(String testName) { boolean result = excludes.contains(testName); if (result) _excluded++; return result; } /** * Answer a boolean if testName, comprised of a full class name and test description, * is included based on current filter settings. * * @param testName the fully qualified name * @return boolean indicating whether or not a testName is filtered */ public boolean isFiltered(String testName) { if(filters.size() == 0) return true; for(int i = 0; i<filters.size(); i++) { if(testName.indexOf((String)filters.elementAt(i)) != -1) return true; } return false; } protected void postResults(String testName, boolean passed, String description, String testLog, long elapsedTime) { System.out.print(testName); if (passed) _passed++; else _failed++; System.out.print(passed ? " passed (" : " failed ("); System.out.print(description); System.out.println(")"); if (testLog.length() > 0 && !passed) { System.out.print("TESTLOG: "); System.out.println(testLog); } if (!noserver) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dataOutput = new DataOutputStream(baos); dataOutput.writeUTF(testName); dataOutput.writeBoolean(passed); dataOutput.writeUTF(description); dataOutput.writeUTF(testLog); dataOutput.writeLong(elapsedTime); dataOutput.close(); clientConnection.postData(serverURL, baos.toByteArray()); } catch (Exception e) { System.out.println("Error in assertTrue()"); System.out.println("Exception " + e); } } } protected Hashtable getOptions() { return options; } protected Object getMidlet() { return midlet; } protected void postMessage(String testName, String description) { System.out.print(testName); System.out.println(" Interactive request:"); System.out.println(description); if (noserver) { System.out.println("Error, there is no server specified"); return; } else { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dataOutput = new DataOutputStream(baos); dataOutput.writeUTF(testName); dataOutput.writeUTF(description); dataOutput.close(); clientConnection.postData(interactiveURL, baos.toByteArray()); } catch (Exception e) { System.out.println("Error in assertTrue()"); System.out.println("Exception " + e); } } } private void run() { // if (!loadTestResources()) return; loadHardcodedTestResources(); if (!noserver) { try { Class clazz = Class.forName(clientClass); clientConnection = (ClientConnection) clazz.newInstance(); } catch (Throwable e) { System.out.println("Connection class " + clientClass + " cannot be instantiated"); return; } } Enumeration e = testClasses.elements(); while (e.hasMoreElements()) { String className = (String) e.nextElement(); Class testClass=null; try { testClass = Class.forName(className); TestCase tests = (TestCase) testClass.newInstance(); tests.testRunner(this); tests.runTests(); } catch (Exception testException) { System.out.println("Exception running test " + className); System.out.println(testException); return; } } StringBuffer results = new StringBuffer(); results.append(_passed + _failed + _excluded); results.append(" tests, "); results.append(_passed); results.append(" passed, "); results.append(_excluded); results.append(" excluded, "); results.append(_failed); results.append(" failed\r\n"); if (_failed == 0) results.append("All Tests Passed"); else results.append("There were test failures"); System.out.println(results); } private boolean loadTestResources() { InputStream res = this.getClass().getResourceAsStream("/testres"); if (res == null) { System.out.println("Could not find TestRunner resource file, exiting..."); return false; } // Any exceptions result in test failure try { DataInputStream dis = new DataInputStream(res); // Get the Client Class to use as a connection clientClass = dis.readUTF(); // Get the server URL to write results to serverURL = dis.readUTF(); // Get the server URL for interactive tests interactiveURL = dis.readUTF(); // Get the number of tests classes int testClassCount = dis.readInt(); // Load all the testClass names while (testClassCount-- > 0) { testClasses.addElement(dis.readUTF()); } int excludeCount = dis.readInt(); // Load all the testClass names while (excludeCount-- > 0) { excludes.addElement(dis.readUTF()); } // Load the number of options int optionCount = dis.readInt(); while (optionCount-- > 0) { String key = dis.readUTF(); String value = dis.readUTF(); options.put(key, value); } //Load the test filters int filterCount = dis.readInt(); while(filterCount-- > 0) { filters.addElement(dis.readUTF()); } res.close(); } catch (IOException e) { System.out.println("Resource file contains errors, exiting..."); return false; } return true; } private void loadHardcodedTestResources() { testClasses.addElement("com.ibm.tck.javax.microedition.io.file.ConnectionClosedException.Init"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.AvailableSize"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.CanRead"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.CanWrite"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.Create"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.Delete"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.DirectorySize"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.Exists"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.FileSize"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.GetName"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.GetPath"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.GetURL"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.IsDirectory"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.IsHidden"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.LastModified"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.List"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.Mkdir"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.Open"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.OpenDataInputStream"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.OpenDataOutputStream"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.OpenInputStream"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.OpenOutputStream"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.OpenOutputStream_Long"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.PackageDiscovery"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.Rename"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetFileConnection"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetHidden"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetReadable"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetWritable"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.TotalSize"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.Truncate"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.UsedSize"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileSystemListener.RootChanged"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileSystemRegistry.AddFileSystemListener"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileSystemRegistry.ListRoots"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.FileSystemRegistry.RemoveFileSystemListener"); testClasses.addElement("com.ibm.tck.javax.microedition.io.file.IllegalModeException.Init"); // Exclude these methods because they rely on functionality // that we haven't yet implemented. We should implement it! excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.AvailableSize#test0001"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.AvailableSize#test0006"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.AvailableSize#test0007"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.CanRead#test0002"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.CanRead#test0004"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.CanWrite#test0002"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.CanWrite#test0004"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.DirectorySize#test0002"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.DirectorySize#test0003"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.DirectorySize#test0004"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.IsHidden#test0001"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.IsHidden#test0003"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.IsHidden#test0007"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.IsHidden#test0008"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.LastModified#test0002"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.LastModified#test0004"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.List#test0003"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.List#test0003"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.List#test0006"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.List#test0006"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetHidden#test0001"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetHidden#test0002"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetHidden#test0005"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetHidden#test0006"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetHidden#test0008"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetHidden#test0009"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetHidden#test0010"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetHidden#test0011"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetHidden#test0012"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetHidden#test0013"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetReadable#test0001"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetReadable#test0002"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetWritable#test0001"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.SetWritable#test0002"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.TotalSize#test0001"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.TotalSize#test0003"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileConnection.UsedSize#test0001"); // Exclude these methods because they rely on the server-based // interactive mode of the test runner, which we don't support. // We should figure out how to make them non-interactive! excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileSystemRegistry.AddFileSystemListener#test0001"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileSystemRegistry.ListRoots#test0001"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileSystemRegistry.ListRoots#test0002"); excludes.addElement("com.ibm.tck.javax.microedition.io.file.FileSystemRegistry.RemoveFileSystemListener#test0001"); options.put("FilesystemTestPath", "//tcktestdir/"); } }