Coverage-Driven Test Code Generation for Concurrent Classes Valerio - - PowerPoint PPT Presentation

coverage driven test code generation
SMART_READER_LITE
LIVE PREVIEW

Coverage-Driven Test Code Generation for Concurrent Classes Valerio - - PowerPoint PPT Presentation

Coverage-Driven Test Code Generation for Concurrent Classes Valerio Terragni Shing-Chi Cheung Department of Computer Science and Engineering The Hong Kong University of Science and Technology {vterragni, scc}@cse.ust.hk 20 May 2016 1


slide-1
SLIDE 1

20 May 2016

Coverage-Driven Test Code Generation for Concurrent Classes

Valerio Terragni Shing-Chi Cheung Department of Computer Science and Engineering The Hong Kong University of Science and Technology {vterragni, scc}@cse.ust.hk

1

slide-2
SLIDE 2

Input

Class Under Test (CUT)

Automated Test Code Generation for Concurrent Classes

public class CUT{ int x= 0; public void setX(int n){ x = n; } public synchronized void inc(){ $temp = x; x = $temp + 1; } }

2

slide-3
SLIDE 3

Output

Test code that expose concurrency bugs (if any)

Automated Test Code Generation for Concurrent Classes

2

slide-4
SLIDE 4

Output

Test code that expose concurrency bugs (if any)

Automated Test Code Generation for Concurrent Classes

private void runTest() throws Throwable { = new Thread(new Runnable() { public void run() { } }); = new Thread(new Runnable() { public void run() { } }); T1.start(); T2.start(); sout.setX(0); sout.inc(); final CUT sout = new CUT(); Thread T2 Thread T1

2

slide-5
SLIDE 5

Output

Test code that expose concurrency bugs (if any)

Automated Test Code Generation for Concurrent Classes

sout.setX(0); sout.inc(); final CUT sout = new CUT();

Shared Object Under Test

Thread T2 Thread T1

2

slide-6
SLIDE 6

Output

Test code that expose concurrency bugs (if any)

Automated Test Code Generation for Concurrent Classes

sout.setX(0); sout.inc(); final CUT sout = new CUT();

Shared Object Under Test

Thread T2 Thread T1

2

method call sequences

slide-7
SLIDE 7

Input

Class Under Test (CUT)

Output

Test code that expose concurrency bugs (if any)

public class CUT{ int x= 0; public void setX(int n){ x = n; } public synchronized void inc(){ $temp = x; x = $temp + 1; } } T1 T2 sout.setX(0); sout.inc(); final CUT sout = new CUT();

3

Automated Test Code Generation for Concurrent Classes

slide-8
SLIDE 8

Input

Class Under Test (CUT)

Output

Test code that expose concurrency bugs (if any)

public class CUT{ int x= 0; public void setX(int n){ x = n; } public synchronized void inc(){ $temp = x; x = $temp + 1; } } T1 T2 sout.setX(0); sout.inc(); final CUT sout = new CUT(); $temp = x; x = $temp + 1; x = n;

3

Automated Test Code Generation for Concurrent Classes

slide-9
SLIDE 9

Input

Class Under Test (CUT)

Output

Test code that expose concurrency bugs (if any)

public class CUT{ int x= 0; public void setX(int n){ x = n; } public synchronized void inc(){ $temp = x; x = $temp + 1; } } T1 T2 sout.setX(0); sout.inc(); final CUT sout = new CUT(); serializability violation $temp = x; x = $temp + 1; x = n; buggy interleaving

3

Automated Test Code Generation for Concurrent Classes

slide-10
SLIDE 10

Random generation [Pradel et. al. PLDI 2012, Nistor et. al. ICSE 2012]

  • Many randomly generated tests are needed for effective bug detection
  • Explore the interleaving space of many tests is too expensive!

4

slide-11
SLIDE 11

Coverage-driven Test Code Generation

  • Research Problem

Generate fewer tests that collectively achieve the highest coverage with respect to a given interleaving coverage criterion

4

slide-12
SLIDE 12

Coverage-driven Test Code Generation

  • Research Problem

An example of interleaving coverage criterion are the 11 problematic access patterns violating atomic-set serializability [Vaziri POPL 2006] R(x) W(x) W(x) T1 T2

W(x) write on shared memory location x R(x) write on shared memory location x 4

slide-13
SLIDE 13
  • Interleavings that match a problematic access pattern
  • Usually computed with respect to a given test code

Coverage Requirements

5

slide-14
SLIDE 14
  • Coverage driven test code generation requires to compute coverage requirements for

all possible test codes

Coverage Requirements

5

slide-15
SLIDE 15
  • Coverage driven test code generation requires to compute coverage requirements for

all possible test codes

Coverage Requirements

R(x) W(x) W(x) T1 T2 problematic access pattern

5

slide-16
SLIDE 16
  • Coverage driven test code generation requires to compute coverage requirements for

all possible test codes

Coverage Requirements

R(x) W(x) W(x) public class CUT{ int x= 0; public void setX(int n){ } public synchronized void inc(){ } } T1 T2 $temp = x; x = $temp + 1; x = n; Class Under Test problematic access pattern

5

slide-17
SLIDE 17
  • Coverage driven test code generation requires to compute coverage requirements for

all possible test codes

Coverage Requirements

R(x) W(x) W(x) public class CUT{ int x= 0; public void setX(int n){ } public synchronized void inc(){ } } T1 T2 $temp = x; x = $temp + 1; x = n; coverage requirements Class Under Test problematic access pattern

5

slide-18
SLIDE 18

Challenge

Compute the executable domain of interleaving coverage criteria is machine undecidable [Ramalingam, TOPLAS 2000] It requires Context-sensitive and synchronization-sensitive analysis

6

slide-19
SLIDE 19

Challenge

6

slide-20
SLIDE 20

Challenge

ConSuite [Steenbuck et al., ICST 2013]

  • Compute context-insensitive and synchronization-insensitive coverage

requirements statically

6

slide-21
SLIDE 21

R(x) W(x) W(x) problematic access pattern

Step 1

T1 T2

ConSuite [Steenbuck et al., ICST 2013]

7

Collect context-insensitive coverage requirements (statically)

slide-22
SLIDE 22

R(x) W(x) W(x) public class CUT{ int x= 0, z = 0; public void m1(int n){ } private void m4(int v1){ } } problematic access pattern

Step 1

T1 T2 $temp = x; x = $temp + v1; x = n; Class Under Test

ConSuite [Steenbuck et al., ICST 2013]

7

Collect context-insensitive coverage requirements (statically)

slide-23
SLIDE 23

R(x) W(x) W(x) problematic access pattern

Step 1

T1 T2 x = n; x = n; coverage requirement Class Under Test

ConSuite [Steenbuck et al., ICST 2013]

static match of bytecode instructions

7

context-insensitive Collect context-insensitive coverage requirements (statically)

slide-24
SLIDE 24

R(x) W(x) W(x) problematic access pattern

Step 1

T1 T2 $temp = x; x = n; $temp = x; coverage requirement Class Under Test

ConSuite [Steenbuck et al., ICST 2013]

static match of bytecode instructions

7

context-insensitive Collect context-insensitive coverage requirements (statically)

slide-25
SLIDE 25

R(x) W(x) W(x) problematic access pattern

Step 1

T1 T2 $temp = x; x = $temp + v1; x = n; x = $temp + v1; coverage requirement Class Under Test

ConSuite [Steenbuck et al., ICST 2013]

static match of bytecode instructions

7

context-insensitive Collect context-insensitive coverage requirements (statically)

slide-26
SLIDE 26

Step 1

$temp = x; x = $temp + v1; x = n; coverage requirement

ConSuite [Steenbuck et al., ICST 2013]

static match of bytecode instructions

7

context-insensitive Collect context-insensitive coverage requirements (statically)

slide-27
SLIDE 27

Step 1

$temp = x; x = $temp + v1; x = n; coverage requirement

ConSuite [Steenbuck et al., ICST 2013]

static match of bytecode instructions

7

context-insensitive

  • Miss coverage requirements
  • Miss the generation of failure

inducing test codes Collect context-insensitive coverage requirements (statically)

slide-28
SLIDE 28
  • Context-insensitive coverage requirement

ConSuite

[Steenbuck et al., ICST 2013]

$temp = x; x; = $temp + v1; x= n

8

Step 2 Coverage-driven test code generation

slide-29
SLIDE 29
  • Context-insensitive coverage requirement
  • Test code generation

public synchronized void m1(int n){ x = n; } ConSuite

[Steenbuck et al., ICST 2013]

$temp = x; x; = $temp + v1; x= n

final CUT sout = new CUT(); T1 sout.m1(0);

8

Step 2 Coverage-driven test code generation

slide-30
SLIDE 30
  • Context-insensitive coverage requirement
  • Test code generation

private void m4(int v1){ $temp = x; x = $temp + v1; } public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); } ConSuite

[Steenbuck et al., ICST 2013]

$temp = x; x; = $temp + v1; x= n

final CUT sout = new CUT(); T1 T2 sout.m1(0); sout.m3(10);

8

Step 2 Coverage-driven test code generation

slide-31
SLIDE 31
  • Context-insensitive coverage requirement
  • Test code generation

private void m4(int v1){ $temp = x; x = $temp + v1; } public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); } ConSuite

[Steenbuck et al., ICST 2013]

$temp = x; x; = $temp + v1; x= n

final CUT sout = new CUT(); T1 T2 sout.m1(0); sout.m3(10); infeasible

$temp = x; x = $temp + v1; x= n

8

Step 2 Coverage-driven test code generation

slide-32
SLIDE 32

Context and synchronization insensitivity misses the generation of this failure inducing test code public class CUT{ int x= 0, z =0; final CUT sout = new CUT(); T1 T2 sout.m1(0); sout.m2() sout.m3(10);

9

ConSuite

[Steenbuck et al., ICST 2013]

slide-33
SLIDE 33

Context and synchronization insensitivity misses the generation of this failure inducing test code public class CUT{ int x= 0, z =0; public void m2(){ z = 1; } final CUT sout = new CUT(); T1 T2 sout.m1(0); sout.m2() sout.m3(10);

z = 1

9

ConSuite

[Steenbuck et al., ICST 2013]

slide-34
SLIDE 34

Context and synchronization insensitivity misses the generation of this failure inducing test code public class CUT{ int x= 0, z =0; private void m4(int v1){ $temp = x; x = $temp + v1; } public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); } final CUT sout = new CUT(); T1 T2 sout.m1(0); sout.m2() sout.m3(10);

z = 1

9

ConSuite

[Steenbuck et al., ICST 2013]

slide-35
SLIDE 35

Context and synchronization insensitivity misses the generation of this failure inducing test code public class CUT{ int x= 0, z =0; private void m4(int v1){ $temp = x; x = $temp + v1; } public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); } final CUT sout = new CUT(); T1 T2 sout.m1(0); sout.m2() sout.m3(10);

z = 1

9

ConSuite

[Steenbuck et al., ICST 2013]

slide-36
SLIDE 36

Context and synchronization insensitivity misses the generation of this failure inducing test code public class CUT{ int x= 0, z =0; private void m4(int v1){ $temp = x; x = $temp + v1; } public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); } final CUT sout = new CUT(); T1 T2 sout.m1(0); sout.m2() sout.m3(10);

z = 1

9

ConSuite

[Steenbuck et al., ICST 2013]

slide-37
SLIDE 37

Context and synchronization insensitivity misses the generation of this failure inducing test code public class CUT{ int x= 0, z =0; private void m4(int v1){ $temp = x; x = $temp + v1; } public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); } final CUT sout = new CUT(); T1 T2 sout.m1(0); sout.m2() sout.m3(10);

z = 1

9

ConSuite

[Steenbuck et al., ICST 2013]

slide-38
SLIDE 38

Context and synchronization insensitivity misses the generation of this failure inducing test code public class CUT{ int x= 0, z =0; private void m4(int v1){ $temp = x; x = $temp + v1; } public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); } final CUT sout = new CUT(); T1 T2 sout.m1(0); sout.m2() sout.m3(10);

FEASIBLE interleaving

z = 1 $temp = x; x; = $temp + v1; x= n

9

ConSuite

[Steenbuck et al., ICST 2013]

slide-39
SLIDE 39

Context and synchronization insensitivity misses the generation of this failure inducing test code public class CUT{ int x= 0, z =0; private void m4(int v1){ $temp = x; x = $temp + v1; } public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); } final CUT sout = new CUT(); T1 T2 sout.m1(0); sout.m2() sout.m3(10);

FEASIBLE interleaving

z = 1

Without context and synchronization sensitivity this test is unlikely generated

$temp = x; x; = $temp + v1; x= n

9

ConSuite

[Steenbuck et al., ICST 2013]

slide-40
SLIDE 40

Our Intuition

10

Step 1 Collect context-insensitive coverage requirements (statically) Step 2 Coverage-driven test code generation

slide-41
SLIDE 41

Our Intuition

  • Context-sensitive and synchronization-sensitive information can be collected precisely

and efficiently during sequential test code generation

10

Step 1 Collect context-insensitive coverage requirements (statically) Step 2 Coverage-driven test code generation

slide-42
SLIDE 42

Our Intuition

  • Context-sensitive and synchronization-sensitive information can be collected precisely

and efficiently during sequential test code generation

  • Coverage metric (Sequential coverage)
  • Granularity at outer-most method call
  • Ordered sequence of object’s fields accesses
  • Context and synchronization sensitive
  • lock acquires and releases
  • calling context

10

Step 1 Collect context-insensitive coverage requirements (statically) Step 2 Coverage-driven test code generation

slide-43
SLIDE 43

AutoConTest

11

slide-44
SLIDE 44

AutoConTest

11

class CUT Call Sequence Generator

increase sequential coverage

slide-45
SLIDE 45

AutoConTest

11

class CUT Call Sequence Generator

increase sequential coverage

Concurrent Test Assembler

final CUT sout = new CUT(); T1 T2

pairwise combinations

slide-46
SLIDE 46

AutoConTest

11

class CUT Call Sequence Generator

increase sequential coverage

Concurrent Test Assembler

final CUT sout = new CUT(); T1 T2

pairwise combinations

Interleaving Explorer

compute the interleaving based coverage requirements

$temp = x; x; = $temp + v1; x= n

slide-47
SLIDE 47

Call Sequence Generator

class CUT Call Sequence Generator

12

slide-48
SLIDE 48

Call Sequence Generator

class CUT Call Sequence Generator

sout.m3(10); sout.m2(); CUT sout = new CUT();

12

slide-49
SLIDE 49

Call Sequence Generator

class CUT Call Sequence Generator

sout.m3(10); sout.m2(); CUT sout = new CUT(); public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); }

12

slide-50
SLIDE 50

Call Sequence Generator

class CUT Call Sequence Generator

sout.m3(10); sout.m2(); CUT sout = new CUT(); public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); }

12

slide-51
SLIDE 51

Call Sequence Generator

class CUT Call Sequence Generator

sout.m3(10); sout.m2(); CUT sout = new CUT(); public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); }

12

slide-52
SLIDE 52

Call Sequence Generator

class CUT Call Sequence Generator

sout.m3(10); sout.m2(); CUT sout = new CUT(); public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); }

12

slide-53
SLIDE 53

Call Sequence Generator

class CUT Call Sequence Generator

sout.m3(10); sout.m2(); CUT sout = new CUT(); private void m4(int v1){ $temp = x; x = $temp + 1; }

12

slide-54
SLIDE 54

Call Sequence Generator

class CUT Call Sequence Generator

sout.m3(10); sout.m2(); CUT sout = new CUT(); private void m4(int v1){ $temp = x; x = $temp + 1; }

12

slide-55
SLIDE 55

Call Sequence Generator

class CUT Call Sequence Generator

sout.m3(10); sout.m2(); CUT sout = new CUT(); private void m4(int v1){ $temp = x; x = $temp + 1; }

12

new m3’s behaviour

slide-56
SLIDE 56

Call Sequence Generator

class CUT Call Sequence Generator

sout.m3(10); sout.m2(); CUT sout = new CUT(); public void m2(){ z = 1; }

12

new m3’s behaviour

slide-57
SLIDE 57

Call Sequence Generator

class CUT Call Sequence Generator

sout.m3(10); sout.m2(); CUT sout = new CUT(); public void m2(){ z = 1; }

12

new m3’s behaviour new m2’s behaviour

slide-58
SLIDE 58

Call Sequence Generator

class CUT Call Sequence Generator

sout.m3(10); sout.m2(); CUT sout = new CUT();

increase sequential coverage

public void m2(){ z = 1; }

12

new m3’s behaviour new m2’s behaviour

slide-59
SLIDE 59

Call Sequence Generator

class CUT Call Sequence Generator

sout.m2(); sout.m3(10); CUT sout = new CUT(); public void m2(){ z = 1; }

12

slide-60
SLIDE 60

Call Sequence Generator

class CUT Call Sequence Generator

sout.m2(); sout.m3(10); CUT sout = new CUT(); public void m2(){ z = 1; }

12

slide-61
SLIDE 61

Call Sequence Generator

class CUT Call Sequence Generator

sout.m2(); sout.m3(10); CUT sout = new CUT(); private void m4(int v1){ $temp = x; x = $temp + 1; } public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); } public void m2(){ z = 1; }

12

slide-62
SLIDE 62

Call Sequence Generator

class CUT Call Sequence Generator

sout.m2(); sout.m3(10); CUT sout = new CUT(); private void m4(int v1){ $temp = x; x = $temp + 1; } public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); } public void m2(){ z = 1; }

12

slide-63
SLIDE 63

Call Sequence Generator

class CUT Call Sequence Generator

sout.m2(); sout.m3(10); CUT sout = new CUT(); private void m4(int v1){ $temp = x; x = $temp + 1; } public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); } public void m2(){ z = 1; }

12

slide-64
SLIDE 64

Call Sequence Generator

class CUT Call Sequence Generator

sout.m2(); sout.m3(10); CUT sout = new CUT(); private void m4(int v1){ $temp = x; x = $temp + 1; } public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); } public void m2(){ z = 1; }

12

slide-65
SLIDE 65

Call Sequence Generator

class CUT Call Sequence Generator

sout.m2(); sout.m3(10); CUT sout = new CUT(); private void m4(int v1){ $temp = x; x = $temp + 1; } public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); } public void m2(){ z = 1; }

12

slide-66
SLIDE 66

Call Sequence Generator

class CUT Call Sequence Generator

sout.m2(); sout.m3(10); CUT sout = new CUT(); private void m4(int v1){ $temp = x; x = $temp + 1; } public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); } public void m2(){ z = 1; }

12

slide-67
SLIDE 67

Call Sequence Generator

class CUT Call Sequence Generator

sout.m2(); sout.m3(10); CUT sout = new CUT();

increase sequential coverage

private void m4(int v1){ $temp = x; x = $temp + 1; } public void m3(int v1){ if(z ==0){ synchronized (this){ m4(v1); } } else m4(v1); } public void m2(){ z = 1; }

12

new m3’s behaviour

slide-68
SLIDE 68

Call Sequence Generator

13

CUT sout = new CUT();

  • Search Space
  • CUT methods
  • fixed pool of parameters

values (at each iteration)

slide-69
SLIDE 69

Call Sequence Generator

sout.m1(1);

13

CUT sout = new CUT();

  • Search Space
  • CUT methods
  • fixed pool of parameters

values (at each iteration)

slide-70
SLIDE 70

Call Sequence Generator

…….

sout.m1(1);

13

CUT sout = new CUT(); sout.m1(0); sout.m3(10); sout.m2();

  • Search Space
  • CUT methods
  • fixed pool of parameters

values (at each iteration)

…….

slide-71
SLIDE 71

Call Sequence Generator

…….

sout.m1(1);

13

CUT sout = new CUT(); sout.m1(0); sout.m3(10); sout.m2();

…….

sout.m1(0); sout.m3(10); sout.m2(); sout.m1(1);

  • Search Space
  • CUT methods
  • fixed pool of parameters

values (at each iteration) sout.m2();

……. …….

slide-72
SLIDE 72

Call Sequence Generator

…….

sout.m1(1);

13

CUT sout = new CUT(); sout.m1(0); sout.m3(10); sout.m2(); CUT sout = new CUT(); sout.m3(10); sout.m2();

…….

sout.m1(0); sout.m3(10); sout.m2(); sout.m1(1);

  • Search Space
  • CUT methods
  • fixed pool of parameters

values (at each iteration) sout.m2();

……. …….

slide-73
SLIDE 73

Call Sequence Generator

…….

13

CUT sout = new CUT(); sout.m3(10); sout.m2(); CUT sout = new CUT(); sout.m3(10);

…….

  • sout.m2();

……. …….

slide-74
SLIDE 74
  • Saturation-based stopping criterion
  • Stop extending a node if the latest K extensions have not increased the

sequential coverage

Call Sequence Generator

…….

sout.m1(1);

14

CUT sout = new CUT(); sout.m1(0); sout.m3(10); sout.m2();

…….

sout.m1(0); sout.m3(10); sout.m2(); sout.m1(1); sout.m2();

……. …….

  • Systematic exploration
  • DFS (search order)
slide-75
SLIDE 75

Call Sequence Generator

…….

sout.m1(1);

15

CUT sout = new CUT(); sout.m1(0); sout.m3(10); sout.m2();

…….

sout.m1(0); sout.m3(10); sout.m2(); sout.m1(1); sout.m2();

……. …….

  • Systematic exploration
  • DFS (search order)
slide-76
SLIDE 76

Call Sequence Generator

15

  • Systematic exploration
  • DFS (search order)
slide-77
SLIDE 77
  • To minimize the number of tests and maximize the coverage
  • At each iteration identify an optimal sequence

with the highest coverage improvement # method calls that increase sequential coverage

Call Sequence Generator

15

slide-78
SLIDE 78
  • To minimize the number of tests and maximize the coverage
  • At each iteration identify an optimal sequence

with the highest coverage improvement # method calls that increase sequential coverage

Call Sequence Generator

15

  • search space is too huge!
slide-79
SLIDE 79

Search Space Pruning Strategies

Depth pruning

16

slide-80
SLIDE 80

Search Space Pruning Strategies

Depth pruning

16

slide-81
SLIDE 81

Search Space Pruning Strategies

Breadth pruning Depth pruning

16

slide-82
SLIDE 82

Search Space Pruning Strategies

Breadth pruning Depth pruning

16

slide-83
SLIDE 83

Search Space Pruning Strategies

Breadth pruning Depth pruning

16

slide-84
SLIDE 84

Search Space Pruning Strategies

Breadth pruning Depth pruning

16

Assumption: The sequential execution of call sequences is deterministic

slide-85
SLIDE 85

Search Space Pruning Strategies

Breadth pruning Depth pruning

  • Redundancy
  • Based on program states and sequential

coverage

16

Assumption: The sequential execution of call sequences is deterministic

slide-86
SLIDE 86

Search Space Pruning Strategies

Breadth pruning Depth pruning

  • Redundancy
  • Based on program states and sequential

coverage

16

Assumption: The sequential execution of call sequences is deterministic Theorem 1 The unexplored descendants of a node representing a redundant call sequence do not need to be explored in

  • rder to reach the optimal solution
slide-87
SLIDE 87

Search Space Pruning Strategies

Breadth pruning Depth pruning

  • 16

Theorem 1 The unexplored descendants of a node representing a redundant call sequence do not need to be explored in

  • rder to reach the optimal solution
slide-88
SLIDE 88

Concurrent Test Assembler

17

class CUT Call Sequence Generator

slide-89
SLIDE 89

Concurrent Test Assembler

17

class CUT Call Sequence Generator

slide-90
SLIDE 90

Concurrent Test Assembler

Concurrent Test Assembler

17

class CUT Call Sequence Generator

slide-91
SLIDE 91

Concurrent Test Assembler

Concurrent Test Assembler

final CUT sout = new CUT(); T1 T2

17

final CUT sout = new CUT(); T1 T2 final CUT sout = new CUT(); T1 T2

  • The returned call sequences returned call

sequences are concurrently pair-wise tested

  • Necessary condition for increasing

interleaving coverage (Theorem 2)

class CUT Call Sequence Generator

slide-92
SLIDE 92

Interleaving Explorer

class CUT Call Sequence Generator Concurrent Test Assembler Interleaving Explorer

18

final CUT sout = new CUT(); T1 T2 sout.m1(0); sout.m2() sout.m3(10);

slide-93
SLIDE 93

Interleaving Explorer

class CUT Call Sequence Generator Concurrent Test Assembler Interleaving Explorer

18

final CUT sout = new CUT(); T1 T2 sout.m1(0); sout.m2() sout.m3(10); To compute the interleaving coverage requirements of the test code Predictive Trace Analysis (PTA) [Lai et al. ICSE 2016]

slide-94
SLIDE 94

Interleaving Explorer

class CUT Call Sequence Generator Concurrent Test Assembler Interleaving Explorer

18

final CUT sout = new CUT(); T1 T2 sout.m1(0); sout.m2() sout.m3(10); To check if the requirements are feasible or infeasible Thread Scheduler

slide-95
SLIDE 95

Interleaving Explorer

class CUT Call Sequence Generator Concurrent Test Assembler Interleaving Explorer

18

final CUT sout = new CUT(); T1 T2 sout.m1(0); sout.m2() sout.m3(10); Challenge: non-deterministic interferences

slide-96
SLIDE 96

Subjects

19

6 real, known concurrency bugs atomic-set serializability violations

BUG ID Code Base Class Under Test CUT SLOC 1 Apache Commons 2.4 [..].lang.math.IntRange 278 2 Google Commons 1.0 [...]AbstractMultiMap$AsMap 1125 3 Java JDK 1.1.7 java.util.Vector 216 4 JFreeChart 0.9 [...]chart.axis.NumberAxis 1298 5 Java JDK 1.1.7 java.util.logging.Logger 992 6 Java JDK 1.4.2 java.util.Vector 326

slide-97
SLIDE 97

RQ1:Cost-Effectiveness

BUG ID Code Base CUT SLOC 1 Apache Commons 2.4 278 2 Google Commons 1.0 1125 3 Java JDK 1.1.7 216 4 JFreeChart 0.9 1298 5 Java JDK 1.1.7 992 6 Java JDK 1.4.2 326 Time first fault 22 sec 29 sec 65 sec 35 sec 45 sec 30 sec

20

slide-98
SLIDE 98

RQ1:Cost-Effectiveness

BUG ID Code Base CUT SLOC 1 Apache Commons 2.4 278 2 Google Commons 1.0 1125 3 Java JDK 1.1.7 216 4 JFreeChart 0.9 1298 5 Java JDK 1.1.7 992 6 Java JDK 1.4.2 326 Time first fault 22 sec 29 sec 65 sec 35 sec 45 sec 30 sec

20

slide-99
SLIDE 99

RQ1:Cost-Effectiveness

BUG ID Code Base CUT SLOC 1 Apache Commons 2.4 278 2 Google Commons 1.0 1125 3 Java JDK 1.1.7 216 4 JFreeChart 0.9 1298 5 Java JDK 1.1.7 992 6 Java JDK 1.4.2 326 Time first fault 22 sec 29 sec 65 sec 35 sec 45 sec 30 sec generate the first failing test code and trigger the first faulty interleaving

20

slide-100
SLIDE 100

RQ1:Cost-Effectiveness

BUG ID Code Base CUT SLOC 1 Apache Commons 2.4 278 2 Google Commons 1.0 1125 3 Java JDK 1.1.7 216 4 JFreeChart 0.9 1298 5 Java JDK 1.1.7 992 6 Java JDK 1.4.2 326 Time first fault 22 sec 29 sec 65 sec 35 sec 45 sec 30 sec generate the first failing test code and trigger the first faulty interleaving For all subjects the first generated test manifested the bug

20

slide-101
SLIDE 101

RQ2:Comparison with ConTeGen

BUG ID Code Base CUT SLOC 1 Apache Commons 2.4 278 2 Google Commons 1.0 1125 3 Java JDK 1.1.7 216 4 JFreeChart 0.9 1298 5 Java JDK 1.1.7 992 6 Java JDK 1.4.2 326 Time first fault 22 sec 29 sec 65 sec 35 sec 45 sec 30 sec ConTeGen [Pradel et. al. PLDI 2012] http://thread-safe.org/

  • State-of-The-Art in Random based

concurrent test code generation

  • We used the same interleaving

explorer of AutoConTest

  • different random seeds best result
  • Time-budget of one hour

ConTeGen AutoConTest

21

slide-102
SLIDE 102

RQ2:Comparison with ConTeGen

BUG ID Code Base CUT SLOC 1 Apache Commons 2.4 278 2 Google Commons 1.0 1125 3 Java JDK 1.1.7 216 4 JFreeChart 0.9 1298 5 Java JDK 1.1.7 992 6 Java JDK 1.4.2 326 Time first fault 22 sec 29 sec 65 sec 35 sec 45 sec 30 sec Time first fault 66 sec *1hr 1,014 sec 156 sec *1hr 2,254 sec ConTeGen AutoConTest

21

slide-103
SLIDE 103

RQ2:Comparison with ConTeGen

BUG ID Code Base CUT SLOC 1 Apache Commons 2.4 278 2 Google Commons 1.0 1125 3 Java JDK 1.1.7 216 4 JFreeChart 0.9 1298 5 Java JDK 1.1.7 992 6 Java JDK 1.4.2 326 Coverage 19 1 2 23 1 33 Coverage = # unique and feasible interleaving coverage requirements (atomic-set violations) The same bug could lead to different atomic-set violations Coverage 91 2 3 1 ConTeGen AutoConTest

22

slide-104
SLIDE 104

RQ2:Comparison with ConTeGen

BUG ID Code Base CUT SLOC 1 Apache Commons 2.4 278 2 Google Commons 1.0 1125 3 Java JDK 1.1.7 216 4 JFreeChart 0.9 1298 5 Java JDK 1.1.7 992 6 Java JDK 1.4.2 326 Coverage 19 1 2 23 1 33 Coverage = # unique and feasible interleaving coverage requirements (atomic-set violations) The same bug could lead to different atomic-set violations Coverage 91 2 3 1 ConTeGen AutoConTest

22

slide-105
SLIDE 105

RQ2:Coverage Comparison

0% 10% 20% 30% 40% 50% 60% 70% 80% 600 1200 1800 2400 3000 3600 % interleaving coverage Time (seconds) AutoConTest ConTeGen On average (for all subjects), AutoConTest achieved in less than 40 seconds the same percentage of coverage achieved by ConTeGen in one hour.

23

slide-106
SLIDE 106

RQ2:Test Code Size Comparison

BUG ID Code Base CUT SLOC 1 Apache Commons 2.4 278 2 Google Commons 1.0 1125 3 Java JDK 1.1.7 216 4 JFreeChart 0.9 1298 5 Java JDK 1.1.7 992 6 Java JDK 1.4.2 326 # tests 7 3 17 1 3 1 Test code SLOC 1,742 1,898 1,232 1,351 3,161 2,729 ConTeGen AutoConTest # tests 110 130 185 99 230 167 Test code SLOC 2,157 19 1,437 114 105 104

24

slide-107
SLIDE 107

RQ2:Test Code Size Comparison

BUG ID Code Base CUT SLOC 1 Apache Commons 2.4 278 2 Google Commons 1.0 1125 3 Java JDK 1.1.7 216 4 JFreeChart 0.9 1298 5 Java JDK 1.1.7 992 6 Java JDK 1.4.2 326 # tests 7 3 17 1 3 1 Test code SLOC 1,742 1,898 1,232 1,351 3,161 2,729 ConTeGen AutoConTest # tests 110 130 185 99 230 167 Test code SLOC 2,157 19 1,437 114 105 104

24

slide-108
SLIDE 108

RQ2:Test Code Size Comparison

BUG ID Code Base CUT SLOC 1 Apache Commons 2.4 278 2 Google Commons 1.0 1125 3 Java JDK 1.1.7 216 4 JFreeChart 0.9 1298 5 Java JDK 1.1.7 992 6 Java JDK 1.4.2 326 # tests 7 3 17 1 3 1 Test code SLOC 1,742 1,898 1,232 1,351 3,161 2,729 ConTeGen AutoConTest # tests 110 130 185 99 230 167 Test code SLOC 2,157 19 1,437 114 105 104

24

Or generated test suites are more effective than much larger test suites generated randomly

slide-109
SLIDE 109

RQ3:Redundancy-based Pruning Strategies

ENABLED BUG ID Time (ms) # unique method calls that increase coverage 1 1,598 25 2 1,741 6 3 1,931 23 4 7,098 56 5 2,911 24 6 2,866 44

25

DISABLED Time (ms) # unique method calls that increase coverage 1 hr (time-out) 25 1 hr (time-out) 6 1 hr (time-out) 24 1 hr (time-out) 56 1 hr (time-out) 24 1 hr (time-out) 44

Optimal sequence at the first iteration saturation based stopping criterion k = 3

slide-110
SLIDE 110

RQ3:Redundancy-based Pruning Strategies

The pruning strategies detected optimal sequence more than 1530× faster, in only one case the solution was sub-optimal.

ENABLED BUG ID Time (ms) # unique method calls that increase coverage 1 1,598 25 2 1,741 6 3 1,931 23 4 7,098 56 5 2,911 24 6 2,866 44

25

DISABLED Time (ms) # unique method calls that increase coverage 1 hr (time-out) 25 1 hr (time-out) 6 1 hr (time-out) 24 1 hr (time-out) 56 1 hr (time-out) 24 1 hr (time-out) 44

Optimal sequence at the first iteration saturation based stopping criterion k = 3

slide-111
SLIDE 111

Conclusion

26