Automated Transplantation and Differential Testing for Clones Tianyi - - PowerPoint PPT Presentation

automated transplantation and differential testing for
SMART_READER_LITE
LIVE PREVIEW

Automated Transplantation and Differential Testing for Clones Tianyi - - PowerPoint PPT Presentation

Automated Transplantation and Differential Testing for Clones Tianyi Zhang, Miryung Kim University of California, Los Angeles 1 Problem Statement Code clones are common in modern software systems. Developers often find it difficult to


slide-1
SLIDE 1

Automated Transplantation and Differential Testing for Clones

Tianyi Zhang, Miryung Kim University of California, Los Angeles

1

slide-2
SLIDE 2

Problem Statement

  • Code clones are common in modern software systems.
  • Developers often find it difficult to examine the runtime behavior of clones.
  • This problem is exacerbated by a lack of tests. 46% of clone pairs are only

partially covered by existing test suites.

  • We present Grafter to reuse tests between clones and examine behavior

differences.

2

slide-3
SLIDE 3

public class Copy extends Task{ private IncludePatternSet includes; public void setIncludes(String patterns){ … StringTokenizer tok = new StringTokenizer(patterns, “,”); while(tok.hasMoreTokens()){ includes.addPattern(tok.next); } … } } class IncludePatternSet { public Set<String> set; public void addPattern(String s) { set.add(s); }; } public class Delete extends Task{ private ExcludePatternSet excludes; public void setExcludes(String patterns){ … StringTokenizer tok = new StringTokenizer(patterns, “,”); while(tok.hasMoreTokens()){ excludes.addPattern(tok.next); } … } } class ExcludePatternSet { public Set<String> set; public void addPattern(String s) { set.add(s); }; }

A pair of similar but not identical clones that are detected by an existing clone detection tool, Deckard [ICSE 2007].

Copy.java Delete.java

3

* The example is adapted from Apache Ant 1.9.6 for presentation purposes .

slide-4
SLIDE 4

public class Copy extends Task{ private IncludePatternSet includes; public void setIncludes(String patterns){ … + String[] tokens = StringUtils.split(patterns, “,”); + for(String tok : tokens){ + includes.addPattern(tok); + } … } } public class Delete extends Task{ private ExcludePatternSet excludes; public void setExcludes(String patterns){ … + String[] tokens = StringUtils.split(patterns, “.”); + for(String tok : tokens){ + excludes.addPattern(tok); + } … } }

A programmer updates the use of StringTokenizer to StringUtils.split in the Copy and Delete classes.

Copy.java Delete.java

4

* The example is adapted from Apache Ant 1.9.6 for presentation purposes . test ?

slide-5
SLIDE 5

Limitation of Existing Techniques

  • Existing test reuse technique for clones works only at a method or class level and

requires a reuse plan. [Makady & Walker]

  • Existing differential testing or random testing techniques are not geared towards intra

method clones [Geno, Diffut, Randoop]

  • Existing clone inconsistency detection techniques do not detect behavioral differences

between clones [Jiang et al., CBCD, SPA]

5

slide-6
SLIDE 6

Grafter: Automated Test Reuse and Differential Testing

6

testCopy Copy.java (recipient)

public class Copy extends Task{ private IncludePatternSet includes; … String[] tokens = StringUtils.split(patterns, “,”); for(String tok : tokens){ includes.addPattern(tok); } … public class Delete extends Task{ private ExcludePatternSet excludes; … String[] tokens = StringUtils.split(patterns, “.”); for(String tok : tokens){ excludes.addPattern(tok); } …

Delete.java (donor)

String[] tokens = StringUtils.split(patterns, “.”); for(String tok : tokens){ excludes.addPattern(tok); }

Success ? Failure

slide-7
SLIDE 7

Grafter: Automated Test Reuse and Differential Testing

7

testCopy Copy.java

public class Copy extends Task{ private IncludePatternSet includes; … String[] tokens = StringUtils.split(patterns, “,”); for(String tok : tokens){ includes.addPattern(tok); } … public class Delete extends Task{ private ExcludePatternSet excludes; … String[] tokens = StringUtils.split(patterns, “.”); for(String tok : tokens){ excludes.addPattern(tok); } …

Delete.java

String[] tokens = StringUtils.split(patterns, “.”); for(String tok : tokens){ excludes.addPattern(tok); }

Success Failure

slide-8
SLIDE 8

Grafter Approach Overview

8

Variation Identification Code Transplantation Data Propagation Differential Testing

Test Suite

Clone Pair A B

Test Clone A Clone B T1 pass fail T2 pass pass State Clone A Clone B S1 “string” “string” S2 true false

slide-9
SLIDE 9

Grafter Approach Overview

9

Variation Identification Code Transplantation Data Propagation Differential Testing

  • Name Variation
  • Type Variation
  • Method Call

Variation

  • Declare Variables
  • Transform Types
  • Declare Methods
  • Recursive Calls
  • Populate intermediate

input data to clone

  • Transfer intermediate
  • utput back to test
  • Test Comparison
  • State Comparison
slide-10
SLIDE 10

Grafter Approach Overview

10

Variation Identification Code Transplantation Data Propagation Differential Testing

  • Name Variation
  • Type Variation
  • Method Call

Variation

  • Declare Variables
  • Transform Types
  • Declare Methods
  • Recursive Calls
  • Populate intermediate

input data to clone

  • Transfer intermediate
  • utput back to test
  • Test Comparison
  • State Comparison

Variation Identification Code Transplantation Data Propagation Differential Testing

  • Name Variation
  • Type Variation
  • Method Call

Variation

  • Declare Variables
  • Transform Types
  • Declare Methods
  • Recursive Calls
  • Populate intermediate

input data to clone

  • Transfer intermediate
  • utput back to test
  • Test Comparison
  • State Comparison
slide-11
SLIDE 11

Grafter Approach Overview

11

Variation Identification Code Transplantation Data Propagation Differential Testing

  • Name Variation
  • Type Variation
  • Method Call

Variation

  • Declare Variables
  • Transform Types
  • Declare Methods
  • Recursive Calls
  • Populate intermediate

input data to clone

  • Transfer intermediate
  • utput back to test
  • Test Comparison
  • State Comparison
slide-12
SLIDE 12

Grafter Approach Overview

12

Variation Identification Code Transplantation Data Propagation Differential Testing

  • Name Variation
  • Type Variation
  • Method Call

Variation

  • Declare Variables
  • Transform Types
  • Declare Methods
  • Recursive Calls
  • Populate intermediate

input data to clone

  • Transfer intermediate
  • utput back to test
  • Test Comparison
  • State Comparison
slide-13
SLIDE 13

13

Variation Identification Code Transplantation Data Propagation Differential Testing

public class Delete extends Task{ private ExcludePatternSet excludes; public void setExcludes(String patterns){ … String[] tokens = StringUtils.split(patterns, “.”); for(String tok : tokens){ excludes.addPattern(tok); } } … public class Copy extends Task{ private IncludePatternSet includes; public void setIncludes(String patterns){ … String[] tokens = StringUtils.split(patterns, “,”); for(String tok : tokens){ includes.addPattern(tok); } } …

Step 1: Variation Identification

slide-14
SLIDE 14

Step 1: Variation Identification

14

Variation Identification

Code Transplantation Data Propagation Differential Testing

public class Delete extends Task{ private ExcludePatternSet excludes; public void setExcludes(String patterns){ … String[] tokens = StringUtils.split(patterns, “.”); for(String tok : tokens){ excludes.addPattern(tok); } } … public class Copy extends Task{ private IncludePatternSet includes; public void setIncludes(String patterns){ … String[] tokens = StringUtils.split(patterns, “,”); for(String tok : tokens){ includes.addPattern(tok); } } …

slide-15
SLIDE 15

Step 2: Code Transplantation

15

Variation Identification

Code Transplantation

Data Propagation Differential Testing

public class Delete extends Task{ private ExcludePatternSet excludes; public void setExcludes(String patterns){ … String[] tokens = StringUtils.split(patterns, “.”); for(String tok : tokens){ excludes.addPattern(tok); } } … public class Copy extends Task{ private IncludePatternSet includes; public void setIncludes(String patterns){ … String[] tokens = StringUtils.split(patterns, “,”); for(String tok : tokens){ includes.addPattern(tok); } } … String[] tokens = StringUtils.split(patterns, “.”); for(String tok : tokens){ excludes.addPattern(tok); }

slide-16
SLIDE 16

Step 2: Code Transplantation

16

Variation Identification

Code Transplantation

Data Propagation Differential Testing

public class Delete extends Task{ private ExcludePatternSet excludes; public void setExcludes(String patterns){ … String[] tokens = StringUtils.split(patterns, “.”); for(String tok : tokens){ excludes.addPattern(tok); } } … public class Copy extends Task{ private IncludePatternSet includes; + private ExcludePatternSet excludes; public void setIncludes(String patterns){ … + excludes = new ExcludePatternSet(); String[] tokens = StringUtils.split(patterns, “.”); for(String tok : tokens){ excludes.addPattern(tok); } } …

slide-17
SLIDE 17

Step 3: Data Propagation

17

Variation Identification Code Transplantation

Data Propagation

Differential Testing

public class Delete extends Task{ private ExcludePatternSet excludes; public void setExcludes(String patterns){ … String[] tokens = StringUtils.split(patterns, “.”); for(String tok : tokens){ excludes.addPattern(tok); } } … public class Copy extends Task{ private IncludePatternSet includes; + private ExcludePatternSet excludes; public void setIncludes(String patterns){ … + excludes = new ExcludePatternSet(); + excludes.set = includes.set; String[] tokens = StringUtils.split(patterns, “.”); for(String tok : tokens){ excludes.addPattern(tok); } + includes.set = excludes.set; } …

slide-18
SLIDE 18

Step 4: Differential Testing

18

Variation Identification Code Transplantation Data Propagation

Differential Testing

Test Copy.java Delete.java testCopy pass fail State Copy.java Delete.java patterns

“src/*.java, test/*.java” “src/*.java, test/*.java”

tokens

[“src/*.java”, “test/*.java”] [“src/*”, “java, test/*”, “java”]

in(ex)cludes

<IncludePatternSet> <set> [“src/*.java”, “test/*.java”] </set> </IncludePatternSet> <ExcludePatternSet> <set> [“src/*”, “java, test/*”, “java”] </set> </ExcludePatternSet>

Test-level Comparison State-level Comparison

slide-19
SLIDE 19
  • Our tool & dataset are now publicly available.

19

Tool & Dataset: http://web.cs.ucla.edu/~tianyi.zhang/grafter.html

slide-20
SLIDE 20
  • Behavioral differences are represented in tables and highlighted

for ease of investigation.

20

slide-21
SLIDE 21

Evaluation Dataset

  • Our dataset contains 52 pairs of non-identical clones from 3 open source

projects.

  • Our dataset includes 38 Type II clones and 14 Type III clones, based on a

well-known clone taxonomy [Roy et al.].

21

Subject Version Description LOC Test# Branch Stmt Clone Pair Apache Ant 1.9.6 A software build framework 267,048 1,864 45% 50% 18 Java APNS 1.0.0 A Java client for Apple Push Notification service (APNs) 8,362 103 59% 67% 7 XML Security 2.0.5 A XML signature and encryption library 121,594 396 59% 65% 27

slide-22
SLIDE 22

Research Questions

  • RQ1. What is Grafter’s transplantation capability?
  • RQ2. How does Grafter compare with a static approach by

Jiang et al. in its ability to detect differences in clones?

  • RQ3. How sensitive is Grafter in detecting behavioral

differences caused by mutants?

22

slide-23
SLIDE 23
  • RQ1. Transplantation Success and Test Reuse Capability
  • Grafter successfully grafts 49 of 52

pairs of clones

  • Grafter inserts 6 lines of stub code on

average to ensure type safety

  • Grafter doubles the test coverage for

partially tested clone pairs

23

28% 42% 60% 77% 58% 85% 65% 82% 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% Branch Stmt Branch Stmt Partially Fully Before After 14 4 4 1 17 7 3 2 4 6 8 10 12 14 16 18 Type II Type III Type II Type III Type II Type III Ant APNS XMLSec Clone Pair# Success Failure

slide-24
SLIDE 24
  • RQ2. Behavioral Difference Detection
  • Jiang et al. [FSE’07] present a static approach that detects three pre-

defined cloning inconsistencies: (1) renaming mistake, (2) control construct inconsistency, and (3) control predicate inconsistency

  • Grafter exposes behavioral differences in 84% clone pairs while Jiang et
  • al. detect syntactic inconsistency in 33% clone pairs only.

24

Grafter

Jiang et al.

16% 43% 41%

No Differences State Differences Only Test and State Differences

67% 2% 31%

No Cloning Bug Inconsistent Conditional Predicate Renaming Mistake

slide-25
SLIDE 25
  • We systematically injected 361 mutants on 30 pairs of clones with no

existing test behavioral differences

  • We compare its behavioral differencing capability with a static approach

by Jiang et al.

  • RQ3. Robustness

25

Operator Description Example AOR Arithmetic operator replacement LOR Logical operator replacement COR Conditional operator replacement ROR Relational operator replacement SOR Shift operator replacement ORU Operator replacement unary STD Statement deletion operator: delete (omit) a single statement LVR Literal value replacement: replace by a positive value, a negative value or zero

a b a b + → − | a b a b ∧ →

& & a b a b ∨ →

a b a b == → >=

a b a b → ? =

( , ) / / ( , ) foo a b foo a b →

a a ¬ →: 1 →

slide-26
SLIDE 26
  • RQ3. Robustness

26

public void setType(String type) { if ( type == null && type.length() == 0){ this.type = null; } else { URI tmpType = null; try { tmpType = new URI(type); } catch (URISyntaxException ex) { … } this.type = tmpType.toString(); } }

Mutation Example from Apache XML Security

public void setEncoding(String encoding) { if (encoding == null && encoding.length() == 0){ this.encoding = null; } else { URI tmpEncoding = null; try { tmpEncoding = new URI(encoding); } catch (URISyntaxException ex) { … } this.encoding = tmpEncoding.toString(); } } type != null

slide-27
SLIDE 27
  • RQ3. Robustness
  • Grafter detects 36% more mutants using the test-level comparison and

almost 2X more mutants using the state-level comparison

  • Grafter is less biased to mutant types than Jiang et al.

27

167 231 127 194 130 234 50 100 150 200 250 300 350 400

Test-level Comparison State-level Comparison Jiang et al. Detected Mutants Undetected Mutants

0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%

ROR LVR COR STD ORU AOR Test-level Comparison State-level Comparison Jiang et al.

slide-28
SLIDE 28

Conclusion

  • This work introduces the first test transplantation and reuse approach for

enabling runtime behavior comparison between clones.

  • Grafter’s code transplantation succeeds in 94% of the cases
  • The fine-grained differential testing can detect up to 2X more seeded

faults than a baseline static cloning bug finder.

28

slide-29
SLIDE 29

Q&A

29