CMPSCI 521/621 Homework 2 Solutions Problem 1 Direct data dependencies: 3 is directly data dependent on 1 and 5 5 is directly data dependent on 1,3, and 5 7 is directly data dependent on 1,3, and 5 Note, these data dependencies are explicitly listed in the answer to question 2 c). Control flow dependencies: A node s v is control dependent on node s u iff there exists a path s u P s v not containing the immediate forward dominator of s u. The immediate forward dominators (ifd) of the nodes in the graph are as follows: ifd(1)=2; ifd(2)=4; ifd(3)=4; ifd(4)=6; ifd(5)=6; ifd(6)=7. Thus, the control flow dependencies are: 2 is control dependent on 6 3 is control dependent on 2 and 6 4 is control dependent on 6 5 is control dependent on 4 and 6 6 is control dependent on 6 Problem 2 a) 1,2,3,4,5,6,7 covers all the nodes (statements) but does not cover all the branches (e.g., branches 2-4, 4-6, 6-2 are not covered). b) All-def requirements: In parenthesis, we also list how the all-def requirements below correspond to the def-use pairs from 2 c). d 1 (x) to a use of x (corresponds to requirements a or b from 2 c)) d 1 (y) to a use of y (c or d or e) d 3 (x) to a use of x (f or g) d 5 (y) to a use of y (h or i or j) Paths: 1,2,4,6,7 (b,e); 1,2,3,4,5,6,7 (c,d,f,g,j). Does not provide all-uses coverage as not every use of a given definition is reached (e.g., d 1 (x) does not reach u 5 (x) ). c) All-uses requirements: a : d 1 (x) to u 5 (x) b : d 1 (x) to u 7 (x) c : d 1 (y) to u 3 (y) d : d 1 (y) to u 5 (y) 1
e : d 1 (y) to u 7 (y) f : d 3 (x) to u 5 (x) g : d 3 (x) to u 7 (x) h : d 5 (y) to u 3 (y) i : d 5 (y) to u 5 (y) j : d 5 (y) to u 7 (y) Paths: 1,2,3,4,5,6,7 (c,d,f,g,j); 1,2,4,6,7 (b,e); 1,2,4,5,6,2,3,4,5,6,7 (a,d,f,g,h,i) These paths do not provide All-du coverage, because they do not satisfy some of the all-du requirements listed below (e.g., they don t satisfy requirement b 1 ). d) If a node has two outgoing edges, let T and F (for true and false) denote the left and right outgoing edges respectively. Thus, for example, the edge from node 2 to node 4 will be denoted with 2T and the edge from node 2 to node 3 will be denoted with 2F. To achieve All-Du coverage, we need all definition-clear subpaths that are cycle-free or are simple cycles 1 from each definition to each use reached by that definition and each successor node of the use. Thus, for each of the def-use pairs in part c), we need to find all def-clear subpaths (form the definition to the use) that are cycle free or are simple cycles. All-Du requirements: a : d 1 (x) to u 5 (x), [2T, 4T ] b 1 : d 1 (x) to u 7 (x), [4T, 6F ] b 2 : d 1 (x) to u 7 (x), [4F, 6F ] c : d 1 (y) to u 3 (x), [2F ] d 1 : d 1 (y) to u 5 (y), [2T, 4T, 6F ] d 2 : d 1 (y) to u 5 (y), [2F, 4T, 6F ] e 1 : d 1 (y) to u 7 (y), [2T, 4F, 6F ] e 2 : d 1 (y) to u 7 (y), [2F, 4F, 6F ] f : d 3 (x) to u 5 (x), [4T, 6F ] g 1 : d 3 (x) to u 7 (x), [4F, 6F ] g 2 : d 3 (x) to u 7 (x), [4T, 6F ] h : d 5 (y) to u 3 (y), [6T, 2F ] i 1 : d 5 (y) to u 5 (y), [6T, 2T, 4T ] i 2 : d 5 (y) to u 5 (y), [6T, 2F, 4T ] j : d 5 (y) to u 7 (y), [6F ] Paths: 1,2,3,4,5,6,7 (c, d 2, f, g 2, j); 1,2,4,6,7 (b 2, e 1 ); 1,2,4,5,6,2,3,4,5,6,7 (a, d 1, f, g 2, h, i 2, j); 1,2,4,5,6,7 (b 1 ), 1,2,3,4,6,7 (e 2, g 1 ), 1,2,4,5,6,2,4,5,6,7 (i 1 ). e) Context coverage for node 7 Requirements: a : {d 1 (x), d 1 (y)} b : {d 1 (x), d 5 (y)} c : {d 3 (x), d 1 (y)} d : {d 3 (x), d 5 (y)} 1 Strictly speaking, the only cycles on a path from a def to a use allowed by the All-Du coverage definition are cycles such that only the first and the last node on that path are the same (i.e. the path has to be a simple cycle). Since the first node on a path from a def to a use is the node containing the def and the last node on such a path is the node containing the use, a simple cycle implies that the def and the use are at the same node. If the def and the use are at different nodes, then the path from the def to the use cannot be a simple cycle and thus the definition of All-Du requires that this path be cycle free. 2
Paths: 1,2,4,6,7 (a); 1,2,4,5,6,7 (b); 1,2,3,4,6,7 (c); 1,2,3,4,5,6,7 (d) f) Ordered context coverage for node 7: Requirements (square brackets are used to indicate sequence): a : [d 1 (x), d 1 (y)] b : [d 1 (x), d 5 (y)] c : [d 1 (y), d 3 (x)] d : [d 3 (x), d 5 (y)] e : [d 5 (y), d 3 (x)] Paths: The same paths as in part e) plus 1,2,4,5,6,2,3,4,6,7 to cover requirement e. Problem 3 Because of the existence of infeasible paths in a control flow graph. Suppose x is assigned a value of 117 at node 3 and the conditional at node 4 is if (x < 50) then node 5, else node 6. In that case, the path from node 3 to node 5 is infeasible and thus the definition of x at node 3 cannot reach the use of x at node 5. Problem 4 No, criterion A will not always detect more faults than criterion B for this program. The fact that the given test set satisfying criterion A found more faults than the given test set satisfying criterion B may be due to the specific input values of these two specific test sets. For example, the test set satisfying criteria B may have contained input values that lead to coincidental correctness of the program. Another test set satisfying criteria B may not lead to coincidental correctness of the program and it is possible that this test set finds more errors than a test set satisfying criteria A. For the same reason, criteria A will not always detect more faults than criteria B for any program. Problem 5 The costs associated with testing include the creation of the set of test cases, determining the oracles for these test cases, executing these test cases, determining if the selected testing criteria have been satisfied and creating additional test cases to satisfy the the criterion in case it has not been satisfied by the previous set of test cases. The costs associated with statement coverage are usually significantly lower than the costs associated with mutation testing. There are a smaller number of test cases that need to be created for statement coverage. These test cases would probably kill some of the mutant programs, such as those that delete each statement, but many more test cases would usually be needed to kill the additional mutants. Also, coming up with a test case that covers a statement is usually easier than coming up with a test case to kill a mutant. Since there are usually many more test cases for mutation testing, the cost of determining the oracles and executing the program with these test cases would also be higher. For statement coverage, one has to determine if a statement can be executed and this can sometimes be difficult. For mutation testing, one has to determine if the surviving mutants are equivalent to the original program or a test case exists that can kill the mutant, and this is usually more difficult and thus more costly. 3
Problem 6 Computation tree for the given code segment. X is integer between 2 and 4, Y is a Boolean. The symbol # is used to represent an uninitialized value. Problem 7 Transfer set = {(A 2, D 3 ), (A 2, B 4 ), (D 3, B 4 )} Transfer Routes: Route 1: (A 2, D 3 ), (A 2, B 4 ), (D 3, B 4 ) Route 2: (A 2, D 3 ), (A 2, B 4 ) Route 3: (A 2, D 3 ), (A 2, B 4 ), (D 3, B 4 ) Route 4: (A 2, D 3 ), (A 2, B 4 ), (D 3, B 4 ) Origination condition: c 5 Constraint based on the final expression at statement 4 (for any route that can transfer the fault to the final expression at node 4, we want the value of b at statement 4 in the correct program to be different from the value of b at statement 4 in the incorrect prorram): b b, where b is the value of b at statement 4 in the correct program. b b a(d 1) a (d 1) a(ab 1) a (a b 1) a 2 b a a 2 b a a 2 b a 2 b a a b(a a )(a + a ) a a (we can divide both sides by (a a ) since a a 0 by origination condition.) b(a + a ) 1 b(2b + c + 2b + 5) 1 b(4b + c + 5) 1 4b + c + 5 1/b, if b 0 c 1/b 4b 5, if b 0. Thus, the constraint is b = 0 (b 0 c 1/b 4b 5). Route 1 Constraints: b 0 d 1 = 0 a 0 b 0 d = 1 2b + c 0 b 0 (2b + c)b = 1 2b + c 0 (2b + c)b = 1 Thus, b=1 and c=-1, for example, will reveal the fault as they satisfy the conditions for route 1, the origination incorrect program output=0). Route 2 Constraints: b = 0 d 1 0 b = 0 d 1 b = 0 (2b + c)b 1 b = 0 Thus, b=0 will reveal the fault, as long as c 5. (E.g, for b=0, c=0, correct program outputs -5, incorrect 0) 4
Route 3 Constraints: b 0 d 1 0 a = 0 b 0 d 1 2b + c = 0 b 0 (2b + c)b 1 2b + c = 0 b 0 2b+c = 0 Thus, b=1, c=-2, for example, will reveal the fault as they satisfy the conditions for route 3, the origination incorrect program output=0). Route 4 Constraints: b 0 d 1 0 a 0 b 0 d 1 a 0 b 0 (2b+c)b 1 2b+c 0 Thus, b=1, c=1, for example, will reveal the fault as they satisfy the conditions for route 4, the origination incorrect program output=6). Note that b=-1 and c=-2, which violates the constraint based on the final expression at statement 4 but satisfies the conditions for routes 1,3 and 4, will not reveal the fault. The program outputs -12 for both versions with the correct and with the incorrect line 2. 5