151 this.testBody = (unused) -> testBody.run(); |
151 this.testBody = (unused) -> testBody.run(); |
152 this.beforeActions = Collections.emptyList(); |
152 this.beforeActions = Collections.emptyList(); |
153 this.afterActions = Collections.emptyList(); |
153 this.afterActions = Collections.emptyList(); |
154 this.testDesc = TestDesc.createBuilder().get(); |
154 this.testDesc = TestDesc.createBuilder().get(); |
155 this.dryRun = false; |
155 this.dryRun = false; |
|
156 this.workDir = createWorkDirName(testDesc); |
156 } |
157 } |
157 |
158 |
158 TestInstance(MethodCall testBody, List<ThrowingConsumer> beforeActions, |
159 TestInstance(MethodCall testBody, List<ThrowingConsumer> beforeActions, |
159 List<ThrowingConsumer> afterActions, boolean dryRun) { |
160 List<ThrowingConsumer> afterActions, boolean dryRun) { |
160 assertCount = 0; |
161 assertCount = 0; |
162 this.testBody = testBody; |
163 this.testBody = testBody; |
163 this.beforeActions = beforeActions; |
164 this.beforeActions = beforeActions; |
164 this.afterActions = afterActions; |
165 this.afterActions = afterActions; |
165 this.testDesc = testBody.createDescription(); |
166 this.testDesc = testBody.createDescription(); |
166 this.dryRun = dryRun; |
167 this.dryRun = dryRun; |
|
168 this.workDir = createWorkDirName(testDesc); |
167 } |
169 } |
168 |
170 |
169 void notifyAssert() { |
171 void notifyAssert() { |
170 assertCount++; |
172 assertCount++; |
171 } |
173 } |
203 throw skippedTestException; |
205 throw skippedTestException; |
204 } |
206 } |
205 } |
207 } |
206 |
208 |
207 Path workDir() { |
209 Path workDir() { |
208 Path result = Path.of("."); |
210 return workDir; |
209 List<String> components = new ArrayList<>(); |
|
210 |
|
211 String testFunctionName = functionName(); |
|
212 if (testFunctionName != null) { |
|
213 components.add(testFunctionName); |
|
214 } |
|
215 |
|
216 if (isPrametrized()) { |
|
217 components.add(String.format("%08x", fullName().hashCode())); |
|
218 } |
|
219 |
|
220 if (!components.isEmpty()) { |
|
221 result = result.resolve(String.join(".", components)); |
|
222 } |
|
223 |
|
224 return result; |
|
225 } |
|
226 |
|
227 boolean isPrametrized() { |
|
228 return Stream.of(testDesc.functionArgs, testDesc.instanceArgs).anyMatch( |
|
229 Objects::nonNull); |
|
230 } |
211 } |
231 |
212 |
232 @Override |
213 @Override |
233 public void run() throws Throwable { |
214 public void run() throws Throwable { |
234 final String fullName = fullName(); |
215 final String fullName = fullName(); |
237 Object testInstance = testConstructor.apply(testBody); |
218 Object testInstance = testConstructor.apply(testBody); |
238 beforeActions.forEach(a -> ThrowingConsumer.toConsumer(a).accept( |
219 beforeActions.forEach(a -> ThrowingConsumer.toConsumer(a).accept( |
239 testInstance)); |
220 testInstance)); |
240 try { |
221 try { |
241 if (!dryRun) { |
222 if (!dryRun) { |
242 Files.createDirectories(workDir()); |
223 Files.createDirectories(workDir); |
243 testBody.accept(testInstance); |
224 testBody.accept(testInstance); |
244 } |
225 } |
245 } finally { |
226 } finally { |
246 afterActions.forEach(a -> TKit.ignoreExceptions(() -> a.accept( |
227 afterActions.forEach(a -> TKit.ignoreExceptions(() -> a.accept( |
247 testInstance))); |
228 testInstance))); |
253 } else if (status == null) { |
234 } else if (status == null) { |
254 status = Status.Failed; |
235 status = Status.Failed; |
255 } |
236 } |
256 |
237 |
257 if (!KEEP_WORK_DIR.contains(status)) { |
238 if (!KEEP_WORK_DIR.contains(status)) { |
258 TKit.deleteDirectoryRecursive(workDir()); |
239 TKit.deleteDirectoryRecursive(workDir); |
259 } |
240 } |
260 |
241 |
261 TKit.log(String.format("%s %s; checks=%d", status, fullName, |
242 TKit.log(String.format("%s %s; checks=%d", status, fullName, |
262 assertCount)); |
243 assertCount)); |
263 } |
244 } |
270 return Functional.ThrowingSupplier.toSupplier(() -> Class.forName( |
251 return Functional.ThrowingSupplier.toSupplier(() -> Class.forName( |
271 ste.getClassName())).get(); |
252 ste.getClassName())).get(); |
272 } |
253 } |
273 } |
254 } |
274 return null; |
255 return null; |
|
256 } |
|
257 |
|
258 private static boolean isCalledByJavatest() { |
|
259 StackTraceElement st[] = Thread.currentThread().getStackTrace(); |
|
260 for (StackTraceElement ste : st) { |
|
261 if (ste.getClassName().startsWith("com.sun.javatest.")) { |
|
262 return true; |
|
263 } |
|
264 } |
|
265 return false; |
|
266 } |
|
267 |
|
268 private static Path createWorkDirName(TestDesc testDesc) { |
|
269 Path result = Path.of("."); |
|
270 if (!isCalledByJavatest()) { |
|
271 result = result.resolve(testDesc.clazz.getSimpleName()); |
|
272 } |
|
273 |
|
274 List<String> components = new ArrayList<>(); |
|
275 |
|
276 final String testFunctionName = testDesc.functionName; |
|
277 if (testFunctionName != null) { |
|
278 components.add(testFunctionName); |
|
279 } |
|
280 |
|
281 final boolean isPrametrized = Stream.of(testDesc.functionArgs, |
|
282 testDesc.instanceArgs).anyMatch(Objects::nonNull); |
|
283 if (isPrametrized) { |
|
284 components.add(String.format("%08x", testDesc.testFullName().hashCode())); |
|
285 } |
|
286 |
|
287 if (!components.isEmpty()) { |
|
288 result = result.resolve(String.join(".", components)); |
|
289 } |
|
290 |
|
291 return result; |
275 } |
292 } |
276 |
293 |
277 private enum Status { |
294 private enum Status { |
278 Passed("[ OK ]"), |
295 Passed("[ OK ]"), |
279 Failed("[ FAILED ]"), |
296 Failed("[ FAILED ]"), |
298 private final ThrowingFunction testConstructor; |
315 private final ThrowingFunction testConstructor; |
299 private final ThrowingConsumer testBody; |
316 private final ThrowingConsumer testBody; |
300 private final List<ThrowingConsumer> beforeActions; |
317 private final List<ThrowingConsumer> beforeActions; |
301 private final List<ThrowingConsumer> afterActions; |
318 private final List<ThrowingConsumer> afterActions; |
302 private final boolean dryRun; |
319 private final boolean dryRun; |
|
320 private final Path workDir; |
303 |
321 |
304 private final static Set<Status> KEEP_WORK_DIR = Functional.identity( |
322 private final static Set<Status> KEEP_WORK_DIR = Functional.identity( |
305 () -> { |
323 () -> { |
306 final String propertyName = "keep-work-dir"; |
324 final String propertyName = "keep-work-dir"; |
307 Set<String> keepWorkDir = TKit.tokenizeConfigProperty( |
325 Set<String> keepWorkDir = TKit.tokenizeConfigProperty( |