-
Notifications
You must be signed in to change notification settings - Fork 791
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
Run tests using JUnit5 platform and remove SpockRunner #770
Conversation
@anuraaga what are your plans about this? |
I'm going to examine it more - didn't expect content length and exceptions to eat up my days :P |
I'm going to play a bit more with this, most tests work. But some still have the dreaded "SEVERE: java.lang.LinkageError: loader constraint violation: loader 'bootstrap' wants to load class io.opentelemetry.trace.Span$Kind. A different class with the same name was previously loaded by 'app'. (io.opentelemetry.trace.Span$Kind is in unnamed module of loader 'app')" type of error, so may have to give up. Seems to be a difference in behavior of class loading when using the junit5 runner, even when delegating to vintage. |
2358e49
to
d5549e2
Compare
@@ -42,7 +42,7 @@ import static org.junit.Assume.assumeTrue | |||
abstract class HttpClientTest extends AgentTestRunner { | |||
protected static final BODY_METHODS = ["POST", "PUT"] | |||
protected static final CONNECT_TIMEOUT_MS = 1000 | |||
protected static final BASIC_AUTH_KEY = "custom authorization header" | |||
protected static final BASIC_AUTH_KEY = "custom-authorization-header" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this PR PlayJavaWEClientTest fails because of invalid header name characters (space) which looks correct to me... The Play tests have a couple other assertions that fail (TimeoutException vs ConnectException) that seem similarly like they should be failing, as if on current master we're not actually running these tests so I need to investigate more what's going on...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as if on current master we're not actually running these tests
oh, wow, they were not, before this PR!!!
cc: @tylerbenson
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@anuraaga could you elaborate... which task isn't failing that should be? Any idea why they aren't being executed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't end up digging on the why, but I think it was this test that started failing with this PR
Netty threw a validation error because of the spaces in this header name which seems right to me.
it's gone green!!! 🟢🟩🟢🟩🟢 |
agent-tooling/src/test/groovy/io/opentelemetry/auto/test/HelperInjectionTest.groovy
Outdated
Show resolved
Hide resolved
…-instr-java into junit-platform
…ockRunner, but Grizzly?
import spock.lang.AutoCleanup | ||
import spock.lang.Shared | ||
|
||
@RunWith(SpockRunner) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I thought I finally had a good mental model of what's going on in our tests, a grizzly shows up 🐻
I think one of the reasons a couple of test failed is because with JUnit5, there is no way to intercept class loading
junit-team/junit5#201
This is a fundamental aspect of JUnit5 so presumably even when using the vintage engine, the limitation applies.
I noticed only two tests in the entire repo actually seem to rely on this behavior though, so I gave them special treatment. At that point, it seemed SpockRunner
doesn't actually do anything anymore, so I tried removing it completely. Everything worked, except for this one test.
@trask if you feel like it, maybe you could look at this test without and with SpockRunner and teach me what function it's serving and why it would only affect this test :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's a tricky one...
There are two things conspiring against that test:
- the test code itself gets instrumented, not only the library under test (
GrizzlyAsyncHttpClientTest$AsyncCompletionHandlerMock
) - the instrumentation that gets injected into that test code uses
InstrumentationContext
, and tries to put anull
value into it
Because AsyncCompletionHandlerMock
is a nested class inside of the test, it appears that class is loaded before we install bytebuddy, which means we can only retransform it, which means InstrumentationContext
cannot use the (fast) field-backed provider, and instead has to use the WeakMap
.
This is fine.
But then comes (2) and tries to put a null value into the WeakMap
, which is what then causes the NPE.
Moving AsyncCompletionHandlerMock
out into a top-level class resolves the issue.
I'll also open an issue about the WeakMap
implementation not supporting null
values, though in general we don't use the the WeakMap
when running as -javaagent:...
, since in that case we are typically able to do initial transform (not structure limited re-transform) and so we can inject a field into the class and use the field-backed provider.
@anuraaga can you please summarise the intent of this PR? I mean, you want to run tests with junit5. Ok, but what tests? All tests? Some tests? |
The intent is to run all the tests with JUnit5 - I think it's more future-proof, including if we want to move to Spock 3 which is based on JUnit5 at some point. I was hoping the vintage runner would work the exact same way but of course hopes don't always pan out :) I'm not married to this PR, |
I am confused :) What is a relationship between Spock and Junit? You don't propose to remove Spock, do you? |
Nope :) JUnit is a test runner framework as well as a framework for writing tests So this PR changes from JUnit4 + Sputnik -> Spock And from my reading of Spock 2.0, I think (not sure) sputnik is gone too and it becomes |
…-instr-java into junit-platform
@@ -24,6 +24,7 @@ ext { | |||
kotlin : "1.3.72", | |||
coroutines : "1.3.0", | |||
springboot : "2.3.1.RELEASE", | |||
junit5 : "5.7.0-M1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need a milestone or current stable is enough?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this milestone fixed a spock issue
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api' | ||
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-params' | ||
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine' | ||
testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need both old and new engines?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need new engine for any Java tests, we have one PatchLoggerTest
. If we get to Spock 2.0 we'll remove vintage at that point.
} | ||
} | ||
|
||
// Needs a fresh classloader. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No clue :P Filed an issue
…-instr-java into junit-platform
…-instr-java into junit-platform
…y#770) * Run tests with JUnit platform * Matcher * Restore * Don't mix JUnit4 with JUunit5 in spring tests * Separate out tests that need custom class loader. * Separate out test for a couple classes that need it, try to remove SpockRunner, but Grizzly? * Remove SpockRunner * Fix grizzly * Remove assumeTrue workaround. * Comments
I noticed that we're adding junit platform tests in the spring instrumentation and figured it'd be good if we go ahead and upgrade to give us the option of using it. I'm still interested in doing a side-by-side comparison of spock and junit5 just to see :)
This also tries to simplify the tests by removing
SpockRunner
- only three tests actually depended on its behavior, and it seems OK to let Gradle take care of the classloader isolation instead of using a JUnit runner which constrains options for the future.