Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing with ASM Bytecode

Let's say I am instrumenting a class, in which I want to add a couple of instructions to some parts of a method. For instance, let's consider the case where I want develop a visitor V to rename method call instructions existent in method C.m() from C.n() to C.n_detour().

What would be the easiest way to test that after running V over C, one would indeed get the desired results? I'm talking about xUnit style testing here.

At first I thought I could run TraceMethodVisitor over C, and compare it to a string of my own, but it turned out that there is a lot of "decoration" instructions (such as line numbering, etc) that are largely irrelevant to my tests (see Formatting the output of a TraceClassVisitor).

Theoretically I know I could make some visitor that'd run and check both the existence of a C.n_detour() and the non-existence of C.n(), but I'd rather use something more along the lines of the above approach (comparing instruction per instruction).

I took a look at ASM's Tree API, but it doesn't look that much better, as those decoration instructions show up there, too.

Does anyone have experience in the past testing code using ASM?

like image 591
devoured elysium Avatar asked Apr 01 '26 07:04

devoured elysium


1 Answers

Make C.n_detour() protected, extend C in a test case and count the number of invocations.

Pattern: All your instrumentations will create some new side effect - that's why you're instrumenting in the first place - so write tests which check whether side effect is there or not. Don't test for a specific implementation of the instrumentation but for the general "does it have the desired effect".

Might need a new classloader to put the instrumented version of C on the classpath.

If you use Maven, I suggest to instrument in one module and put the tests into a second module.

like image 87
Aaron Digulla Avatar answered Apr 02 '26 19:04

Aaron Digulla