1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
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 (String s : suites) {
for (String[] option : options) {
Test t = AjctestsAdapter.make(s, option);
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();
}
}
|