comparison graal/com.oracle.max.base/src/com/sun/max/test/TestEngine.java @ 3733:e233f5660da4

Added Java files from Maxine project.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sat, 17 Dec 2011 19:59:18 +0100
parents
children bc8527f3071c
comparison
equal deleted inserted replaced
3732:3e2e8b8abdaf 3733:e233f5660da4
1 /*
2 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package com.sun.max.test;
24
25 import java.io.*;
26 import java.util.*;
27 import java.util.regex.Pattern;
28
29 import com.sun.max.*;
30 import com.sun.max.program.*;
31 import com.sun.max.util.*;
32
33 /**
34 * The {@code TestEngine} class implements the basic test engine for the testing framework, including loading of test
35 * cases and organizing their output.
36 */
37 public class TestEngine {
38
39 protected int verbose = 2;
40
41 protected final LinkedList<TestCase> allTests;
42 protected final LinkedList<TestCase> failTests;
43 protected final LinkedList<TestCase> passTests;
44 protected final LinkedList<File> skipFiles;
45 protected final Queue<TestCase> queue;
46 protected final Registry<TestHarness> registry;
47 protected int finished;
48 protected ProgressPrinter progress;
49
50 public TestEngine(Registry<TestHarness> registry) {
51 allTests = new LinkedList<TestCase>();
52 failTests = new LinkedList<TestCase>();
53 passTests = new LinkedList<TestCase>();
54 skipFiles = new LinkedList<File>();
55 queue = new LinkedList<TestCase>();
56 this.registry = registry;
57 }
58
59 public static void main(String[] args) {
60 final TestEngine e = new TestEngine(new Registry<TestHarness>(TestHarness.class, true));
61 e.parseAndRunTests(args);
62 e.report(System.out);
63 }
64
65 public synchronized void addTest(TestCase testCase) {
66 testCase.testNumber = allTests.size();
67 allTests.add(testCase);
68 queue.offer(testCase);
69 }
70
71 public synchronized void skipFile(File file) {
72 skipFiles.add(file);
73 }
74
75 public void setVerboseLevel(int level) {
76 verbose = level;
77 }
78
79 public void report(PrintStream stream) {
80 progress.report();
81 if (skipFiles.size() > 0) {
82 stream.println(skipFiles.size() + " file(s) skipped");
83 for (File f : skipFiles) {
84 stream.println(f.getName());
85 }
86 }
87 }
88
89 public void parseAndRunTests(String[] args) {
90 this.parseAndRunTests(args, null);
91 }
92
93 public void parseAndRunTests(String[] args, String filter) {
94 parseTests(args, true, filter);
95 progress = new ProgressPrinter(System.out, allTests.size(), verbose, false);
96 for (TestCase tcase = queue.poll(); tcase != null; tcase = queue.poll()) {
97 runTest(tcase);
98 }
99 }
100
101 public void parseTests(String[] args, boolean sort) {
102 this.parseTests(args, sort, null);
103 }
104
105 public void parseTests(String[] args, boolean sort, String filter) {
106 for (String arg : args) {
107 final File f = new File(arg);
108 parseTests(f, registry, sort, filter);
109 }
110 }
111
112 public Iterable<TestCase> getAllTests() {
113 return allTests;
114 }
115
116 private synchronized TestCase dequeue() {
117 return queue.remove();
118 }
119
120 private void runTest(TestCase testCase) {
121 try {
122 // run the test (records thrown exceptions internally)
123 startTest(testCase);
124 testCase.test();
125 final Class<TestHarness<TestCase>> type = null;
126 // evaluate the result of test
127 final TestResult result = Utils.cast(type, testCase.harness).evaluateTest(this, testCase);
128 testCase.result = result;
129 } catch (Throwable t) {
130 // there was an exception evaluating the result of the test
131 testCase.result = new TestResult.UnexpectedException("Unexpected exception in test evaluation", t);
132 } finally {
133 finishTest(testCase);
134 }
135 }
136
137 private synchronized void startTest(TestCase testCase) {
138 progress.begin(testCase.file.toString());
139 }
140
141 private synchronized void finishTest(TestCase testCase) {
142 final boolean passed = testCase.result.isSuccess();
143 if (passed) {
144 passTests.add(testCase);
145 progress.pass();
146 } else {
147 failTests.add(testCase);
148 progress.fail(testCase.result.failureMessage(testCase));
149 }
150 }
151
152 private void parseTests(File file, Registry<TestHarness> reg, boolean sort, String filter) {
153 if (!file.exists()) {
154 throw new Error("file " + file + " not found.");
155 }
156 if (file.isDirectory()) {
157 for (File dirFile : getFilesFromDirectory(file, sort)) {
158 if (!dirFile.isDirectory()) {
159 parseFile(dirFile, reg, filter);
160 }
161 }
162 } else {
163 parseFile(file, reg, filter);
164 }
165 }
166
167 private File[] getFilesFromDirectory(File dir, boolean sort) {
168 final File[] list = dir.listFiles();
169 if (sort) {
170 Arrays.sort(list);
171 }
172 return list;
173 }
174
175 private void parseFile(File file, Registry<TestHarness> reg, String filter) {
176 if (filter != null) {
177 if (filter.startsWith("~")) {
178 filter = filter.substring(1);
179 if (!Pattern.compile(filter).matcher(file.getName()).find()) {
180 return;
181 }
182 } else {
183 if (!file.getName().contains(filter)) {
184 return;
185 }
186 }
187 }
188 parseFile(file, reg);
189 }
190
191 private void parseFile(File file, Registry<TestHarness> reg) {
192 try {
193 final Properties props = parseTestProperties(file);
194 final String hname = props.getProperty("Harness");
195
196 if (hname != null) {
197 // only try to create tests if a harness is specified.
198 try {
199 final TestHarness harness = reg.getInstance(hname, false);
200 if (harness == null) {
201 throw ProgramError.unexpected("invalid harness: " + hname);
202 } else {
203 harness.parseTests(this, file, props);
204 }
205 } catch (Throwable t) {
206 throw ProgramError.unexpected("unexpected exception while parsing " + file, t);
207 }
208 } else {
209 skipFile(file);
210 }
211 } catch (FileNotFoundException e) {
212 throw ProgramError.unexpected("file " + file + " not found.");
213 } catch (IOException e) {
214 throw ProgramError.unexpected(e);
215 }
216 }
217
218 private Properties parseTestProperties(File file) throws FileNotFoundException, IOException {
219 final BufferedReader reader = new BufferedReader(new FileReader(file));
220 final Properties vars = new Properties();
221 boolean lineFound = false;
222
223 while (true) {
224 // read any of the beginning lines that contain '@'
225 final String line = reader.readLine();
226
227 if (line == null) {
228 break;
229 }
230
231 final int indx1 = line.indexOf('@');
232 final int indx2 = line.indexOf(':');
233
234 if (indx1 < 0 || indx2 < 0) {
235 // this line does not match: break out if already matched
236 if (lineFound) {
237 break;
238 }
239 continue;
240 }
241 lineFound = true;
242
243 final String var = line.substring(indx1 + 1, indx2).trim();
244 final String value = line.substring(indx2 + 1).trim();
245 if (vars.get(var) != null) {
246 // if there is already a value, append.
247 vars.put(var, vars.get(var) + " " + value);
248 } else {
249 vars.put(var, value);
250 }
251 }
252 reader.close();
253 return vars;
254 }
255
256 private boolean loadingPackages;
257
258 public boolean loadingPackages() {
259 return loadingPackages;
260 }
261
262 public void setLoadingPackages(boolean loadingPackages) {
263 this.loadingPackages = loadingPackages;
264 }
265 }