Setac: A Phased Deterministic Testing Framework for Scala Actors

Slides:



Advertisements
Similar presentations
MPI Message Passing Interface
Advertisements

OPERATING SYSTEMS PROCESSES
Impossibility of Distributed Consensus with One Faulty Process
The Building Blocks: Send and Receive Operations
PROTOCOL VERIFICATION & PROTOCOL VALIDATION. Protocol Verification Communication Protocols should be checked for correctness, robustness and performance,
Go Language * Go - Routines * Channels. New Concepts Do not communicate by sharing memory; instead, share memory by communicating. creating shared memory.
CHESS: A Systematic Testing Tool for Concurrent Software CSCI6900 George.
Vertically Integrated Analysis and Transformation for Embedded Software John Regehr University of Utah.
I/O Hardware n Incredible variety of I/O devices n Common concepts: – Port – connection point to the computer – Bus (daisy chain or shared direct access)
Concurrency, Threads, and Events Robbert van Renesse.
Parrot: A Practical Runtime for Deterministic, Stable, and Reliable threads HEMING CUI, YI-HONG LIN, HAO LI, XINAN XU, JUNFENG YANG, JIRI SIMSA, BEN BLUM,
Distributed Programming in Scala with APGAS Philippe Suter, Olivier Tardieu, Josh Milthorpe IBM Research Picture by Simon Greig.
Scala Actors -Terrance Dsilva.  Thankfully, Scala offers a reasonable, flexible approach to concurrency  Actors aren’t a concept unique to Scala.
Windows.Net Programming Series Preview. Course Schedule CourseDate Microsoft.Net Fundamentals 01/13/2014 Microsoft Windows/Web Fundamentals 01/20/2014.
CSE 486/586 CSE 486/586 Distributed Systems PA Best Practices Steve Ko Computer Sciences and Engineering University at Buffalo.
Austin Java Users Group developerWorks article – µActor Library BARRY FEIGENBAUM, PH. D. 02/26/13.
Chapter 3: Processes. 3.2 Silberschatz, Galvin and Gagne ©2005 Operating System Concepts Chapter 3: Processes Process Concept Process Scheduling Operations.
1 Concurrency Architecture Types Tasks Synchronization –Semaphores –Monitors –Message Passing Concurrency in Ada Java Threads.
Title Line Subtitle Line Top of Content Box Line Top of Footer Line Left Margin LineRight Margin Line Top of Footer Line Top of Content Box Line Subtitle.
ICS 313: Programming Language Theory Chapter 13: Concurrency.
2/20/2016 EEC492/693/793 - iPhone Application Development 12/20/2016 EEC492/693/793 - iPhone Application Development 1 EEC-492/693/793 iPhone Application.
Operating Systems Unit 2: – Process Context switch Interrupt Interprocess communication – Thread Thread models Operating Systems.
Channels. Models for Communications Synchronous communications – E.g. Telephone call Asynchronous communications – E.g. .
Testing Concurrent Programs Sri Teja Basava Arpit Sud CSCI 5535: Fundamentals of Programming Languages University of Colorado at Boulder Spring 2010.
Parallel Programming Models EECC 756 David D. McGann 18 May, 1999.
CS203 Programming with Data Structures Introduction to Threads and Synchronization California State University, Los Angeles.
Tom Van Cutsem, Vrije Universiteit Brussel
Chapter 13: I/O Systems.
Last Class: Introduction
REAL-TIME OPERATING SYSTEMS
Module 12: I/O Systems I/O hardware Application I/O Interface
Chapter 3: Process Concept
The Mach System Sri Ramkrishna.
Background on the need for Synchronization
Prof. Leonardo Mostarda University of Camerino
CPE555A: Real-Time Embedded Systems
Advanced Topics in Concurrency and Reactive Programming: Asynchronous Programming Majeed Kassis.
Chapter 8 – Software Testing
Parallel Programming By J. H. Wang May 2, 2017.
Threads and Cooperation
5-High-Performance Embedded Systems using Concurrent Process (cont.)
Threads and Concurrency in Java: Part 2
Setac: A Phased Deterministic Testing Framework for Scala Actors
Shanna-Shaye Forbes Ben Lickly Man-Kit Leung
Chapter 4: Threads.
Threads and Data Sharing
OPERATING SYSTEMS PROCESSES
MPI-Message Passing Interface
Model Checking for an Executable Subset of UML
Operating System Concepts
CS703 - Advanced Operating Systems
CS 501: Software Engineering Fall 1999
Chapter 5: I/O Systems.
Background and Motivation
SCTP-based Middleware for MPI
Channels.
Semaphores Chapter 6.
Concurrency: Mutual Exclusion and Process Synchronization
Chapter 13: I/O Systems I/O Hardware Application I/O Interface
OS Components and Structure
November 1, 2007 In cooperation with:
Channels.
Channels.
Outline Chapter 2 (cont) Chapter 3: Processes Virtual machines
Outline Chapter 3: Processes Chapter 4: Threads So far - Next -
Chapter 3: Process Concept
Chapter 13: I/O Systems.
MapReduce: Simplified Data Processing on Large Clusters
Module 12: I/O Systems I/O hardwared Application I/O Interface
Presentation transcript:

Setac: A Phased Deterministic Testing Framework for Scala Actors Samira Tasharofi Jun 02, 2011 Stanford, CA

Setac Testing Framework Motivation Schedule is a source of non-determinism in concurrent programs Shared memory: order of accesses Message-passing: order of messages The output of the program might be different for a given input depending on the schedule The bugs may only show up during some specific schedules Systematic exploration can lead to state space explosion Setac Testing Framework 11/29/2018

Setac Testing Framework Actor Model Actor is a computational entity with a mail box and local state Deliver a message Append the message to the mail box Process a message Extract a message from the mail box and execute that Determined by message handler In response to a message it processes: Changes its local state Sends messages to other actors Creates new actors Setac Testing Framework 11/29/2018

Setac Testing Framework Actors in Scala Package scala.actors in Scala library Developed by Philipp Haller Features Synchronous and asynchronous communication Dynamic creation/destroying of actors Exception handling Remote actors Customization of the thread pool executing actors Setac Testing Framework 11/29/2018 Setac Testing Framework

Example: BoundedBuffer class BoundedBuffer(maxSize: Int) extends Actor { var content = new Array[Int](size) var head, tail, curSize = 0 start override def act() = loop { react { case Put(x) if (curSize < maxSize) => { content(tail) = x tail = (tail + 1) % size curSize += 1 } case Get if (curSize > 0) => { val r = content(head) head = (head + 1) % size curSize -= 1 reply(r) class Producer(buf: Actor) extends Actor { start override def act() = loop { react { case Produce(values) => values.foreach(v => buf ! Put(v)) } class Consumer(buf: Actor) extends Actor { var token = -1 start override def act() = loop { react { case Consume(count) => for (i <- 0 to count-1) token = (buf !? Get).asInstanceOf[Int] } Setac Testing Framework 11/29/2018 Setac Testing Framework

Setac Testing Framework BufferTest producer Put(4), Put(5) class BufferTest { @Test def testBuffer() { val buf = new BoundedBuffer(1) val consumer = new Consumer(buf) val producer = new Producer(buf) producer ! Produce(List(4, 5)) consumer ! Consume(2) // consumer should receive 4 and 5 assert(… ) } buffer(1) Get, Get 4, 5 consumer Setac Testing Framework 11/29/2018

Setac Testing Framework Buggy BoundedBuffer class BoundedBuffer(maxSize: Int) extends Actor { var content = new Array[Int](size) var head, tail, curSize = 0 start override def act() = loop { react { case Put(x) if (curSize maxSize) => { content(tail) = x tail = (tail + 1) % size curSize += 1 } case Get if (curSize > 0) => { val r = content(head) head = (head + 1) % size curSize -= 1 reply(r) Bug < <= A buffer with capacity of one. Setac Testing Framework 11/29/2018 Setac Testing Framework

Buggy BoundedBuffer: Schedules in BufferTest class BoundedBuffer(maxSize: Int) extends Actor { var content = new Array[Int](size) var head, tail, curSize = 0 start override def act() = loop { react { case Put(x) if (curSize maxSize) => { content(tail) = x tail = (tail + 1) % size curSize += 1 } case Get if (curSize > 0) => { val r = content(head) head = (head + 1) % size curSize -= 1 reply(r) consumer producer buffer(1) Put(4) <= Get 4 Put(5) 5 Get Error! 5 5 Setac Testing Framework 11/29/2018 Setac Testing Framework

Correct BoundedBuffer: Checking Assertions in Test class BoundedBuffer(maxSize: Int) extends Actor { var content = new Array[Int](size) var head, tail, curSize = 0 start override def act() = loop { react { case Put(x) if (curSize < maxSize) => { content(tail) = x tail = (tail + 1) % size curSize += 1 } case Get if (curSize > 0) => { val r = content(head) head = (head + 1) % size curSize -= 1 reply(r) class SimpleBufferTest { @Test def testBuffer() { val buf = new BoundedBuffer(1) buf ! Put(4) assert(buf.curSize == 1) } Fails!! buffer Put(4) … mailbox content, head, tail, curSize local state Fails!! assert Setac Testing Framework 11/29/2018 Setac Testing Framework

Testing Actor Programs Problems: How to write unit tests for Actor programs while controlling the schedule? How to check assertions at appropriate times? Current Solutions: Using synchronization constructs, e.g. Latches and Barriers Using Thread.sleep Setac Testing Framework 11/29/2018

BufferTest: A Test Schedule Consumer Producer BoundedeBuffer(1) Phase 1 Get Check assertions Put(4) 4 Phase 2 Put(5) Check assertions Get Phase 3 5 Check assertions Setac Testing Framework 11/29/2018 Setac Testing Framework

Traditional: BufferTest class BufferTest { @Test def testBuffer() { val putLatch = new CountDownLatch(2) val getLatch = new CountDownLatch(2) val buf = new BoundedBuffer(1, putLatch, getLatch) val consumeLatch = new CountDownLatch(1) val consumer = new Consumer(buf, consumeLatch) val producer = new Producer(buf) //Phase 1 consumer ! Consume(1) consumeLatch.await() Thread.sleep(1000) assert(consumer.getState == State.Blocked && buf.curSize == 0) // … } consumer producer buffer(1) Get Phase 1 class Consumer(buf: Actor, consumeLatch: CountDownLatch) extends Actor { var token = -1 start override def act() = loop { react { case Consume(count) => consumeLatch.countDown() for (i <- 0 to count-1) token = (buf !? Get).asInstanceOf[Int] } Setac Testing Framework 11/29/2018

Traditional: BufferTest (cont) consumer producer buffer(1) Put(4) class BoundedBuffer(maxSize: Int, putLatch: CountDownLatch, getLatch: CountDownLatch) extends Actor { var content = new Array[Int](size) var head, tail, curSize = 0 start override def act() = loop { react { case Put(x) if (curSize < maxSize) => { content(tail) = x tail = (tail + 1) % size curSize += 1 putLatch.countDown() } case Get if (curSize > 0) => { val r = content(head) head = (head + 1) % size curSize -= 1 reply(r) getLatch.countDown() Phase 2 4 Put(5) Get Phase 3 5 class BufferTest { @Test def testBuffer() { // … //Phase 2 producer ! Produce(List(4, 5)) putLatch.await() assert(consumer.token == 4 && buf.curSize == 1) // Phase 3 consumer ! Consume(1) getLatch.await() assert(consumer.token == 5 && buf.curSize == 0) } Setac Testing Framework 11/29/2018 Setac Testing Framework

Traditional BufferTest Problems Unreliable Thread.sleep Complexity and Deadlock possibility Latches and Barriers Costly Changing the program under test Setac Testing Framework 11/29/2018

Setac Testing Framework Specify tests with some constraints on the schedule Partial order of schedule messages Centralized schedule, less complexity Checking assertions when the system is stable There is no message that can be processed No progress in the system No change in the run time environment Minimal changes in the program under test Setac Testing Framework 11/29/2018

Setac Testing Framework Setac: BufferTest class BufferTest extends SetacTest { @Test def testBuffer() { val buf = new BoundedBuffer(1) val consumer = new Consumer(buf) val producer = new Producer(buf) val put4 = createScheduleMessage(producer, buf, Put(4)) val put5 = createScheduleMessage(producer, buf, Put(5)) val gets = createMultipleScheduleMessage(2, consumer, buf, Get) producer ! Produce(List(4, 5)) consumer ! Consume(2) //Phase 1 setSchedule(gets(0)) assertWhenStable(consumer.isBlocked && buf.curSize == 0) //Phase 2 setSchedule(put4 -> put5) assertWhenStable(consumer.token == 4 && buf.curSize == 1 && put5.isProcessed) // Phase 3 setSchedule(gets(1)) assertWhenStable(consumer.token == 5 && buf.curSize == 0) } Setac Testing Framework 11/29/2018

Setac: BufferTest (cont) class BoundedBuffer(size: Int) extends Actor { // … } class Consumer(buf: Actor) extends Actor { class Producer(buf: Actor) extends Actor { TestActor { TestActor { TestActor { Setac Testing Framework 11/29/2018 Setac Testing Framework

Setac Testing Framework Setac: BufferTest Removed Thread.sleep More reliable Removed synchronization constructs, e.g. Latches Reduced complexity Minimized changes in the program under test Setac Testing Framework 11/29/2018

Setac Testing Framework Setac APIs Follows widely used style for unit testing Integrated with Junit Refined over time based on examples Checking assertions when system is stable Total and partial order of schedule messages Status of Test messages Processed, delivered, etc. Status of actors Mail box: Number of messages, content of mail box, etc. Execution Status: Blocked, Running, Suspended Setac Testing Framework 11/29/2018

Setac Testing Framework Limitations Handling non-stable systems receiveWithin, reactWithin, etc. in a loop Use assertAfter API in Setac Managing anonymous actors E.g., Futures Handling actors whose source code is not available Setac Testing Framework 11/29/2018

Setac Testing Framework Future Work Integrate Setac with Scala actor library To eliminate the required change in the program under test To remove some of its limitations Extend the solution for Akka actors Integrate with ScalaTest Evaluate Setac on larger number of examples Speed, expressiveness Setac Testing Framework 11/29/2018

Setac Testing Framework Conclusions Large number of schedules in actor programs Only some schedules might be important to test It is non-trivial to force specific schedule and check assertions at appropriate times Sleeps - unreliable Latches – hard to write/read Changes in the program under test- high cost Setac Reliable Easy to write Very minimal changes in the program under test Open for collaboration Please try it: http://mir.cs.illinois.edu/setac/ Setac Testing Framework 11/29/2018