简体   繁体   English

使用 gradle 和 JUnit5 进行 ByteBuddy 代理测试

[英]ByteBuddy agent test with gradle and JUnit5

I've faced some weird behavior when I try to test my Java Agent written using ByteBuddy当我尝试测试使用 ByteBuddy 编写的 Java 代理时,我遇到了一些奇怪的行为

The agent intercepts annotated methods/classes and profile them, nothing complicated代理拦截带注释的方法/类并分析它们,没有什么复杂的

class ByteInstrumentationConfigurer implements BootstrapConfigurer {

    @Override
    void init(...) {
        def instrumentation = ByteBuddyAgent.install()
        new AgentBuilder.Default()
                .type(isAnnotatedWith(TimeProfiling.class))
                .transform((builder, typeDescription, classLoader, module) ->
                        builder.method(not(isAnnotatedWith(Generated))) //ignore groovy generated methods (getMetaClass, etc.)
                            .intercept(MethodDelegation.to(TimeProfilingInterceptor.class)))
                .with(stdoutToLoggerWriter.withTransformationsOnly())
                .installOn(instrumentation) 

And I've got some unit tests where I verify that interceptor method was called我有一些单元测试,我验证拦截器方法被调用

class TimeProfilingInterceptorTest {

    static MockedStatic<TimeProfilingInterceptor> timeProfilingInterceptorMockedStatic

    static {
        //agent installation happens here
        new ByteInstrumentationConfigurer().init([:], [:])
        timeProfilingInterceptorMockedStatic = mockStatic(TimeProfilingInterceptor, CALLS_REAL_METHODS)
    }
    
    @Test
    void profilingEnabledClassLevelTest() {
        //some mocking for my classes here
        testCallingComponent.callClassLevelComponentMethod()
        timeProfilingInterceptorMockedStatic.verify(()->
                TimeProfilingInterceptor.measureAndLogExecutionTime(any(),any(),any()),times(2))
}

And now, when I start this test using from IDEA I see, that 2 my classes were transformed现在,当我使用 IDEA 开始这个测试时,我看到,我的 2 个类被转换了

[Byte Buddy] TRANSFORM com.kmslh.manager.profiling.components.MethodLevelTimeProfilingComponent [sun.misc.Launcher$AppClassLoader@18b4aac2, null, Thread[main,5,main], loaded=false] [字节好友] 转换 com.kmslh.manager.profiling.components.MethodLevelTimeProfilingComponent [sun.misc.Launcher$AppClassLoader@18b4aac2, null, Thread[main,5,main],loaded=false]

[Byte Buddy] TRANSFORM com.kmslh.manager.profiling.components.ClassLevelTimeProfilingComponent [sun.misc.Launcher$AppClassLoader@18b4aac2, null, Thread[main,5,main], loaded=false] [字节好友] 转换 com.kmslh.manager.profiling.components.ClassLevelTimeProfilingComponent [sun.misc.Launcher$AppClassLoader@18b4aac2, null, Thread[main,5,main],loaded=false]

But if I run this tests using gradle test\\build task - no classes transformed.但是如果我使用gradle test\\build 任务运行这个测试 - 没有类转换。 If I output full info - i see that classloader in this case is org.codehaus.groovy.runtime.callsite.CallSiteClassLoader .如果我输出完整信息 - 我看到在这种情况下类加载器是org.codehaus.groovy.runtime.callsite.CallSiteClassLoader

[Byte Buddy] DISCOVERY com.kmslh.manager.profiling.components.ClassLevelTimeProfilingComponent$exposedMethod [org.codehaus.groovy.runtime.callsite.CallSiteClassLoader@3b1a332, null, Thread[Test worker,5,main], loaded=false] [Byte Buddy] IGNORE com.kmslh.manager.profiling.components.ClassLevelTimeProfilingComponent$exposedMethod [org.codehaus.groovy.runtime.callsite.CallSiteClassLoader@3b1a332, null, Thread[Test worker,5,main], loaded=false] [Byte Buddy] COMPLETE com.kmslh.manager.profiling.components.ClassLevelTimeProfilingComponent$exposedMethod [org.codehaus.groovy.runtime.callsite.CallSiteClassLoader@3b1a332, null, Thread[Test worker,5,main], loaded=false] [字节好友] 发现 com.kmslh.manager.profiling.components.ClassLevelTimeProfilingComponent$exposedMethod [org.codehaus.groovy.runtime.callsite.CallSiteClassLoader@3b1a332, null, Thread[Test worker,5,main],loaded=false] [字节好友] IGNORE com.kmslh.manager.profiling.components.ClassLevelTimeProfilingComponent$exposedMethod [org.codehaus.groovy.runtime.callsite.CallSiteClassLoader@3b1a332, null, Thread[Test worker,5,main],loaded=false] [字节Buddy] COMPLETE com.kmslh.manager.profiling.components.ClassLevelTimeProfilingComponent$exposedMethod [org.codehaus.groovy.runtime.callsite.CallSiteClassLoader@3b1a332, null, Thread[Test worker,5,main],loaded=false]

Not sure is it an issue or not, but I'm out of ideas.不确定这是否是一个问题,但我没有想法。 Also I've tried to rewrite test to Java - no result.我也尝试将测试重写为 Java - 没有结果。

Any suggestions to try?有什么建议可以尝试吗?

UPD 1更新 1

From what I see - when test started from gradle - no auxiliary classes created从我所看到的 - 当测试从 gradle 开始时 - 没有创建auxiliary

From your log, the Gradle tests run a different class loader than in your example where things work.从您的日志中,Gradle 测试运行的类加载器与您的示例中运行的类加载器不同。 I assume therefore that your matcher is sensitive to the class loader that is being used.因此,我假设您的匹配器对正在使用的类加载器很敏感。 Also, make sure your ignore matcher does not exclude the class loader in the parallel tests.此外,请确保您的忽略匹配器不会在并行测试中排除类加载器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM