From a303931ebcf72494bdb75395b350ff640a0ff1f3 Mon Sep 17 00:00:00 2001 From: Andy Clement Date: Wed, 23 Jan 2019 19:45:07 -0800 Subject: mavenizing testing-client module - wip --- .../src/main/java/org/aspectj/testing/Tester.java | 981 +++++++++++++++++++++ .../org/aspectj/testing/server/TestServer.java | 188 ++++ testing-client/src/org/aspectj/testing/Tester.java | 981 --------------------- .../src/org/aspectj/testing/server/TestServer.java | 188 ---- .../test/java/org/aspectj/testing/TesterTest.java | 239 +++++ .../aspectj/testing/TestingClientModuleTests.java | 30 + .../java/org/aspectj/testing/TestingTests.java | 35 + .../org/aspectj/testing/server/TestServerTest.java | 40 + 8 files changed, 1513 insertions(+), 1169 deletions(-) create mode 100644 testing-client/src/main/java/org/aspectj/testing/Tester.java create mode 100644 testing-client/src/main/java/org/aspectj/testing/server/TestServer.java delete mode 100644 testing-client/src/org/aspectj/testing/Tester.java delete mode 100644 testing-client/src/org/aspectj/testing/server/TestServer.java create mode 100644 testing-client/src/test/java/org/aspectj/testing/TesterTest.java create mode 100644 testing-client/src/test/java/org/aspectj/testing/TestingClientModuleTests.java create mode 100644 testing-client/src/test/java/org/aspectj/testing/TestingTests.java create mode 100644 testing-client/src/test/java/org/aspectj/testing/server/TestServerTest.java (limited to 'testing-client/src') diff --git a/testing-client/src/main/java/org/aspectj/testing/Tester.java b/testing-client/src/main/java/org/aspectj/testing/Tester.java new file mode 100644 index 000000000..500c4c363 --- /dev/null +++ b/testing-client/src/main/java/org/aspectj/testing/Tester.java @@ -0,0 +1,981 @@ +/* ******************************************************************* + * Copyright (c) 1999-2000 Xerox Corporation. + * 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: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.testing; + +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.bridge.Message; +import org.aspectj.util.LangUtil; + +import java.util.*; +import java.io.*; + +/** + * Testing client interface for checking results and reporting + * to a delegate IMessageHandler. + * Harnesses providing this interface for test clients must + * set it up by calling + * {@link #setBASEDIR(File)} + * {@link #setMessageHandler(IMessageHandler)} and + * {@link #clear()} for each test, as appropriate. + * (That means that IMessageHandler must be loaded from a class + * loader common to the harness and Tester.) + * If clients submit a failing check, this registers the message + * and throws an AbortException holding the message; this + * AbortException will not have the correct stack trace; + * all the information should be encoded in the message. + * Find any original exception thrown in the message itself. + */ + // XXX consider creating exception for new API throwFailure(String m) +public class Tester { + /** delegate for reporting results */ + private static IMessageHandler messageHandler; + + /** base directory for calculating relative paths to event files */ + private static File BASEDIR; + + /** + * collection of notes submitted + */ + private static Set notes; + + /** List to hold events submitted. */ + private static List actualEvents = new ArrayList<>(); + + /** List to hold events we expect. */ + private static List expectedEvents = new ArrayList<>(); + + static { + setBASEDIR(new File(".")); + setMessageHandler(IMessageHandler.SYSTEM_ERR); + clear(); + } + + /** + * Set directory used for calculating relative paths + * (currently only to an events file) + * @param baseDir the File for an existing directory + */ + public static void setBASEDIR(File baseDir) { + if (null == baseDir) throw new IllegalArgumentException("null baseDir"); + if (!baseDir.isDirectory()) throw new IllegalArgumentException("not a directory: " + baseDir); + BASEDIR = baseDir; + } + + public static File getBASEDIR() { + return BASEDIR; + } + + + /** + * Set the message handler used for this Tester. + * When given a message of kind FAIL, this handler + * must complete abruptly or return false (i.e., not handled completely) + * so the Tester throws an AbortException. + * @see checkFailed(..). + */ + public static void setMessageHandler(IMessageHandler handler) { + if (null == handler) throw new IllegalArgumentException("null handler"); + if (messageHandler != handler) messageHandler = handler; + } + + + public static void clear() { + clearNotes(); + clearEvents(); + } + + /** XXX deprecated #clear() */ + public static void clearNotes() { + notes = new HashSet(); + } + + /** XXX deprecated #clear() */ + public static void clearEvents() { + actualEvents = new ArrayList<>(); + expectedEvents = new ArrayList<>(); + } + + + /** Add an actual event */ + public static void event(String s) { + actualEvents.add(s); + } + + /** + * Add a note to {@link #notes}. + * @param note Message to add. + * XXX deprecated event(String) + */ + public static void note(Object note) { + notes.add(note); + } + + /** + * Checks that note was added using {@link #note}, + * and fails using note.toString() is it wasn't found. + * + * @param note Message that should've been added using {@link #note}. + * XXX deprecated checkEvent(String) + */ + public static void check(Object note) { + check(note, "expected note \"" + note.toString() + "\""); + } + + /** + * Checks that note was added using {@link #note}, + * and fails using message is it wasn't found. + * + * @param note Message that should've been added using {@link #note}. + * @param message Message with which to fail if node + * wasn't added. + */ + public static void check(Object note, String message) { + check(notes.contains(note), message); + } + + /** + * Reports that t shouldn't have been thrown. + * using t as the message. + * + * @param t Thrown exception. + * @see #throwable(Throwable,String) + */ + public static void throwable(Throwable t) { + throwable(t, null); + } + + + /** + * Reports that t shouldn't have been thrown. + * using msg as the message. + * + * @param thrown Thrown exception. + * @param msg Message with which to report error. + */ + public static void throwable(Throwable thrown, String msg) { + handle(msg, thrown, true); + } + + /** + * Report the error message unconditionally. + * + * @param message Error to report. + */ + public static void checkFailed(String message) { + handle(message, null, true); + } + + /** + * Check that expectedNotes is equal to {@link #notes} + * , fail with msg and create a new instance of {@link #notes}. + * NOTE: expectedNotes is a String, so + * it must match with {@link java.util.HashSet#toString()}. + * + * @param expectedNotes String we expect + * {@link #notes} to match. + * @param msg Message with which to fail. + */ + public static void checkAndClear(String expectedNotes, String msg) { + checkEqual(notes, expectedNotes, msg); + clearNotes(); + } + + /** + * Reports an error using message if + * test == false. + * + * @param test Determines whether we call {@link #checkFailed}. + * @param message Message to pass {@link #checkFailed} if + * test == false. + */ + public static void check(boolean test, String message) { + if (!test) checkFailed(message); + } + + /** + * Checks that the values of value and + * expectedValue are equal. Both or either + * can be null. Calls {@link #checkFailed} with message + * if the arrays aren't equal. + * + * @param value One test set. + * @param expectedValue The other test set. + * @param message Message with which to fail. + */ + public static void checkEqual(Object[] value, + Object[] expectedValue, + String message) + { + if (value == null) { + if (expectedValue == null) return; + checkFailed(message+" null array found"); + return; + } + int n = value.length; + if (n != expectedValue.length) { + checkFailed(message+" expected array of length "+expectedValue.length + +" got "+ n); + return; + } + for(int i=0; is == t. + * + * @param s a known value. + * @param t another known value. + */ + public static void checkNotEqual(boolean s, boolean t) { + checkNotEqual(s, t, s + " shouldn't equal " + t); + } + /** + * Fails with message msg if s == t. + * + * @param s a known value. + * @param t another known value. + * @param msg the failure message. + */ + public static void checkNotEqual(boolean s, boolean t, String msg) { + if (s == t) checkFailed(msg); + } + + /** + * Fails if s == t. + * + * @param s a known value. + * @param t another known value. + */ + public static void checkNotEqual(byte s, byte t) { + checkNotEqual(s, t, s + " shouldn't equal " + t); + } + /** + * Fails with message msg if s == t. + * + * @param s a known value. + * @param t another known value. + * @param msg the failure message. + */ + public static void checkNotEqual(byte s, byte t, String msg) { + if (s == t) checkFailed(msg); + } + + /** + * Fails if s == t. + * + * @param s a known value. + * @param t another known value. + */ + public static void checkNotEqual(char s, char t) { + checkNotEqual(s, t, s + " shouldn't equal " + t); + } + /** + * Fails with message msg if s == t. + * + * @param s a known value. + * @param t another known value. + * @param msg the failure message. + */ + public static void checkNotEqual(char s, char t, String msg) { + if (s == t) checkFailed(msg); + } + + /** + * Fails if s == t. + * + * @param s a known value. + * @param t another known value. + */ + public static void checkNotEqual(short s, short t) { + checkNotEqual(s, t, s + " shouldn't equal " + t); + } + /** + * Fails with message msg if s == t. + * + * @param s a known value. + * @param t another known value. + * @param msg the failure message. + */ + public static void checkNotEqual(short s, short t, String msg) { + if (s == t) checkFailed(msg); + } + + /** + * Fails if s == t. + * + * @param s a known value. + * @param t another known value. + */ + public static void checkNotEqual(int s, int t) { + checkNotEqual(s, t, s + " shouldn't equal " + t); + } + /** + * Fails with message msg if s == t. + * + * @param s a known value. + * @param t another known value. + * @param msg the failure message. + */ + public static void checkNotEqual(int s, int t, String msg) { + if (s == t) checkFailed(msg); + } + + /** + * Fails if s == t. + * + * @param s a known value. + * @param t another known value. + */ + public static void checkNotEqual(long s, long t) { + checkNotEqual(s, t, s + " shouldn't equal " + t); + } + /** + * Fails with message msg if s == t. + * + * @param s a known value. + * @param t another known value. + * @param msg the failure message. + */ + public static void checkNotEqual(long s, long t, String msg) { + if (s == t) checkFailed(msg); + } + + /** + * Fails if s == t. + * + * @param s a known value. + * @param t another known value. + */ + public static void checkNotEqual(float s, float t) { + checkNotEqual(s, t, s + " shouldn't equal " + t); + } + /** + * Fails with message msg if s == t. + * + * @param s a known value. + * @param t another known value. + * @param msg the failure message. + */ + public static void checkNotEqual(float s, float t, String msg) { + if (s == t) checkFailed(msg); + } + + /** + * Fails if s == t. + * + * @param s a known value. + * @param t another known value. + */ + public static void checkNotEqual(double s, double t) { + checkNotEqual(s, t, s + " shouldn't equal " + t); + } + /** + * Fails with message msg if s == t. + * + * @param s a known value. + * @param t another known value. + * @param msg the failure message. + */ + public static void checkNotEqual(double s, double t, String msg) { + if (s == t) checkFailed(msg); + } + + /** + * Fails if s == t. + * + * @param s a known value. + * @param t another known value. + */ + public static void checkNotEqual(Object s, Object t) { + checkNotEqual(s, t, s + " shouldn't equal " + t); + } + /** + * Fails with message msg if s == t + * or both s and t are null. + * + * @param s a known value. + * @param t another known value. + * @param msg the failure message. + */ + public static void checkNotEqual(Object s, Object t, String msg) { + if ((s != null && s.equals(t)) || + (t != null && t.equals(s)) || + (s == null && t == null)) { + checkFailed(msg); + } + } + + /** + * Compares value and expectedValue + * with failing message "compare". + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @see #checkEqual(int,int,String) + */ + public static void checkEqual(int value, int expectedValue) { + checkEqual(value, expectedValue, "compare"); + } + + /** + * Fails if the passed in value is null. + * + * @param o the expected non-null thing. + * @param name the name of o. + */ + public static void checkNonNull(Object o, String name) { + if (o == null) checkFailed(name + " shouldn't be null"); + } + + /** + * Compared value and expectedValue + * and fails with message if they aren't equal. + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @param msg Message with which to fail. + */ + public static void checkEqual(int value, int expectedValue, String message) { + if (value == expectedValue) return; + if (value < expectedValue) { + message = message+": "+value+" < "+expectedValue; + } else { + message = message+": "+value+" > "+expectedValue; + } + checkFailed(message); + } + + /** + * Compares value and expectedValue + * with failing message "compare". + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @see #checkEqual(float,float,String) + */ + public static void checkEqual(float value, float expectedValue) { + checkEqual(value, expectedValue, "compare"); + } + + /** + * Compared value and expectedValue + * and fails with message if they aren't equal. + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @param msg Message with which to fail. + */ + public static void checkEqual(float value, float expectedValue, String msg) { + if (Float.isNaN(value) && Float.isNaN(expectedValue)) return; + if (value == expectedValue) return; + if (value < expectedValue) { + msg = msg+": "+value+" < "+expectedValue; + } else { + msg = msg+": "+value+" > "+expectedValue; + } + checkFailed(msg); + } + + /** + * Compares value and expectedValue + * with failing message "compare". + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @see #checkEqual(long,long,String) + */ + public static void checkEqual(long value, long expectedValue) { + checkEqual(value, expectedValue, "compare"); + } + + /** + * Compared value and expectedValue + * and fails with message if they aren't equal. + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @param msg Message with which to fail. + */ + public static void checkEqual(long value, long expectedValue, String msg) { + if (value == expectedValue) return; + if (value < expectedValue) { + msg = msg+": "+value+" < "+expectedValue; + } else { + msg = msg+": "+value+" > "+expectedValue; + } + checkFailed(msg); + } + + /** + * Compares value and expectedValue + * with failing message "compare". + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @see #checkEqual(double,double,String) + */ + public static void checkEqual(double value, double expectedValue) { + checkEqual(value, expectedValue, "compare"); + } + + /** + * Compared value and expectedValue + * and fails with message if they aren't equal. + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @param msg Message with which to fail. + */ + public static void checkEqual(double value, double expectedValue, String msg) { + if (Double.isNaN(value) && Double.isNaN(expectedValue)) return; + if (value == expectedValue) return; + if (value < expectedValue) { + msg = msg+": "+value+" < "+expectedValue; + } else { + msg = msg+": "+value+" > "+expectedValue; + } + checkFailed(msg); + } + + /** + * Compares value and expectedValue + * with failing message "compare". + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @see #checkEqual(short,short,String) + */ + public static void checkEqual(short value, short expectedValue) { + checkEqual(value, expectedValue, "compare"); + } + + /** + * Compared value and expectedValue + * and fails with message if they aren't equal. + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @param msg Message with which to fail. + */ + public static void checkEqual(short value, short expectedValue, String msg) { + if (value == expectedValue) return; + if (value < expectedValue) { + msg = msg+": "+value+" < "+expectedValue; + } else { + msg = msg+": "+value+" > "+expectedValue; + } + checkFailed(msg); + } + + /** + * Compares value and expectedValue + * with failing message "compare". + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @see #checkEqual(byte,byte,String) + */ + public static void checkEqual(byte value, byte expectedValue) { + checkEqual(value, expectedValue, "compare"); + } + + /** + * Compares value and expectedValue + * with failing message msg. + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @param msg Message with which to fail. + */ + public static void checkEqual(byte value, byte expectedValue, String msg) { + if (value == expectedValue) return; + if (value < expectedValue) { + msg = msg+": "+value+" < "+expectedValue; + } else { + msg = msg+": "+value+" > "+expectedValue; + } + checkFailed(msg); + } + + /** + * Compares value and expectedValue + * with failing message "compare". + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @see #checkEqual(char,char,String) + */ + public static void checkEqual(char value, char expectedValue) { + checkEqual(value, expectedValue, "compare"); + } + + /** + * Compares value and expectedValue + * with failing message msg. + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @param msg Message with which to fail. + */ + public static void checkEqual(char value, char expectedValue, String msg) { + if (value == expectedValue) return; + if (value < expectedValue) { + msg = msg+": "+value+" < "+expectedValue; + } else { + msg = msg+": "+value+" > "+expectedValue; + } + checkFailed(msg); + } + + /** + * Compares value and expectedValue + * with failing message "compare". + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @see #checkEqual(boolean,boolean,String) + */ + public static void checkEqual(boolean value, boolean expectedValue) { + checkEqual(value, expectedValue, "compare"); + } + + /** + * Compares value and expectedValue + * with failing message msg. + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @param msg Message with which to fail. + */ + public static void checkEqual(boolean value, boolean expectedValue, String msg) { + if (value == expectedValue) return; + msg = msg+": "+value+" != "+expectedValue; + checkFailed(msg); + } + + /** + * Checks whether the entries of set are equal + * using equals to the corresponding String in + * expectedSet and fails with message msg. + * + * @param set Unkown set of values. + * @param expectedSet Expected String of values. + * @param msg Message with which to fail. + */ + public static void checkEqual(Collection set, String expectedSet, String msg) { + checkEqual(set, LangUtil.split(expectedSet), msg); + } + + /** + * Checks whether the entries of set are equal + * using equals to the corresponding entry in + * expectedSet and fails with message msg, + * except that duplicate actual entries are ignored. + * This issues fail messages for each failure; when + * aborting on failure, only the first will be reported. + * + * @param set Unkown set of values. + * @param expectedSet Expected String of values. + * @param msg Message with which to fail. + */ + public static void checkEqualIgnoreDups(Collection set, String[] expected, String msg, + boolean ignoreDups) { + String[] diffs = diffIgnoreDups(set, expected, msg, ignoreDups); + if (0 < diffs.length) { + check(false, "" + Arrays.asList(diffs)); + } +// for (int i = 0; i < diffs.length; i++) { +// check(false, diffs[i]); +// } + } + + /** @return String[] of differences '{un}expected msg "..." {not} found' */ + private static String[] diffIgnoreDups(Collection set, String[] expected, String msg, + boolean ignoreDups) { + ArrayList result = new ArrayList<>(); + ArrayList actual = new ArrayList<>(set); + BitSet hits = new BitSet(); + for (int i = 0; i < expected.length; i++) { + if (!actual.remove(expected[i])) { + result.add(" expected " + msg + " \"" + expected[i] + "\" not found"); + } else { + hits.set(i); + if (ignoreDups) { + while (actual.remove(expected[i])) ; // remove all instances of it + } + } + } + for (String act: actual) { + result.add(" unexpected " + msg + " \"" + act + "\" found"); + } + return (String[]) result.toArray(new String[0]); + } + + /** + * Checks whether the entries of set are equal + * using equals to the corresponding entry in + * expectedSet and fails with message msg. + * + * @param set Unkown set of values. + * @param expectedSet Expected String of values. + * @param msg Message with which to fail. + */ + public static void checkEqual(Collection set, String[] expected, String msg) { + checkEqualIgnoreDups(set, expected, msg, false); + } + + /** + * Compares value and expectedValue + * with failing message "compare". + * + * @param value Unkown value. + * @param expectedValue Expected value. + * @see #checkEqual(Object,Object,String) + */ + public static void checkEqual(Object value, Object expectedValue) { + checkEqual(value, expectedValue, "compare"); + } + + /** + * Checks whether the entries of set are equal + * using equals to the corresponding String in + * expectedSet and fails with message msg. + * + * @param set Unkown set of values. + * @param expectedSet Expected String of values. + * @param msg Message with which to fail. + */ + public static void checkEqual(Object value, Object expectedValue, String msg) { + if (value == null && expectedValue == null) return; + if (value != null && value.equals(expectedValue)) return; + msg = msg+": "+value+" !equals "+expectedValue; + checkFailed(msg); + } + + /** + * Checks whether the entries of set are equal + * using equals to the corresponding String in + * expectedSet and fails with message msg. + * + * @param set Unkown set of values. + * @param expectedSet Expected String of values. + * @param msg Message with which to fail. + */ + public static void checkEq(Object value, Object expectedValue, String msg) { + if (value == expectedValue) return; + msg = msg+": "+value+" != "+expectedValue; + checkFailed(msg); + } + + /** add expected events */ + public static void expectEvent(String s) { + if (null != s) { + expectedEvents.add(s); + } + } + + /** add expected events */ + public static void expectEvent(Object s) { + if (null != s) { + expectEvent(s.toString()); + } + } + + /** + * add expected events, parse out ; from string + * Expect those messages in s separated by + * ":;, ". + * + * @param s String containg delimited,expected messages. + */ + public static void expectEventsInString(String s) { + if (null != s) { + StringTokenizer tok = new StringTokenizer(s, ":;, "); + while (tok.hasMoreTokens()) { + expectEvent(tok.nextToken()); + } + } + } + + public static void expectEventsInString(String[] ra) { + expectEvents((Object[]) ra); + } + + /** add expected events */ + public static void expectEvents(Object[] events) { + if (null != events) { + for (int i = 0; i < events.length; i++) { + if (null != events[i]) { + expectEvent(events[i].toString()); + } + } + } + } + + /** add expected events */ + public static void expectEvents(String[] events) { + if (null != events) { + for (int i = 0; i < events.length; i++) { + if (null != events[i]) { + expectEvent(events[i].toString()); + } + } + } + } + + /** check actual and expected have same members */ + public static void checkAllEvents() { + checkAndClearEvents((String[]) expectedEvents.toArray(new String[0])); + } + + /** also ignore duplicate actual entries for expected */ + public static void checkAllEventsIgnoreDups() { + final boolean ignoreDups = true; + final String[] exp = (String[]) expectedEvents.toArray(new String[0]); + checkEqualIgnoreDups(actualEvents, exp, "event", ignoreDups); + clearEvents(); + } + + /** Check events, file is line-delimited. If there is a non-match, signalls + * a single error for the first event that does not match the next event in + * the file. The equivalence is {@link #checkEqualLists}. Blank lines are + * ignored. lines that start with '//' are ignored. */ + public static void checkEventsFromFile(String eventsFile) { + // XXX bug reads into current expected and checks all - separate read and check + try { + File file = new File(getBASEDIR(), eventsFile); // XXX TestDriver + BufferedReader in = new BufferedReader(new FileReader(file)); + //final File parentDir = (null == file? null : file.getParentFile()); + String line; + List expEvents = new ArrayList(); + while ((line = in.readLine()) != null) { + line = line.trim(); + if ((line.length() < 1) || (line.startsWith("//"))) continue; + expEvents.add(line); + } + checkEqualLists(actualEvents, expEvents, " from " + eventsFile); + } catch (IOException ioe) { + throwable(ioe); + } + } + + + /** Check to see that two lists of strings are the same. Order is important. + * Trimmable whitespace is not important. Case is important. + * + * @param actual one list to check + * @param expected another list + * @param message a context string for the resulting error message if the test fails. + */ + public static void checkEqualLists(List/*String*/ actual, List/*String*/ expected, + String message) { + Iterator a = actual.iterator(); + Iterator e = expected.iterator(); + int ai = 0; + int ei = 0; + for (; a.hasNext(); ) { + if (! e.hasNext()) { + checkFailed("unexpected [" + ai + "] \"" + a.next() + "\" " + message); + return; + } + String a0 = ((String) a.next()).trim(); + String e0 = ((String) e.next()).trim(); + if (! a0.equals(e0)) { + checkFailed("expected [" + ei + "] \"" + e0 + + "\"\n but found [" + ai + "] \"" + a0 + "\"\n " + message); + return; + } + ai++; + ei++; + } + while (e.hasNext()) { + checkFailed("expected [" + ei + "] \"" + e.next() + "\" " + message); + ei++; + } + } + + /** Check events, expEvents is space delimited */ + public static void checkEvents(String expEvents) { + checkEqual(actualEvents, expEvents, "event"); + } + + /** Check events, expEvents is an array */ + public static void checkEvents(String[] expEvents) { + checkEqual(actualEvents, expEvents, "event"); + } + + /** Check events and clear after check*/ + public static void checkAndClearEvents(String expEvents) { + checkEvents(expEvents); + clearEvents(); + } + + /** Check events and clear after check*/ + public static void checkAndClearEvents(String[] expEvents) { + checkEvents(expEvents); + clearEvents(); + } + + /** XXX deprecated */ + public static void printEvents() { // XXX no clients? + for (Iterator i = actualEvents.iterator(); i.hasNext(); ) { + System.out.println(i.next()); // XXX System.out + } + } + + /** + * Report an uncaught exeption as an error + * @param thrown Throwable to print. + * @see #maxStackTrace + */ + public void unexpectedExceptionFailure(Throwable thrown) { + handle("unexpectedExceptionFailure", thrown, true); + } + + /** + * Handle message by delegation to message handler, doing + * IMessage.FAIL if (fail || (thrown != null) and IMessage.INFO + * otherwise. + */ + + private static void handle(String message, Throwable thrown, boolean fail) { + final boolean failed = fail || (null != thrown); + IMessage.Kind kind = (failed ? IMessage.FAIL : IMessage.INFO); + IMessage m = new Message(message, kind, thrown, null); + /*final boolean handled = */messageHandler.handleMessage(m); + } +// private static void resofhandle(String message, Throwable thrown, boolean fail) { +// /* If FAIL and the message handler returns false (normally), +// * Then this preserves "abort" semantics by throwing an +// * abort exception. +// */ +// if (failed) { +// if (handled) { +// String s = "Tester expecting handler to return false or " +// + "complete abruptly when passed a fail, for " + m; +// m = new Message(s, IMessage.DEBUG, null, null); +// messageHandler.handleMessage(m); +// } else { +// throw AbortException.borrowPorter(m); +// } +// } +// } + +} diff --git a/testing-client/src/main/java/org/aspectj/testing/server/TestServer.java b/testing-client/src/main/java/org/aspectj/testing/server/TestServer.java new file mode 100644 index 000000000..80cbc357b --- /dev/null +++ b/testing-client/src/main/java/org/aspectj/testing/server/TestServer.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2006,2017 IBM Corporation and others. + * 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 + *******************************************************************************/ +package org.aspectj.testing.server; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.StringTokenizer; + +/** + * @author Matthew Webster + * @author Andy Clement + */ +public class TestServer implements Runnable { + + private static final boolean debug = Boolean.getBoolean("org.aspectj.testing.server.debug"); + + private boolean exitOnError = true; + private File workingDirectory; + private ClassLoader rootLoader; + private Map loaders = new HashMap<>(); + + private String mainClass = "UnknownClass"; + private String mainLoader = "UnknownLoader"; + + public void initialize () throws IOException { + createRootLoader(); + loadConfiguration(); + } + + private void loadConfiguration () throws IOException { + File file = new File(workingDirectory,"server.properties"); + Properties props = new Properties(); + FileInputStream in = new FileInputStream(file); + props.load(in); + in.close(); + + Enumeration enu = props.propertyNames(); + while (enu.hasMoreElements()) { + String key = (String)enu.nextElement(); + if (key.startsWith("loader.")) { + createLoader(props.getProperty(key)); + } + else if (key.equals("main")) { + StringTokenizer st = new StringTokenizer(props.getProperty(key),","); + mainClass = st.nextToken(); + mainLoader = st.nextToken(); + } + } + } + + private void createLoader (String property) throws IOException { + ClassLoader parent = rootLoader; + + StringTokenizer st = new StringTokenizer(property,","); + String name = st.nextToken(); + String classpath = st.nextToken(); + if (debug) System.err.println("Creating loader "+name+" with classpath "+classpath); + if (st.hasMoreTokens()) { + String parentName = st.nextToken(); + parent = (ClassLoader)loaders.get(parentName); + if (parent == null) error("No such loader: " + parentName); + } + + List urlList = new ArrayList<>(); + st = new StringTokenizer(classpath,";"); + while (st.hasMoreTokens()) { + String fileName = st.nextToken(); + File file = new File(workingDirectory,fileName).getCanonicalFile(); + if (!file.exists()) error("Missing or invalid file: " + file.getPath()); + URL url = file.toURI().toURL(); + urlList.add(url); + } + URL[] urls = new URL[urlList.size()]; + urlList.toArray(urls); + ClassLoader loader = new URLClassLoader(urls, parent); + if (debug) System.err.println("? TestServer.createLoader() loader=" + loader + ", name='" + name + "', urls=" + urlList + ", parent=" + parent); + + loaders.put(name,loader); + } + + private void createRootLoader() throws IOException { + List urlList = new ArrayList<>(); + + // Sandbox + URL url = workingDirectory.getCanonicalFile().toURI().toURL(); + urlList.add(url); + + // Find the AspectJ root folder (i.e. org.aspectj) + File aspectjBase = new File(".").getCanonicalFile(); + while (aspectjBase!= null && !aspectjBase.getName().equals("org.aspectj")) { + aspectjBase = aspectjBase.getParentFile(); + } + if (aspectjBase == null) { + error("Unable to locate 'org.aspectj' in "+new File(".").getCanonicalPath()); + } + urlList.add(new File(aspectjBase,"runtime/bin").toURI().toURL()); + urlList.add(new File(aspectjBase,"aspectjrt/bin").toURI().toURL()); + urlList.add(new File(aspectjBase,"aspectj5rt/bin").toURI().toURL()); + + URL[] urls = new URL[urlList.size()]; + urlList.toArray(urls); + ClassLoader parent = getClass().getClassLoader().getParent(); + rootLoader = new URLClassLoader(urls,parent); + if (debug) System.err.println("? TestServer.createRootLoader() loader=" + rootLoader + ", urlList=" + urlList + ", parent=" + parent); + } + + public void setExitOntError (boolean b) { + exitOnError = b; + } + + public void setWorkingDirectory (String name) { + workingDirectory = new File(name); + if (!workingDirectory.exists()) error("Missing or invalid working directory: " + workingDirectory.getPath()); + } + + public static void main(String[] args) throws Exception { + System.out.println("Starting ..."); + + TestServer server = new TestServer(); + server.setWorkingDirectory(args[0]); + server.initialize(); + + Thread thread = new Thread(server,"application"); + thread.start(); + thread.join(); + + System.out.println("Stopping ..."); + } + + public void run() { + System.out.println("Running " + mainClass); + runClass(mainClass,(ClassLoader)loaders.get(mainLoader)); + } + + private void runClass (String className, ClassLoader classLoader) { + try { + Class clazz = Class.forName(className,false,classLoader); + invokeMain(clazz,new String[] {}); + } + catch (ClassNotFoundException ex) { + ex.printStackTrace(); + error(ex.toString()); + } + } + + public void invokeMain (Class clazz, String[] args) + { + Class[] paramTypes = new Class[1]; + paramTypes[0] = args.getClass(); + + try { + Method method = clazz.getDeclaredMethod("main",paramTypes); + Object[] params = new Object[1]; + params[0] = args; + method.invoke(null,params); + } + catch (InvocationTargetException ex) { + Throwable th = ex.getTargetException(); + th.printStackTrace(); + error(th.toString()); + } + catch (Throwable th) { + th.printStackTrace(); + error(th.toString()); + } + } + + private void error (String message) { + System.out.println(message); + if (exitOnError) System.exit(0); + } +} diff --git a/testing-client/src/org/aspectj/testing/Tester.java b/testing-client/src/org/aspectj/testing/Tester.java deleted file mode 100644 index 500c4c363..000000000 --- a/testing-client/src/org/aspectj/testing/Tester.java +++ /dev/null @@ -1,981 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2000 Xerox Corporation. - * 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: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing; - -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.bridge.Message; -import org.aspectj.util.LangUtil; - -import java.util.*; -import java.io.*; - -/** - * Testing client interface for checking results and reporting - * to a delegate IMessageHandler. - * Harnesses providing this interface for test clients must - * set it up by calling - * {@link #setBASEDIR(File)} - * {@link #setMessageHandler(IMessageHandler)} and - * {@link #clear()} for each test, as appropriate. - * (That means that IMessageHandler must be loaded from a class - * loader common to the harness and Tester.) - * If clients submit a failing check, this registers the message - * and throws an AbortException holding the message; this - * AbortException will not have the correct stack trace; - * all the information should be encoded in the message. - * Find any original exception thrown in the message itself. - */ - // XXX consider creating exception for new API throwFailure(String m) -public class Tester { - /** delegate for reporting results */ - private static IMessageHandler messageHandler; - - /** base directory for calculating relative paths to event files */ - private static File BASEDIR; - - /** - * collection of notes submitted - */ - private static Set notes; - - /** List to hold events submitted. */ - private static List actualEvents = new ArrayList<>(); - - /** List to hold events we expect. */ - private static List expectedEvents = new ArrayList<>(); - - static { - setBASEDIR(new File(".")); - setMessageHandler(IMessageHandler.SYSTEM_ERR); - clear(); - } - - /** - * Set directory used for calculating relative paths - * (currently only to an events file) - * @param baseDir the File for an existing directory - */ - public static void setBASEDIR(File baseDir) { - if (null == baseDir) throw new IllegalArgumentException("null baseDir"); - if (!baseDir.isDirectory()) throw new IllegalArgumentException("not a directory: " + baseDir); - BASEDIR = baseDir; - } - - public static File getBASEDIR() { - return BASEDIR; - } - - - /** - * Set the message handler used for this Tester. - * When given a message of kind FAIL, this handler - * must complete abruptly or return false (i.e., not handled completely) - * so the Tester throws an AbortException. - * @see checkFailed(..). - */ - public static void setMessageHandler(IMessageHandler handler) { - if (null == handler) throw new IllegalArgumentException("null handler"); - if (messageHandler != handler) messageHandler = handler; - } - - - public static void clear() { - clearNotes(); - clearEvents(); - } - - /** XXX deprecated #clear() */ - public static void clearNotes() { - notes = new HashSet(); - } - - /** XXX deprecated #clear() */ - public static void clearEvents() { - actualEvents = new ArrayList<>(); - expectedEvents = new ArrayList<>(); - } - - - /** Add an actual event */ - public static void event(String s) { - actualEvents.add(s); - } - - /** - * Add a note to {@link #notes}. - * @param note Message to add. - * XXX deprecated event(String) - */ - public static void note(Object note) { - notes.add(note); - } - - /** - * Checks that note was added using {@link #note}, - * and fails using note.toString() is it wasn't found. - * - * @param note Message that should've been added using {@link #note}. - * XXX deprecated checkEvent(String) - */ - public static void check(Object note) { - check(note, "expected note \"" + note.toString() + "\""); - } - - /** - * Checks that note was added using {@link #note}, - * and fails using message is it wasn't found. - * - * @param note Message that should've been added using {@link #note}. - * @param message Message with which to fail if node - * wasn't added. - */ - public static void check(Object note, String message) { - check(notes.contains(note), message); - } - - /** - * Reports that t shouldn't have been thrown. - * using t as the message. - * - * @param t Thrown exception. - * @see #throwable(Throwable,String) - */ - public static void throwable(Throwable t) { - throwable(t, null); - } - - - /** - * Reports that t shouldn't have been thrown. - * using msg as the message. - * - * @param thrown Thrown exception. - * @param msg Message with which to report error. - */ - public static void throwable(Throwable thrown, String msg) { - handle(msg, thrown, true); - } - - /** - * Report the error message unconditionally. - * - * @param message Error to report. - */ - public static void checkFailed(String message) { - handle(message, null, true); - } - - /** - * Check that expectedNotes is equal to {@link #notes} - * , fail with msg and create a new instance of {@link #notes}. - * NOTE: expectedNotes is a String, so - * it must match with {@link java.util.HashSet#toString()}. - * - * @param expectedNotes String we expect - * {@link #notes} to match. - * @param msg Message with which to fail. - */ - public static void checkAndClear(String expectedNotes, String msg) { - checkEqual(notes, expectedNotes, msg); - clearNotes(); - } - - /** - * Reports an error using message if - * test == false. - * - * @param test Determines whether we call {@link #checkFailed}. - * @param message Message to pass {@link #checkFailed} if - * test == false. - */ - public static void check(boolean test, String message) { - if (!test) checkFailed(message); - } - - /** - * Checks that the values of value and - * expectedValue are equal. Both or either - * can be null. Calls {@link #checkFailed} with message - * if the arrays aren't equal. - * - * @param value One test set. - * @param expectedValue The other test set. - * @param message Message with which to fail. - */ - public static void checkEqual(Object[] value, - Object[] expectedValue, - String message) - { - if (value == null) { - if (expectedValue == null) return; - checkFailed(message+" null array found"); - return; - } - int n = value.length; - if (n != expectedValue.length) { - checkFailed(message+" expected array of length "+expectedValue.length - +" got "+ n); - return; - } - for(int i=0; is == t. - * - * @param s a known value. - * @param t another known value. - */ - public static void checkNotEqual(boolean s, boolean t) { - checkNotEqual(s, t, s + " shouldn't equal " + t); - } - /** - * Fails with message msg if s == t. - * - * @param s a known value. - * @param t another known value. - * @param msg the failure message. - */ - public static void checkNotEqual(boolean s, boolean t, String msg) { - if (s == t) checkFailed(msg); - } - - /** - * Fails if s == t. - * - * @param s a known value. - * @param t another known value. - */ - public static void checkNotEqual(byte s, byte t) { - checkNotEqual(s, t, s + " shouldn't equal " + t); - } - /** - * Fails with message msg if s == t. - * - * @param s a known value. - * @param t another known value. - * @param msg the failure message. - */ - public static void checkNotEqual(byte s, byte t, String msg) { - if (s == t) checkFailed(msg); - } - - /** - * Fails if s == t. - * - * @param s a known value. - * @param t another known value. - */ - public static void checkNotEqual(char s, char t) { - checkNotEqual(s, t, s + " shouldn't equal " + t); - } - /** - * Fails with message msg if s == t. - * - * @param s a known value. - * @param t another known value. - * @param msg the failure message. - */ - public static void checkNotEqual(char s, char t, String msg) { - if (s == t) checkFailed(msg); - } - - /** - * Fails if s == t. - * - * @param s a known value. - * @param t another known value. - */ - public static void checkNotEqual(short s, short t) { - checkNotEqual(s, t, s + " shouldn't equal " + t); - } - /** - * Fails with message msg if s == t. - * - * @param s a known value. - * @param t another known value. - * @param msg the failure message. - */ - public static void checkNotEqual(short s, short t, String msg) { - if (s == t) checkFailed(msg); - } - - /** - * Fails if s == t. - * - * @param s a known value. - * @param t another known value. - */ - public static void checkNotEqual(int s, int t) { - checkNotEqual(s, t, s + " shouldn't equal " + t); - } - /** - * Fails with message msg if s == t. - * - * @param s a known value. - * @param t another known value. - * @param msg the failure message. - */ - public static void checkNotEqual(int s, int t, String msg) { - if (s == t) checkFailed(msg); - } - - /** - * Fails if s == t. - * - * @param s a known value. - * @param t another known value. - */ - public static void checkNotEqual(long s, long t) { - checkNotEqual(s, t, s + " shouldn't equal " + t); - } - /** - * Fails with message msg if s == t. - * - * @param s a known value. - * @param t another known value. - * @param msg the failure message. - */ - public static void checkNotEqual(long s, long t, String msg) { - if (s == t) checkFailed(msg); - } - - /** - * Fails if s == t. - * - * @param s a known value. - * @param t another known value. - */ - public static void checkNotEqual(float s, float t) { - checkNotEqual(s, t, s + " shouldn't equal " + t); - } - /** - * Fails with message msg if s == t. - * - * @param s a known value. - * @param t another known value. - * @param msg the failure message. - */ - public static void checkNotEqual(float s, float t, String msg) { - if (s == t) checkFailed(msg); - } - - /** - * Fails if s == t. - * - * @param s a known value. - * @param t another known value. - */ - public static void checkNotEqual(double s, double t) { - checkNotEqual(s, t, s + " shouldn't equal " + t); - } - /** - * Fails with message msg if s == t. - * - * @param s a known value. - * @param t another known value. - * @param msg the failure message. - */ - public static void checkNotEqual(double s, double t, String msg) { - if (s == t) checkFailed(msg); - } - - /** - * Fails if s == t. - * - * @param s a known value. - * @param t another known value. - */ - public static void checkNotEqual(Object s, Object t) { - checkNotEqual(s, t, s + " shouldn't equal " + t); - } - /** - * Fails with message msg if s == t - * or both s and t are null. - * - * @param s a known value. - * @param t another known value. - * @param msg the failure message. - */ - public static void checkNotEqual(Object s, Object t, String msg) { - if ((s != null && s.equals(t)) || - (t != null && t.equals(s)) || - (s == null && t == null)) { - checkFailed(msg); - } - } - - /** - * Compares value and expectedValue - * with failing message "compare". - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @see #checkEqual(int,int,String) - */ - public static void checkEqual(int value, int expectedValue) { - checkEqual(value, expectedValue, "compare"); - } - - /** - * Fails if the passed in value is null. - * - * @param o the expected non-null thing. - * @param name the name of o. - */ - public static void checkNonNull(Object o, String name) { - if (o == null) checkFailed(name + " shouldn't be null"); - } - - /** - * Compared value and expectedValue - * and fails with message if they aren't equal. - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @param msg Message with which to fail. - */ - public static void checkEqual(int value, int expectedValue, String message) { - if (value == expectedValue) return; - if (value < expectedValue) { - message = message+": "+value+" < "+expectedValue; - } else { - message = message+": "+value+" > "+expectedValue; - } - checkFailed(message); - } - - /** - * Compares value and expectedValue - * with failing message "compare". - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @see #checkEqual(float,float,String) - */ - public static void checkEqual(float value, float expectedValue) { - checkEqual(value, expectedValue, "compare"); - } - - /** - * Compared value and expectedValue - * and fails with message if they aren't equal. - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @param msg Message with which to fail. - */ - public static void checkEqual(float value, float expectedValue, String msg) { - if (Float.isNaN(value) && Float.isNaN(expectedValue)) return; - if (value == expectedValue) return; - if (value < expectedValue) { - msg = msg+": "+value+" < "+expectedValue; - } else { - msg = msg+": "+value+" > "+expectedValue; - } - checkFailed(msg); - } - - /** - * Compares value and expectedValue - * with failing message "compare". - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @see #checkEqual(long,long,String) - */ - public static void checkEqual(long value, long expectedValue) { - checkEqual(value, expectedValue, "compare"); - } - - /** - * Compared value and expectedValue - * and fails with message if they aren't equal. - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @param msg Message with which to fail. - */ - public static void checkEqual(long value, long expectedValue, String msg) { - if (value == expectedValue) return; - if (value < expectedValue) { - msg = msg+": "+value+" < "+expectedValue; - } else { - msg = msg+": "+value+" > "+expectedValue; - } - checkFailed(msg); - } - - /** - * Compares value and expectedValue - * with failing message "compare". - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @see #checkEqual(double,double,String) - */ - public static void checkEqual(double value, double expectedValue) { - checkEqual(value, expectedValue, "compare"); - } - - /** - * Compared value and expectedValue - * and fails with message if they aren't equal. - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @param msg Message with which to fail. - */ - public static void checkEqual(double value, double expectedValue, String msg) { - if (Double.isNaN(value) && Double.isNaN(expectedValue)) return; - if (value == expectedValue) return; - if (value < expectedValue) { - msg = msg+": "+value+" < "+expectedValue; - } else { - msg = msg+": "+value+" > "+expectedValue; - } - checkFailed(msg); - } - - /** - * Compares value and expectedValue - * with failing message "compare". - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @see #checkEqual(short,short,String) - */ - public static void checkEqual(short value, short expectedValue) { - checkEqual(value, expectedValue, "compare"); - } - - /** - * Compared value and expectedValue - * and fails with message if they aren't equal. - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @param msg Message with which to fail. - */ - public static void checkEqual(short value, short expectedValue, String msg) { - if (value == expectedValue) return; - if (value < expectedValue) { - msg = msg+": "+value+" < "+expectedValue; - } else { - msg = msg+": "+value+" > "+expectedValue; - } - checkFailed(msg); - } - - /** - * Compares value and expectedValue - * with failing message "compare". - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @see #checkEqual(byte,byte,String) - */ - public static void checkEqual(byte value, byte expectedValue) { - checkEqual(value, expectedValue, "compare"); - } - - /** - * Compares value and expectedValue - * with failing message msg. - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @param msg Message with which to fail. - */ - public static void checkEqual(byte value, byte expectedValue, String msg) { - if (value == expectedValue) return; - if (value < expectedValue) { - msg = msg+": "+value+" < "+expectedValue; - } else { - msg = msg+": "+value+" > "+expectedValue; - } - checkFailed(msg); - } - - /** - * Compares value and expectedValue - * with failing message "compare". - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @see #checkEqual(char,char,String) - */ - public static void checkEqual(char value, char expectedValue) { - checkEqual(value, expectedValue, "compare"); - } - - /** - * Compares value and expectedValue - * with failing message msg. - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @param msg Message with which to fail. - */ - public static void checkEqual(char value, char expectedValue, String msg) { - if (value == expectedValue) return; - if (value < expectedValue) { - msg = msg+": "+value+" < "+expectedValue; - } else { - msg = msg+": "+value+" > "+expectedValue; - } - checkFailed(msg); - } - - /** - * Compares value and expectedValue - * with failing message "compare". - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @see #checkEqual(boolean,boolean,String) - */ - public static void checkEqual(boolean value, boolean expectedValue) { - checkEqual(value, expectedValue, "compare"); - } - - /** - * Compares value and expectedValue - * with failing message msg. - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @param msg Message with which to fail. - */ - public static void checkEqual(boolean value, boolean expectedValue, String msg) { - if (value == expectedValue) return; - msg = msg+": "+value+" != "+expectedValue; - checkFailed(msg); - } - - /** - * Checks whether the entries of set are equal - * using equals to the corresponding String in - * expectedSet and fails with message msg. - * - * @param set Unkown set of values. - * @param expectedSet Expected String of values. - * @param msg Message with which to fail. - */ - public static void checkEqual(Collection set, String expectedSet, String msg) { - checkEqual(set, LangUtil.split(expectedSet), msg); - } - - /** - * Checks whether the entries of set are equal - * using equals to the corresponding entry in - * expectedSet and fails with message msg, - * except that duplicate actual entries are ignored. - * This issues fail messages for each failure; when - * aborting on failure, only the first will be reported. - * - * @param set Unkown set of values. - * @param expectedSet Expected String of values. - * @param msg Message with which to fail. - */ - public static void checkEqualIgnoreDups(Collection set, String[] expected, String msg, - boolean ignoreDups) { - String[] diffs = diffIgnoreDups(set, expected, msg, ignoreDups); - if (0 < diffs.length) { - check(false, "" + Arrays.asList(diffs)); - } -// for (int i = 0; i < diffs.length; i++) { -// check(false, diffs[i]); -// } - } - - /** @return String[] of differences '{un}expected msg "..." {not} found' */ - private static String[] diffIgnoreDups(Collection set, String[] expected, String msg, - boolean ignoreDups) { - ArrayList result = new ArrayList<>(); - ArrayList actual = new ArrayList<>(set); - BitSet hits = new BitSet(); - for (int i = 0; i < expected.length; i++) { - if (!actual.remove(expected[i])) { - result.add(" expected " + msg + " \"" + expected[i] + "\" not found"); - } else { - hits.set(i); - if (ignoreDups) { - while (actual.remove(expected[i])) ; // remove all instances of it - } - } - } - for (String act: actual) { - result.add(" unexpected " + msg + " \"" + act + "\" found"); - } - return (String[]) result.toArray(new String[0]); - } - - /** - * Checks whether the entries of set are equal - * using equals to the corresponding entry in - * expectedSet and fails with message msg. - * - * @param set Unkown set of values. - * @param expectedSet Expected String of values. - * @param msg Message with which to fail. - */ - public static void checkEqual(Collection set, String[] expected, String msg) { - checkEqualIgnoreDups(set, expected, msg, false); - } - - /** - * Compares value and expectedValue - * with failing message "compare". - * - * @param value Unkown value. - * @param expectedValue Expected value. - * @see #checkEqual(Object,Object,String) - */ - public static void checkEqual(Object value, Object expectedValue) { - checkEqual(value, expectedValue, "compare"); - } - - /** - * Checks whether the entries of set are equal - * using equals to the corresponding String in - * expectedSet and fails with message msg. - * - * @param set Unkown set of values. - * @param expectedSet Expected String of values. - * @param msg Message with which to fail. - */ - public static void checkEqual(Object value, Object expectedValue, String msg) { - if (value == null && expectedValue == null) return; - if (value != null && value.equals(expectedValue)) return; - msg = msg+": "+value+" !equals "+expectedValue; - checkFailed(msg); - } - - /** - * Checks whether the entries of set are equal - * using equals to the corresponding String in - * expectedSet and fails with message msg. - * - * @param set Unkown set of values. - * @param expectedSet Expected String of values. - * @param msg Message with which to fail. - */ - public static void checkEq(Object value, Object expectedValue, String msg) { - if (value == expectedValue) return; - msg = msg+": "+value+" != "+expectedValue; - checkFailed(msg); - } - - /** add expected events */ - public static void expectEvent(String s) { - if (null != s) { - expectedEvents.add(s); - } - } - - /** add expected events */ - public static void expectEvent(Object s) { - if (null != s) { - expectEvent(s.toString()); - } - } - - /** - * add expected events, parse out ; from string - * Expect those messages in s separated by - * ":;, ". - * - * @param s String containg delimited,expected messages. - */ - public static void expectEventsInString(String s) { - if (null != s) { - StringTokenizer tok = new StringTokenizer(s, ":;, "); - while (tok.hasMoreTokens()) { - expectEvent(tok.nextToken()); - } - } - } - - public static void expectEventsInString(String[] ra) { - expectEvents((Object[]) ra); - } - - /** add expected events */ - public static void expectEvents(Object[] events) { - if (null != events) { - for (int i = 0; i < events.length; i++) { - if (null != events[i]) { - expectEvent(events[i].toString()); - } - } - } - } - - /** add expected events */ - public static void expectEvents(String[] events) { - if (null != events) { - for (int i = 0; i < events.length; i++) { - if (null != events[i]) { - expectEvent(events[i].toString()); - } - } - } - } - - /** check actual and expected have same members */ - public static void checkAllEvents() { - checkAndClearEvents((String[]) expectedEvents.toArray(new String[0])); - } - - /** also ignore duplicate actual entries for expected */ - public static void checkAllEventsIgnoreDups() { - final boolean ignoreDups = true; - final String[] exp = (String[]) expectedEvents.toArray(new String[0]); - checkEqualIgnoreDups(actualEvents, exp, "event", ignoreDups); - clearEvents(); - } - - /** Check events, file is line-delimited. If there is a non-match, signalls - * a single error for the first event that does not match the next event in - * the file. The equivalence is {@link #checkEqualLists}. Blank lines are - * ignored. lines that start with '//' are ignored. */ - public static void checkEventsFromFile(String eventsFile) { - // XXX bug reads into current expected and checks all - separate read and check - try { - File file = new File(getBASEDIR(), eventsFile); // XXX TestDriver - BufferedReader in = new BufferedReader(new FileReader(file)); - //final File parentDir = (null == file? null : file.getParentFile()); - String line; - List expEvents = new ArrayList(); - while ((line = in.readLine()) != null) { - line = line.trim(); - if ((line.length() < 1) || (line.startsWith("//"))) continue; - expEvents.add(line); - } - checkEqualLists(actualEvents, expEvents, " from " + eventsFile); - } catch (IOException ioe) { - throwable(ioe); - } - } - - - /** Check to see that two lists of strings are the same. Order is important. - * Trimmable whitespace is not important. Case is important. - * - * @param actual one list to check - * @param expected another list - * @param message a context string for the resulting error message if the test fails. - */ - public static void checkEqualLists(List/*String*/ actual, List/*String*/ expected, - String message) { - Iterator a = actual.iterator(); - Iterator e = expected.iterator(); - int ai = 0; - int ei = 0; - for (; a.hasNext(); ) { - if (! e.hasNext()) { - checkFailed("unexpected [" + ai + "] \"" + a.next() + "\" " + message); - return; - } - String a0 = ((String) a.next()).trim(); - String e0 = ((String) e.next()).trim(); - if (! a0.equals(e0)) { - checkFailed("expected [" + ei + "] \"" + e0 - + "\"\n but found [" + ai + "] \"" + a0 + "\"\n " + message); - return; - } - ai++; - ei++; - } - while (e.hasNext()) { - checkFailed("expected [" + ei + "] \"" + e.next() + "\" " + message); - ei++; - } - } - - /** Check events, expEvents is space delimited */ - public static void checkEvents(String expEvents) { - checkEqual(actualEvents, expEvents, "event"); - } - - /** Check events, expEvents is an array */ - public static void checkEvents(String[] expEvents) { - checkEqual(actualEvents, expEvents, "event"); - } - - /** Check events and clear after check*/ - public static void checkAndClearEvents(String expEvents) { - checkEvents(expEvents); - clearEvents(); - } - - /** Check events and clear after check*/ - public static void checkAndClearEvents(String[] expEvents) { - checkEvents(expEvents); - clearEvents(); - } - - /** XXX deprecated */ - public static void printEvents() { // XXX no clients? - for (Iterator i = actualEvents.iterator(); i.hasNext(); ) { - System.out.println(i.next()); // XXX System.out - } - } - - /** - * Report an uncaught exeption as an error - * @param thrown Throwable to print. - * @see #maxStackTrace - */ - public void unexpectedExceptionFailure(Throwable thrown) { - handle("unexpectedExceptionFailure", thrown, true); - } - - /** - * Handle message by delegation to message handler, doing - * IMessage.FAIL if (fail || (thrown != null) and IMessage.INFO - * otherwise. - */ - - private static void handle(String message, Throwable thrown, boolean fail) { - final boolean failed = fail || (null != thrown); - IMessage.Kind kind = (failed ? IMessage.FAIL : IMessage.INFO); - IMessage m = new Message(message, kind, thrown, null); - /*final boolean handled = */messageHandler.handleMessage(m); - } -// private static void resofhandle(String message, Throwable thrown, boolean fail) { -// /* If FAIL and the message handler returns false (normally), -// * Then this preserves "abort" semantics by throwing an -// * abort exception. -// */ -// if (failed) { -// if (handled) { -// String s = "Tester expecting handler to return false or " -// + "complete abruptly when passed a fail, for " + m; -// m = new Message(s, IMessage.DEBUG, null, null); -// messageHandler.handleMessage(m); -// } else { -// throw AbortException.borrowPorter(m); -// } -// } -// } - -} diff --git a/testing-client/src/org/aspectj/testing/server/TestServer.java b/testing-client/src/org/aspectj/testing/server/TestServer.java deleted file mode 100644 index 80cbc357b..000000000 --- a/testing-client/src/org/aspectj/testing/server/TestServer.java +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006,2017 IBM Corporation and others. - * 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 - *******************************************************************************/ -package org.aspectj.testing.server; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.StringTokenizer; - -/** - * @author Matthew Webster - * @author Andy Clement - */ -public class TestServer implements Runnable { - - private static final boolean debug = Boolean.getBoolean("org.aspectj.testing.server.debug"); - - private boolean exitOnError = true; - private File workingDirectory; - private ClassLoader rootLoader; - private Map loaders = new HashMap<>(); - - private String mainClass = "UnknownClass"; - private String mainLoader = "UnknownLoader"; - - public void initialize () throws IOException { - createRootLoader(); - loadConfiguration(); - } - - private void loadConfiguration () throws IOException { - File file = new File(workingDirectory,"server.properties"); - Properties props = new Properties(); - FileInputStream in = new FileInputStream(file); - props.load(in); - in.close(); - - Enumeration enu = props.propertyNames(); - while (enu.hasMoreElements()) { - String key = (String)enu.nextElement(); - if (key.startsWith("loader.")) { - createLoader(props.getProperty(key)); - } - else if (key.equals("main")) { - StringTokenizer st = new StringTokenizer(props.getProperty(key),","); - mainClass = st.nextToken(); - mainLoader = st.nextToken(); - } - } - } - - private void createLoader (String property) throws IOException { - ClassLoader parent = rootLoader; - - StringTokenizer st = new StringTokenizer(property,","); - String name = st.nextToken(); - String classpath = st.nextToken(); - if (debug) System.err.println("Creating loader "+name+" with classpath "+classpath); - if (st.hasMoreTokens()) { - String parentName = st.nextToken(); - parent = (ClassLoader)loaders.get(parentName); - if (parent == null) error("No such loader: " + parentName); - } - - List urlList = new ArrayList<>(); - st = new StringTokenizer(classpath,";"); - while (st.hasMoreTokens()) { - String fileName = st.nextToken(); - File file = new File(workingDirectory,fileName).getCanonicalFile(); - if (!file.exists()) error("Missing or invalid file: " + file.getPath()); - URL url = file.toURI().toURL(); - urlList.add(url); - } - URL[] urls = new URL[urlList.size()]; - urlList.toArray(urls); - ClassLoader loader = new URLClassLoader(urls, parent); - if (debug) System.err.println("? TestServer.createLoader() loader=" + loader + ", name='" + name + "', urls=" + urlList + ", parent=" + parent); - - loaders.put(name,loader); - } - - private void createRootLoader() throws IOException { - List urlList = new ArrayList<>(); - - // Sandbox - URL url = workingDirectory.getCanonicalFile().toURI().toURL(); - urlList.add(url); - - // Find the AspectJ root folder (i.e. org.aspectj) - File aspectjBase = new File(".").getCanonicalFile(); - while (aspectjBase!= null && !aspectjBase.getName().equals("org.aspectj")) { - aspectjBase = aspectjBase.getParentFile(); - } - if (aspectjBase == null) { - error("Unable to locate 'org.aspectj' in "+new File(".").getCanonicalPath()); - } - urlList.add(new File(aspectjBase,"runtime/bin").toURI().toURL()); - urlList.add(new File(aspectjBase,"aspectjrt/bin").toURI().toURL()); - urlList.add(new File(aspectjBase,"aspectj5rt/bin").toURI().toURL()); - - URL[] urls = new URL[urlList.size()]; - urlList.toArray(urls); - ClassLoader parent = getClass().getClassLoader().getParent(); - rootLoader = new URLClassLoader(urls,parent); - if (debug) System.err.println("? TestServer.createRootLoader() loader=" + rootLoader + ", urlList=" + urlList + ", parent=" + parent); - } - - public void setExitOntError (boolean b) { - exitOnError = b; - } - - public void setWorkingDirectory (String name) { - workingDirectory = new File(name); - if (!workingDirectory.exists()) error("Missing or invalid working directory: " + workingDirectory.getPath()); - } - - public static void main(String[] args) throws Exception { - System.out.println("Starting ..."); - - TestServer server = new TestServer(); - server.setWorkingDirectory(args[0]); - server.initialize(); - - Thread thread = new Thread(server,"application"); - thread.start(); - thread.join(); - - System.out.println("Stopping ..."); - } - - public void run() { - System.out.println("Running " + mainClass); - runClass(mainClass,(ClassLoader)loaders.get(mainLoader)); - } - - private void runClass (String className, ClassLoader classLoader) { - try { - Class clazz = Class.forName(className,false,classLoader); - invokeMain(clazz,new String[] {}); - } - catch (ClassNotFoundException ex) { - ex.printStackTrace(); - error(ex.toString()); - } - } - - public void invokeMain (Class clazz, String[] args) - { - Class[] paramTypes = new Class[1]; - paramTypes[0] = args.getClass(); - - try { - Method method = clazz.getDeclaredMethod("main",paramTypes); - Object[] params = new Object[1]; - params[0] = args; - method.invoke(null,params); - } - catch (InvocationTargetException ex) { - Throwable th = ex.getTargetException(); - th.printStackTrace(); - error(th.toString()); - } - catch (Throwable th) { - th.printStackTrace(); - error(th.toString()); - } - } - - private void error (String message) { - System.out.println(message); - if (exitOnError) System.exit(0); - } -} diff --git a/testing-client/src/test/java/org/aspectj/testing/TesterTest.java b/testing-client/src/test/java/org/aspectj/testing/TesterTest.java new file mode 100644 index 000000000..d538a63f7 --- /dev/null +++ b/testing-client/src/test/java/org/aspectj/testing/TesterTest.java @@ -0,0 +1,239 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * 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: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.testing; + +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessageHandler; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import junit.framework.TestCase; +import junit.textui.TestRunner; + +/** + * Test the Tester client API's. + * See also tests/harness/*.java and tests/ajcHarnessTests.xml for harness- + * driven Tester tests. + * @author isberg + */ +public class TesterTest extends TestCase { + + + private static final String ME + = "org.aspectj.testing.TesterTest"; + + /** @param args ignored */ + public static void main(String[] args) { + TestRunner.main(new String[] {ME}); + } + + /** + * Constructor for TesterTest. + * @param arg0 + */ + public TesterTest(String arg0) { + super(arg0); + } + + /** + * Test the usage pattern + *
Tester.event("foo");
+     * Tester.checkEvents(new String[] { "foo" }); 
+ */ + public void testEventArrayPattern() { + MyTestReporter reporter = new MyTestReporter(); + Tester.setMessageHandler(reporter); + + //--------- positive test - got expected events + reporter.clear(); + Tester.clear(); + Tester.event("one"); + Tester.event("two"); + Tester.checkEvents(new String[] { "one", "two"}); + reporter.assertSize(0); + + //--------- failed to get expected events + reporter.clear(); + Tester.clear(); + Tester.checkEvents(new String[] { "one"}); + assertTrue(reporter.gotFail("one")); + reporter.assertSize(1); + + //--------- got and didn't get expected events + reporter.clear(); + Tester.clear(); + Tester.event("one"); + Tester.event("two"); + Tester.checkEvents(new String[] { "one", "two", "three"}); + reporter.assertSize(1); + assertTrue(reporter.gotFail("three")); + } + + /** + * Test the usage pattern + *
Tester.event("foo");
+     * Tester.expectEvent("foo");
+     * Tester.checkAllEvents();
+ */ + public void testEventStringPattern() { + MyTestReporter reporter = new MyTestReporter(); + Tester.setMessageHandler(reporter); + + //--------- positive test - got expected events + reporter.clear(); + Tester.clear(); + Tester.event("one"); + Tester.event("two"); + Tester.expectEvent("one"); + Tester.expectEvent("two"); + Tester.checkAllEvents(); + reporter.assertSize(0); + + //--------- failed to get expected events + reporter.clear(); + Tester.clear(); + Tester.expectEvent("one"); + Tester.checkAllEvents(); + assertTrue(reporter.gotFail("one")); + reporter.assertSize(1); + + //--------- got and didn't get expected events + reporter.clear(); + Tester.clear(); + Tester.expectEvent("one"); + Tester.expectEvent("two"); + Tester.expectEvent("three"); + Tester.event("one"); + Tester.event("two"); + Tester.checkAllEvents(); + assertTrue(reporter.gotFail("three")); + reporter.assertSize(1); + } + + /** + * Test the usage pattern + *
Tester.note("foo");
+     * Tester.check("foo");
+ */ + public void testNotePattern() { + MyTestReporter reporter = new MyTestReporter(); + Tester.setMessageHandler(reporter); + + //--------- positive test - got expected events + reporter.clear(); + Tester.clear(); + Tester.note("one"); + Tester.note("two"); + Tester.check("one"); + Tester.check("two"); + reporter.assertSize(0); + + //--------- failed to get expected events + reporter.clear(); + Tester.clear(); + Tester.check("one"); + Tester.checkAllEvents(); + assertTrue(reporter.gotFail("one")); + reporter.assertSize(1); + + //--------- got and didn't get expected events + reporter.clear(); + Tester.clear(); + Tester.note("one"); + Tester.check("one"); + Tester.note("two"); + Tester.check("two"); + Tester.check("three"); + assertTrue(reporter.gotFail("three")); + reporter.assertSize(1); + } + + /** + * Stub to record failures emitted by Tester. + * @author isberg + */ + public static class MyTestReporter implements IMessageHandler { + public ArrayList failures = new ArrayList<>(); + public ArrayList passes = new ArrayList<>(); + + public void clear() { + failures.clear(); + passes.clear(); + } + + void assertSize(int size) { + assertTrue(-1 < size); + assertTrue("failures: " + failures, size == failures.size()); + } + + boolean gotPass(String substring) { + return gotItem(passes, substring); + } + + boolean gotFail(String substring) { + return gotItem(failures, substring); + } + + boolean gotItem(List list, String substring) { + for (IMessage element: list) { + String s = element.getMessage(); + if ((null != s) && (-1 != s.indexOf(substring))) { + return true; + } + } + return false; + } + + public boolean isIgnoring(IMessage.Kind kind) { + return false; + } + + public void dontIgnore(IMessage.Kind kind) { + ; + } + + public void ignore(IMessage.Kind kind) { + } + + public boolean handleMessage(IMessage message) { + (message.isFailed() ? failures : passes).add(message); + return true; + } + } +} +// /** +// * @see ReporterI#abortWithFailure(String, Throwable) +// */ +// public void abortWithFailure(String message, Throwable exception) { +// if (null == exception) { +// check(message, true); +// } else { +// String s = message + Util.unqualifiedClassName(exception) +// + ": " + exception.getMessage(); +// check(s, false); +// } +// } +// +// /** +// * @see ReporterI#check(String, boolean) +// */ +// public boolean check(String message, boolean passed) { +// (!passed ? failures : passes).add(message); +// return passed; +// } +// + diff --git a/testing-client/src/test/java/org/aspectj/testing/TestingClientModuleTests.java b/testing-client/src/test/java/org/aspectj/testing/TestingClientModuleTests.java new file mode 100644 index 000000000..b5dfd039c --- /dev/null +++ b/testing-client/src/test/java/org/aspectj/testing/TestingClientModuleTests.java @@ -0,0 +1,30 @@ +package org.aspectj.testing; +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * 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: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +// default package + +import junit.framework.*; + +public class TestingClientModuleTests extends TestCase { + + public static Test suite() { + TestSuite suite = new TestSuite(TestingClientModuleTests.class.getName()); + suite.addTest(TestingTests.suite()); + return suite; + } + + public TestingClientModuleTests(String name) { super(name); } + +} diff --git a/testing-client/src/test/java/org/aspectj/testing/TestingTests.java b/testing-client/src/test/java/org/aspectj/testing/TestingTests.java new file mode 100644 index 000000000..ea5e7ee14 --- /dev/null +++ b/testing-client/src/test/java/org/aspectj/testing/TestingTests.java @@ -0,0 +1,35 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * 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: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.testing; + +import org.aspectj.testing.server.TestServerTest; + +import junit.framework.*; + +public class TestingTests extends TestCase { + + public static Test suite() { + TestSuite suite = new TestSuite(TestingTests.class.getName()); + // for now, do not include SuiteTest because it would take 15 minutes + //$JUnit-BEGIN$ + suite.addTestSuite(TesterTest.class); + suite.addTestSuite(TestServerTest.class); + //$JUnit-END$ + return suite; + } + + public TestingTests(String name) { super(name); } + +} diff --git a/testing-client/src/test/java/org/aspectj/testing/server/TestServerTest.java b/testing-client/src/test/java/org/aspectj/testing/server/TestServerTest.java new file mode 100644 index 000000000..0c278588e --- /dev/null +++ b/testing-client/src/test/java/org/aspectj/testing/server/TestServerTest.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * 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: + * Matthew Webster - initial implementation + *******************************************************************************/ +package org.aspectj.testing.server; + +import java.io.IOException; + +import junit.framework.TestCase; + +public class TestServerTest extends TestCase { + + private TestServer server; + + protected void setUp() throws Exception { + super.setUp(); + server = new TestServer(); + server.setExitOntError(false); + } + + public void testInitialize() { + try { + server.setWorkingDirectory("../testing-client/testdata"); + server.initialize(); + } + catch (IOException ex) { + fail(ex.toString()); + } + } + + public void testSetWorkingDirectory() { + server.setWorkingDirectory("../testing-client/testdata"); + } +} -- cgit v1.2.3