Softrare Reliability Methods

Slides:



Advertisements
Similar presentations
Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Advertisements

Recognising Languages We will tackle the problem of defining languages by considering how we could recognise them. Problem: Is there a method of recognising.
Modeling Software Systems Lecture 2 Book: Chapter 4.
Lecture 2: testing Book: Chapter 9 What is testing? Testing is not showing that there are no errors in the program. Testing cannot show that the program.
Program verification: flowchart programs
Lexical Analysis Dragon Book: chapter 3.
Model Checking and Testing combined
Program verification: flowchart programs Book: chapter 7.
Black Box Checking Book: Chapter 9 Model Checking Finite state description of a system B. LTL formula. Translate into an automaton P. Check whether L(B)
Automatic Verification Book: Chapter 6. How can we check the model? The model is a graph. The specification should refer the the graph representation.
Program Verification Using Hoares Logic Book: Chapter 7.
Formal Methods and Testing Goal: software reliability Use software engineering methodologies to develop the code. Use formal methods during code development.
1 Program verification: flowchart programs (Book: chapter 7)
Program verification: flowchart programs Book: chapter 7.
Modeling issues Book: chapters 4.12, 5.4, 8.4, 10.1.
Problems and Their Classes
CS 267: Automated Verification Lecture 8: Automata Theoretic Model Checking Instructor: Tevfik Bultan.
Partial Order Reduction: Main Idea
Copyright , Doron Peled and Cesare Tinelli. These notes are based on a set of lecture notes originally developed by Doron Peled at the University.
1 Model checking. 2 And now... the system How do we model a reactive system with an automaton ? It is convenient to model systems with Transition systems.
Automatic Verification Book: Chapter 6. What is verification? Traditionally, verification means proof of correctness automatic: model checking deductive:
Reasoning About Code; Hoare Logic, continued
Hoare’s Correctness Triplets Dijkstra’s Predicate Transformers
Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 11.
1 1 CDT314 FABER Formal Languages, Automata and Models of Computation Lecture 3 School of Innovation, Design and Engineering Mälardalen University 2012.
SOFTWARE TESTING. INTRODUCTION  Software Testing is the process of executing a program or system with the intent of finding errors.  It involves any.
Mutual Exclusion By Shiran Mizrahi. Critical Section class Counter { private int value = 1; //counter starts at one public Counter(int c) { //constructor.
Annoucements  Next labs 9 and 10 are paired for everyone. So don’t miss the lab.  There is a review session for the quiz on Monday, November 4, at 8:00.
Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 13.
Software Failure: Reasons Incorrect, missing, impossible requirements * Requirement validation. Incorrect specification * Specification verification. Faulty.
ISBN Chapter 3 Describing Syntax and Semantics.
Software Reliability CIS 640 Adapted from the lecture notes by Doron Pelel (
1 Formal Methods in SE Qaisar Javaid Assistant Professor Lecture 05.
CMSC 345, Version 11/07 SD Vick from S. Mitchell Software Testing.
Introduction to Computability Theory
CS 536 Spring Global Optimizations Lecture 23.
4/25/08Prof. Hilfinger CS164 Lecture 371 Global Optimization Lecture 37 (From notes by R. Bodik & G. Necula)
25/06/2015Marius Mikucionis, AAU SSE1/22 Principles and Methods of Testing Finite State Machines – A Survey David Lee, Senior Member, IEEE and Mihalis.
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 18 Program Correctness To treat programming.
Prof. Fateman CS 164 Lecture 221 Global Optimization Lecture 22.
Chapter 11: Limitations of Algorithmic Power
Testing an individual module
Describing Syntax and Semantics
Prof. Bodik CS 164 Lecture 16, Fall Global Optimization Lecture 16.
OHT 9.1 Galin, SQA from theory to implementation © Pearson Education Limited 2004 Chapter 9.3 Software Testing Strategies.
Software Testing and QA Theory and Practice (Chapter 4: Control Flow Testing) © Naik & Tripathy 1 Software Testing and Quality Assurance Theory and Practice.
Software Testing Sudipto Ghosh CS 406 Fall 99 November 9, 1999.
System/Software Testing
CMSC 345 Fall 2000 Unit Testing. The testing process.
Chapter 3 (Part 3): Mathematical Reasoning, Induction & Recursion  Recursive Algorithms (3.5)  Program Correctness (3.6)
CSI 3125, Axiomatic Semantics, page 1 Axiomatic semantics The assignment statement Statement composition The "if-then-else" statement The "while" statement.
Unit Testing 101 Black Box v. White Box. Definition of V&V Verification - is the product correct Validation - is it the correct product.
Software Engineering1  Verification: The software should conform to its specification  Validation: The software should do what the user really requires.
Strings Basic data type in computational biology A string is an ordered succession of characters or symbols from a finite set called an alphabet Sequence.
Static Techniques for V&V. Hierarchy of V&V techniques Static Analysis V&V Dynamic Techniques Model Checking Simulation Symbolic Execution Testing Informal.
Program Correctness. The designer of a distributed system has the responsibility of certifying the correctness of the system before users start using.
SOFTWARE TESTING LECTURE 9. OBSERVATIONS ABOUT TESTING “ Testing is the process of executing a program with the intention of finding errors. ” – Myers.
Verification vs. Validation Verification: "Are we building the product right?" The software should conform to its specification.The software should conform.
1 Software Testing. 2 What is Software Testing ? Testing is a verification and validation activity that is performed by executing program code.
A Review of Software Testing - P. David Coward
Software Testing.
Control Flow Testing Handouts
Input Space Partition Testing CS 4501 / 6501 Software Testing
Outline of the Chapter Basic Idea Outline of Control Flow Testing
Structural testing, Path Testing
Types of Testing Visit to more Learning Resources.
UNIT-4 BLACKBOX AND WHITEBOX TESTING
Test Case Test case Describes an input Description and an expected output Description. Test case ID Section 1: Before execution Section 2: After execution.
UNIT-4 BLACKBOX AND WHITEBOX TESTING
Presentation transcript:

Softrare Reliability Methods Prof. Doron A. Peled Bar Ilan University, Israel And Univeristy of warwick, UK Version 2008

Some related books: Mainly: Also:

Goal: software reliability Use software engineering methodologies to develop the code. Use formal methods during code development 2

What are formal methods? Techniques for analyzing systems, based on some mathematics. This does not mean that the user must be a mathematician. Some of the work is done in an informal way, due to complexity.

Examples for FM Deductive verification: Using some logical formalism, prove formally that the software satisfies its specification. Model checking: Use some software to automatically check that the software satisfies its specification. Testing: Check executions of the software according to some coverage scheme.

Typical situation: Boss: Mark, I want that the new internet marketing software will be flawless. OK? Mark: Hmmm. Well, ..., Aham, Oh! Ah??? Where do I start? Bob: I have just the solution for you. It would solve everything.

Some concerns Which technique? Which tool? Which experts? What limitations? What methodology? At which points? How expensive? How many people? Needed expertise. Kind of training. Size limitations. Exhaustiveness. Reliability. Expressiveness. Support.

Badmouth Formal methods can only be used by mathematicians. The verification process is itself prone to errors, so why bother? Using formal methods will slow down the project.

Some answers... Formal methods can only be used by mathematicians. Wrong. They are based on some math but the user should not care. The verification process is itself prone to errors, so why bother? We opt to reduce the errors, not eliminate them. Using formal methods will slow down the project. Maybe it will speed it up, once errors are found earlier.

Some exaggerations Automatic verification can always find errors. Deductive verification can show that the software is completely safe. Testing is the only industrial practical method.

Our approach Learn several methods (deductive verification, model checking, testing process algebra). Learn advantages and limitations, in order to choose the right methods and tools. Learn how to combine existing methods.

Emphasis The process: Selecting the tools, Modeling, Verification, Locating errors. Use of tools: Hands on. PVS, SPIN Visual notation: Statecharts, MSCs, UML.

Some emphasis The process of selecting and using formal methods. The appropriate notation. In particular, visual notation. Hands-on experience with tools.

The unbearable easiness of grading During class, choose some small project in groups, e.g., Explore some examples using tools. Implementing a simple algorithm. Dealing with new material. or covering advanced subject. - Office presentation (1 hour). - Written description (2-3 pages + computer output or 6-10 pages). - Class presentation (0.5-1.5 hours per group).

Example topics Project: Advanced topics: Verify some example using some tools. Communication protocols. Mutual exclusion. Advanced topics: Abstractions. Reductions. Partitions. Static analysis. Verifying pushdown automata. Verifying security protocols.

Where do we start? Boss: Mark, can you verify this for me? Mark: OK, first I have to ...

Things to do Check the kind of software to analyze. Choose methods and tools. Express system properties. Model the software. Apply methods. Obtain verification results. Analyze results. Identify errors. Suggest correction.

Different types of software Sequential. Concurrent. Distributed. Reactive. Protocols. Abstract algorithms. Finite state.

Specification: Informal, textual, visual The value of x will be between 1 and 5, until some point where it will become 7. In any case it will never be negative. (1<=x<=5 U (x=7/\ [] x>=0)) X=7 1<=x<=5 X>=0

Verification methods Finite state machines. Apply model checking. Apply deductive verification (theorem proving). Program too big, too complicated. Apply testing techniques. Apply a combination of the above!

Modeling Use the program text. Translate to a programming language embedded in some proof system. Translate to some notation (transition system). Translate to finite automata. Use visual notation. Special case: black box system.

Modeling Software Systems for Analysis (Book: Chapter 4)

Modelling and specification for verification and validation How to specify what the software is supposed to do? Can we use the UML model or parts of it? How to model it in a way that allows us to check it?

Systems of interest Sequential systems. Concurrent systems (multi-threaded). Distributive systems. Reactive systems. Embedded systems (software + hardware).

Sequential systems. Perform some computational task. Have some initial condition, e.g., 0in A[i] integer. Have some final assertion, e.g., 0in-1 A[i]A[i+1]. (What is the problem with this spec?) Are supposed to terminate.

Concurrent Systems Involve several computation agents. Termination may indicate an abnormal event (interrupt, strike). May exploit diverse computational power. May involve remote components. May interact with users (Reactive). May involve hardware components (Embedded).

Problems in modeling systems Representing concurrency: - Allow one transition at a time, or - Allow coinciding transitions. Granularity of transitions. Assignments and checks? Application of methods? Global (all the system) or local (one thread at a time) states.

Modeling. The states based model. V={v0,v1,v2, …} - a set of variables, over some domain. p(v0, v1, …, vn) - a parametrized assertion, e.g., v0=v1+v2 /\ v3>v4. A state is an assignment of values to the program variables. For example: s=<v0=1,v2=3,v3=7,…,v18=2> For predicate (first order assertion) p: p(s) is p under the assignment s. Example: p is x>y /\ y>z. s=<x=4, y=3, z=5>. Then we have 4>3 /\ 3>5, which is false. 2

State space The state space of a program is the set of all possible states for it. For example, if V={a, b, c} and the variables are over the naturals, then the state space includes: <a=0,b=0,c=0>,<a=1,b=0,c=0>, <a=1,b=1,c=0>,<a=932,b=5609,c=6658>… 6

Atomic Transitions Each atomic transition represents a small piece of code such that no smaller piece of code is observable. Is a:=a+1 atomic? In some systems, e.g., when a is a register and the transition is executed using an inc command. 7

Non atomicity Execute the following when a=0 in two concurrent processes: P1:a=a+1 P2:a=a+1 Result: a=2. Is this always the case? Consider the actual translation: P1:load R1,a inc R1 store R1,a P2:load R2,a inc R2 store R2,a a may be also 1. 8

Scenario P1:load R1,a a=0 R1=0 P2:load R2,a R2=0 inc R1 R1=1 inc R2 store R2,a P1:load R1,a inc R1 store R1,a a=0 R1=0 R2=0 R1=1 R2=1 a=1

Representing transitions Each transition has two parts: The enabling condition: a predicate. The transformation: a multiple assignment. For example: a>b  (c,d ):=(d,c ) This transition can be executed in states where a>b. The result of executing it is switching the value of c with d. 9

Initial condition A predicate I. The program can start from states s such that I (s) holds. For example: I (s)=a >b /\ b >c. 10

A transition system A (finite) set of variables V over some domain. A set of states S. A (finite) set of transitions T, each transition e t has an enabling condition e, and a transformation t. An initial condition I. 11

Example V={a, b, c, d, e}. S: all assignments of natural numbers for variables in V. T={c >0(c,e):=(c -1,e +1), d >0(d,e):=(d -1,e +1)} I: c =a /\ d =b /\ e =0 What does this transition system do? 12

The interleaving model An execution is a maximal finite or infinite sequence of states s0, s1, s2, … That is: finite if nothing is enabled from the last state. The first state s0 satisfies the initial condition, I.e., I (s0). Moving from one state si to its successor si+1 is by executing a transition et: e (si), i.e., si satisfies e. si+1 is obtained by applying t to si. 13

Example: T={c>0(c,e):=(c -1,e +1), d>0(d,e):=(d-1,e+1)} I: c=a /\ d=b /\ e=0 s0=<a=2, b=1, c=2, d=1, e=0> s1=<a=2, b=1, c=1, d=1, e=1> s2=<a=2, b=1, c=1, d=0, e=2> s3=<a=2, b=1 ,c=0, d=0, e=3> 14

The transitions T0:PC0=L0PC0:=NC0 T1:PC0=NC0/\Turn=0 PC0:=CR0 T2:PC0=CR0 (PC0,Turn):=(L0,1) T3:PC1=L1PC1=NC1 T4:PC1=NC1/\Turn=1 PC1:=CR1 T5:PC1=CR1 (PC1,Turn):=(L1,0) L0:While True do NC0:wait(Turn=0); CR0:Turn=1 endwhile || L1:While True do NC1:wait(Turn=1); CR1:Turn=0 endwhile Initially: PC0=L0/\PC1=L1 Is this the only reasonable way to model this program? 17

The state graph:Successor relation between reachable states. Turn=0 L0,L1 Turn=1 L0,L1 T3 T0 T3 T0 T5 T2 Turn=0 L0,NC1 Turn=0 NC0,L1 Turn=1 L0,NC1 Turn=1 NC0,L1 T4 T1 T3 T0 T0 T3 Turn=0 NC0,NC1 Turn=0 CR0,L1 Turn=1 L0,CR1 Turn=1 NC0,NC1 T1 T3 T0 T4 Turn=0 CR0,NC1 Turn=1 NC0,CR1 T2 T5 18

Some important points Reachable states: obtained from an initial state through a sequence of enabled transitions. Executions: the set of maximal paths (finite or terminating in a node where nothing is enabled). Nondeterministic choice: when more than a single transition is enabled at a given state. We have a nondeterministic choice when at least one node at the state graph has more than one successor.

Always ¬(PC0=CR0/\PC1=CR1) (Mutual exclusion) Turn=0 L0,L1 Turn=1 L0,L1 Turn=0 L0,NC1 Turn=0 NC0,L1 Turn=1 L0,NC1 Turn=1 NC0,L1 Turn=0 NC0,NC1 Turn=0 CR0,L1 Turn=1 L0,CR1 Turn=1 NC0,NC1 Turn=0 CR0,NC1 Turn=1 NC0,CR1 19

Always if Turn=0 then at some point Turn=1 L0,L1 Turn=1 L0,L1 Turn=0 L0,NC1 Turn=0 NC0,L1 Turn=1 L0,NC1 Turn=1 NC0,L1 Turn=0 NC0,NC1 Turn=0 CR0,L1 Turn=1 L0,CR1 Turn=1 NC0,NC1 Turn=0 CR0,NC1 Turn=1 NC0,CR1 20

Always if Turn=0 then at some point Turn=1 L0,L1 Turn=1 L0,L1 Turn=0 L0,NC1 Turn=0 NC0,L1 Turn=1 L0,NC1 Turn=1 NC0,L1 Turn=0 NC0,NC1 Turn=0 CR0,L1 Turn=1 L0,CR1 Turn=1 NC0,NC1 Turn=0 CR0,NC1 Turn=1 NC0,CR1 20

Interleaving semantics: Execute one transition at a time. Turn=0 L0,L1 Turn=0 L0,NC1 Turn=1 L0,NC1 Turn=0 NC0,NC1 Turn=1 L0,CR1 Turn=0 CR0,NC1 Need to check the property for every possible interleaving! 20

Interleaving semantics Turn=0 L0,L1 Turn=0 L0,NC1 Turn=0 NC0,NC1 Turn=0 CR0,NC1 Turn=1 L0,NC1 Turn=1 L0,CR1 Turn=0 L0,L1 Turn=0 L0,NC1 20

Busy waiting Initially: PC0=L0/\PC1=L1 T0:PC0=L0PC0:=NC0 T1:PC0=NC0/\Turn=0PC0:=CR0 T1’:PC0=NC0/\Turn=1PC0:=NC0 T2:PC0=CR0(PC0,Turn):=(L0,1) T3:PC1==L1PC1=NC1 T4:PC1=NC1/\Turn=1PC1:=CR1 T4’:PC1=NC1/\Turn=0PC1:=NC1 T5:PC1=CR1(PC1,Turn):=(L1,0) L0:While True do NC0:wait(Turn=0); CR0:Turn=1 endwhile || L1:While True do NC1:wait(Turn=1); CR1:Turn=0 endwhile Initially: PC0=L0/\PC1=L1 17

Always when Turn=0 then at some point Turn=1 L0,L1 Turn=1 L0,L1 T1’ T4’ Turn=0 L0,NC1 Turn=0 NC0,L1 Turn=1 L0,NC1 Turn=1 NC0,L1 Turn=0 NC0,NC1 Turn=0 CR0,L1 Turn=1 L0,CR1 Turn=1 NC0,NC1 Turn=0 CR0,NC1 Turn=1 NC0,CR1 Now it does not hold! (Red subgraph generates a counterexample execution.) 20

Combinatorial explosion V1:=1 Vn:=1 V1:=3 Vn:=3 … V1:=2 Vn:=2 How many states?

Global states … … … 3n states v1=1,v2=1…vn=1 v1=2,v2=1…vn=1

Program verification: flowchart programs (Book: chapter 7)

History Verification of flowchart programs: Floyd, 1967 Hoare’s logic: Hoare, 1969 Linear Temporal Logic: Pnueli, Krueger, 1977 Model Checking: Clarke & Emerson, 1981

Program Verification Predicate (first order) logic. Partial correctness, Total correctness Flowchart programs Invariants, annotated programs Well founded ordering (for termination) Hoare’s logic

Predicate (first order logic) Variables, functions, predicates Terms Formulas (assertions)

Signature Variables: v1, x, y18 Each variable represents a value of some given domain (int, real, string, …). Function symbols: f(_,_), g2(_), h(_,_,_). Each function has an arity (number of paramenters), a domain for each parameter, and a range. f:int*int->int (e.g., addition), g:real->real (e.g., square root) A constant is a predicate with arity 0. Relation symbols: R(_,_), Q(_). Each relation has an arity, and a domain for each parameter. R : real*real (e.g., greater than). Q : int (e.g., is a prime).

Terms Terms are objects that have values. Each variable is a term. Applying a function with arity n to n terms results in a new term. Examples: v1, 5.0, f(v1,5.0), g2(f(v1,5.0)) More familiar notation: sqr(v1+5.0)

Formulas Applying predicates to terms results in a formula. R(v1,5.0), Q(x) More familiar notation: v1>5.0 One can combine formulas with the boolean operators (and, or, not, implies). R(v1,5.0)->Q(x) x>1 -> x*x>x One can apply existentail and universal quantification to formulas. x Q(X) x1 R(x1,5.0) x y R(x,y)

A model, A proofs A model gives a meaning (semantics) to a first order formula: A relation for each relation symbol. A function for each function symbol. A value for each variable. An important concept in first order logic is that of a proof. We assume the ability to prove that a formula holds for a given model. Example proof rule (MP) : 

Flowchart programs Input variables: X=x1,x2,…,xl Program variables: Y=y1,y2,…,ym Output variables: Z=z1,z2,…,zn start Z=h(X,Y) Y=f(X) halt

Assignments and tests T F Y=g(X,Y) t(X,Y)

Initial condition start Initial condition: the values for the input variables for which the program must work. x1>=0 /\ x2>0 (y1,y2)=(0,x1) y2>=x2 F T (y1,y2)=(y1+1,y2-x2) (z1,z2)=(y1,y2) halt

The input-output claim start The relation between the values of the input and the output variables at termination. x1=z1*x2+z2 /\ 0<=z2<x2 (y1,y2)=(0,x1) y2>=x2 T F (y1,y2)=(y1+1,y2-x2) (z1,z2)=(y1,y2) halt

Partial correctness, Termination, Total correctness Partial correctness: if the initial condition holds and the program terminates then the input-output claim holds. Termination: if the initial condition holds, the program terminates. Total correctness: if the initial condition holds, the program terminates and the input-output claim holds.

Subtle point: The program is partially correct with respect to start halt (y1,y2)=(0,x1) y2>=x2 (y1,y2)=(y1+1,y2-x2) (z1,z2)=(y1,y2) T F The program is partially correct with respect to x1>=0/\x2>=0 and totally correct with respect to x1>=0/\x2>0

Annotating a scheme start A Assign an assertion for each pair of nodes. The assertion expresses the relation between the variable when the program counter is located between these nodes. (y1,y2)=(0,x1) B T F y2>=x2 C D (y1,y2)=(y1+1,y2-x2) (z1,z2)=(y1,y2) E halt

Invariants Invariants are assertions that hold at each state throughout the execution of the program. One can attach an assertion to a particular location in the code: e.g., at(B) (B). This is also an invariant; in other locations, at(B) does not hold hence the implication holds. If there is an assertion attached to each location, (A), (B),  (C), (D), (E), then their disjunction is also an invariant: (A)\/(B)\/ (C)\/(D)\/(E) (since location is always at one of these locations).

Annotating a scheme with invariants start A A): x1>=0 /\ x2>=0 B): x1=y1*x2+y2 /\ y2>=0 C): x1=y1*x2+y2 /\ y2>=0 /\ y2>=x2 D):x1=y1*x2+y2 /\ y2>=0 /\ y2<x2 E):x1=z1*x2+z2 /\ 0<=z2<x2 Notice: (A) is the initial condition,  Eis the input-output condition. (y1,y2)=(0,x1) B T F y2>=x2 C D (y1,y2)=(y1+1,y2-x2) (z1,z2)=(y1,y2) E A) Is the precondition of (y1,y2)=(0,x1) and B) is its postcondition halt

Preliminary: Relativizing assertions (B) : x1= y1 * x2 + y2 /\ y2 >= 0 Relativize B) w.r.t. the assignment, obtaining B) [Y\g(X,Y)] (I.e., (B) expressed w.r.t. variables at A.)  (B)A =x1=0 * x2 + x1 /\ x1>=0 Think about two sets of variables, before={x, y, z, …} after={x’,y’,z’…}. Rewrite (B) using after, and the assignment as a relation between the set of variables. Then eliminate after by substitution. Here: x1’=y1’ * x2’ + y2’ /\ y2’>=0 /\ x1’=x1 /\ x2’=x2 /\ y1’=0 /\ y2’=x1 now eliminate x1’, x2’, y1’, y2’. A (y1,y2)=(0,x1) Y=g(X,Y) B A (y1,y2)=(0,x1) B

Preliminary: Relativizing assertions (B)A (y1,y2)=(0,x1) Y=g(X,Y) A): B Y=g(X,Y) A (B) (y1,y2)=(0,x1) B

Verification conditions: assignment A)  B)A where B)A = B)[Y\g(X,Y)] A): x1>=0 /\ x2>=0 B): x1=y1*x2+y2 /\ y2>=0 B)A= x1=0*x2+x1 /\ x1>=0 A (y1,y2)=(0,x1) Y=g(X,Y) B A (y1,y2)=(0,x1) B

Second assignment C): x1=y1*x2+y2 /\ y2>=0 /\ y2>=x2 B): x1=y1*x2+y2 /\ y2>=0 B)C: x1=(y1+1)*x2+y2-x2 /\ y2-x2>=0 C (y1,y2)=(y1+1,y2-x2) B

Third assignment D):x1=y1*x2+y2 /\ y2>=0 /\ y2<x2 E):x1=z1*x2+z2 /\ 0<=z2<x2 E)D: x1=y1*x2+y2 /\ 0<=y2<x2 D (z1,z2)=(y1,y2) E

Verification conditions: tests B T F t(X,Y) B) /\ t(X,Y)  C) B) /\¬t(X,Y)  D) B): x1=y1*x2+y2 /\y2>=0 C): x1=y1*x2+y2 /\ y2>=0 /\ y2>=x2 D):x1=y1*x2+y2 /\ y2>=0 /\ y2<x2 C D B T F y2>=x2 C D

Verification conditions: tests B T F t(X,Y) C C) D t(X,Y) ¬t(X,Y) B) B T F y2>=x2 C D

Partial correctness proof: An induction on length of execution Initially, states satisfy the initial conditions. Then, passing from one set of states to another, we preserve the invariants at the appropriate location. We prove: starting with a state satisfying the initial conditions, if are at a point in the execution, the invariant there holds. Not a proof of termination! A) no B) yes start A C) (y1,y2)=(0,x1) B T F no B) y2>=x2 C D yes (y1,y2)=(y1+1,y2-x2) (z1,z2)=(y1,y2) E D) halt

Exercise: prove partial correctness start (y1,y2)=(0,1) Initial condition: x>=0 Input-output claim: z=x! F T y1=x (y1,y2)=(y1+1,(y1+1)*y2) z=y2 halt

What have we achieved? For each statement S that appears between points X and Y we showed that if the control is in X when (X) holds (the precondition of S) and S is executed, then (Y) (the postcondition of S) holds. Initially, we know that (A) holds. The above two conditions can be combined into an induction on the number of statements that were executed: If after n steps we are at point X, then (X) holds. 15

Another example start (y1,y2,y3)=(0,0,1) A halt y2>x (y1,y3)=(y1+1,y3+2) z=y1 B C D F true false E y2=y2+y3 (A) : x>=0 (F) : z^2<=x<(z+1)^2 z is the biggest number that is not greater than sqrt x. 16

Some insight start (y1,y2,y3)=(0,0,1) A halt y2>x (y1,y3)=(y1+1,y3+2) z=y1 B C D F true false E y2=y2+y3 1+3+5+…+(2n+1)=(n+1)^2 y2 accumulates the above sum, until it is bigger than x. y3 ranges over odd numbers 1,3,5,… y1 is n-1. 17

Invariants start (y1,y2,y3)=(0,0,1) A halt y2>x (y1,y3)=(y1+1,y3+2) z=y1 B C D F true false E y2=y2+y3 It is sufficient to have one invariant for every loop (cycle in the program’s graph). We will have (C)=y1^2<=x /\ y2=(y1+1)^2 /\ y3=2*y1+1 18

Obtaining (B) start (y1,y2,y3)=(0,0,1) A halt y2>x (y1,y3)=(y1+1,y3+2) z=y1 B C D F true false E y2=y2+y3 By backwards substitution in (C). (C)=y1^2<=x /\ y2=(y1+1)^2 /\ y3=2*y1+1 (B)=y1^2<=x /\ y2+y3=(y1+1)^2 /\ 19

Check assignment condition start (y1,y2,y3)=(0,0,1) A halt y2>x (y1,y3)=(y1+1,y3+2) z=y1 B C D F true false E y2=y2+y3 (A)=x>=0 (B)=y1^2<=x /\ y2+y3=(y1+1)^2 /\ y3=2*y1+1 (B) relativized is 0^2<=x /\ 0+1=(0+1)^2 /\ 1=2*0+1 Simplified: x>=0 20

Obtaining (D) start (y1,y2,y3)=(0,0,1) A halt y2>x (y1,y3)=(y1+1,y3+2) z=y1 B C D F true false E y2=y2+y3 By backwards substitution in (B). (B)=y1^2<=x /\ y2+y3=(y1+1)^2 /\ y3=2*y1+1 (D)=(y1+1)^2<=x /\ y2+y3+2=(y1+2)^2 /\ y3+2=2*(y1+1)+1 21

Checking start (y1,y2,y3)=(0,0,1) A halt y2>x (y1,y3)=(y1+1,y3+2) z=y1 B C D F true false E y2=y2+y3 (C)=y1^2<=x /\ y2=(y1+1)^2 /\ y3=2*y1+1 (C)/\y2<=x)  (D) (D)=(y1+1)^2<=x /\ y2+y3+2=(y1+2)^2 /\ y3+2=2*(y1+1)+1 22

y1^2<=x /\ y1^2<=x /\ y2=(y1+1)^2 /\ y2=(y1+1)^2 /\ y3=2*y1+1 /\y2<=x  (y1+1)^2<=x /\ y2+y3+2=(y1+2)^2 /\ y3+2=2*(y1+1)+1 y1^2<=x /\ y2=(y1+1)^2 /\ y3=2*y1+1 /\y2<=x  (y1+1)^2<=x /\ y2+y3+2=(y1+2)^2 /\ y3+2=2*(y1+1)+1 y1^2<=x /\ y2=(y1+1)^2 /\ y3=2*y1+1 /\y2<=x  (y1+1)^2<=x /\ y2+y3+2=(y1+2)^2 /\ y3+2=2*(y1+1)+1 23

Not finished! start A (y1,y2,y3)=(0,0,1) Still needs to: Calculate (E) by substituting backwards from (F). Check that (C)/\y2>x(E) B y2=y2+y3 C false true y2>x D E (y1,y3)=(y1+1,y3+2) z=y1 F halt 24

Exercise: prove partial correctness. Initially: x1>0/\x2>0 Exercise: prove partial correctness. Initially: x1>0/\x2>0. At termination: z1=gcd(x1,x2). start (y1,y2)=(x1,x2) y1=y2 F T y1>y2 F T z1=y1 y2=y2-y1 y1=y1-y2 halt

Annotation of program with invariants gcd(y1,y2)=gcd(x1,x2)/\y1>0/\y2>0/\y1>y2 start gcd(y1,y2)=gcd(x1,x2)/\y1>0/\y2>0/\y1<y2 A x1>0 /\ x2>0 (y1,y2)=(x1,x2) gcd(y1,y2)=gcd(x1,x2)/\y1>0/\y2>0 B C gcd(y1,y2)=gcd(x1,x2)/\y1>0/\y2>0/\y1y2 y1=y2 T F D G y1=gcd(x1,x2) F T y1>y2 z1=y1 E F y2=y2-y1 y1=y1-y2 H z1=gcd(x1,x2) halt

Part 1 y1=y2 T F F T start y1>y2 z1=y1 y2=y2-y1 y1=y1-y2 (A)= x1>0 /\ x2>0 start (B)=gcd(y1,y2)=gcd(x1,x2) /\y1>0/\y2>0 A (B)’rel= gcd(x1,x2)=gcd(x1,x2)/\x1>0/\x2>0 (y1,y2)=(x1,x2) (A) (B)’rel B C y1=y2 T F D G F T y1>y2 z1=y1 E F y2=y2-y1 y1=y1-y2 H halt

Part 2a y1=y2 T F F T start y1>y2 z1=y1 y2=y2-y1 y1=y1-y2 (B)= gcd(y1,y2)=gcd(x1,x2)/\y1>0/\y2>0 start (C)=gcd(y1,y2)=gcd(x1,x2)/\y1>0/\y2>0/\y1y2 A (y1,y2)=(x1,x2) (B)/\¬(y1=y2) (C) B C y1=y2 T F D G F T y1>y2 z1=y1 E F y2=y2-y1 y1=y1-y2 H halt

Part 2b y1=y2 T F F T start y1>y2 z1=y1 y2=y2-y1 y1=y1-y2 (B)= gcd(y1,y2)=gcd(x1,x2)/\y1>0/\y2>0 start (G)= y1=gcd(x1,x2) A (B)/\(y1=y2) (G) (y1,y2)=(x1,x2) B C y1=y2 T F D G F T y1>y2 z1=y1 E F y2=y2-y1 y1=y1-y2 H halt

Part 3 y1=y2 T F F T start y1>y2 z1=y1 y2=y2-y1 y1=y1-y2 (F)=(gcd(y1,y2)=gcd(x1,x2) /\y1>0/\y2>0/\y1>y2 start (D)/\(y1>y2) (F) (E)=gcd(y1,y2)=gcd(x1,x2) /\y1>0/\y2>0/\y1<y2 A (D)/\¬(y1>y2) (E) (y1,y2)=(x1,x2) B (D)= gcd(y1,y2)=gcd(x1,x2)/\y1>0/\y2>0/\y1y2 C y1=y2 T F G D F T y1>y2 z1=y1 E F y2=y2-y1 y1=y1-y2 H halt

Part 4 y1=y2 T F F T start y1>y2 z1=y1 y2=y2-y1 y1=y1-y2 (B)’rel1= gcd(y1,y2-y1)=gcd(x1,x2) /\y1>0/\y2-y1>0 (F)= gcd(y1,y2)=gcd(x1,x2) /\y1>0/\y2>0/\y1>y2 (B)’rel2= gcd(y1-y2,y2)=gcd(x1,x2) /\y1-y2>0/\y2>0 start (E)= gcd(y1,y2)=gcd(x1,x2)/\y1>0/\y2>0/\y1<y2 A x1>0 /\ x2>0 (y1,y2)=(x1,x2) (B)= gcd(y1,y2)=gcd(x1,x2) /\y1>0/\y2>0 B C y1=y2 T F D G F T y1>y2 z1=y1 E F y2=y2-y1 y1=y1-y2 H halt (E) (B)’rel1 (F) (B)’rel2

Part 5 y1=y2 T F F T start y1>y2 z1=y1 y2=y2-y1 y1=y1-y2 (H)’rel= y1=gcd(x1,x2) A (y1,y2)=(x1,x2) B (G)= y1=gcd(x1,x2) C y1=y2 T F D G F T y1>y2 z1=y1 E F (H)= z1=gcd(x1,x2) y2=y2-y1 y1=y1-y2 H halt (G) (H)’rel2

Proving termination

Well-founded sets Partially ordered set (W,<): If a<b and b<c then a<c (transitivity). If a<b then not b<a (asymmetry). Not a<a (irreflexivity). Well-founded set (W,<): Partially ordered. No infinite decreasing chain a1>a2>a3>…

Examples for well founded sets Natural numbers with the bigger than relation. Finite sets with the set inclusion relation. Strings with the substring relation. Tuples with alphabetic order: (a1,b1)>(a2,b2) iff a1>a2 or [a1=a2 and b1>b2]. (a1,b1,c1)>(a2,b2,c2) iff a1>a2 or [a1=a2 and b1>b2] or [a1=a2 and b1=b2 and c1>c2].

Why does the program terminate start y2 starts as x1. Each time the loop is executed, y2 is decremented. y2 is natural number The loop cannot be entered again when y2<x2. A (y1,y2)=(0,x1) B y2>=x2 C true false D (y1,y2)=(y1+1,y2-x2) (z1,z2)=(y1,y2) E halt

Proving termination Choose a well-founded set (W,<). Attach a function u(N) to each point N. Annotate the flowchart with invariants, and prove their consistency conditions. Prove that j(N)  (u(N) in W).

How not to stay in a loop? Show that u(M)>=u(N)’rel. At least once in each loop, show that u(M)>u(N). M S N M T N

How not to stay in a loop? M For stmt: j(M)(u(M)>=u(N)’rel) Relativize since we need to compare values not syntactic expressions. For test (true side): (j(M)/\test)(u(M)>=u(N)) For test (false side): (j(M)/\¬test)(u(M)>=u(L)) stmt N M true false test N L

What did we achieve? There are finitely many control points. The value of the function u cannot increase. If we return to the same control point, the value of u must decrease (its a loop!). The value of u can decrease only a finite number of times.

Why does the program terminate start u(A)=x1 u(B)=y2 u(C)=y2 u(D)=y2 u(E)=z2 W: naturals > : greater than A (y1,y2)=(0,x1) B y2>=x2 C true false D (y1,y2)=(y1+1,y2-x2) (z1,z2)=(y1,y2) E halt

Recall partial correctness annotation start A (y1,y2)=(0,x1) j(A): x1>=0 /\ x2>=0 j(B): x1=y1*x2+y2 /\ y2>=0 j(C): x1=y1*x2+y2 /\ y2>=0 /\ y2>=x2 j(D):x1=y1*x2+y2 /\ y2>=0 /\ y2<x2 j(E):x1=z1*x2+z2 /\ 0<=z2<x2 B true false y2>=x2 C D (y1,y2)=(y1+1,y2-x2) (z1,z2)=(y1,y2) E halt

Strengthen for termination start A j(A): x1>=0 /\ x2>0 j(B): x1=y1*x2+y2 /\ y2>=0/\x2>0 j(C): x1=y1*x2+y2 /\ y2>=0/\y2>=x2/\x2>0 j(D):x1=y1*x2+y2 /\ y2>=0 /\ y2<x2/\x2>0 j(E):x1=z1*x2+z2 /\ 0<=z2<x2 (y1,y2)=(0,x1) B true false y2>=x2 C D (y1,y2)=(y1+1,y2-x2) (z1,z2)=(y1,y2) E halt

Strengthen for termination j(A): x1>=0 /\ x2>0 u(A)>=0 j(B): x1=y1*x2+y2 /\ y2>=0/\x2>0u(B)>=0 j(C): x1=y1*x2+y2 /\y2>=0 /\y2>=x2/\x2>0u(c)>=0 j(D):x1=y1*x2+y2 /\ y2>=0 /\ y2<x2/\x2>0u(D)>=0 j(E):x1=z1*x2+z2 /\ 0<=z2<x2u(E)>=0 This proves that u(M) is natural for each point M. u(A)=x1 u(B)=y2 u(C)=y2 u(D)=y2 u(E)=z2

We shall show: start halt (y1,y2)=(y1+1,y2-x2) (z1,z2)=(y1,y2) B D E false y2>=x2 C true u(A)=x1 u(B)=y2 u(C)=y2 u(D)=y2 u(E)=z2 j(A)u(A)>=u(B)’rel j(B)u(B)>=u(C) j(C)u(C)>u(B)’rel j(B)u(B)>=u(D) j(D)u(D)>=u(E)’rel

Proving decrement start halt (y1,y2)=(y1+1,y2-x2) (z1,z2)=(y1,y2) B D E false y2>=x2 C true j(C): x1=y1*x2+y2 /\ y2>=0 /\ y2>=x2/\x2>0 u(C)=y2 u(B)=y2 u(B)’rel=y2-x2 j(C)  y2>y2-x2 (notice that j(C)  x2>0)

Integer square prog. start (y1,y2,y3)=(0,0,1) A halt y2>x (y1,y3)=(y1+1,y3+2) z=y1 B C D F true false E y2=y2+y3 j(C)=y1^2<=x /\ y2=(y1+1)^2 /\ y3=2*y1+1 j(B)=y1^2<=x /\ y2+y3=(y1+1)^2 /\y3=2*y1+1

start (y1,y2,y3)=(0,0,1) A halt y2>x (y1,y3)=(y1+1,y3+2) z=y1 B C D F true false E y2=y2+y3 u(A)=x+1 u(B)=x-y2+1 u(C)=max(0,x-y2+1) u(D)=x-y2+1 u(E)=u(F)=0 u(A)>=u(B)’rel u(B)>u(C)’rel u(C)>=u(D) u(C)>=u(E) u(D)>=u(B)’rel Need some invariants, i.e., y2<=x/\y3>0 at points B and D, and y3>0 at point C.

Algorithmic Testing

Why testing? Reduce design/programming errors. Can be done during development, before production/marketing. Practical, simple to do. Check the real thing, not a model. Scales up reasonably. Being state of the practice for decades.

Part 1: Testing of black box finite state machine Wants to know: In what state we started? In what state we are? Transition relation Conformance Satisfaction of a temporal property Know: Transition relation Size or bound on size

Finite automata (Mealy machines) S - finite set of states. (size n) S - set of inputs. (size d) O - set of outputs, for each transition. (s0  S - initial state). δ  S  S  S - transition relation (deterministic but sometimes not defined for each input per each state).   S  S  O - output on edges. Notation: δ(s,a1a2..an)= δ(… (δ(δ(s,a1),a2) … ),an) (s,a1a2..an)= (s,a1)(δ(s,a1),a2)…(δ(… δ(δ(s,a1),a2) … ),an)

Finite automata (Mealy machines) S - finite set of states. (size n) S– set of inputs. (size d) O – set of outputs, for each transition. (s0  S - initial state). δ  S  S  S - transition relation.   S  S O – output on edge. S={s1, s2, s3 }, S={a, b }, O={0,1 }. δ(s1,a)=s3 (also s1=a=>s3), δ(s1,b)=s2,(also s1=b=>s2)… (s1,a)=0 , (s1,b)=1,… δ(s1,ab)=s1, (s1,ab)=01 s1 s3 s2 a/0 b/1 b/0

Why deterministic machines? Otherwise no amount of experiments would guarantee anything. If dependent on some parameter (e.g., temperature), we can determinize, by taking parameter as additional input. We still can model concurrent system. It means just that the transitions are deterministic. All kinds of equivalences are unified into language equivalence. Also: connected machine (otherwise we may never get to the completely separate parts).

Determinism b/1 a/1 When the black box is nondeterministic, we might never test some choices.

Preliminaries: separating sequences b/1 b/0 A set of sequences X such that if we execute them from different states, at least one of them will give a different output sequence. s≠t µX (s, µ )≠(s, µ ) Start with one block containing all states {s1, s2, s3}.

A: separate to blocks of states with different output. The states are separated into {s1, s3}, {s2} using the string b. But s1 and s3 have the same outputs to same inputs.

Repeat B : Separate blocks based on input that cause moving to different blocks. If string X separated blocks B1, B2, and letter a splits part of block C to move to B1 and part to B2, then aX separates C into C1, C2, accordingly. s1 s2 a/0 b/1 b/0 a/0 s3 a/0 Separate first block using b to three singleton blocks obtaining separation sequence bb. Separating sequences: b, bb. Max rounds: n-1, sequences: n-1, length: n-1.

Want to know the state of the machine (at end): Homing sequence. Know: transition relation. Don’t know: which state we start. Want to know: which state we end up. After firing homing sequence, we know in what state we are by observing the outputs. Find a sequence µ such that δ(s, µ )≠δ(t, µ )  (s, µ )≠(t, µ ) So, given an input µ that is executed from state s, we look at a table of outputs and according to a table, know in which state r we are.

Homing sequence Algorithm: Put all the states in one block (initially we do not know what is the current state). Then repeatedly separate blocks, as long as they are not singletons, as follows: Take a non singleton block, append a distinguishing sequence µ that separates at least two states in that block. Update each block to the states after executing µ. (Blocks may not be disjoint, its not a partition!) Note: blocks do not have to be disjoint! Max length of sequence: (n-1)2 (Lower bound: n(n-1)/2.)

Example (homing sequence) b/1 b/0 {s1, s2, s3} b 1 1 {s1, s2} {s3} b 1 1 {s1} {s2} {s3} On input b and output 1, we still don’t know if we were in s1 or s3, i.e., if we are currently in s2 or s1. So separate these cases with another b.

Synchronizing sequence One sequence takes the machine to the same final state, regardless of the initial state or the outputs. That is: find a sequence µ such that for each states s, t, δ(s, µ )=δ(t, µ ) Not every machine has a synchronizing sequence. Can be checked whether exists and if so, can be found in polynomial time. a/1 b/1 a/0 b/0

Algorithm for synchronizing sequeneces Construct a graph with ordered pairs of nodes (s,t) such that (s,t )=a=>(s’,t’ ) when s=a=>s’, t=a=>t’. (Ignore self loops, e.g., on (s2,s2).) a/0 s1 b/1 b/0 s1,s1 a/0 b s2 s3 b/1 s2,s2 s1,s2 b a/1 a a b b b a s3,s3 s2,s3 s1,s3 b

Algorithm continues (2) There is an input sequence from both s≠t to some r iff there is a path in this graph from (s,t ) to (r,r ). There is a synchronization sequence iff some twins node (r,r ) is reachable from every pair of distinct nodes. In this case it is (s2,s2 ). s1,s1 b s2,s2 s1,s2 b a a b b b a s3,s3 s2,s3 s1,s3 b If original automaton is not strongly connected, there is no synchronizing sequence. Otherwise, all twins are reachable from each other in product graph. Thus, in this case, if there is not twins node (r,r) reachable from all pairs, there is some pair (Si,Sj) from which no twins node is reachable, thus no sequence will synchronize Si and Sj.

Algorithm continues (3) Notation:δ(S,x)= {t |sS,δ(s,x)=t } i=1; S1=S Take some nodes s≠tSi, and find a shortest path labeled xi to some twins (r,r ). i=i+1; Si:=δ(Si-1,x ). If |Si |>1,goto 2., else goto 4. Concatenate x1x2…xk. s1,s1 b s2,s2 s1,s2 b a a b b b a s3,s3 s2,s3 s1,s3 b Number of sequences ≤ n-1. Each of length ≤ n(n-1)/2. Overall O(n(n-1)2/2).

Example: s1,s1 s2,s2 s1,s2 s3,s3 s2,s3 s1,s3 (s2,s3)=a=>(s2,s2) (s1,s2)=ba=>(s2,s2) x2:=ba δ({s1,s2},ba)={s2} So x1x2=aba is a synchronization sequence, bringing every state into state s2. s1,s1 b s2,s2 s1,s2 b a a b b b a s3,s3 s2,s3 s1,s3 b

State identification: Want to know in which state the system has started (was reset to). Can be a preset distinguishing sequence (fixed), or a tree (adaptive). May not exist (PSPACE complete to check if preset exists, polynomial for adaptive). Best known algorithm: exponential length for preset, polynomial for adaptive [LY].

Sometimes cannot identify initial state Start with a: in case of being in s1 or s3 we’ll move to s1 and cannot distinguish. Start with b: In case of being in s1 or s2 we’ll move to s2 and cannot distinguish. b/1 a/1 s1 s3 s2 b/0 The kind of experiment we do affects what we can distinguish. Much like the Heisenberg principle in Physics.

So… We’ll assume resets from now on!

 Conformance testing Unknown deterministic finite state system B. Known: n states and alphabet . An abstract model C of B. C satisfies all the properties we want from B. C has m states. Check conformance of B and C. Another version: only a bound n on the number of states l is known. 

Check conformance with a given state machine b/0 b/1 ? = Black box machine has no more states than specification machine (errors are mistakes in outputs, mistargeted edges). Specification machine is reduced, connected, deterministic. Machine resets reliably to a single initial state (or use homing sequence).

Conformance testing [Ch,V] b/1  b/1 b/1 a/1 a/1 b/1  a/1 b/1 Cannot distinguish if reduced or not.

Conformance testing (cont.)  b b a a a  a b b a a b Need: bound on number of states of B.

Preparation: Construct a spanning tree, and separating sequences b/1 a/1 s1 s3 s2 b/0 s1 s2 s3 b/1 a/1 Given an initial state, we can reach any state of the automaton.

How the algorithm works? Reset According to the spanning tree, force a sequence of inputs to go to each state. From each state, perform the distinguishing sequences. From each state, make a single transition, check output, and use distinguishing sequences to check that in correct target state. Reset s1 a/1 b/1 s3 s2 Distinguishing sequences

Comments Checking the different distinguishing sequences (m-1 of them) means each time resetting and returning to the state under experiment. A reset can be performed to a distinguished state through a homing sequence. Then we can perform a sequence that brings us to the distinguished initial state. Since there are no more than m states, and according to the experiment, no less than m states, there are m states exactly. Isomorphism between the transition relation is found, hence from minimality the two automata recognize the same languages.

Combination lock automaton Assume accepting states. Accepts only words with a specific suffix (cdab in the example). c d a b s1 s2 s3 s4 s5 Any other input

When only a bound on size of black box is known… Black box can “pretend” to behave as a specification automaton for a long time, then upon using the right combination, make a mistake. a/1 Pretends to be s1 a/1 b/1 b/1 s1 s2 b/1 a/1 a/1 s3 Pretends to be s3 b/0

Conformance testing algorithm [VC] Reset Reset The worst that can happen is a combination lock automaton that behaves differently only in the last state. The length of it is the difference between the size n of the black box and the specification m. Reach every state on the spanning tree and check every word of length n-m+1 or less. Check that after the combination we are at the state we are supposed to be, using the distinguishing sequences. No need to check transitions: already included in above check. Complexity: m2 n dn-m+1 Probabilistic complexity: Polynomial. s1 a/1 b/1 s3 s2 Words of length n-m+1 Distinguishing sequences

Part 2: Software testing (Book: chapter 9) Testing is not about showing that there are no errors in the program. Testing cannot show that the program performs its intended goal correctly. So, what is software testing? Testing is the process of executing the program in order to find errors. A successful test is one that finds an error.

Some software testing stages Unit testing – the lowest level, testing some procedures. Integration testing – different pieces of code. System testing – testing a system as a whole. Acceptance testing – performed by the customer. Regression testing – performed after updates. Stress testing – checking the code under extreme conditions. Mutation testing – testing the quality of the test suite.

Some drawbacks of testing There are never sufficiently many test cases. Testing does not find all the errors. Testing is not trivial and requires considerable time and effort. Testing is still a largely informal task.

Black-Box (data-driven, input-output) testing The testing is not based on the structure of the program (which is unknown). In order to ensure correctness, every possible input needs to be tested - this is impossible! The goal: to maximize the number of errors found.

testing White Box Is based on the internal structure of the program. There are several alternative criterions for checking “enough” paths in the program. Even checking all paths (highly impractical) does not guarantee finding all errors (e.g., missing paths!)

Some testing principles A programmer should not test his/her own program. One should test not only that the program does what it is supposed to do, but that it does not do what it is not supposed to. The goal of testing is to find errors, not to show that the program is errorless. No amount of testing can guarantee error-free program. Parts of programs where a lot of errors have already been found are a good place to look for more errors. The goal is not to humiliate the programmer!

Inspections and Walkthroughs Manual testing methods. Done by a team of people. Performed at a meeting (brainstorming). Takes 90-120 minutes. Can find 30%-70% of errors.

Code Inspection Team of 3-5 people. One is the moderator. He distributes materials and records the errors. The programmer explains the program line by line. Questions are raised. The program is analyzed w.r.t. a checklist of errors.

Checklist for inspections Control flow Each loop terminates? DO/END statements match? Input/output OPEN statements correct? Format specification correct? End-of-file case handled? Data declaration All variables declared? Default values understood? Arrays and strings initialized? Variables with similar names? Correct initialization?

Walkthrough Team of 3-5 people. Moderator, as before. Secretary, records errors. Tester, play the role of a computer on some test suits on paper and board.

Selection of test cases (for white-box testing) The main problem is to select a good coverage criterion. Some options are: Cover all paths of the program. Execute every statement at least once. Each decision has a true or false value at least once. Each condition is taking each truth value at least once. Check all possible combinations of conditions in each decision.

Cover all the paths of the program Infeasible. Consider the flow diagram on the left. It corresponds to a loop. The loop body has 5 paths. If the loops executes 20 times there are 5^20 different paths! May also be unbounded!

How to cover the executions? IF (A>1) & (B=0) THEN X=X/A; END; IF (A=2) | (X>1) THEN X=X+1; END; Choose values for A,B,X. Value of X may change, depending on A,B. What do we want to cover? Paths? Statements? Conditions?

Statement coverage Execute every statement at least once By choosing A=2,B=0,X=3 each statement will be chosen. The case where the tests fail is not checked! IF (A>1) & (B=0) THEN X=X/A; END; IF (A=2) | (X>1) THEN X=X+1; END; Now x=1.5

Decision coverage (if, while checks) Each decision has a true and false outcome at least once. Can be achieved using A=3,B=0,X=3 A=2,B=1,X=1 Problem: Does not test individual conditions. E.g., when X>1 is erroneous in second decision. IF (A>1) & (B=0) THEN X=X/A; END; IF (A=2) | (X>1) THEN X=X+1; END;

Decision coverage A=3,B=0,X=3 IF (A>1) & (B=0) THEN X=X/A; END; IF (A=2) | (X>1) THEN X=X+1; END; Now x=1

Decision coverage IF (A>1) & (B=0) THEN X=X/A; END; A=2,B=1,X=1  The case where A1 and the case where x>1 where not checked! IF (A>1) & (B=0) THEN X=X/A; END; IF (A=2)|(X>1) THEN X=X+1; END;

Condition coverage Each condition has a true and false value at least once. For example: A=1,B=0,X=3 A=2,B=1,X=0 lets each condition be true and false once. Problem:covers only the path where the first test fails and the second succeeds. IF (A>1) & (B=0) THEN X=X/A; END; IF (A=2) | (X>1) THEN X=X+1; END;

Condition coverage A=1,B=0,X=3  IF (A>1) & (B=0) THEN X=X/A; END; IF (A=2) | (X>1) THEN X=X+1; END; A=1,B=0,X=3 

Condition coverage A=2,B=1,X=0  IF (A>1) & (B=0) THEN X=X/A; END; IF (A=2) | (X>1) THEN X=X+1; END; A=2,B=1,X=0  Did not check the first THEN part at all!!! Can use condition+decision coverage.

Multiple Condition Coverage Test all combinations of all conditions in each test. IF (A>1) & (B=0) THEN X=X/A; END; IF (A=2) | (X>1) THEN X=X+1; END; A>1,B=0 A>1,B≠0 A1,B=0 A1,B≠0 A=2,X>1 A=2,X1 A≠2,X>1 A≠2,X1

A smaller number of cases: A=2,B=0,X=4 A=2,B=1,X=1 A=1,B=0,X=2 A=1,B=1,X=1 Note the X=4 in the first case: it is due to the fact that X changes before being used! IF (A>1) & (B=0) THEN X=X/A; END; IF (A=2) | (X>1) THEN X=X+1; END; Further optimization: not all combinations. For C /\ D, check (C, D), (C, D), (C, D). For C \/ D, check (C, D), (C, D), (C, D).

Preliminary:Relativizing assertions (Book: Chapter 7) (B) : x1= y1 * x2 + y2 /\ y2 >= 0 Relativize B) w.r.t. the assignment becomes B) [Y\g(X,Y)] (I.e., ( B) expressed w.r.t. variables at A.)  (B)A =x1=0 * x2 + x1 /\ x1>=0 Think about two sets of variables, before={x, y, z, …} after={x’,y’,z’…}. Rewrite (B) using after, and the assignment as a relation between the set of variables. Then eliminate after. Here: x1’=y1’ * x2’ + y2’ /\ y2’>=0 /\ x1=x1’ /\ x2=x2’ /\ y1’=0 /\ y2’=x1 now eliminate x1’, x2’, y1’, y2’. A (y1,y2)=(0,x1) Y=g(X,Y) B A (y1,y2)=(0,x1) B

Verification conditions: tests B T F t(X,Y) C)  B)= t(X,Y) /\C) D)  B)=t(X,Y) /\D) B)= D) /\ y2x2 C D B T F y2>=x2 C D

How to find values for coverage? Put true at end of path. Propagate path backwards. On assignment, relativize expression. On “yes” edge of decision, add decision as conjunction. On “no” edge, add negation of decision as conjunction. Can be more specific when calculating condition with multiple condition coverage. A>1 & B=0 no yes X=X/A A=2 | X>1 true no yes X=X+1 true

How to find values for coverage? (A≠2 /\ X/A>1) /\ (A>1 & B=0) A>1 & B=0 A≠2 /\ X/A>1 no yes Need to find a satisfying assignment: A=3, X=6, B=0 Can also calculate path condition forwards. X=X/A A≠2 /\ X>1 A=2 | X>1 true no yes X=X+1 true

How to cover a flow chart? Cover all nodes, e.g., using search strategies: DFS, BFS. Cover all paths (usually impractical). Cover each adjacent sequence of N nodes. Probabilistic testing. Using random number generator simulation. Based on typical use. Chinese Postman: minimize edge traversal Find minimal number of times time to travel each edge using linear programming or dataflow algorithms.

Test cases based on data-flow analysis Partition the program into pieces of code with a single entry/exit point. For each piece find which variables are set/used/tested. Various covering criteria: from each set to each use/test From each set to some use/test. X:=3 t>y x>y z:=z+x

Test case design for black box testing Equivalence partition Boundary value analysis Cause-effect graphs

Equivalence partition Goals: Find a small number of test cases. Cover as much possibilities as you can. Try to group together inputs for which the program is likely to behave the same. Specification condition Valid equivalence class Invalid equivalence

Example: A legal variable Begins with A-Z Contains [A-Z0-9] Has 1-6 characters. Specification condition Valid equivalence class Invalid equivalence class Starting char Starts A-Z Starts other 1 2 Chars [A-Z0-9] Has others 3 4 1-6 chars 0 chars, >6 chars Length 5 6 7

Equivalence partition (cont.) Add a new test case until all valid equivalence classes have been covered. A test case can cover multiple such classes. Add a new test case until all invalid equivalence class have been covered. Each test case can cover only one such class. Valid equivalence class Invalid equivalence class Specification condition

Example AB36P (1,3,5) 1XY12 (2) A17#%X (4) (6) VERYLONG (7) Specification condition Valid equivalence class Invalid equivalence class Starting char Starts A-Z Starts other 1 2 Chars [A-Z0-9] Has others 3 4 1-6 chars 0 chars, >6 chars Length 5 6 7

Boundary value analysis In every element class, select values that are closed to the boundary. If input is within range -1.0 to +1.0, select values -1.001, -1.0, -0.999, 0.999, 1.0, 1.001. If needs to read N data elements, check with N-1, N, N+1. Also, check with N=0.

For Unit Testing Driver Driver Write “drivers”, which replaces procedures calling the code. Write “stubs”, which replaces procedures called by the code. Tested unit Stub Stub Stub

Bucket sort: With bugs!! package bucket; import java.util.*; import java.math.*; public class BugBucketSort { public static void main(String[] args) Random r = new Random(100); r.nextInt(100); LinkedList<Integer> ls = new LinkedList<Integer>(); for (int j = 0; j < 10; j++) ls.push(r.nextInt(100)); System.out.println(ls); bucketSort(ls); } public static void bucketSort(LinkedList<Integer> ls) LinkedList<HashMap<Integer,Integer>> la = new LinkedList<HashMap<Integer,Integer>>(); for (int i = 0 ; i<11; i++)//BUG should be 10 instead of 11 la.add(new HashMap<Integer,Integer>()); System.out.println("\nValues in the array: "+la.size()); for (int j = 0; j < ls.size(); j++) la.get((int)ls.get(j)/10).put((int)ls.get(j)%10, ls.get(j)); System.out.println("\nThe ordered array is:"); System.out.print("["); for (int i = 0; i < la.size(); i++) for (int k = 1; k < 10; k++)//BUG needs to start with k=0 if(la.get(i).containsKey(k)) System.out.print(la.get(i).get(k)+" "); System.out.println("]"); Bucket sort: With bugs!!

Bucket sort: Without bugs!! package bucket; import java.util.*; import java.math.*; public class BucketSort { public static void main(String[] args) Random r = new Random(100); r.nextInt(100); LinkedList<Integer> ls = new LinkedList<Integer>(); for (int j = 0; j < 10; j++) ls.push(r.nextInt(100)); System.out.println(ls); // System.out.println((int) 17 / 5); bucketSort(ls); } public static void bucketSort(LinkedList<Integer> ls) LinkedList<HashMap<Integer,Integer>> la = new LinkedList<HashMap<Integer,Integer>>(); for (int i = 0 ; i<10; i++) la.add(new HashMap<Integer,Integer>()); System.out.println("\nValues in the array: "+la.size()); for (int j = 0; j < ls.size(); j++) la.get((int)ls.get(j)/10).put((int)ls.get(j)%10, ls.get(j)); System.out.println("\nThe ordered array is:"); System.out.print("["); for (int i = 0; i < la.size(); i++) for (int k = 0; k < 10; k++) if(la.get(i).containsKey(k)) System.out.print(la.get(i).get(k)+" "); System.out.println("]"); }} Bucket sort: Without bugs!!

class MergeSortAlgorithm { public static int [] mergeSort(int array[]) { int loop; int rightIndex = 0; int [] leftArr = new int[array.length / 2]; int [] rightArr = new int[(array.length - array.length) / 2]; if (array.length <= 1) return array; for (loop = 0 ; loop < leftArr.length ; ++loop) leftArr[loop] = array[loop]; for (; rightIndex < rightArr.length ; ++loop) rightArr[rightIndex++] = array[loop]; mergeSort(leftArr); rightArr = mergeSort(rightArr); array = merge(leftArr,rightArr); return array; } public static int [] merge(int [] leftArr , int [] rightArr) { int [] newArray = new int[leftArr.length + rightArr.length]; int leftIndex = 0; int rightIndex = 0; int newArrayIndex = 0; while (leftIndex < leftArr.length && rightIndex < rightArr.length) { if (leftArr[leftIndex] < rightArr[rightIndex]) newArray[newArrayIndex] = leftArr[leftIndex++]; newArray[newArrayIndex] = rightArr[rightIndex++];} while (rightIndex < rightArr.length) newArray[newArrayIndex++] = rightArr[rightIndex++]; while (leftIndex < leftArr.length) newArray[newArrayIndex++] = leftArr[leftIndex++]; return newArray;} public static void print(int [] arr , String caller) { int loop; for (loop = 0 ; loop < arr.length ; ++loop) System.out.println("caller " + caller + " : " + arr[loop]);} public static void main(String [] args) { int []originalArray = {1,5,4,3,7}; print(originalArray,"before"); originalArray = mergeSort(originalArray); print(originalArray,"after"); }}

class MergeSortAlgorithm { public static int [] mergeSort(int array[]) { int loop; int rightIndex = 0; int [] leftArr = new int[array.length / 2]; int [] rightArr = new int[(array.length - array.length) / 2]; // BUG if (array.length <= 1) return array; for (loop = 0 ; loop < leftArr.length ; ++loop) leftArr[loop] = array[loop]; for (; rightIndex < rightArr.length ; ++loop) rightArr[rightIndex++] = array[loop]; mergeSort(leftArr); // BUG rightArr = mergeSort(rightArr); array = merge(leftArr,rightArr); return array; } public static int [] merge(int [] leftArr , int [] rightArr) { int [] newArray = new int[leftArr.length + rightArr.length]; int leftIndex = 0; int rightIndex = 0; int newArrayIndex = 0; while (leftIndex < leftArr.length && rightIndex < rightArr.length) { if (leftArr[leftIndex] < rightArr[rightIndex]) newArray[newArrayIndex] = leftArr[leftIndex++]; newArray[newArrayIndex] = rightArr[rightIndex++]; // TWO BUGS} while (rightIndex < rightArr.length) newArray[newArrayIndex++] = rightArr[rightIndex++]; while (leftIndex < leftArr.length) newArray[newArrayIndex++] = leftArr[leftIndex++]; return newArray;} public static void print(int [] arr , String caller) { int loop; for (loop = 0 ; loop < arr.length ; ++loop) System.out.println("caller " + caller + " : " + arr[loop]);} public static void main(String [] args) { int []originalArray = {1,5,4,3,7}; print(originalArray,"before"); originalArray = mergeSort(originalArray); print(originalArray,"after"); }}