aboutsummaryrefslogtreecommitdiffstats
path: root/testing-client/src/main/java
diff options
context:
space:
mode:
authorAndy Clement <aclement@pivotal.io>2019-01-23 19:45:07 -0800
committerAndy Clement <aclement@pivotal.io>2019-01-23 19:45:07 -0800
commita303931ebcf72494bdb75395b350ff640a0ff1f3 (patch)
tree2e0346be1fda535f80f603aa4214784e704952e9 /testing-client/src/main/java
parent44f6584f48c77f58ad80115bff0dd637831df939 (diff)
downloadaspectj-a303931ebcf72494bdb75395b350ff640a0ff1f3.tar.gz
aspectj-a303931ebcf72494bdb75395b350ff640a0ff1f3.zip
mavenizing testing-client module - wip
Diffstat (limited to 'testing-client/src/main/java')
-rw-r--r--testing-client/src/main/java/org/aspectj/testing/Tester.java981
-rw-r--r--testing-client/src/main/java/org/aspectj/testing/server/TestServer.java188
2 files changed, 1169 insertions, 0 deletions
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 <b>will not</b> 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;
+
+ /** <code>List</code> to hold events submitted. */
+ private static List<String> actualEvents = new ArrayList<>();
+
+ /** <code>List</code> to hold events we expect. */
+ private static List<String> 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 <code>note</code> was added using {@link #note},
+ * and fails using <code>note.toString()</code> 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 <code>note</code> was added using {@link #note},
+ * and fails using <code>message</code> is it wasn't found.
+ *
+ * @param note Message that should've been added using {@link #note}.
+ * @param message Message with which to fail if <code>node</code>
+ * wasn't added.
+ */
+ public static void check(Object note, String message) {
+ check(notes.contains(note), message);
+ }
+
+ /**
+ * Reports that <code>t</code> shouldn't have been thrown.
+ * using <code>t</code> as the message.
+ *
+ * @param t Thrown exception.
+ * @see #throwable(Throwable,String)
+ */
+ public static void throwable(Throwable t) {
+ throwable(t, null);
+ }
+
+
+ /**
+ * Reports that <code>t</code> shouldn't have been thrown.
+ * using <code>msg</code> 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 <code>message</code> unconditionally.
+ *
+ * @param message Error to report.
+ */
+ public static void checkFailed(String message) {
+ handle(message, null, true);
+ }
+
+ /**
+ * Check that <code>expectedNotes</code> is equal to {@link #notes}
+ * , fail with <code>msg</code> and create a new instance of {@link #notes}.
+ * <i>NOTE: <code>expectedNotes</code> is a <code>String</code>, so
+ * it must match with {@link java.util.HashSet#toString()}</i>.
+ *
+ * @param expectedNotes <code>String</code> 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 <code>message</code> if
+ * <code>test == false</code>.
+ *
+ * @param test Determines whether we call {@link #checkFailed}.
+ * @param message Message to pass {@link #checkFailed} if
+ * <code>test == false</code>.
+ */
+ public static void check(boolean test, String message) {
+ if (!test) checkFailed(message);
+ }
+
+ /**
+ * Checks that the values of <code>value</code> and
+ * <code>expectedValue</code> are equal. Both or either
+ * can be null. Calls {@link #checkFailed} with <code>message</code>
+ * 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; i<n; i++) {
+ if (!value[i].equals(expectedValue[i])) {
+ checkFailed(message+": "+value[i]+" != "+
+ expectedValue[i]+" at index "+i);
+ }
+ }
+ }
+
+ /**
+ * Fails if <code>s == t</code>.
+ *
+ * @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 <code>msg</code> if <code>s == t</code>.
+ *
+ * @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 <code>s == t</code>.
+ *
+ * @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 <code>msg</code> if <code>s == t</code>.
+ *
+ * @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 <code>s == t</code>.
+ *
+ * @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 <code>msg</code> if <code>s == t</code>.
+ *
+ * @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 <code>s == t</code>.
+ *
+ * @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 <code>msg</code> if <code>s == t</code>.
+ *
+ * @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 <code>s == t</code>.
+ *
+ * @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 <code>msg</code> if <code>s == t</code>.
+ *
+ * @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 <code>s == t</code>.
+ *
+ * @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 <code>msg</code> if <code>s == t</code>.
+ *
+ * @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 <code>s == t</code>.
+ *
+ * @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 <code>msg</code> if <code>s == t</code>.
+ *
+ * @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 <code>s == t</code>.
+ *
+ * @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 <code>msg</code> if <code>s == t</code>.
+ *
+ * @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 <code>s == t</code>.
+ *
+ * @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 <code>msg</code> if <code>s == t</code>
+ * or both <code>s</code> and <code>t</code> are <code>null</code>.
+ *
+ * @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 <code>value</code> and <code>expectedValue</code>
+ * with failing message <code>"compare"</code>.
+ *
+ * @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 <code>null</code>.
+ *
+ * @param o the expected non-null thing.
+ * @param name the name of <code>o</code>.
+ */
+ public static void checkNonNull(Object o, String name) {
+ if (o == null) checkFailed(name + " shouldn't be null");
+ }
+
+ /**
+ * Compared <code>value</code> and <code>expectedValue</code>
+ * and fails with <code>message</code> 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 <code>value</code> and <code>expectedValue</code>
+ * with failing message <code>"compare"</code>.
+ *
+ * @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 <code>value</code> and <code>expectedValue</code>
+ * and fails with <code>message</code> 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 <code>value</code> and <code>expectedValue</code>
+ * with failing message <code>"compare"</code>.
+ *
+ * @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 <code>value</code> and <code>expectedValue</code>
+ * and fails with <code>message</code> 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 <code>value</code> and <code>expectedValue</code>
+ * with failing message <code>"compare"</code>.
+ *
+ * @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 <code>value</code> and <code>expectedValue</code>
+ * and fails with <code>message</code> 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 <code>value</code> and <code>expectedValue</code>
+ * with failing message <code>"compare"</code>.
+ *
+ * @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 <code>value</code> and <code>expectedValue</code>
+ * and fails with <code>message</code> 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 <code>value</code> and <code>expectedValue</code>
+ * with failing message <code>"compare"</code>.
+ *
+ * @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 <code>value</code> and <code>expectedValue</code>
+ * with failing message <code>msg</code>.
+ *
+ * @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 <code>value</code> and <code>expectedValue</code>
+ * with failing message <code>"compare"</code>.
+ *
+ * @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 <code>value</code> and <code>expectedValue</code>
+ * with failing message <code>msg</code>.
+ *
+ * @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 <code>value</code> and <code>expectedValue</code>
+ * with failing message <code>"compare"</code>.
+ *
+ * @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 <code>value</code> and <code>expectedValue</code>
+ * with failing message <code>msg</code>.
+ *
+ * @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 <code>set</code> are equal
+ * using <code>equals</code> to the corresponding String in
+ * <code>expectedSet</code> and fails with message <code>msg</code>.
+ *
+ * @param set Unkown set of values.
+ * @param expectedSet Expected <code>String</code> 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 <code>set</code> are equal
+ * using <code>equals</code> to the corresponding entry in
+ * <code>expectedSet</code> and fails with message <code>msg</code>,
+ * 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 <code>String</code> 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<String> set, String[] expected, String msg,
+ boolean ignoreDups) {
+ ArrayList<String> result = new ArrayList<>();
+ ArrayList<String> 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 <code>set</code> are equal
+ * using <code>equals</code> to the corresponding entry in
+ * <code>expectedSet</code> and fails with message <code>msg</code>.
+ *
+ * @param set Unkown set of values.
+ * @param expectedSet Expected <code>String</code> 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 <code>value</code> and <code>expectedValue</code>
+ * with failing message <code>"compare"</code>.
+ *
+ * @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 <code>set</code> are equal
+ * using <code>equals</code> to the corresponding String in
+ * <code>expectedSet</code> and fails with message <code>msg</code>.
+ *
+ * @param set Unkown set of values.
+ * @param expectedSet Expected <code>String</code> 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 <code>set</code> are equal
+ * using <code>equals</code> to the corresponding String in
+ * <code>expectedSet</code> and fails with message <code>msg</code>.
+ *
+ * @param set Unkown set of values.
+ * @param expectedSet Expected <code>String</code> 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 <code>s</code> separated by
+ * <code>":;, "</code>.
+ *
+ * @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 <code>Throwable</code> 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<String,ClassLoader> 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<URL> 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<URL> 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);
+ }
+}