Università degli Studi di Salerno Dipartimento di Informatica Tesi di laurea di I livello Individuazione di bug in programmi Java con l’ausilio dei tool JUnit e Java Path Finder Relatore Candidata Salvatore La Torre Mariangela Petraglia 0512101790 Correttezza dei sistemi digitali (1) • La tecnologia è in continua evoluzione: smartphone, pc, tablet, Internet Of Thing; in generale tutti i sistemi digitali; • Con tali sistemi si ha necessità di utilizzare software corretti; • Un software corretto deve rispettare dei requisiti funzionali, se uno o più non sono rispettati, tale software potrebbe essere soggetto a bug; Correttezza dei sistemi digitali (2) • Un bug è un errore di progettazione in un software; • Tali errori posso essere la conseguenza di grandi catastrofi come: distruzione della sonda spaziale Mariner 1 -> un trattino mancante nel codice; esplosione razzo Ariane 5 -> il sistema tentò di memorizzare un numero in virgola mobile di 64 bit in un spazio da 16; distruzione di una caserma americana -> il missile Patriot mancò l’intercettazione del missile SCUD a causa di calcolo inaccurato del tempo (errori di arrotondamento); Tecniche di verifica dei sistemi Esistono varie tecniche che permettono di constatare la correttezza dei sistemi: • Peer review: analisi statica sul codice; • Testing: esecuzione del codice con input prestabiliti e confronto output con oracolo; • Emulazione: si progetta un sistema hardware che replica le funzionalità del sistema hardware da verificare; • Simulazione: modello di circuito che ricrea le funzionalità del sistema da verificare; • Analisi strutturale: tecnica la quale include sintesi, analisi di temporizzazione e • Model checking: modello formale e delle proprietà del sistema da verificare; verifica di equivalenza; Selezione di tecniche complementari Per questo lavoro di tesi sono state selezionate due tecniche di verifica complementari: 1. Testing -> JUnit 2. Model checking -> Java Path Finder Esempio: Testing vs. Model checking (1) public class Rand { public static void main (String[] args) { System.out.println ("computing c = a/(b+a - 2).."); Random random = new Random(42); // (1) int a = random.nextInt(2); // (2) System.out.printf("a=%d \n", a); //... lots of code here int b = random.nextInt(3); // (3) System.out.printf("a=%d ,b=%d \n", a, b); int c = a / ( b+a -2 ); System.out.printf ("=> c=%d } } // (4) , a=%d, b=%d \n", c, a, b); Esempio: Testing vs. Model checking (2) Testing computing c = a/(b+a - 2).. a=1 a=1 , b=0 => c=-1 , a=1, b=0 Model checking computing c = a/(b+a - 2).. a=0 a=0 , b=0 => c=0 , a=0, b=0 a=0 , b=1 => c=0 , a=0, b=1 a=0 , b=2 ======================================= error 1 gov.nasa.jpf.vm.NoUncaughtExceptionsProperty java.lang.ArithmeticException: division by zero at Rand.main (Rand.java:35) Obiettivi della tesi • Apprendere concetti teorici sul testing e model checking; • Applicare la metodologia del testing con JUnit; • Applicare la metodologia del model checking con Java Path Finder; comprendere le caratteristiche a sé associate, ad esempio listener; JUnit: scrivere test case public class Calcolatrice{ public class CalcolatriceTest extends TestCase{ public double somma (double a, double b){ return a+b; } Calcolatrice calc = new Calcolatrice(); public double sottrazione (double a, double b){ return a+b; //bug } @Test public void testSomma(){ int a = 5; int b = 10; assertEquals (15.0, calc.somma(a, b), 15); } //altri metodi } @Test public void testSottrazione(){ int a = 5; int b = 10; assertEquals (5.0, calc.sottrazione(a, b), 5); } //gli altri metodi test } Java Path Finder public class RaceCondition extends Thread { public static int counter = 0; public String nome; public RaceCondition (String nome){ this.nome = nome; } @Override public void run() { counter++; System.out.println(counter); } public static void main (String[] args){ RaceCondition t1 = new RaceCondition("T1"); RaceCondition t2 = new RaceCondition("T2"); t1.start(); t2.start(); } } Configurazione *.jpf target = tesi.RaceCondition Output ……. 1 1 1 ==================================== results no errors detected Configurazione *.jpf con listener target = tesi.RaceCondition listener = .listener.PreciseRaceDetector Output con listener gov.nasa.jpf.listener.PreciseRaceDetector race for field tesi.RaceCondition.counter Thread-1 at tesi.RaceCondition.run(RaceCondition.java:24) "System.out.println(counter);" READ: getstatic tesi.RaceCondition.counter Thread-2 at tesi.RaceCondition.run(RaceCondition.java:23) "counter++;" WRITE: putstatic tesi.RaceCondition.counter Considerazioni sul lavoro svolto e conclusioni • L’approccio al testing e al tool, JUnit, è stato piuttosto semplice in quanto il percorso di studi offre queste conoscenze • L’approccio al model checking e a Java Path Finder è stato abbastanza difficile, in quanto erano concetti nuovi (struttura di Kripke, logiche temporali, modellazione di sistemi digitali); Grazie a tutti per l’attenzione!!!