Unit Testing in Java with an Emphasis on Concurrency Corky Cartwright Rice and Halmstad Universities Summer 2013

Similar documents
Test-First Java Concurrency for the Classroom

CMSC 330: Organization of Programming Languages

The Java Memory Model

CMSC 132: Object-Oriented Programming II. Threads in Java

Computation Abstractions. Processes vs. Threads. So, What Is a Thread? CMSC 433 Programming Language Technologies and Paradigms Spring 2007

Problems with Concurrency

Parallelism Marco Serafini

THREADS & CONCURRENCY

Concurrency in Object Oriented Programs 1. Object-Oriented Software Development COMP4001 CSE UNSW Sydney Lecturer: John Potter

Lecture 24: Java Threads,Java synchronized statement

COMP 322: Fundamentals of Parallel Programming

Assertions, pre/postconditions

Overview. CMSC 330: Organization of Programming Languages. Concurrency. Multiprocessors. Processes vs. Threads. Computation Abstractions

Chapter 4 Defining Classes I

CMSC 132: Object-Oriented Programming II

Lecture 32: Volatile variables, Java memory model

Thread Safety. Review. Today o Confinement o Threadsafe datatypes Required reading. Concurrency Wrapper Collections

Threads and Java Memory Model

Java Threads. COMP 585 Noteset #2 1

Ch 9: Control flow. Sequencers. Jumps. Jumps

Testing Concurrent Software

Problems with Concurrency. February 19, 2014

Java s Implementation of Concurrency, and how to use it in our applications.

Software Speculative Multithreading for Java

Threads Questions Important Questions

Program Correctness and Efficiency. Chapter 2

The New Java Technology Memory Model

CMSC 433 Programming Language Technologies and Paradigms. Concurrency

Monitors; Software Transactional Memory

Modular Reasoning about Aliasing using Permissions

Java Threads. Introduction to Java Threads

Advances in Programming Languages

Comp 311 Principles of Programming Languages Lecture 21 Semantics of OO Languages. Corky Cartwright Mathias Ricken October 20, 2010

Object Oriented Software Design - I

Synchronization in Java

Runtime assertion checking of multithreaded Java programs

High Performance Computing Course Notes Shared Memory Parallel Programming

MASSACHUSETTS INSTITUTE OF TECHNOLOGY Computer Systems Engineering: Spring Quiz I Solutions

Message Passing. Advanced Operating Systems Tutorial 7

G Programming Languages Spring 2010 Lecture 13. Robert Grimm, New York University

CSE 230. Concurrency: STM. Slides due to: Kathleen Fisher, Simon Peyton Jones, Satnam Singh, Don Stewart

CSE 153 Design of Operating Systems

Principles of Software Construction: Concurrency, Part 2

Multithreading and Interactive Programs

A Deterministic Concurrent Language for Embedded Systems

Thread Synchronization Policies in DrJava

Object Oriented Programming. Week 10 Part 1 Threads

Dealing with Issues for Interprocess Communication

Advances in Programming Languages

Testing Concurrent Software

Specification of a transacted memory for smart cards in Java and JML

Synchronization SPL/2010 SPL/20 1

THREADS & CONCURRENCY

AP COMPUTER SCIENCE JAVA CONCEPTS IV: RESERVED WORDS

Concurrency. Glossary

Operating Systems 2 nd semester 2016/2017. Chapter 4: Threads

Concurrency: Past and Present

Multitasking Multitasking allows several activities to occur concurrently on the computer. A distinction is usually made between: Process-based multit

Outline. Threads. Single and Multithreaded Processes. Benefits of Threads. Eike Ritter 1. Modified: October 16, 2012

THREADS AND CONCURRENCY

Exception Handling Introduction. Error-Prevention Tip 13.1 OBJECTIVES

Multithreading and Interactive Programs

Why testing and analysis. Software Testing. A framework for software testing. Outline. Software Qualities. Dependability Properties

Threads SPL/2010 SPL/20 1

Fortgeschrittene objektorientierte Programmierung (Advanced Object-Oriented Programming)

INF 212 ANALYSIS OF PROG. LANGS CONCURRENCY. Instructors: Crista Lopes Copyright Instructors.

CSE332: Data Abstractions Lecture 23: Programming with Locks and Critical Sections. Tyler Robison Summer 2010

MuClipse Requirements Specification

Embedded System Programming

Module 6: Process Synchronization. Operating System Concepts with Java 8 th Edition

Chapter 4: Threads. Operating System Concepts 9 th Edition

CS 2112 Lecture 20 Synchronization 5 April 2012 Lecturer: Andrew Myers

CMSC 330: Organization of Programming Languages. Concurrency & Multiprocessing

Programmazione Avanzata e Paradigmi Ingegneria e Scienze Informatiche - UNIBO a.a 2013/2014 Lecturer: Alessandro Ricci

Introduction to Concurrency Principles of Concurrent System Design

Software Project Seminar VII: Tools of the Craft. 23 march 2006 Jevgeni Kabanov

CS 455: INTRODUCTION TO DISTRIBUTED SYSTEMS [THREADS] Frequently asked questions from the previous class survey

Chair of Software Engineering. Java and C# in depth. Carlo A. Furia, Marco Piccioni, Bertrand Meyer. Java: concurrency

Thread Programming. Comp-303 : Programming Techniques Lecture 11. Alexandre Denault Computer Science McGill University Winter 2004

Java Memory Model. Jian Cao. Department of Electrical and Computer Engineering Rice University. Sep 22, 2016

So#ware Architecture

OS06: Monitors in Java

Casting -Allows a narrowing assignment by asking the Java compiler to "trust us"

Advanced MEIC. (Lesson #18)

OPERATING SYSTEM. Chapter 4: Threads

Monitors; Software Transactional Memory

User Space Multithreading. Computer Science, University of Warwick

Thread-Local. Lecture 27: Concurrency 3. Dealing with the Rest. Immutable. Whenever possible, don t share resources

Introduction to JUnit. Data Structures and Algorithms for Language Processing

Chapter 4: Threads. Chapter 4: Threads

CSE 160 Lecture 7. C++11 threads C++11 memory model

Objectives for this class meeting. 1. Conduct review of core concepts concerning contracts and pre/post conditions

A Sophomoric Introduction to Shared-Memory Parallelism and Concurrency Lecture 5 Programming with Locks and Critical Sections

Discussion CSE 224. Week 4

11/19/2013. Imperative programs

MultiJav: A Distributed Shared Memory System Based on Multiple Java Virtual Machines. MultiJav: Introduction

Chapter 4: Threads. Operating System Concepts 9 th Edition

Key-value store with eventual consistency without trusting individual nodes

Project Loom Ron Pressler, Alan Bateman June 2018

Object Oriented Programming and Design in Java. Session 18 Instructor: Bert Huang

Transcription:

Unit Testing in Java with an Emphasis on Concurrency Corky Cartwright Rice and Halmstad Universities Summer 2013

Software Engineering Culture Three Guiding Visions Data-driven design Test-driven development Mostly functional coding (no gratuitous mutation) Codified in Design Recipe taught in How to Design Programs by Felleisen et al (available for free online: www.htdp.org [first edition], www.ccs.neu.edu/home/matthias/htdp2e/draft, [second edition]) and Elements of Object-Oriented Design (available online at. The target languages are Scheme and Java.

Moore s Law

Extrapolate the Future

Timeliness CPU clock frequencies stagnate Multi-Core CPUs provide additional processing power, but multiple s needed to use multiple cores. Writing concurrent programs is difficult!

Tutorial Outline Introduce unit testing in single-ed (deterministic) setting using lists Demonstrate problems introduced by concurrency and their impact on unit testing Show how some of the most basic problems can be overcome by using the right policies and tools.

(Sequential) Unit Testing Unit tests Test parts of the program (including( whole!) Integrate with program development; commits to repository must pass all unit tests Automate testing during maintenance phase Serve as documentation Prevent bugs from reoccurring Help keep the code repository clean Help keep the code repository clean Effective with a single of control

Universal Test-Driven Design Recipe Analyze the problem: define the data and determine top level operations. Give sample data values. Define type signatures, contracts, and headers for all top level operations. In Java, the type signature is part of the header. Give input-output examples including critical boundary cases for each operation. Write a template for each operation, typically based on structural decomposition of primary argument (the receiver in OO methods). Code each method by filling in templates Test every method (using I/O examples!) and ascertain that every method is tested on sufficient set of examples. White-box testing matters!

Sequential Case Studies: Functional Lists and Bi-Lists A List<E> is either Empty<E>(), or Cons<E>(e, l) where e is an E and l is List<E> A BiList<E> is a mutable data structure containing a possibly empty sequence of objects of type E that can be traversed in either direction using a BiListIterator<E>.

Review Elements of Sequential Unit Testing Unit tests depend on deterministic behavior Known input, expected output Success Failure correct behavior flawed code Outcome of test is meaningful if test is deterministic

Problems Due to Concurrency Thread scheduling is nondeterministic and machine-dependent Code may be executed under different schedules Different schedules may produce different results Known input, expected output(s?) Success correct behavior in this schedule, may be flawed in other schedule Failure flawed code Success of unit test is meaningless

Recommended Resources on Concurrent Programming in Java Explicit Concurrency: Comp 402 web site from 2009 Brian Goetz, Java Concurrency in Practice (available onlne at this website) Coping with Multicore Emerging parallel extensions of Java/Scala that guarantee determinism (in designated subset) and do not require explicit synchronization and avoid JMM issues Habanero Java Habanero Scala

Problems Due to Java Memory Model JMM is MUCH weaker than sequential consistency Writes to shared data may be held pending indefinitely unless target is declared volatile or is shielded by the same lock as subsequent reads. Why not always use locking (synchronized)? Significant overhead Increases likelihood of deadlock Extremely difficult to reason about program execution for specific inputs because so many schedules are allowed. A model that accommodates compiler writers rather than software developers.

Hidden Pitfalls in Using JUnit to Test Concurrent Java Junit Is Completely Broken for Concurrent Code Units: Fails to detect exceptions and failed assertions in s other than the main (!) Fails to detect if auxiliary is still running when main terminates; all execution is aborted when main terminates. Fails to ensure that all auxiliary s were joined by main before termination. (In Habanero Java, all programs are implicity enclosed a comprehensive join called finish() but not in Java.)

Possible Solutions to Concurrent Testing Problems Programming Language Features Ensure that bad things cannot happen; perhaps ensure determinism (reducing testing to sequential semantics!) May restrict programmers Comprehensive Testing Testing if bad things happen in any schedule All schedules may be too stringent for programs involving GUIs Does not limit space of solutions but testing burden is greatly increased. Good testing tools are essential.

Coping with the Java Memory Model Avoid using synchronized and minimize the size of synchronized blocks to reduce likelihood of deadlock. Identify all classes that can be shared and make all fields in such classes either final or volatile. Ensures sequential consistency (almost). Array elements are still technically a problem because they cannot be marked as volatile. The ConcurrentUtilities library includes a special form of array with volatile elements.

Improvements to Junit ConcJUnit developed by my former Uncaught exceptions and failed assertions graduate student Mathias Ricken fixes Not caught in child s all of the problems with Junit. Developed for Java 6; Java 7 not yet supported. Mathias developed some other tools to help test concurrent programs but none of them have yet reached production quality (e.g., random delays/yields). Research idea: JVM from Hell.

Sample JUnit Tests public class Test extends TestCase { public void testexception() { throw new RuntimeException("booh!"); public void testassertion() { assertequals(0, 1); if (0!=1) throw new AssertionFailedError(); Both tests fail.

Problematic JUnit Tests Main public class Test extends TestCase { public void testexception() { new Thread(new Runnable() { public void run() { throw thrownew new RuntimeException("booh!"); ).start(); Child Main Child spawns uncaught! end of test success!

Problematic JUnit Tests Main public class Test extends TestCase { public void testexception() { new Thread(new Runnable() { public void run() { throw thrownew new RuntimeException("booh!"); ).start(); Child Main Child spawns uncaught! end of test success!

Problematic JUnit Tests Main public class Test extends TestCase { public void testexception() { new Thread(new Runnable() { public void run() { throw thrownew new RuntimeException("booh!"); ).start(); Child Uncaught exception, test should fail but does not!

Problematic JUnit Tests Main public class Test extends TestCase { public void testfailure() { new Thread(new Runnable() { public void run() { throw fail("this thrownew new RuntimeException("booh!"); fails!"); ).start(); Child Uncaught exception, test should fail but does not!

Thread Group for JUnit Tests Test public class Test extends TestCase { public void testexception() { new Thread(new Runnable() { public void run() { throw thrownew new RuntimeException("booh!"); ).start(); Child invokes checks TestGroup s Uncaught Exception Handler

Thread Group for JUnit Tests Test public class Test extends TestCase { public void testexception() { new Thread(new Runnable() { public void run() { throw thrownew new RuntimeException("booh!"); ).start(); Child spawns and waits resumes Main Test Child spawns uncaught! end of test invokes group s handler check group s handler failure!

Improvements to JUnit Uncaught exceptions and failed assertions Not caught in child s Thread group with exception handler JUnit test runs in a separate, not main Child s are created in same group When test ends, check if handler was invoked Detection of uncaught exceptions and failed assertions in child s that occurred before test s end Past tense: occurred!

Child Thread Outlives Parent Test public class Test extends TestCase { public void testexception() { new Thread(new Runnable() { public void run() { throw thrownew new RuntimeException("booh!"); ).start(); Child spawns and waits resumes Main Test Child spawns uncaught! end of test invokes group s handler check group s handler failure!

Child Thread Outlives Parent Test public class Test extends TestCase { public void testexception() { new Thread(new Runnable() { public void run() { throw thrownew new RuntimeException("booh!"); ).start(); Child check group s spawns and waits resumes handler Main Test Child spawns end of test success! uncaught! Too late! invokes group s handler

Enforced Join public class Test extends TestCase { public void testexception() { Thread new Thread(new t = Thread(new Runnable() Runnable() { { public void run() { throw throw new new RuntimeException("booh!"); RuntimeException("booh!"); ); t.start(); t.join(); Test Child

Testing Using ConcJUnit Replacement for junit.jar or as plugin JAR for JUnit 4.7 compatible with Java 6 (not 7 or 8) Available as binary and source at http://www.concutest.org/ Results from DrJava s unit tests Child for communication with slave VM still alive in test Several reader and writer s still alive in low level test (calls to join() missing) DrJava currently does not use ConcJUnit Tests based on a custom-made class extending junit.framework.testcase Does not check if join() calls are missing

Conclusion Improved JUnit now detects problems in other s Only in chosen schedule Needs schedule-based execution Annotations ease documentation and checking of concurrency invariants Open-source library of Java API invariants Support programs for schedule-based execution

Future Work Adversary scheduling using delays/yields (JVM from Hell) Schedule-Based Execution (Impractical?) Replay stored schedules Generate representative schedules Dynamic race detection (what races bugs?) Randomized schedules (JVM from Hell) Support annotations from Floyd-Hoare logic Declare and check contracts (preconditions & postconditions for methods) Declare and check class invariants

Extra Slides

Tractability of Comprehensive Testing Test all possible schedules Concurrent unit tests meaningful again Number of schedules (N) t: : # of s, s: : # of slices per detail

Extra: Number of Schedules Product of s-combinations For 1: choose s out of ts time slices For 2: choose s out of ts-s time slices For t-1: choose s out of 2s time slices For t-1: choose s out of s time slices W C L back

Tractability of Comprehensive Testing If program is race-free, we do not have to simulate all switches Threads interfere only at critical points : lock operations, shared or volatile variables, etc. Code between critical points cannot affect outcome Simulate all possible arrangements of blocks delimited by critical points Run dynamic race detection in parallel Lockset algorithm (e.g. Eraser by Savage et al)

Critical Points Example Local Var 1 Thread 1 lock access unlock All lock accesses access unlock protected by lock Shared Var Lock Thread 2 All accesses protected by lock lock access unlock All accesses protected by lock Local variables don t need locking Local Var 1

Fewer Schedules Fewer critical points than switches Reduces number of schedules Example: Two s, but no communication N = 1 Unit tests are small Reduces number of schedules Hopefully comprehensive simulation is tractable If not, heuristics are still better than nothing

Limitations Improvements only check chosen schedule A different schedule may still fail Requires comprehensive testing to be meaningful May still miss uncaught exceptions Specify absolute parent group, not relative Cannot detect uncaught exceptions in a program s uncaught exception handler (JLS limitation) details

Extra: Limitations May still miss uncaught exceptions Specify absolute parent group, not relative (rare) Koders.com: 913 matches ThreadGroup vs. 49,329 matches for Thread Cannot detect uncaught exceptions in a program s uncaught exception handler (JLS limitation) Koders.com: 32 method definitions for uncaughtexception method back

Extra: DrJava Statistics Unit tests passed failed not run Invariants met failed % failed KLOC event 2004 736 610 36 90 5116 4161 965 18.83% 107 1 2006 881 881 0 0 34412 30616 3796 11.03% 129 99 back