Erlang/QuickCheck Thomas Arts, IT University John Hughes, Chalmers University Gothenburg.

Slides:



Advertisements
Similar presentations
Software Testing with QuickCheck Lecture 1 Properties and Generators.
Advertisements

CS 267: Automated Verification Lecture 8: Automata Theoretic Model Checking Instructor: Tevfik Bultan.
SAT Based Abstraction/Refinement in Model-Checking Based on work by E. Clarke, A. Gupta, J. Kukula, O. Strichman (CAV’02)
CSE 1301 Lecture 5B Conditionals & Boolean Expressions Figures from Lewis, “C# Software Solutions”, Addison Wesley Briana B. Morrison.
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.
Slide 1 of 10 Job Event Basics A Job Event is the name for the collection of components that comprise a scheduled job. On the iSeries a the available Job.
Page 1 Mutual Exclusion* Distributed Systems *referred to slides by Prof. Paul Krzyzanowski at Rutgers University and Prof. Mary Ellen Weisskopf at University.
Decision Tree Rong Jin. Determine Milage Per Gallon.
CS 582 / CMPE 481 Distributed Systems
Ordering and Consistent Cuts Presented By Biswanath Panda.
Distributed Systems Fall 2009 Logical time, global states, and debugging.
Test Data Generators Lecture 5. Why Distinguish Instructions? Functions always give the same result for the same arguments Instructions can behave differently.
Tirgul 7. Find an efficient implementation of a dynamic collection of elements with unique keys Supported Operations: Insert, Search and Delete. The keys.
1 Advanced Material The following slides contain advanced material and are optional.
Dependent Types for Reasoning About Distributed Systems Paul Sivilotti - Ohio State Hongwei Xi - Cincinnati.
12-Jul-15COMP28112 Lecture 141 COMP28112 – Lecture 14 The Quest for Performance (lab exercise 3)
.NET Mobile Application Development Remote Procedure Call.
CS510AP Quick Check Monads. QuickCheck Quick check is a Haskell library for doing random testing. You can read more about quickcheck at –
Computer Science Lecture 12, page 1 CS677: Distributed OS Last Class Vector timestamps Global state –Distributed Snapshot Election algorithms.
Time, Clocks, and the Ordering of Events in a Distributed System Leslie Lamport (1978) Presented by: Yoav Kantor.
Verification technique on SA applications using Incremental Model Checking 컴퓨터학과 신영주.
JS Arrays, Functions, Events Week 5 INFM 603. Agenda Arrays Functions Event-Driven Programming.
CSE 486/586 CSE 486/586 Distributed Systems PA Best Practices Steve Ko Computer Sciences and Engineering University at Buffalo.
Monads Technion – Institute of Technology Software Design (236700) Author: Gal Lalouche - Technion 2015 © 1.
1 Validation & Verification Chapter VALIDATION & VERIFICATION Very Difficult Very Important Conceptually distinct, but performed simultaneously.
Tanenbaum & Van Steen, Distributed Systems: Principles and Paradigms, 2e, (c) 2007 Prentice-Hall, Inc. All rights reserved Chapter 6 Synchronization.
Designing For Testability. Incorporate design features that facilitate testing Include features to: –Support test automation at all levels (unit, integration,
(or what I learned from Neil about software testing) John Hughes Chalmers University/Quviq AB.
Introduction to Testing 1. Testing  testing code is a vital part of the development process  the goal of testing is to find defects in your code  Program.
Testing in Erlang. Different testing tools EUnit (standard lightweight xUnit solution for Erlang) Common Test (OTP based distributed testing tool) Qucik.
Deriving Combinator Implementations Lecture 4, Designing and Using Combinators John Hughes.
1cs Intersection of Concurrent Accesses A fundamental property of Web sites: Concurrent accesses by multiple users Concurrent accesses intersect.
Testing and Debugging Version 1.0. All kinds of things can go wrong when you are developing a program. The compiler discovers syntax errors in your code.
Supported by ELTE IKKK, Ericsson Hungary, in cooperation with University of Kent Erlang refactoring with relational database Anikó Víg and Tamás Nagy Supervisors:
On Reducing the Global State Graph for Verification of Distributed Computations Vijay K. Garg, Arindam Chakraborty Parallel and Distributed Systems Laboratory.
QuickCheck: A Lightweight Tool for Random Testing of Haskell Programs By Koen Claessen, Juhn Hughes ME: Mike Izbicki.
Threaded Programming in Python Adapted from Fundamentals of Python: From First Programs Through Data Structures CPE 401 / 601 Computer Network Systems.
1 FUNCTIONS - I Chapter 5 Functions help us write more complex programs.
Chapter 10 Verification and Validation of Simulation Models
Testing Abstract Data Structures with QuickCheck Thomas Arts Quviq AB / Chalmers.
2015 Concurrency: logical properties 1 ©Magee/Kramer 2 nd Edition Chapter 14 Logical Properties Satisfied? Not satisfied?
May University of Glasgow Generalising Feature Interactions in Muffy Calder, Alice Miller Dept. of Computing Science University of Glasgow.
Scientific Debugging. Errors in Software Errors are unexpected behaviors or outputs in programs As long as software is developed by humans, it will contain.
Lecture 5 1 CSP tools for verification of Sec Prot Overview of the lecture The Casper interface Refinement checking and FDR Model checking Theorem proving.
D u k e S y s t e m s Asynchronous Replicated State Machines (Causal Multicast and All That) Jeff Chase Duke University.
Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.
1/32 This Lecture Substitution model An example using the substitution model Designing recursive procedures Designing iterative procedures Proving that.
PROGRAMMING PRE- AND POSTCONDITIONS, INVARIANTS AND METHOD CONTRACTS B MODULE 2: SOFTWARE SYSTEMS 13 NOVEMBER 2013.
1 Temporal logic. 2 Prop. logic: model and reason about static situations. Example: Are there truth values that can be assigned to x,y simultaneously.
Searching CSE 103 Lecture 20 Wednesday, October 16, 2002 prepared by Doug Hogan.
CMPSC 16 Problem Solving with Computers I Spring 2014 Instructor: Tevfik Bultan Lecture 4: Introduction to C: Control Flow.
1 Phase Testing. Janice Regan, For each group of units Overview of Implementation phase Create Class Skeletons Define Implementation Plan (+ determine.
 Simulation enables the study of complex system.  Simulation is a good approach when analytic study of a system is not possible or very complex.  Informational,
Today’s Agenda  Quiz 4  Temporal Logic Formal Methods in Software Engineering1.
Mutual Exclusion Algorithms. Topics r Defining mutual exclusion r A centralized approach r A distributed approach r An approach assuming an organization.
Defensive Programming. Good programming practices that protect you from your own programming mistakes, as well as those of others – Assertions – Parameter.
CS3771 Today: Distributed Coordination  Previous class: Distributed File Systems Issues: Naming Strategies: Absolute Names, Mount Points (logical connection.
IST 210: PHP Basics IST 210: Organization of Data IST2101.
Functional Processing of Collections (Advanced) 6.0.
Topic 4: Distributed Objects Dr. Ayman Srour Faculty of Applied Engineering and Urban Planning University of Palestine.
Test Data Generators. Why Distinguish Instructions? Functions always give the same result for the same arguments Instructions can behave differently on.
Jeremy Nimmer, page 1 Automatic Generation of Program Specifications Jeremy Nimmer MIT Lab for Computer Science Joint work with.
Threaded Programming in Python
Test Data Generators.
Koen Lindström Claessen
Chapter 10 Verification and Validation of Simulation Models
Higher-Order Procedures
Arrays in Java What, why and how Copyright Curt Hill.
P1 : Distributed Bitcoin Miner
Dynamic Binary Translators and Instrumenters
Presentation transcript:

Erlang/QuickCheck Thomas Arts, IT University John Hughes, Chalmers University Gothenburg

A little set theory… Recall that X [ Y = Y [ X?

A little set theory… Recall that X [ Y = Y [ X? Erlang has a sets library. Does this hold?

A little set theory… Recall that X [ Y = Y [ X? Erlang has a sets library. Does this hold? Property: X [ Y = Y [ X

A little set theory… Recall that X [ Y = Y [ X? Erlang has a sets library. Does this hold? Property: 8 X. 8 Y. X [ Y = Y [ X

A little set theory… Recall that X [ Y = Y [ X? Erlang has a sets library. Does this hold? Property: 8 X:Set. 8 Y:Set. X [ Y = Y [ X

A little set theory… Recall that X [ Y = Y [ X? Erlang has a sets library. Does this hold? Property: 8 X:Set. 8 Y:Set. X [ Y = Y [ X In Erlang/QuickCheck: ?FORALL(X,set(), ?FORALL(Y,set(), sets:union(X,Y) == sets:union(Y,X)))

A little set theory… Recall that X [ Y = Y [ X? Erlang has a sets library. Does this hold? Property: 8 X:Set. 8 Y:Set. X [ Y = Y [ X In Erlang/QuickCheck: prop_union_commutes() -> ?FORALL(X,set(), ?FORALL(Y,set(), sets:union(X,Y) == sets:union(Y,X))).

Verifying the property 12> qc:quickcheck( setsspec:prop_union_commutes()).

Verifying the property 12> qc:quickcheck( setsspec:prop_union_commutes()) Falsifiable, after 45 successful tests: ok ”function call” These sets are a counterexample.

Fixing the Property Sets are not represented uniquely by the sets library union builds two different representations of the same set equal(S1,S2) -> lists:sort(sets:to_list(S1)) == lists:sort(sets:to_list(S2)). prop_union_commutes() -> ?FORALL(X,set(), ?FORALL(Y,set(), equal(sets:union(X,Y),sets:union(Y,X)))).

Checking the fixed property 15> qc:quickcheck( setsspec:prop_union_commutes()) OK, passed 100 tests ok

What is QuickCheck? A language for stating properties of programs (implemented as a library of functions and macros). A tool for testing properties in randomly generated cases.

Properties Boolean expressions + ?FORALL + ?IMPLIES. prop_positive_squares() -> ?FORALL(X,int(),X*X>=0). prop_larger_squares() -> ?FORALL(X,int(), ?IMPLIES(X>1, X*X>X)). A precondition

What are int() and set()? Types?

What are int() and set()? Types? NO!!! Test data generators. –Define a set of values for test data… –…plus a probability distribution over that set. Test data generators are defined by the programmer.

Defining generators We often want to define one generator in terms of another, e.g. squares of ints. But we cannot do this by writing N = int(), N*N Returns a test data generator, not an integer. Result should be a generator, not an integer.

Defining generators We often want to define one generator in terms of another, e.g. squares of ints. But we cannot do this by writing N = int(), N*N We define a generator language to handle generators as an ADT. ?LET(N,int(),return(N*N)) Bind a name to the value generated. Convert a value to a constant generator.

How can we generate sets? An ADT can only be generated using the ADT operations. Choose randomly between all ways of creating a set.

A generator for sets set() -> frequency([ {6,?LET(L,list(int()), {6,?LET(S,set(),?LET(E,int(), {1,?LET(P,function(bool()),?LET(S,set(), …]). weights ?FORALL performs a call when it sees

A problem with random generation How do we know we tested a reasonable range of cases, when we don’t see them?

A problem with random generation How do we know we tested a reasonable range of cases, when we don’t see them? Simple approach: collect statistics on test cases, so we see a summary of the test data. (A simple way to measure test coverage, which is a tangled topic in its own right).

An instrumented property prop_union_commutes() -> ?FORALL(X,set(), ?FORALL(Y,set(), collect(sets:size(sets:union(X,Y)), equal(sets:union(X,Y), sets:union(Y,X))))). Collect statistics on the sizes of the resulting sets.

Output: the distribution of set sizes 27> qc:quickcheck( setsspec:prop_union_commutes()) OK, passed 100 tests 7% 7 6% 12 5% 13 4% 8 3% 17 3% 16 3% 14 3% 11 3% 5 2% 24 2% 9 2% 0 1% 20 1% 10 1% 22 1% 21 1% 18 ok 16% 3 11% 4 9% 2 8% 6 8% 1

Testing concurrent programs A simple resource allocator: start() – starts the server claim() – claims the resource free() – releases the resource These functions are called for their effect, not their result. How can we write QuickCheck properties for them? in the client

Traces Concurrent programs generate traces of events. We can write properties of traces – they are lists!

Testing the resource allocator client() -> claim(), free(), client(). clients(N) – spawns N clients. system(N) -> start(), clients(N). ?FORALL(N,nat(), ?FORALL(T,?TRACE(3,system(N)), … property of T …))

The trace recorder Running system Trace recorder Events What should the recorded events be? How should we capture them?

Random traces: a problem What does this print? test_spawn() -> spawn(io,format,["a"]), spawn(io,format,["b"]).

Random traces: a problem What does this print? test_spawn() -> spawn(io,format,["a"]), spawn(io,format,["b"]). ab – every time!

Random traces: a problem What does this print? test_spawn() -> spawn(io,format,["a"]), spawn(io,format,["b"]). ab – every time! But ba should also be a possible trace – the Erlang scheduler is too predictable!

Solution: simulate a random scheduler Insert calls of event(Event) in code under test. –Sends Event to trace recorder –Waits for a reply, sent in random order Allows the trace recorder to simulate a random scheduler. Answers question: which events should be recorded?

Simple example revisited do(E) -> event(spawned), event(E). ?FORALL(T, ?TRACE(3,begin spawn(?MODULE,do,[a]), spawn(?MODULE,do,[b]) end), collect(rename_pids(nowaits(T)),true)))

Simple example revisited OK, passed 100 tests 18% [{exit,{pid,1},normal}, {event,{pid,2},spawned}, {event,{pid,3},spawned}, {event,{pid,3},b}, {exit,{pid,3},normal}, {event,{pid,2},a}, {exit,{pid,2},normal}, timeout] 18% [{exit,{pid,1},normal}, {event,{pid,2},spawned}, {event,{pid,3},spawned}, {event,{pid,2},a}, {exit,{pid,2},normal}, {event,{pid,3},b}, {exit,{pid,3},normal}, timeout]

Simple example revisited OK, passed 100 tests 18% [{exit,{pid,1},normal}, {event,{pid,2},spawned}, {event,{pid,3},spawned}, {event,{pid,3},b}, {exit,{pid,3},normal}, {event,{pid,2},a}, {exit,{pid,2},normal}, timeout] 18% [{exit,{pid,1},normal}, {event,{pid,2},spawned}, {event,{pid,3},spawned}, {event,{pid,2},a}, {exit,{pid,2},normal}, {event,{pid,3},b}, {exit,{pid,3},normal}, timeout] Pids are renamed for collecting statistics Trace recorder times out if no events happen for a while

A surprise! Pid=spawn(fun()-> event(spawned), event(ok) end), event(spawn), exit(Pid,kill), event(kill) 1% [{event,{pid,1},spawn}, {event,{pid,2},spawned}, {event,{pid,2},ok}, {event,{pid,1},kill}, {exit,{pid,2},killed}, {exit,{pid,2},noproc}, {exit,{pid,1},normal}, timeout] No doubt there is a good reason…

Trace properties The resource allocator guarantees exclusion Instrumented code: client() -> event(request), claim(), event(claimed), event(freeing), free(), client().

Trace properties The resource allocator guarantees exclusion ?FORALL(N,nat(), ?FORALL(T,?TRACE(3,system(N)), satisfies(T, always(timplies(?MATCHES({event,_,claimed}), next(until(?MATCHES({event,_,freeing}), tnot(?MATCHES({event,_,claimed})))))))))

Trace properties The resource allocator guarantees exclusion ?FORALL(N,nat(), ?FORALL(T,?TRACE(3,system(N)), satisfies(T, always(timplies(?MATCHES({event,_,claimed}), next(until(?MATCHES({event,_,freeing}), tnot(?MATCHES({event,_,claimed}))))))))) The trace T satisfies…

Trace properties The resource allocator guarantees exclusion ?FORALL(N,nat(), ?FORALL(T,?TRACE(3,system(N)), satisfies(T, always(timplies(?MATCHES({event,_,claimed}), next(until(?MATCHES({event,_,freeing}), tnot(?MATCHES({event,_,claimed}))))))))) …it’s always true that…

Trace properties The resource allocator guarantees exclusion ?FORALL(N,nat(), ?FORALL(T,?TRACE(3,system(N)), satisfies(T, always(timplies(?MATCHES({event,_,claimed}), next(until(?MATCHES({event,_,freeing}), tnot(?MATCHES({event,_,claimed}))))))))) …if the current event is claimed…

Trace properties The resource allocator guarantees exclusion ?FORALL(N,nat(), ?FORALL(T,?TRACE(3,system(N)), satisfies(T, always(timplies(?MATCHES({event,_,claimed}), next(until(?MATCHES({event,_,freeing}), tnot(?MATCHES({event,_,claimed}))))))))) …then after this event…

Trace properties The resource allocator guarantees exclusion ?FORALL(N,nat(), ?FORALL(T,?TRACE(3,system(N)), satisfies(T, always(timplies(?MATCHES({event,_,claimed}), next(until(?MATCHES({event,_,freeing}), tnot(?MATCHES({event,_,claimed}))))))))) …until a freeing event happens…

Trace properties The resource allocator guarantees exclusion ?FORALL(N,nat(), ?FORALL(T,?TRACE(3,system(N)), satisfies(T, always(timplies(?MATCHES({event,_,claimed}), next(until(?MATCHES({event,_,freeing}), tnot(?MATCHES({event,_,claimed}))))))))) …there will be no further claimed event.

Trace property language Based on linear temporal logic –Logical operations: tand, tor, tnot, ?TIMPLIES. –Temporal operations: always, eventually, next, until. –Event matching operations: ?MATCHES, ?AFTER, ?NOW.

A failing property The resource is always eventually granted. prop_eventually_granted(N) -> ?FORALL(T,?TRACE(3,system(2)), satisfies(T, always(?AFTER({event,Pid,request}, eventually(N, tor(?NOW({event,Pid2,claimed}, Pid==Pid2), ?MATCHES(more))))))).

A failing property The resource is always eventually granted. prop_eventually_granted(N) -> ?FORALL(T,?TRACE(3,system(2)), satisfies(T, always(?AFTER({event,Pid,request}, eventually(N, tor(?NOW({event,Pid2,claimed}, Pid==Pid2), ?MATCHES(more))))))). After at most N steps End of the recorded trace Failing trace of 23 steps found after 80 successful tests.

In progress Testing generic leader election behaviour Properties –Eventually a leader is elected, even in the presence of failures –There is always at most one elected leader

Experience There are as many bugs in properties as in programs! –QuickCheck checks for consistency between the two, helps improve understanding Random testing is effective at finding errors. Changes our perspective on testing –Not ”what cases should I test?” –But ”what properties ought to hold?”

QuickCheck is Fun! Try it out!

References Erlang/QuickCheck is based on a Haskell original by Claessen and Hughes. –QuickCheck: A Lightweight Tool for Random Testing of Haskell Programs, ICFP –Testing Monadic Code with QuickCheck, Haskell Workshop –Specification Based Testing with QuickCheck, in Fun of Programming, Palgrave, –Testing and Tracing Functional Programs, in Advanced Functional Programming Summer School, Springer-Verlag LNCS, 2002.

Questions?

Answers (The remaining slides may be used to answer specific questions).

Random functions are pure functions! 1> F = qc:gen(qc:function(qc:nat()),10). #Fun 2> F(1). 8 3> F(2). 9 4> F(3). 3 5> F(1). 8 Invokes a generator Random results But consistent ones

Controlling sizes Test cases are regenerated w.r.t. a size parameter, which increases during testing. prop_union_commutes() -> ?SIZED(N,resize(5*N,…)) Set sizes now range up to 135 elements. Bind N to the size parameter Reset the size parameter