Marshalling Deja vu traces

This post is part of a series about the framework Deja vu.

The previous post examplified the core Deja vu framework. As mentioned the examples did not reflect how it should be done in a real setup i.e. we ran a use case that failed deterministically. We are more interested in the bugs that lurks and only reveal themselves under very specific circumstances. These kinds of bugs is what Deja vu is created for.

I’ve added a module jsonmarshaller to the Deja vu project. This module makes it possible to marshal/un-marshal traces and also has functionality for generating source code for a test case replicating the trace. Marshalling is handled by jackson.

A ‘real’ setup

Lets create a use case that fails non-deterministicly (and therefore easier could sneak into production).

So this will only fail if the nanotime modulo 1001 is 0. We wait for this situation to occur by creating a test that executes the use case over and over again:

Once the bug show it’s face we use the TestGenerator to create the source code of a test replicating the error. A run of “non_deterministic” is shown below.

Voilà: We have cornered the bug for the specific provider output (hey I’m not francophile or anything!)!

Fixing the bug

Running the generated test will consistently produce the same result as the non-deterministic production bug. So it is now possible to debug and step through the use case as we see fit. We produce the following fix for the bug:

Running the test again will now give us a green light!

End of trace

The bug we just fixed was fixable because we knew all provider outputs. Suppose the crash happened before the last provider was called. If such a trace was fixed we would run into a situation where the DejaVuTest would not know what to provide. When such a situation happens the DejaVuProvider will throw an EndOfTraceException. This exception is caught by the framework and since this only happens because the test has been fixed, null will be returned. For such a case the test is considered successful.

Other limitations

Fixing and maybe re-factoring the traced code might lead to situations where the actual code and the given DejaVuUseCase no longer matches. This can either be when the input types have changed, when an integration point has changed output type, or when changing the order in which integration points are invoked. Are such changes necessary to fix a bug the test should be removed.

Even if a test is removed because of incompatibility, the trace would be very relevant to keep. A trace is part of the history of an application – trace entities are first class citizens among the other domain entities!

This post is part of a series about the framework Deja vu. Next: Circuit breaker pattern.

Leave a Reply

Close Menu