270 likes | 284 Views
Regression Test Selection for AspectJ Software. Guoqing Xu and Atanas Rountev Ohio State University ICSE’07. Outline. Background and motivation Regression test selection AspectJ semantics and challenges Contributions A control-flow representation for AspectJ software
E N D
Regression Test Selection for AspectJ Software Guoqing Xu and Atanas Rountev Ohio State University ICSE’07
Outline • Background and motivation • Regression test selection • AspectJ semantics and challenges • Contributions • A control-flow representation for AspectJ software • A graph traversal algorithm for test selection • Experimental evaluation • Conclusions
Regression Test Selection • Select a safe subset of regression tests • Harrold et al., OOPSLA 01 • Java interclass graph (JIG): intra- and inter-procedural flow of control • Simultaneous JIG traversal for P and P' Program P Execute P and record coverage JIG edge coverage matrix Select tests Dangerous edges in P Program P Identify dangerous entities Program P'
Motivation and Challenges • Aspects can change dramatically the behavior of the original code • Why not select tests based on the woven bytecode? • The discrepancy between the source code and the bytecode can be significant • Compiler-specific artificial code • Shown in our experimental study • A more general question • What is an appropriate static representation for AspectJ software for regression test selection and other analyses?
AspectJ Semantics • Join points, pointcuts, and advices • before, around (with proceed), after • Shadow • Textual part of the program executed during the time span of a join point • Dynamic pointcut/advice: triggered only when certain run-time conditions hold • if… • Advice precedence rules
Running Example /* before1 */ before(Point p, int x) : setterX(p) && args(x) throws … { … if (…) throw ex … } /* around1 */ void around(Point p, int x) : setterX(p) && args(x) && if(x==0) { … proceed(p,x); … } /* before2 */ before(Point p) : setterX(p) { … } /* after1 */ after(Point p) : setterX(p) { … } class Point { int x; void setX(int x) { this.x = x; } static void main(String[] a) { Point p = new Point(); p.setX(10); } } aspect BoundPoint { pointcutsetterX(Point p) : call(void Point.setX(*)) && target(p); … // advices }
AspectJ Semantic try { before1(); if (x==0) around1(); else { before2(); p.setX(); } } catch(Throwable e) { after1(); throw e; } after1(); around1() { before2(); p.setX(); } main(…) { … p.setX(10); … }
Control-Flow Representation • AspectJ Inter-module Graph (AJIG) • JIG-like representation for “normal” calls • No join points • New representation for interactions at join points • Interaction graph • Multiple advices applicable at a join point • Model complex interactions among multiple advices • Dynamic advices • E.g. model the invocation of around1 in the example • void around(Point p, int x) : … if(x==0)
Multiple Advice Invocation • Input: a list of advices that statically match a shadow • Sort the list using precedence rules, taking into account the shadow • before1, around1, before2, p.setX,after1 • Build advice nesting tree • Create a root node, and put every advice under root • Scan the list, build around subtrees; advices that are invoked within an around advice A are the children of A • Parent-child relationships represent nesting of advice time span
Advice Nesting Tree before1 p.setX after1 around1 before2 root before1 around1 after1 p.setX before2
Modeling of “proceed” • Important observation • Advices at one level are invoked by the call toproceedin their parent advice • Introduction of placeholder methods ph_* • A call to a ph_proceedrepresents a call to proceed • ph_root is called to replace the shadow • The CFG for a ph_proceedmethod contains a sequence of call/return nodes pairs for all advices that are invoked by proceed
root before1 after1 around1 p.setX before2
Handling of After Advices • Normal subgraph • {after1} • Exceptional subgraph • {after1} Normal subgraph Exceptional subgraph
Handling of Dynamic Advices • Challenges • No way to know whether a dynamic advice is invoked at run time • Advices that are nested within a dynamic around advice A are still invoked even if A is not invoked • Solutions • Introduce placeholder decision making nodes ph_decision • Create a ph_decisionnode before the call node of each dynamic advice
Example • Create a ph_decison node • Create a “T” edge going from ph_decison to the guarded advice • Create an “F” edge • For a non-around advice, link the edge to the next call node • For an around advice, link the edge to the call node of its ph_proceed • Redirect edges ph_decision T F F before1 return ph_decision T F around1 ph_proceed1 return return exit
Graph Traversal Algorithm • Edge-level comparison for edges outside the interaction graph • Interaction graph comparison • Interprocedural traversal • Compare the calling structure • Schedule advice bodies for further processing • Intraprocedural comparison • Edge-level comparison for advice bodies
Inter-procedural traversal Case 1: if ad1 != ad2 e is dangerous
Inter-procedural traversal Case 2: e is dangerous
Inter-procedural traversal Case 3: if ad1 == ad2 e is dangerous else ‘T’ is dangerous 3a: if ad1 is non-around compare(e’’, e’) 3b:else compare(ph, e’)
23.8% more 35% more
Study 1 (Cond.) • Compiler changes names of existing advices when adding a new advice • Compiler inlines an advice when removing some control flow paths from it • Compiler generates try-catch block, when adding an afterThrowing advice • Compiler inserts dynamic residue that performs run-time check before dynamic advice • Conclusion • These are not program changes • Such changes prevent JIG-based approach from selecting the changes only made in the source.
Study 2-Test Suite Reduction bean tracing quicksort telecom
Study 2-Test Suite Reduction nullcheck dcm JIG- 98.8% AJIG- 69.0% loc
Conclusions • Bytecode level analysis does not work for AspectJ program • A source code level control-flow representation AJIG • Multiple advice invocation • Dynamic advice • A graph traversal algorithm • Evaluation • Our approach outperforms the JIG-based approach
Empirical Evaluation %ic = #dynamic interactions/#static interactions