Bugs in production systems are typically communicated in stack traces. But why don't we communicate in unit tests?
This presentation discuss a concrete open source Java framework that allows production systems to communicate bugs as test cases. It will produce deterministic, sand-boxable test cases having identical execution paths as the original run. Using the framework correctly will even make multi-threaded scenarios re-playable.
4. Spot of bother
• Why are errors communicated in stack traces?
• Why are production bugs hunted down by inspecting log files?
• Why can’t we communicate in running code?
16. Rules of the game
• Immutable
• Must be serializable++
17. Lucky number bug
1 public class AlmostWorking {
2
3 @Traced
4 public void getLucky() {
5 Long value = timeStamp();
6 Long luckyNumber = 2304432 / ( value % 1001 );
7 System.out.println( "My lucky number is: "+luckyNumber);
8 }
9
10 @Impure
11 private Long timeStamp() {
12 return System.nanoTime();
13 }
14 }
18. Overhead
• Execution overhead in intercepting calls
• Memory overhead in storing ”impure” values
• Immutable overhead
21. @AttachThread
• Includes a thread in a trace
• Trace is not done until trace method is executed...
• ...and all attached threads are done executing
• Impure parts are replayed in same order
22. Example
1 public class WithThreads {
2
3 private ExecutorService executorService;
4
5 public void initialize() {
6 executorService = Executors.newCachedThreadPool();
7 }
8
9 @Traced
10 public void begin( Integer threads) {
11 initialize();
12 for ( int i=0; i<threads; i++ ) {
13 runInThreadPool(new Runner());
14 }
15 }
16
17 @AttachThread
18 private void runInThreadPool( Runnable runnable ) {
19 executorService.submit(runnable);
20 }
21 }