-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Detect cycles in inner class hierarchies #2039
Comments
Tentatively slated for 5.6 M1 for team discussion to determine what the outcome of cycle detection should be. |
Team Decision: Throw an exception during discovery if a cycle is detected. |
It appears that this may be an issue in the Platform rather than (only?) in Jupiter, specifically in |
With the following change to the aforementioned // Detect cycle in hierarchy
boolean cycleDetected = false;
Class<?> superclass = clazz.getSuperclass();
if (superclass != null) {
Class<?> enclosingClass = clazz.getEnclosingClass();
while (enclosingClass != null) {
if (superclass.equals(enclosingClass)) {
cycleDetected = true;
break;
}
enclosingClass = enclosingClass.getEnclosingClass();
}
}
// Search class hierarchy
if (!cycleDetected) {
findNestedClasses(superclass, candidates);
} ... the algorithm no longer recurses indefinitely. This change does not throw an exception if a cycle is detected. Rather, it simply does not follow the cycle. Thus, with this implementation, the following tests are executed. @junit-team/junit-lambda, what do you think about supporting that instead of throwing an exception when a cycle is detected? Keep in mind that whatever we do here will affect any extension or test engine that makes use of |
FYI: current work on this issue can be seen here: /~https://github.com/junit-team/junit5/compare/issues/2039-recursive-nested-hierarchy |
Team Decision: Let's throw an exception instead of silently ignoring the cycle. |
OK. The status quo now results in...
Good like that? |
Prior to this commit, an invocation of ReflectionSupport.findNestedClasses() could result in infinite recursion if an inner class hierarchy formed a cycle via inheritance. This commit addresses this by introducing cycle detection in ReflectionUtils.findNestedClasses. Consequently, the detection of cycles in @nested test class hierarchies will cause the JUnit Jupiter test engine to halt with an exception instead of infinitely recursing. Issue: #2039
Prior to this commit, an invocation of ReflectionSupport.findNestedClasses() could result in infinite recursion if an inner class hierarchy formed a cycle via inheritance. This commit addresses this by introducing cycle detection in ReflectionUtils.findNestedClasses. Consequently, the detection of cycles in @nested test class hierarchies will cause the JUnit Jupiter test engine to halt with an exception instead of infinitely recursing. Closes: #2039
Prior to this commit, an invocation of ReflectionSupport.findNestedClasses() could result in infinite recursion if an inner class hierarchy formed a cycle via inheritance. This commit addresses this by introducing cycle detection in ReflectionUtils.findNestedClasses. Consequently, the detection of cycles in @nested test class hierarchies will cause the JUnit Jupiter test engine to halt with an exception instead of infinitely recursing. Closes: #2039
Upgrading to JUnit5 is breaking a unit test I have.
This class is defined in my test suite and the recursive check fails even though I have not marked any of these classes as @nested. I think this is the suspect code Notice that the code looks for all nested classes (and asserts on finding a cycle) before attempting to filter out using the predicate for @nested. Therefore any class that has this inner inheritance (in my case Groovy Closure and WriteableClosure) is causing an error even if they are not marked as @nested For reference, here is the closure code and its inner class Is there a way for me to disable this recursion check? |
@chavan77me, this issue is already closed. Please open a new issue, and we'll gladly look into it. |
JUnit 5.6 introduced inner class cycle detection in ReflectionSupport.findNestedClasses() (see #2039). Unfortunately, the cycle detection introduced a regression for test classes that contain classes with inner class cycles when those inner classes do not match the predicate supplied to findNestedClasses() (e.g., "is annotated with @nested"). Consequently, an exception is thrown for any inner class cycled detected, even if the cycle would not adversely affect test discovery or execution. This commit fixes this regression by avoiding inner class cycle detection for candidate classes that do match the predicate. For example, within JUnit Jupiter inner class cycle detection is now only performed for inner classes annotated with @nested. Fixes #2249
JUnit 5.6 introduced inner class cycle detection in ReflectionSupport.findNestedClasses() (see #2039). Unfortunately, the cycle detection introduced a regression for test classes that contain classes with inner class cycles when those inner classes do not match the predicate supplied to findNestedClasses() (e.g., "is annotated with @nested"). Consequently, an exception is thrown for any inner class cycled detected, even if the cycle would not adversely affect test discovery or execution. This commit fixes this regression by avoiding inner class cycle detection for candidate classes that do match the predicate. For example, within JUnit Jupiter inner class cycle detection is now only performed for inner classes annotated with @nested. Fixes #2249
JUnit 5.6 introduced inner class cycle detection in ReflectionSupport.findNestedClasses() (see #2039). Unfortunately, the cycle detection introduced a regression for test classes that contain classes with inner class cycles when those inner classes do not match the predicate supplied to findNestedClasses() (e.g., "is annotated with @nested"). Consequently, an exception is thrown for any inner class cycled detected, even if the cycle would not adversely affect test discovery or execution. This commit fixes this regression by avoiding inner class cycle detection for candidate classes that do match the predicate. For example, within JUnit Jupiter inner class cycle detection is now only performed for inner classes annotated with @nested. Fixes #2249
Overview
Since Java allows nested classes to extend other classes, it is possible to introduce a cycle when using
@Nested
test classes.For example, the following compiles in Java. So it's syntactically correct, even though it's semantically invalid. If you attempt to execute
OuterTests
orNestedTests
, the discovery phase in JUnit Jupiter never completes (or at least it does not result in a stack overflow in a reasonable amount of time on my machine).On the other hand, if you execute only
test1()
ortest2()
, each of those will execute as expected.Deliverables
The text was updated successfully, but these errors were encountered: