aboutsummaryrefslogtreecommitdiffstats
path: root/testing-drivers/src/test/java
diff options
context:
space:
mode:
authorAndy Clement <aclement@pivotal.io>2019-01-30 16:29:02 -0800
committerAndy Clement <aclement@pivotal.io>2019-01-30 16:29:02 -0800
commit24676e3ad3d20ad7d9e7ce1d3e03347883c1ddfd (patch)
tree12e2c3875f917c123cc89df3550f9facaf53bbc7 /testing-drivers/src/test/java
parentf4d5e9485ae910220e06b0b6c778587ed6b4ebb3 (diff)
downloadaspectj-24676e3ad3d20ad7d9e7ce1d3e03347883c1ddfd.tar.gz
aspectj-24676e3ad3d20ad7d9e7ce1d3e03347883c1ddfd.zip
mavenizing testing-drivers - wip
Diffstat (limited to 'testing-drivers/src/test/java')
-rw-r--r--testing-drivers/src/test/java/org/aspectj/testing/TestingDriversModuleTests.java36
-rw-r--r--testing-drivers/src/test/java/org/aspectj/testing/drivers/AjcHarnessTestsUsingJUnit.java60
-rw-r--r--testing-drivers/src/test/java/org/aspectj/testing/drivers/AjcTestsUsingJUnit.java48
-rw-r--r--testing-drivers/src/test/java/org/aspectj/testing/drivers/AjctestsAdapter.java382
-rw-r--r--testing-drivers/src/test/java/org/aspectj/testing/drivers/DriversTests.java35
-rw-r--r--testing-drivers/src/test/java/org/aspectj/testing/drivers/HarnessJUnitUtil.java320
-rw-r--r--testing-drivers/src/test/java/org/aspectj/testing/drivers/HarnessSelectionTest.java395
7 files changed, 1276 insertions, 0 deletions
diff --git a/testing-drivers/src/test/java/org/aspectj/testing/TestingDriversModuleTests.java b/testing-drivers/src/test/java/org/aspectj/testing/TestingDriversModuleTests.java
new file mode 100644
index 000000000..8cb8ddf30
--- /dev/null
+++ b/testing-drivers/src/test/java/org/aspectj/testing/TestingDriversModuleTests.java
@@ -0,0 +1,36 @@
+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 org.aspectj.testing.drivers.DriversTests;
+
+import junit.framework.*;
+import junit.framework.Test;
+
+/**
+ * TODO weaver dumping ajcore files when using this interface
+ */
+public class TestingDriversModuleTests extends TestCase {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(TestingDriversModuleTests.class.getName());
+ suite.addTest(DriversTests.suite());
+ return suite;
+ }
+
+ public TestingDriversModuleTests(String name) { super(name); }
+
+}
diff --git a/testing-drivers/src/test/java/org/aspectj/testing/drivers/AjcHarnessTestsUsingJUnit.java b/testing-drivers/src/test/java/org/aspectj/testing/drivers/AjcHarnessTestsUsingJUnit.java
new file mode 100644
index 000000000..efaae5c25
--- /dev/null
+++ b/testing-drivers/src/test/java/org/aspectj/testing/drivers/AjcHarnessTestsUsingJUnit.java
@@ -0,0 +1,60 @@
+/* *******************************************************************
+ * Copyright (c) 2003 Contributors
+ * 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:
+ * Wes Isberg initial implementation
+ * ******************************************************************/
+
+package org.aspectj.testing.drivers;
+
+import org.aspectj.ajdt.internal.core.builder.AjState;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/*
+ * Run harness tests as JUnit test suites.
+ */
+public class AjcHarnessTestsUsingJUnit extends TestCase {
+
+ /**
+ * Create TestSuite with harness validation tests.
+ * @return Test with all TestSuites and TestCases
+ * for the harness itself.
+ */
+ public static TestSuite suite() {
+ TestSuite result = HarnessJUnitUtil.suite(null, null, null);
+ result.addTest(
+ HarnessJUnitUtil.suite("harness",
+ new String[] {"../tests/ajcHarnessTests.xml"},
+ null
+ ));
+ result.addTest(
+ HarnessJUnitUtil.suite("harness selection tests",
+ new String[] {"testdata/incremental/harness/selectionTest.xml"},
+ null
+ ));
+ return result;
+ }
+
+ public AjcHarnessTestsUsingJUnit(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ AjState.FORCE_INCREMENTAL_DURING_TESTING = true;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ AjState.FORCE_INCREMENTAL_DURING_TESTING = false;
+ }
+}
diff --git a/testing-drivers/src/test/java/org/aspectj/testing/drivers/AjcTestsUsingJUnit.java b/testing-drivers/src/test/java/org/aspectj/testing/drivers/AjcTestsUsingJUnit.java
new file mode 100644
index 000000000..423404ee1
--- /dev/null
+++ b/testing-drivers/src/test/java/org/aspectj/testing/drivers/AjcTestsUsingJUnit.java
@@ -0,0 +1,48 @@
+/* *******************************************************************
+ * Copyright (c) 2003 Contributors
+ * 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:
+ * Wes Isberg initial implementation
+ * ******************************************************************/
+
+package org.aspectj.testing.drivers;
+
+import junit.framework.*;
+
+/**
+ * Run ajc tests as JUnit test suites.
+ * This class is named to avoid automatic inclusion in
+ * most JUnit test runs.
+ */
+public class AjcTestsUsingJUnit extends TestCase {
+ private static final String[] SUITES = new String[]
+ { "../tests/ajcTestsFailing.xml",
+ "../tests/ajcTests.xml"
+ };
+
+ private static final String SKIPS =
+ "-ajctestSkipKeywords=purejava,knownLimitation";
+ private static final String[][] OPTIONS = new String[][]
+ { new String[] { SKIPS },
+ new String[] { SKIPS, "-emacssym" }
+ };
+
+ /**
+ * Create TestSuite with all SUITES running all OPTIONS.
+ * @return Test with all TestSuites and TestCases
+ * specified in SUITES and OPTIONS.
+ */
+ public static Test suite() {
+ String name = AjcTestsUsingJUnit.class.getName();
+ return HarnessJUnitUtil.suite(name, SUITES, OPTIONS);
+ }
+
+ public AjcTestsUsingJUnit(String name) {
+ super(name);
+ }
+}
diff --git a/testing-drivers/src/test/java/org/aspectj/testing/drivers/AjctestsAdapter.java b/testing-drivers/src/test/java/org/aspectj/testing/drivers/AjctestsAdapter.java
new file mode 100644
index 000000000..05efb60e6
--- /dev/null
+++ b/testing-drivers/src/test/java/org/aspectj/testing/drivers/AjctestsAdapter.java
@@ -0,0 +1,382 @@
+/* *******************************************************************
+ * Copyright (c) 2003 Contributors
+ * 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:
+ * Wes Isberg initial implementation
+ * ******************************************************************/
+
+package org.aspectj.testing.drivers;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
+import org.aspectj.ajdt.internal.core.builder.AjState;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.IMessageHolder;
+import org.aspectj.bridge.MessageHandler;
+import org.aspectj.bridge.MessageUtil;
+import org.aspectj.testing.harness.bridge.AjcTest;
+import org.aspectj.testing.harness.bridge.RunSpecIterator;
+import org.aspectj.testing.harness.bridge.Sandbox;
+import org.aspectj.testing.harness.bridge.Validator;
+import org.aspectj.testing.run.IRunIterator;
+import org.aspectj.testing.run.RunStatus;
+import org.aspectj.testing.run.Runner;
+
+/*
+ * Adapt Harness tests to JUnit driver. This renders suite files as TestSuite
+ * and AjcTest as TestCase. When run, aborts are reported as error and fails as
+ * failures, with all messages stuffed into the one JUnit exception message.
+ * Test options are supported, but no harness options. The TestSuite
+ * implementation prevents us from re-running tests. In the Eclipse JUnit test
+ * runner, the tests display hierarchically and with annotations and with
+ * messages. You can stop the tests, but not traverse to the source or re-run
+ * the test.
+ */
+public class AjctestsAdapter extends TestSuite {
+ public static final String VERBOSE_NAME = AjctestsAdapter.class.getName()
+ + ".VERBOSE";
+
+ private static final boolean VERBOSE = HarnessJUnitUtil
+ .readBooleanSystemProperty(VERBOSE_NAME);
+
+ /**
+ * Factory to make and populate suite without options.
+ *
+ * @param suitePath
+ * the String path to a harness suite file
+ * @return AjctestJUnitSuite populated with tests
+ */
+ public static AjctestsAdapter make(String suitePath) {
+ return make(suitePath, null);
+ }
+
+ /**
+ * Factory to make and populate suite
+ *
+ * @param suitePath
+ * the String path to a harness suite file
+ * @param options
+ * the String[] options to use when creating tests
+ * @return AjctestJUnitSuite populated with tests
+ */
+ public static AjctestsAdapter make(String suitePath, String[] options) {
+ AjctestsAdapter result = new AjctestsAdapter(suitePath, options);
+ AjcTest.Spec[] tests = AjcTest.Suite.getTests(result.getSpec());
+ if (VERBOSE) {
+ log("loading " + tests.length + " tests in " + suitePath);
+ }
+ for (int i = 0; i < tests.length; i++) {
+ AjcTest.Spec ajcTest = tests[i];
+ result.addTest(new AjcTestSpecAsTest(ajcTest, result));
+ }
+ return result;
+ }
+
+ private static void log(String message) {
+ System.err.println(message);
+ System.err.flush();
+ }
+
+ private final String suitePath;
+
+ private final String[] options;
+
+ private AjcTest.Suite.Spec spec;
+
+ private Runner runner;
+
+ private Validator validator;
+
+ private IMessageHolder holder;
+
+ private Sandbox sandbox;
+
+ private File suiteDir;
+
+ private String name;
+
+ private AjctestsAdapter(String suitePath, String[] options) {
+ this.suitePath = suitePath;
+ String[] opts = new String[0];
+ if (!HarnessJUnitUtil.isEmpty(options)) {
+ opts = new String[options.length];
+ System.arraycopy(options, 0, opts, 0, opts.length);
+ }
+ this.options = opts;
+ }
+
+ public void addTest(Test test) {
+ if (!(test instanceof AjcTestSpecAsTest)) {
+ String m = "expecting AjcTestSpecAsTest, got "
+ + (null == test ? "null test" : test.getClass().getName()
+ + ": " + test);
+ throw new IllegalArgumentException(m);
+ }
+ super.addTest(test);
+ }
+
+ public void addTestSuite(Class testClass) {
+ throw new Error("unimplemented");
+ }
+
+ public String getName() {
+ if (null == name) {
+ name = HarnessJUnitUtil.cleanTestName(suitePath
+ + Arrays.asList(options));
+ }
+ return name;
+ }
+
+ /**
+ * Callback from test to run it using suite-wide holder, etc. The caller is
+ * responsible for calling result.startTest(test) and result.endTest(test);
+ *
+ * @param test
+ * the AjcTestSpecAsTest to run
+ * @param result
+ * the TestResult for any result messages (may be null)
+ */
+ protected void runTest(AjcTestSpecAsTest test, TestResult result) {
+ final Runner runner = getRunner();
+ final Sandbox sandbox = getSandbox();
+ final Validator validator = getValidator();
+ int numIncomplete = 0;
+ final RunStatus status = new RunStatus(new MessageHandler(), runner);
+ status.setIdentifier(test.toString());
+ try {
+ IMessageHolder holder = getHolder();
+ holder.clearMessages();
+ IRunIterator steps = test.spec.makeRunIterator(sandbox, validator);
+ if (0 < holder.numMessages(IMessage.ERROR, true)) {
+ MessageUtil.handleAll(status, holder, IMessage.INFO, true,
+ false);
+ } else {
+ runner.runIterator(steps, status, null);
+ }
+ if (steps instanceof RunSpecIterator) {
+ numIncomplete = ((RunSpecIterator) steps).getNumIncomplete();
+ }
+ } finally {
+ try {
+ // reportResult handles null TestResult
+ HarnessJUnitUtil
+ .reportResult(null, status, test, numIncomplete);
+ } finally {
+ validator.deleteTempFiles(true);
+ }
+ }
+ }
+
+ private File getSuiteDir() {
+ if (null == suiteDir) {
+ File file = new File(suitePath);
+ file = file.getParentFile();
+ if (null == file) {
+ file = new File(".");
+ }
+ suiteDir = file;
+ }
+ return suiteDir;
+ }
+
+ private Validator getValidator() {
+ if (null == validator) {
+ validator = new Validator(getHolder());
+ // XXX lock if keepTemp?
+ }
+ return validator;
+ }
+
+ private Runner getRunner() {
+ if (null == runner) {
+ runner = new Runner();
+ }
+ return runner;
+ }
+
+ private IMessageHolder getHolder() {
+ if (null == holder) {
+ holder = new MessageHandler();
+ }
+ return holder;
+ }
+
+ private AjcTest.Suite.Spec getSpec() {
+ if (null == spec) {
+ IMessageHolder holder = getHolder();
+ spec = HarnessJUnitUtil.getSuiteSpec(suitePath, options,
+ getHolder());
+ if (VERBOSE && holder.hasAnyMessage(null, true)) {
+ MessageUtil.print(System.err, holder, "skip ",
+ MessageUtil.MESSAGE_MOST);
+ }
+ holder.clearMessages();
+ }
+ return spec;
+ }
+
+ private Sandbox getSandbox() {
+ if (null == sandbox) {
+ sandbox = new Sandbox(spec.getSuiteDirFile(), getValidator());
+ }
+ return sandbox;
+ }
+
+ /**
+ * Wrap AjcTest.Spec for lookup by description
+ *
+ * @author wes
+ */
+ public static class SpecTests {
+ private static final HashMap TESTS = new HashMap();
+
+// private static void putSpecTestsFor(String id, SpecTests tests) {
+// TESTS.put(id, tests);
+// }
+
+ private static SpecTests getSpecTestsFor(String id) {
+ SpecTests result = (SpecTests) TESTS.get(id);
+ if (null == result) {
+ throw new Error("no tests found for " + id);
+ }
+ return result;
+ }
+
+ // ------------------------------------
+ final AjctestsAdapter mAjctestsAdapter;
+
+ private final Map mDescriptionToAjcTestSpec;
+
+ // ------------------------------------
+ private SpecTests(AjctestsAdapter ajctestsAdapter, AjcTest.Spec[] tests) {
+ mAjctestsAdapter = ajctestsAdapter;
+ Map map = new HashMap();
+ for (int i = 0; i < tests.length; i++) {
+ map.put(tests[i].getDescription(), tests[i]);
+ }
+
+ mDescriptionToAjcTestSpec = Collections.unmodifiableMap(map);
+ }
+
+ /**
+ * @param description
+ * the String description of the test
+ * @throws IllegalArgumentException
+ * if testName is not found
+ */
+ protected void runTest(String description) {
+ AjcTest.Spec spec = getSpec(description);
+ AjctestsAdapter.AjcTestSpecAsTest ajcTestAsSpec = new AjctestsAdapter.AjcTestSpecAsTest(
+ spec, mAjctestsAdapter);
+ // runTest handles null TestResult
+ mAjctestsAdapter.runTest(ajcTestAsSpec, null);
+ }
+
+ /**
+ * @param description
+ * the String description of the test
+ * @throws IllegalArgumentException
+ * if testName is not found
+ */
+ private AjcTest.Spec getSpec(String description) {
+ AjcTest.Spec spec = (AjcTest.Spec) mDescriptionToAjcTestSpec
+ .get(description);
+ if (null == spec) {
+ throw new IllegalArgumentException("no test for " + description);
+ }
+ return spec;
+ }
+
+ /**
+ * makeUsingTestClass(..) extends this to create TestCase with
+ * test_{name} for each test case.
+ */
+ public static class TestClass extends TestCase {
+ public TestClass() {
+ }
+ private SpecTests mTests;
+
+ /**
+ * Called by code generated in makeUsingTestClass(..)
+ *
+ * @param description
+ * the String identifier of the test stored in SpecTests
+ * mTests.
+ * @throws Error
+ * on first and later uses if getTestsFor() returns
+ * null.
+ */
+ public final void runTest(String description) {
+ if (null == mTests) {
+ String classname = getClass().getName();
+ mTests = getSpecTestsFor(classname);
+ }
+ mTests.runTest(description);
+ }
+ }
+ }
+
+ /** Wrap AjcTest.Spec as a TestCase. Run by delegation to suite */
+ private static class AjcTestSpecAsTest extends TestCase implements
+ HarnessJUnitUtil.IHasAjcSpec {
+ // this could implement Test, but Ant batchtest fails to pull name
+ final String name;
+
+ final AjcTest.Spec spec;
+
+ AjctestsAdapter suite;
+
+ AjcTestSpecAsTest(AjcTest.Spec spec, AjctestsAdapter suite) {
+ super(HarnessJUnitUtil.cleanTestName(spec.getDescription()));
+ this.name = HarnessJUnitUtil.cleanTestName(spec.getDescription());
+ this.suite = suite;
+ this.spec = spec;
+ spec.setSuiteDir(suite.getSuiteDir());
+ }
+
+ public int countTestCases() {
+ return 1;
+ }
+
+ public AjcTest.Spec getAjcTestSpec() {
+ return spec;
+ }
+
+ public void run(TestResult result) {
+ if (null == suite) {
+ throw new Error("need to re-init");
+ }
+ try {
+ AjState.FORCE_INCREMENTAL_DURING_TESTING = true;
+ result.startTest(this);
+ suite.runTest(this, result);
+ } finally {
+ result.endTest(this);
+ suite = null;
+ AjState.FORCE_INCREMENTAL_DURING_TESTING = false;
+ }
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String toString() {
+ return name;
+ }
+ }
+} \ No newline at end of file
diff --git a/testing-drivers/src/test/java/org/aspectj/testing/drivers/DriversTests.java b/testing-drivers/src/test/java/org/aspectj/testing/drivers/DriversTests.java
new file mode 100644
index 000000000..da277f135
--- /dev/null
+++ b/testing-drivers/src/test/java/org/aspectj/testing/drivers/DriversTests.java
@@ -0,0 +1,35 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation,
+ * 2002 Palo Alto Research Center, Incorporated (PARC)
+ * 2003 Contributors.
+ * 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
+ * Wes Isberg added JUnit harness adapters
+ * ******************************************************************/
+
+
+package org.aspectj.testing.drivers;
+
+import junit.framework.*;
+
+public class DriversTests extends TestCase {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(DriversTests.class.getName());
+ // AjcTestsUsingJUnit takes too long to include by default
+ //$JUnit-BEGIN$
+ suite.addTestSuite(HarnessSelectionTest.class);
+ suite.addTest(AjcHarnessTestsUsingJUnit.suite());
+ //$JUnit-END$
+ return suite;
+ }
+
+ public DriversTests(String name) { super(name); }
+
+}
diff --git a/testing-drivers/src/test/java/org/aspectj/testing/drivers/HarnessJUnitUtil.java b/testing-drivers/src/test/java/org/aspectj/testing/drivers/HarnessJUnitUtil.java
new file mode 100644
index 000000000..d3e05f84c
--- /dev/null
+++ b/testing-drivers/src/test/java/org/aspectj/testing/drivers/HarnessJUnitUtil.java
@@ -0,0 +1,320 @@
+/* *******************************************************************
+ * Copyright (c) 2003 Contributors
+ * 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:
+ * Wes Isberg initial implementation
+ * ******************************************************************/
+
+package org.aspectj.testing.drivers;
+
+import java.io.*;
+import java.util.*;
+
+import junit.framework.*;
+
+import org.aspectj.bridge.*;
+//import org.aspectj.bridge.MessageHandler;
+import org.aspectj.testing.harness.bridge.*;
+import org.aspectj.testing.run.IRunStatus;
+import org.aspectj.testing.util.RunUtils;
+import org.aspectj.testing.util.RunUtils.IRunStatusPrinter;
+import org.aspectj.testing.xml.AjcSpecXmlReader;
+
+/**
+ * Utilities for adapting AjcTest.{Suite.}Spec to JUnit.
+ */
+public class HarnessJUnitUtil {
+ /** bug?: eclipse RemoteTestRunner hangs if n>1 */
+ public static final boolean ONE_ERROR_PER_TEST = true;
+ public static final boolean FLATTEN_RESULTS = true;
+ public static final boolean PRINT_OTHER_MESSAGES = false;
+
+ /**
+ * Create TestSuite with all suites running all options.
+ * @param suites the String[] of paths to harness test suite files
+ * @param options the String[][] of option sets to run (may be null)
+ * @return Test with all TestSuites and TestCases
+ * specified in suites and options.
+ */
+ public static TestSuite suite(String name, String[] suites, String[][] options) {
+ if (null == name) {
+ name = AjcHarnessTestsUsingJUnit.class.getName();
+ }
+ TestSuite suite = new TestSuite(name);
+ if (!HarnessJUnitUtil.isEmpty(suites)) {
+ if (HarnessJUnitUtil.isEmpty(options)) {
+ options = new String[][] {new String[0]};
+ }
+ for (int i = 0; i < suites.length; i++) {
+ for (int j = 0; j < options.length; j++) {
+ Test t = AjctestsAdapter.make(suites[i], options[j]);
+ suite.addTest(t);
+ }
+ }
+ }
+ return suite;
+ }
+
+ public static boolean isEmpty(Object[] ra) {
+ return ((null == ra) || (0 == ra.length));
+ }
+ /**
+ * Render status using a given printer.
+ * @param status the IRunStatus to render to String
+ * @param printer the IRunStatusPrinter to use
+ * (defaults to AJC_PRINTER if null)
+ * @return the String rendering of the status,
+ * or "((IRunStatus) null)" if null
+ */
+ public static String render(IRunStatus status, IRunStatusPrinter printer) {
+ if (null == status) {
+ return "((IRunStatus) null)";
+ }
+ if (null == printer) {
+ printer = RunUtils.AJC_PRINTER;
+ }
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ PrintStream out = new PrintStream(outStream);
+ printer.printRunStatus(out, status);
+ out.flush();
+
+ return outStream.toString();
+ }
+
+ /**
+ * Dump results for Test from status into TestResult.
+ * FAIL is a failure,
+ * ERROR and ABORT are errors,
+ * and INFO, WARNING, and DEBUG are ignored.
+ * If test instanceof IHasAjcSpec, and the keywords contain "expect-fail",
+ * then failures are not reported (but passes are reported as a failure).
+ * @param result the TestResult sink
+ * @param status the IRunStatus source
+ * @param test the Test to associate with the results
+ * @param numIncomplete ignored
+ * @return 0 (ignored)
+ */
+ public static int reportResult(
+ TestResult result,
+ IRunStatus status,
+ Test test,
+ int numIncomplete) {
+ boolean expectFail = false;
+ if (test instanceof IHasAjcSpec) {
+ AjcTest.Spec spec = ((IHasAjcSpec) test).getAjcTestSpec();
+ expectFail = spec.getKeywordsList().contains("expect-fail");
+ }
+ if (status.runResult()) {
+ if (expectFail) {
+ String m = "did not fail as expected per expect-fail keyword";
+ reportResultToJUnit(m, false, true, test, result);
+ }
+ } else if (!expectFail) {
+ final boolean includeChildren = true;
+ if (status.hasAnyMessage(IMessage.FAIL, false, includeChildren)) {
+ String m = render(status, null);
+ reportResultToJUnit(m, false, true, test, result);
+ } else if (status.hasAnyMessage(IMessage.ERROR, true, includeChildren)) {
+ String m = render(status, null);
+ reportResultToJUnit(m, true, false, test, result);
+ } // /XXX skip INFO, DEBUG
+ }
+ return 0; // XXX not doing incomplete
+ }
+
+ /**
+ * Report results as error, failure, or success (ignored),
+ * differently if result is null
+ * @param description the String description of the result
+ * @param isError if true, report as failure
+ * @param isFailure if true and not isError, report as failure
+ * @param test the Test case
+ * @param result the TestResult sink - ignored if null
+ * @return 0
+ */
+ private static int reportResultToJUnit(String description, boolean isError, boolean isFailure, Test test, TestResult result) {
+ if (null != result) {
+ if (isError) {
+ result.addError(test, new AssertionFailedError(description));
+ } else if (isFailure) {
+ result.addFailure(test, new AssertionFailedError(description));
+ } // no need to log success
+ } else { // have to throw failure
+ if (isError) {
+ String m = safeTestName(test) + " " + description;
+ throw new Error(m);
+ } else if (isFailure) {
+// String m = safeTestName(test) + " " + description;
+ throw new AssertionFailedError(description);
+ } // no need to log success
+ }
+ return 0;
+ }
+
+// public static int reportResultComplex(
+// TestResult result,
+// IRunStatus status,
+// Test test,
+// int numIncomplete) {
+// int errs = 0;
+// if (FLATTEN_RESULTS) {
+// IRunStatus[] kids = status.getChildren();
+// for (int i = 0; i < kids.length; i++) {
+// errs += reportResult(result, kids[i], test, 0);
+// if ((errs > 0) && ONE_ERROR_PER_TEST) {
+// return errs;
+// }
+// }
+// }
+//
+// Throwable thrown = status.getThrown();
+// if (null != thrown) { // always report this? XXX what if expected?
+// result.addError(test, thrown);
+// errs++;
+// }
+// boolean previewPass = status.runResult();
+// IMessage[] errors = status.getMessages(null, true);
+// for (int i = 0; ((errs == 0) || !ONE_ERROR_PER_TEST)
+// && i < errors.length; i++) {
+// IMessage message = errors[i];
+// if (message.isAbort()) {
+// result.addError(test, new ErrorMessage(message));
+// errs++;
+// } else if (message.isFailed()) {
+// result.addFailure(test, new ErrorMessage(message));
+// errs++;
+// } else if (PRINT_OTHER_MESSAGES || !previewPass) {
+// System.out.println("#### message for " + test + ": ");
+// System.out.println(message);
+// }
+// }
+// if (((errs == 0) || !ONE_ERROR_PER_TEST)
+// && ((errs == 0) != status.runResult())) {
+// String s = "expected pass=" + (errs == 0);
+// result.addFailure(test, new ErrorMessage(s));
+// errs++;
+// }
+// if (((errs == 0) || !ONE_ERROR_PER_TEST)
+// && !status.isCompleted()) {
+// result.addFailure(test, new ErrorMessage("test incomplete? "));
+// errs++;
+// }
+// if (((errs == 0) || !ONE_ERROR_PER_TEST)
+// && (0 < numIncomplete)) {
+// result.addFailure(test, new ErrorMessage("incomplete steps: " + numIncomplete));
+// errs++;
+// }
+// return errs;
+// }
+
+ /**
+ * @return TestCase.getName() or Test.toString() or "nullTest"
+ */
+ public static String safeTestName(Test test) {
+ if (test instanceof TestCase) {
+ return ((TestCase) test).getName();
+ } else if (null != test) {
+ return test.toString();
+ } else {
+ return "nullTest";
+ }
+ }
+
+ /**
+ * Fix up test names for JUnit.
+ * (i.e., workaround eclipse JUnit bugs)
+ * @param name the String identifier for the test
+ * @return the String permitted by (Eclipse) JUnit support
+ */
+ public static String cleanTestName(String name) {
+ name = name.replace(',', ' ');
+ name = name.replace('[', ' ');
+ name = name.replace(']', ' ');
+ name = name.replace('-', ' ');
+ return name;
+ }
+
+ public static boolean readBooleanSystemProperty(String name) {
+ boolean result = false;
+ try {
+ result = Boolean.getBoolean(name);
+ } catch (Throwable t) {
+ // ignore
+ }
+ return result;
+ }
+
+ /**
+ * Get the test suite specifications from the suite file,
+ * apply the options to all,
+ * and report any messages to the holder.
+ * @param suitePath the String path to the harness suite file
+ * @param options the String[] options for the tests - may be null
+ * @param holder the IMessageHolder for any messages - may be null
+ * @return AjcTest.Suite.Spec test descriptions
+ * (non-null but empty if some error)
+ */
+ public static AjcTest.Suite.Spec getSuiteSpec(
+ String suitePath,
+ String[] options,
+ IMessageHolder holder) {
+ if (null == suitePath) {
+ MessageUtil.fail(holder, "null suitePath");
+ return EmptySuite.ME;
+ }
+ File suiteFile = new File(suitePath);
+ if (!suiteFile.canRead() || !suiteFile.isFile()) {
+ MessageUtil.fail(holder, "unable to read file " + suitePath);
+ return EmptySuite.ME;
+ }
+ try {
+ AjcTest.Suite.Spec tempSpec;
+ AbstractRunSpec.RT runtime = new AbstractRunSpec.RT();
+ tempSpec = AjcSpecXmlReader.getReader().
+ readAjcSuite(suiteFile);
+ tempSpec.setSuiteDirFile(suiteFile.getParentFile());
+ if (null == options) {
+ options = new String[0];
+ }
+ runtime.setOptions(options);
+ boolean skip = !tempSpec.adoptParentValues(runtime, holder);
+ if (skip) {
+ tempSpec = EmptySuite.ME;
+ }
+ return tempSpec;
+ } catch (IOException e) {
+ MessageUtil.abort(holder, "IOException", e);
+ return EmptySuite.ME;
+ }
+ }
+
+ private static class EmptySuite extends AjcTest.Suite.Spec {
+ static final EmptySuite ME = new EmptySuite();
+ final ArrayList children;
+ private EmptySuite(){
+ children = new ArrayList() {
+ // XXX incomplete...
+ public void add(int arg0, Object arg1) { fail();}
+ public boolean addAll(int arg0, Collection arg1) { return fail();}
+ public boolean addAll(Collection o) { return fail(); }
+ public boolean add(Object o) { return fail(); }
+ public boolean remove(Object o) { return fail(); }
+ private boolean fail() {
+ throw new Error("unmodifiable");
+ }
+ };
+ }
+ public ArrayList getChildren() {
+ return children;
+ }
+ }
+ public interface IHasAjcSpec {
+ AjcTest.Spec getAjcTestSpec();
+ }
+}
+
diff --git a/testing-drivers/src/test/java/org/aspectj/testing/drivers/HarnessSelectionTest.java b/testing-drivers/src/test/java/org/aspectj/testing/drivers/HarnessSelectionTest.java
new file mode 100644
index 000000000..ac937ac44
--- /dev/null
+++ b/testing-drivers/src/test/java/org/aspectj/testing/drivers/HarnessSelectionTest.java
@@ -0,0 +1,395 @@
+/* *******************************************************************
+ * 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.drivers;
+
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.MessageHandler;
+import org.aspectj.bridge.MessageUtil;
+import org.aspectj.testing.harness.bridge.AbstractRunSpec;
+import org.aspectj.testing.harness.bridge.AjcTest;
+import org.aspectj.testing.harness.bridge.IRunSpec;
+import org.aspectj.testing.run.IRunStatus;
+import org.aspectj.testing.run.RunValidator;
+import org.aspectj.testing.util.BridgeUtil;
+import org.aspectj.testing.util.RunUtils;
+import org.aspectj.testing.xml.AjcSpecXmlReader;
+import org.aspectj.util.LangUtil;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+/**
+ * The harness supports custom-coded queries based on
+ * -ajctest{kind}={query} parameters
+ * (until we move to an XML database with real queries).
+ */
+public class HarnessSelectionTest extends TestCase {
+ private static final String TESTDATA = "../testing-drivers/testdata";
+ private static final String INC_HARNESS_DIR
+ = TESTDATA + "/incremental/harness";
+ private static final String SELECT
+ = INC_HARNESS_DIR + "/selectionTest.xml";
+
+ /** @see testIncrementalSuite() */
+ private static final String INCREMENTAL
+ = INC_HARNESS_DIR + "/suite.xml";
+
+ private static final String TITLE_LIST_ONE
+ = INC_HARNESS_DIR + "/titleListOne.txt";
+
+ private static final String TITLE_LIST_PLURAL
+ = INC_HARNESS_DIR + "/titleListPlural.txt";
+
+ private static Hashtable SPECS = new Hashtable();
+
+ private static AjcTest.Suite.Spec getSpec(String suiteFile) {
+ AjcTest.Suite.Spec result = (AjcTest.Suite.Spec) SPECS.get(suiteFile);
+ if (null == result) {
+ try {
+ result = AjcSpecXmlReader.getReader().readAjcSuite(new File(suiteFile));
+ SPECS.put(suiteFile, result);
+ } catch (IOException e) {
+ e.printStackTrace(System.err);
+ }
+ }
+ try {
+ return (AjcTest.Suite.Spec) result.clone();
+ } catch (CloneNotSupportedException e) {
+ e.printStackTrace(System.err);
+ assertTrue("clone failed: " + e, false);
+ return null; // keep compiler happy
+ }
+ }
+
+ private boolean verbose;
+
+ public HarnessSelectionTest(String name) {
+ super(name);
+ }
+
+ public void testFilesAvailable() {
+ String[] files = new String[] {
+ SELECT, INCREMENTAL, TITLE_LIST_ONE, TITLE_LIST_PLURAL
+ };
+ for (int i = 0; i < files.length; i++) {
+ assertTrue(files[i], new File(files[i]).canRead());
+ }
+ }
+
+ public void testIncrementalSuite() {
+ System.err.println("skipping testIncrementalSuite - too long");
+ if (true) return;
+ if (!eclipseAvailable()) {
+ System.err.println("skipping test - eclipse classes not available");
+ return;
+ }
+ String[] options = new String[]
+ { "!verbose", "!eclipse",
+ };
+ Exp exp = new Exp(6, 6, 0, 6, 0, 0, 0);
+ checkSelection(INCREMENTAL, options, "INFIX IGNORED", exp);
+ }
+
+ public void testKeywordSelectionBoth() {
+ if (!eclipseAvailable()) {
+ System.err.println("skipping test - eclipse classes not available");
+ return;
+ }
+ String[] options = new String[]
+ { "-ajctestRequireKeywords=requireKeyword",
+ "-ajctestSkipKeywords=skipKeyword,skipUnenforcedAjcLimit",
+ "!verbose",
+ "-eclipse",
+ };
+ Exp exp = new Exp(17, 1, 16, 1, 0, 0, 1);
+ checkSelection(SELECT, options, "keyword skipKeyword was found", exp);
+ }
+
+ public void testKeywordSelectionRequire() {
+ if (!eclipseAvailable()) {
+ System.err.println("skipping test - eclipse classes not available");
+ return;
+ }
+ String[] options = new String[]
+ { "-ajctestRequireKeywords=skipKeyword",
+ "!verbose",
+ "-eclipse",
+ };
+ Exp exp = new Exp(17, 1, 16, 1, 0, 0, 16);
+ checkSelection(SELECT, options, "keyword skipKeyword was not found", exp);
+ }
+
+ public void testKeywordSelectionSkip() {
+ if (!eclipseAvailable()) {
+ System.err.println("skipping test - eclipse classes not available");
+ return;
+ }
+ String[] options = new String[]
+ { "-ajctestSkipKeywords=requireKeyword",
+ "!verbose",
+ "-eclipse",
+ };
+ Exp exp = new Exp(17, 0, 17, 0, 0, 0, 17);
+ checkSelection(SELECT, options, "keyword requireKeyword was found", exp);
+ }
+
+ public void testNoOptions() {
+ if (!ajcAvailable()) {
+ System.err.println("skipping test - ajc classes not available");
+ return;
+ }
+ String[] options = new String[]
+ { "!ajc"
+ };
+ Exp exp = new Exp(17, 3, 14, 3, 0, 0, 4);
+ checkSelection(SELECT, options, "normally-valid", exp);
+ }
+
+ public void testEclipseOptionsSkip() {
+ String[] options = new String[]
+ { "-eclipse",
+ "-ajctestRequireKeywords=eclipseOptionSkip"
+ };
+ Exp exp = new Exp(17, 0, 17, 0, 0, 0, 6);
+ checkSelection(SELECT, options, "old ajc 1.0 option", exp);
+ }
+
+ public void testAjcEclipseConflict() {
+ if (!ajcAvailable()) {
+ System.err.println("skipping test - ajc classes not available");
+ return;
+ }
+ String[] options = new String[]
+ { "!ajc"
+ };
+ Exp exp = new Exp(17, 3, 14, 3, 0, 0, 6);
+ checkSelection(SELECT, options, "conflict between !eclipse and !ajc", exp);
+ }
+
+ public void testEclipseConflict() {
+ String[] options = new String[]
+ { "^eclipse",
+ "-ajctestSkipKeywords=skipUnenforcedAjcLimit"
+ };
+ Exp exp = new Exp(17, 3, 14, 3, 0, 0, 6);
+ checkSelection(SELECT, options, "force conflict between eclipse", exp);
+ }
+
+ public void testSinglePR() {
+ String[] options = new String[]
+ { "-eclipse", "-ajctestPR=100"
+ };
+ Exp exp = new Exp(17, 1, 16, 1, 0, 0, 16);
+ checkSelection(SELECT, options, "bugId required", exp);
+ }
+
+ public void testTwoPR() {
+ String[] options = new String[]
+ { "-eclipse", "-ajctestPR=100,101"
+ };
+ Exp exp = new Exp(17, 2, 15, 2, 0, 0, 15);
+ checkSelection(SELECT, options, "bugId required", exp);
+ }
+
+ public void testTitleContainsSubstringSelection() {
+ String[] options = new String[]
+ { "-ajctestTitleContains=run and ",
+ "-eclipse"
+ };
+ Exp exp = new Exp(17, 1, 16, 1, 0, 0, 16);
+ checkSelection(SELECT, options, "run and", exp);
+ }
+
+ public void testTitleContainsSubstringSelectionPlural() {
+ String[] options = new String[]
+ { "-ajctestTitleContains= run and , if skipKeyword ",
+ "-eclipse"
+ };
+ Exp exp = new Exp(17, 2, 15, 2, 0, 0, 15);
+ checkSelection(SELECT, options, "title", exp);
+ }
+
+ public void testTitleContainsExactSelection() {
+ String[] options = new String[]
+ { "-ajctestTitleContains=run and pass",
+ "-eclipse"
+ };
+ Exp exp = new Exp(17, 1, 16, 1, 0, 0, 16);
+ checkSelection(SELECT, options, "run and pass", exp);
+ }
+
+ public void testTitleContainsExactSelectionPlural() {
+ String[] options = new String[]
+ { "-ajctestTitleContains= run and pass , omit if skipKeyword ",
+ "-eclipse"
+ };
+ Exp exp = new Exp(17, 2, 15, 2, 0, 0, 15);
+ checkSelection(SELECT, options, "title", exp);
+ }
+
+ public void testTitleListSelection() {
+ String[] options = new String[]
+ { "-ajctestTitleList=run and pass",
+ "-eclipse"
+ };
+ Exp exp = new Exp(17, 1, 16, 1, 0, 0, 16);
+ checkSelection(SELECT, options, "run and pass", exp);
+ }
+
+ public void testTitleListSelectionPlural() {
+ String[] options = new String[]
+ { "-ajctestTitleList= run and pass , omit if skipKeyword ",
+ "-eclipse"
+ };
+ Exp exp = new Exp(17, 2, 15, 2, 0, 0, 15);
+ checkSelection(SELECT, options, "title", exp);
+ }
+
+ public void testTitleListFileSelection() {
+ String[] options = new String[]
+ { "-ajctestTitleList=" + TITLE_LIST_ONE,
+ "-eclipse"
+ };
+ Exp exp = new Exp(17, 1, 16, 1, 0, 0, 16);
+ checkSelection(SELECT, options, TITLE_LIST_ONE, exp);
+ }
+
+ public void testTitleListFileSelectionPlural() {
+ String[] options = new String[]
+ { "-ajctestTitleList=" + TITLE_LIST_PLURAL,
+ "-eclipse"
+ };
+ Exp exp = new Exp(17, 2, 15, 2, 0, 0, 15);
+ checkSelection(SELECT, options, TITLE_LIST_PLURAL, exp);
+
+ // Now check the "fail only" path
+ options = new String[]
+ { "-ajctestTitleFailList=" + TITLE_LIST_PLURAL,
+ "-eclipse"
+ };
+ // 1 messages skipped when run under 1.4 for other reasons,
+ // so count "skip" instead of TITLE_LIST_PLURAL
+ exp = new Exp(17, 2, 15, 2, 0, 0, 15);
+ checkSelection(SELECT, options, "skip", exp);
+ }
+
+ /**
+ * Run the static test suite with the given options.
+ * @param setupHolder the IMessageHolder for any setup messages
+ * @return null if setup failed or Harness.RunResult if suite completed.
+ */
+ private Harness.RunResult runSuite(String suiteFile, String[] options, MessageHandler setupHolder) {
+ AbstractRunSpec.RT runtime = new AbstractRunSpec.RT();
+ runtime.setOptions(options);
+ AjcTest.Suite.Spec spec = getSpec(suiteFile);
+ assertNotNull(spec);
+ ArrayList<IRunSpec> kids = spec.getChildren();
+ assertNotNull(kids);
+ if ((suiteFile == SELECT) && (17 != kids.size())) {
+ assertTrue("expected 17 kids, got " + kids.size(), false);
+ }
+ if (!spec.adoptParentValues(runtime, setupHolder)) {
+ return null;
+ } else {
+ class TestHarness extends Harness {
+ public RunResult run(AjcTest.Suite.Spec spec) {
+ return super.run(spec);
+ }
+ }
+ TestHarness h = new TestHarness();
+ return h.run(spec);
+ }
+ }
+
+ class Exp {
+ public final int tests;
+ public final int testsRun;
+ public final int skipped;
+ public final int passed;
+ public final int failed;
+ public final int incomplete;
+ public final int infix;
+ Exp(int tests, int testsRun, int skipped, int passed, int failed, int incomplete, int infix) {
+ this.tests = tests;
+ this.testsRun = testsRun;
+ this.skipped = skipped;
+ this.passed = passed;
+ this.failed = failed;
+ this.incomplete = incomplete;
+ this.infix = infix;
+ }
+ }
+
+ public void checkSelection(String suiteFile, String[] options, String infoInfix, Exp exp) {
+ MessageHandler holder = new MessageHandler();
+ Harness.RunResult result = runSuite(suiteFile, options, holder);
+ if (verbose) {
+ MessageUtil.print(System.out, holder, " setup - ");
+ }
+ assertNotNull("Harness.RunResult", result);
+ // XXX sync hack snooping of message text with skip messages, harness
+ final List skipList = MessageUtil.getMessages(holder, IMessage.INFO, false, "skip");
+ final int numSkipped = skipList.size();
+ IRunStatus status = result.status;
+ assertNotNull(status);
+ if (verbose) {
+ RunUtils.print(System.out, "result - ", status);
+ System.out.println(BridgeUtil.childString(status, numSkipped, result.numIncomplete));
+ }
+ assertEquals("skips", exp.skipped, numSkipped);
+ IRunStatus[] children = status.getChildren();
+ assertNotNull(children);
+ assertTrue(children.length + "!= expRun=" + exp.testsRun,
+ exp.testsRun == children.length);
+ int actPass = 0;
+ for (int i = 0; i < children.length; i++) {
+ if (RunValidator.NORMAL.runPassed(children[i])) {
+ actPass++;
+ }
+ }
+ if (exp.passed != actPass) {
+ assertTrue("exp.passed=" + exp.passed + " != actPass=" + actPass, false);
+ }
+ if (!LangUtil.isEmpty(infoInfix)) {
+ int actInfix = MessageUtil.getMessages(holder, IMessage.INFO, false, infoInfix).size();
+ if (actInfix != exp.infix) {
+ String s = "for infix \"" + infoInfix
+ + "\" actInfix=" + actInfix + " != expInfix=" + exp.infix;
+ assertTrue(s, false);
+ }
+ }
+ }
+
+ private boolean ajcAvailable() { // XXX util
+ try {
+ return (null != Class.forName("org.aspectj.compiler.base.JavaCompiler"));
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
+
+ private boolean eclipseAvailable() { // XXX util
+ try {
+ return (null != Class.forName("org.aspectj.ajdt.ajc.AjdtCommand"));
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+}