Universit`adegli studi di RomaTre

Dipartimento di Ingegneria Laurea triennale in Ingegneria Informatica

Tesi di laurea

Metodologie e strumenti per il testing del software di controllo di integrit`adei dati su strutture dati autenticate

Candidato Alessio Treglia Matr. 240930

Relatore Maurizio Pizzonia

Anno accademico 2012/2013

The beginning is always today (Mary Shelley) - Ho imparato un sacco di cose in mezzo agli altri, vestiti uguali Ma non quale ´eil crimine giusto per non passare da criminali (Fabrizio De Andr´e)

Indice

Introduzione 2

1 Contesto e stato dell’arte 3 1.1 FileRock: un servizio di sincronizzazione e backup ...... 3 1.1.1 FileRock client ...... 4 1.2 Strutture dati autenticate ...... 6 1.2.1 Basis e proof ...... 7 1.2.2 Merkle hash tree ...... 7 1.2.3 Merkle hash tree: calcolo della proof ...... 7 1.2.4 Skip list autenticate ...... 9 1.2.5 Authenticated skip list: calcolo della proof ...... 10 1.3 Implementazione: linguaggi e tecnologie ...... 10 1.3.1 Python: caratteristiche e breve storia ...... 11 1.3.2 Testing: Python unittest ...... 12 1.4 Obiettivi previsti ...... 12

2 Analisi e progettazione 15 2.1 Software testing come garanzia di qualit`a ...... 15 2.2 Obiettivi e limitazioni del collaudo ...... 16 2.2.1 Limiti del testing ...... 16 2.3 Verifica e validazione ...... 17 2.3.1 Tecniche di verifica ...... 18 2.3.2 Test fixture e oggetti fittizi ...... 19 2.3.3 Tecniche di validazione ...... 20 2.3.4 Verifica e validazione in FileRock ...... 20 2.4 Garanzia di qualit`a...... 21 2.4.1 Definizioni ...... 21 2.4.2 Indicatori di qualit`ae obiettivi ...... 22

I II INDICE

2.4.3 Garanzia di qualit`ain FileRock ...... 23 2.5 Analisi: scenario iniziale ...... 24 2.5.1 Struttura ...... 24 2.5.2 Analisi delle criticit`ae piano di lavoro ...... 25 2.6 Debian packaging e integrazione in Ubuntu ...... 26

3 Realizzazione del software 27 3.1 Casistiche e tipologie di test ...... 27 3.1.1 Test unitario ...... 28 3.1.2 Test funzionale ...... 29 3.1.3 Test di integrazione ...... 31 3.2 Modello e generazione dati di input ...... 33 3.2.1 Oggetti Dataset per l’incapsulamento del filesystem . . . . . 33 3.2.2 Generazione dati casuali ...... 34 3.3 Supporto all’automazione ...... 34 3.3.1 Caricamento dei dati di input da file di configurazione . . . . 34 3.3.2 Script di esecuzione automatica ...... 35 3.4 Integrazione in Debian e Ubuntu ...... 36 3.4.1 Integrazione in Unity ...... 36 3.4.2 Debian packaging ...... 37

4 Conclusioni 39 4.1 Sviluppi futuri ...... 39 4.2 Conclusioni ...... 39

A Licenza i

Glossario iii

Bibliografia v

Ringraziamenti ix Elenco delle figure

1.1 Calcolo del fingerprint dello stato iniziale ...... 5 1.2 Aggiornamento del fingerprint e caricamento dei file ...... 5 1.3 Verifica di integrit`ae download dei file ...... 5 1.4 Caricamento di file contenuti protetti ...... 6 1.5 Struttura Merkle hash tree ...... 8

1.6 Merkle hash tree, proof per l’elemento e2 ...... 8 1.7 Skip list autenticata. E` indicato il verso di percorrenza del flusso delle informazioni in un cammino...... 9 1.8 Ricalcolo del basis. In grigio i nodi appartenenti al cammino scelto. . 10 1.9 Analisi prestazionale ...... 12

2.1 Sulla sinistra gli attributi oggetti delle misurazioni, a destra le carat- teristiche di qualit`a...... 23

III IV ELENCO DELLE FIGURE Elenco delle tabelle

1.1 Prestazioni: Python si dimostra estremamente veloce con il calcolo su interi long ...... 12

2.1 Analisi della distribuzione degli errori in un progetto software di medie dimensioni ...... 16

V VI ELENCO DELLE TABELLE Introduzione

Le metodologie e le tecniche di collaudo da sempre rappresentano voci importanti nelle valutazioni di allocazione di tempo e risorse per lo sviluppo di software. Bench´e la relazione fra le strategie di assicurazione di qualit`ae il successo o il fallimento di un progetto trovasse gi`asicuri riscontri nell’industria del periodo antecedente al- l’introduzione delle pi`urecenti metodologie agili, queste ultime hanno sicuramente contribuito all’elaborazione di nuove pratiche e strumenti: se fare del buon test- ing era importante quando l’ingegneria ancora si basava su processi sequenziali di analisi e progettazione, alcune delle nuove tecniche agili, aventi come principio fon- dante la riduzione del rischio di insuccesso e basate sulla suddivisione dei processi di produzione in ridotte finestre temporali, accompagnano lo studio dei requisiti di sviluppo del software all’analisi dei requisiti di collaudo.

Il progetto FileRock ´eun software di condivisione di contenuti su Internet prodot- to dalla Heyware s.r.l. E` progettato per l’utenza desktop privata e aziendale e si propone di fornire agli utenti le maggiori garanzie possibili in termini di confiden- zialit`ae integrit`adei dati. Per raggiungere tale obiettivo FileRock incapsula un’im- plementazione proprietaria di un protocollo di comunicazione client-server basato su algoritmi di controllo di integrit`adei dati su strutture dati autenticate ADS, acr`on- imo di Authenticated Data Structures, le quali verranno descritte in seguito.

Questa tesi ha come scopo principale quello di illustrare le strategie e i proces- si decisionali segu`ıti nella progettazione dei componenti software di ausilio ai test, nonch´ele metodologie e gli strumenti utilizzati dal candidato durante la sua esperien- za lavorativa maturata nell’ambito di FileRock, impiegato dalla azienda produttrice del software nel ruolo di Quality Engineer. Il fine ultimo `estato quello di fornire agli sviluppatori degli strumenti open, affidabili e di facile utilizzo che fossero in gra- do di velocizzare la stesura di test case e di automatizzarne l’esecuzione. In primo

1 2 CAPITOLO 0. INTRODUZIONE luogo sono stati esaminati diversi aspetti e casi d’uso dei componenti sottoposti a collaudo. Una volta individuate le priorit`a,si `eproceduto alla scrittura dei casi di test. Durante l’avanzamento dei lavori `estato possibile generalizzare le soluzioni alle problematiche riscontrate e estenderle a scenari pi`uampi. Ci`oha permesso la scrittura di codice riutilizzabile per il collaudo di parti del software non incluse nel progetto iniziale.

Il Capitolo 1 fornisce una rappresentazione dello scenario iniziale e lo stato dei la- vori al momento dell’introduzione del candidato al processo di sviluppo del prodotto. Sono inoltre introdotte le tecnologie, i linguaggi e gli strumenti open source utiliz- zate nella scrittura del codice.

Il Capitolo 2 illustra il processo decisionale, le strategie attuate e le tipologie di problemi risolti per il raggiungimento degli scopi prefissati.

Il Capitolo 3 descrive la scelte progettuali e i dettagli implementativi delle soluzioni ai problemi individuati duranti le fasi di analisi e comprende una selezione di esempi di codice estratti dalla ricca codebase del progetto stesso.

Tutto il codice ´erilasciato nei termini di una licenza libera, la Berkeley Software Distribution (variante a 3 clausole) ed `eliberamente riutilizzabile, modificabile e redistribuibile secondo i termini della licenza stessa. Capitolo 1

Contesto e stato dell’arte

In questo capitolo viene fornita una dettagliata descrizione dello scenario iniziale dei lavori. Verranno quindi introdotte le strutture dati autenticate, componente centrale dell’intera architettura di verifica dell’integrit`anonch`etarget principale delle operazioni di collaudo, le tecnologie e i linguaggi di programmazione utilizzati nello sviluppo del software, nonch´eil risultato delle prime fasi di analisi del progetto.

1.1 FileRock: un servizio di sincronizzazione e backup

FileRock [fila] ´eun servizio di sincronizzazione e backup di dati sul web che con- sente la memorizzazione e la gestione di file grazie all’utilizzo di risorse software e hardware coordinate all’interno di un’architettura remota distribuita.

Le caratteristiche del servizio sono accomunabili a quelle del classico servizio di cloud computing, gli obiettivi prefissati (come descritto in [Nar12]) si possono riassumere nei tre pilastri [Per11] della sicurezza dei dati:

• confidenzialit`a

• integrit`a

• disponibilit`a

Il termine confidenzialit`a si riferisce alle misure di protezione dei dati che garan- tiscono all’utente un controllo totale e esclusivo sulle politiche di accesso agli stessi. Il servizio si offre di garantire all’utente che financo i membri dello staff tecnico e amministrativo saranno impossibilitati ad accedere in lettura ai dati memorizzati.

3 4 CAPITOLO 1. CONTESTO E STATO DELL’ARTE

Il principio di integrit`a si pu`oriassumere nell’impossibilit`aper soggetti non au- torizzati di effettuare modifiche o cancellazioni. Qualora si verificassero modifiche non autorizzate, l’utente sar`asempre in grado di accorgersene.

La disponibilit`a ´eil principio secondo il quale l’utente deve poter accedere ai propri dati in qualsiasi momento. I canali di accesso, i sistemi e gli automatismi di autenticazione devono sempre funzionare correttamente al fine di fornire un servizio continuativo per la fruizione dei dati.

FileRock si prefigge perci`odi fornire un servizio all’utente con lo scopo di sod- disfare i seguenti requisiti:

• i dati si troveranno sempre nell’ultimo stato noto all’utente proprietario degli stessi;

• in caso di guasti e di modifiche malevoli ai dati, l’utente verr`atempestivamente avvisato;

• l’utente ´elibero di non fidarsi dei servizi di sincronizzazione, backup e memo- rizzazione fisica dei propri dati.

1.1.1 FileRock client

L’applicazione client (ovvero il programma in formato eseguibile fornito all’utente), oltre a fornire una interfaccia gradevole e di semplice utilizzo, si occupa princi- palmente di verificare l’integrit`adel patrimonio di dati dell’utente e di gestire le operazioni di cifratura, qualora richieste, in fase di upload dei dati sul server.

Allo stato iniziale viene calcolato una rappresentazione numerica dei contenuti di una cartella privata dell’utente, nota come fingerprint. A un set di contenuti pu`o corrispondere una sola rappresentazione digitale, per evitare collisioni viene utiliz- zato l’algoritmo MD5 [Riv92] per produrre codici hash di lunghezza pari a 128 bit (16-byte).

Quando vengono apportate una o pi`umodifiche ai file presenti nella cartella pri- vata dell’utente, l’applicazione sincronizza i dati con il server e aggiorna il fingerprint. 1.1. FILEROCK: UN SERVIZIO DI SINCRONIZZAZIONE E BACKUP 5

Figura 1.1: Calcolo del fingerprint dello stato iniziale

Figura 1.2: Aggiornamento del fingerprint e caricamento dei file

In fase di download dei dati, il servizio remoto fornisce una prova di integrit`a che verr`asuccessivamente utilizzata dall’applicazione client per verificare la correttez- za dell’operazione richiesta. Se la verifica dell’integrit`aha successo, il client inizia a scaricare i dati in locale; in caso contrario informa immediatamente l’utente del problema riscontrato.

Figura 1.3: Verifica di integrit`ae download dei file 6 CAPITOLO 1. CONTESTO E STATO DELL’ARTE

Fra le caratteristiche avanzate aggiuntive offerte da FileRock c’`ela sopra citata cifratura in locale. L’applicazione applica a una cartella residente sul filesystem a scelta dell’utente un algoritmo di cifratura e provvede al suo caricamento in forma gi`acifrata, impedendo in questo modo ogni eventuale accesso lato server.

Figura 1.4: Caricamento di file contenuti protetti

1.2 Strutture dati autenticate

Le prime apparizioni in ambito crittografico delle strutture dati autenticate si devono a [Mer80], [Koc98] e [NN98], una sintetica descrizione generale viene fornita da [Nar12]: “una struttura dati si dice autenticata se da essa `epossibile trarre sempre una prova di integrit`a,o proof relativa al suo stato corrente.” L’utilizzo avviene in uno scenario in cui una fonte non fidata ha la responsabil- it`adi soddisfare una richiesta, garantendo la veridicit`adella risposta fornita. Nel caso specifico di una implementazione di una struttura dati, le richieste si possono classificare in una ristretta selezione:

• inserimenti

• cancellazioni

• ricerca

Le entit`afondamentali dell’implementazione hanno i nomi di basis e proof. La prima ´eun hash crittografico di un determinato stato della struttura dati, la secon- da `euna coppia formata da un’operazione e un codice hash che permette la verifica 1.2. STRUTTURE DATI AUTENTICATE 7 dell’integrit`adi uno stato della struttura oggetto della richiesta.

1.2.1 Basis e proof

Il basis ´elo strumento principale necessario per dimostrare l’integrit`adella strut- tura dati e del suo contenuto. Trattandosi di un fingerprint di un determinato stato del dataset, una propriet`afondamentale ´eche a due stati diversi corrispondono due basis diversi.

Un agente interessato a verificare l’integrit`adella struttura deve perci`oconoscere il valore corrente del basis. La prova di integrit`a´efornita dalla proof: applicando un algoritmo a tale insieme di informazioni, `epossibile ricalcolare il valore hash dei dati e verificarne l’uguaglianza con un basis fidato. Quest’ultimo pu`oessergli stato comunicato da una fonte fidata (o inoltrato da una fonte non fidata fintanto che firmato dalla fonte fidata) [Nar12].

1.2.2 Merkle hash tree

Una implementazione possibile ´ela Merkle hash tree, proposta in [Mer80]. Tale struttura ´euna particolare istanza di albero di ricerca composta da una funzione di hash H e un insieme di dati ordinati S e caratterizzata come segue:

• i nodi foglia corrispondo agli elementi e di S; sono anch’essi dotati di un’etichet- ta, la quale corrisponde al valore hash H(e) dell’elemento che rappresentano;

• i nodi intermedi sono dotati di etichetta, risultato della funzione di hash applicata sulla concatenazione delle etichette dei nodi figli.

Ne deriva che anche il nodo radice root ´eprovvisto di etichetta, la quale rappre- senta il basis, ovvero il fingerprint dell’intera collezione di dati [Nar12].

1.2.3 Merkle hash tree: calcolo della proof

Per verificare la presenza di un dato nodo e nella struttura dati autenticate, si prenda in considerazione un cammino T dal nodo root al nodo e. Ogni nodo p appartenente a 8 CAPITOLO 1. CONTESTO E STATO DELL’ARTE

Figura 1.5: Struttura Merkle hash tree tale cammino possiede un nodo figlio q, non incluso nel cammino T, che contribuisce al calcolo dell’etichetta del genitore.

Figura 1.6: Merkle hash tree, proof per l’elemento e2

La proof ´ecomposta dall’insieme di tali contributi. Nota la funziona di hash, la proof sopra definita permette di ricalcolare il basis dell’intero insieme dei dati [Nar12]. 1.2. STRUTTURE DATI AUTENTICATE 9

1.2.4 Skip list autenticate

Un’altra possibile implementazione ´erappresentata dalle authenticated skip list, ampiamente analizzate e discusse in [GTS01], [GT01] e [Nar12].

La struttura dati in questione ´euna variante della tradizionale skiplist, introdotte da [Pug90], i cui elementi sono arricchiti delle informazioni di autenticazione.

Una skip list ´ecomposta da un insieme di liste ordinate. Una di queste liste contiene l’intero insieme di dati, le altre costituiscono una parte di ridondanza: ogni elemento ha probabilit`a1/2 di essere presente in una lista se presente nella lista precedente; l’ultima lista contiene esclusivamente gli elementi +∞ e −∞, necessari ai fini della ricerca di elementi all’interno della struttura.

Sfruttando una logica simile a quella utilizzata dai Merkle hash tree, viene com- posto un grafico diretto aciclico a partire dai nodi della skip list. Tale struttura supporta efficienti operazioni di ricerca di un elemento e all’interno di un insieme S.

Figura 1.7: Skip list autenticata. E` indicato il verso di percorrenza del flusso delle informazioni in un cammino.

In Figura 1.7 ´emostrata una skip list autenticata, dove ogni elemento in ogni lista ´eun nodo del grafo ed ´ecaratterizzato da un’etichetta. Ogni etichetta `ecalcola- ta come composizione delle etichette dei nodi figli, il valore del basis ´erappresentato dall’etichetta del nodo root ((−∞,L3)). 10 CAPITOLO 1. CONTESTO E STATO DELL’ARTE

1.2.5 Authenticated skip list: calcolo della proof

Le proof per la verifica della presenza di un elemento e nella struttura si costruiscono con un processo del tutto simile a quello utilizzato nei Merkle hash tree. Dato un cammino T dal nodo (e,L0) alla radice (−∞,L3), si collezionano tutti i nodi che contribuiscono a tale cammino. Nota la funzione di hash, ´esempre possibile ricalcolare tutte le etichette dal nodo di partenza fino al basis. In 1.8 viene mostrato il cammino di computazione per l’elemento 19; i nodi che compongono la proof sono marcati con linee oblique. Per ottenere il fingerprint, ´e necessario ricalcolare le etichette dei nodi grigi fino al nodo radice.

Figura 1.8: Ricalcolo del basis. In grigio i nodi appartenenti al cammino scelto.

Come evidenziato in Figura 1.8, per il computo del basis non ´enecessario conoscere le etichette dei nodi appartenenti al cammino scelto.

1.3 Implementazione: linguaggi e tecnologie

L’implementazione scelta per le strutture dati autenticate si basa sulle authenticated skip list descritte in 4.2. L’implementazione si basa dunque su:

• la stessa struttura dati, che supporta interrogazioni e operazioni di inserimento, cancellazione e modifica;

• un algoritmo per il calcolo del basis;

• una proof e un algoritmo per la generazione della stessa quando associata a un’operazione; 1.3. IMPLEMENTAZIONE: LINGUAGGI E TECNOLOGIE 11

• un algoritmo per la verifica della validit`adell’operazione combinata alla proof da parte dell’applicazione client.

Il codice dell’architettura software e dei testcases per il testing dei componenti responsabili della verifica di integrit`adei dati ´einteramente scritto in linguaggio Python.

1.3.1 Python: caratteristiche e breve storia

Python ´estato inventato e reso pubblico da Guido Van Rossum, un matemati- co olandese, nel febbraio del 1991, con un messaggio pubblicato sul newsgroup alt.sources [Pyt91]. Sulla scelta di Python come linguaggio e dunque strumento principale di sviluppo hanno pesato alcune delle sue pi`uimportanti caratteristiche:

• orientabilit`aagli oggetti: Python supporta ereditariet`a,polimorfismo e incapsulamento in modo semplice e intuitivo;

• semplcit`ad’uso: opera a un alto livello di astrazione e la sua sintassi `ebasata su poche semplici regole;

• potenza e velocit`a: l’implementazione prevede che il codice venga byte- compilato prima della sua esecuzione; in molte situazioni, specialmente quelle che coinvolgono operazioni matematiche con tipi di dati numerici si ´edi- mostrata pi`uveloce di Java e leggermente pi`ulenta di C (i risultati dei test prestazionali sono mostrati in 1.1 e 1.9);

• portabilit`a: scritto in linguaggio ANSI C, l’interprete CPython pu`oessere compilato su tutte le architetture fornite di un compilatore in grado di sup- portare lo standard C-89. E` installato in modo predefinito sulle maggiori dis- tribuzioni GNU/Linux (e.g. Debian, Ubuntu, Fedora) e sulle pi`uimportanti incarnazioni moderne di UNIX come Oracle Solaris e Mac OS X, nonch`esulle diverse varianti della famiglia BSD.

Pi`uapprofondite analisi su comparazioni prestazionali del linguaggio prestazionale si consulti [pyt09]. 12 CAPITOLO 1. CONTESTO E STATO DELL’ARTE

Factorial computatation Java .NET Python Squeak 4 Mono 10.000! 343 ms 137 ms 91 ms 1.200 ms 169 ms 20.000! 1.480 ms 569 ms 372 ms 1.457 ms 701 ms 30.000! 3.424 ms 1.243 ms 836 ms 3.360 ms 1.675 ms 40.000! 6.340 ms 2.101 ms 1.975 ms 6.738 ms 3.042 ms 50.000! 10.493 ms 3.763 ms 3.658 ms 10.019 ms 5.242 ms 60.000! 15.586 ms 7.683 ms 5.788 ms 14.241 ms 10.000 ms Tabella 1.1: Prestazioni: Python si dimostra estremamente veloce con il calcolo su interi long

Figura 1.9: Analisi prestazionale

1.3.2 Testing: Python unittest

Il framework di testing sviluppato dal candidato si basa sul framework fornito di default dal linguaggio: unittest. Tale framework, conosciuto anche come PyUnit deriva dalla popolare suite di testing per Java JUnit, che a sua volta affondava le sue radici nella libreria di testing fornita con il linguaggio Smalltalk.

Insieme a PyUnit, per motivi di praticit`anella scrittura dei test ´estato inoltre utilizzato il framework Nose [nos].

Nose facilita la scrittura di test cases grazie a un intelligente sistema di dis- covering dei metodi di test. Nose consente inoltre una gestione trasparente delle fixtures e dei scenari di test, agevolando la selezione di quest’ultimi in base a criteri di raggruppamento secondo criteri prestabiliti.

1.4 Obiettivi previsti

Gli obiettivi del progetto erano:

• fornire agli sviluppatori di FileRock un framework per il testing del codice Python di facile utilizzo specifico per le problematiche pi`ucomuni; 1.4. OBIETTIVI PREVISTI 13

• collaudare i componenti software responsabili della verifica di integrit`adei dati.

Entrambi gli obiettivi sono stati raggiunti nei limiti di tempo e risorse presta- bilite. 14 CAPITOLO 1. CONTESTO E STATO DELL’ARTE Capitolo 2

Analisi e progettazione

In questo capitolo vengono illustrati il processo decisionale e le strategie applicate durante le fasi di analisi e progettazione del componente software di ausilio ai test.

Verr`ainoltre esposto il risultato dello studio effettuato sugli argomenti riguardan- ti la teoria e le tecniche di validazione, verifica e garanzia di qualit`asulla base dei quali il candidato ha affrontato l’ampia casistica e le diverse tipologie di problemi durante lo sviluppo dei test cases.

2.1 Software testing come garanzia di qualit`a

In modo del tutto simile alla maggior parte dei processi fisici, un componente soft- ware riceve un insieme di dati di ingresso per elaborarli e produrre un insieme di dati di uscita. Qualsiasi attivit`afinalizzata alla valutazione delle caratteristiche di un programma o un sistema e alla verifica che i comportamenti degli stessi diano i risultati previsti rientra nella definizione di software testing [HH88]. ¯

Ci`oin cui un software differisce dagli altri sistemi fisici ´el’insieme solitamente molto ampio di modi in cui ´epossibile che esso fallisca; bench´eun software non risen- ta di difetti di fabbrica (molto spesso i difetti derivano da errori introdotti in fase di progettazione e non dalla scrittura del codice sorgente) n´edi altri fattori ambientali e di usura, cercare di prevedere tutti i possibili errori ´edi fatto impossibile [Pan99].

15 16 CAPITOLO 2. ANALISI E PROGETTAZIONE

2.2 Obiettivi e limitazioni del collaudo

Le attivit`adi testing sono considerate parti integranti dello sviluppo di un software: met`adelle risorse impiegate nello sviluppo vengono solitamente allocate a a pro- cedure di collaudo [Har00], le quali sono dunque generalmente riconducibili a due importanti scopi finali:

• verifica e validazione: in altre parole, validare che il software soddisfi i requisiti e le specifiche e verificare che lo faccia nel modo atteso;

• migliorare la qualit`a: la presenza di difetti rappresenta solo uno degli indici di qualit`adel software (correttezza), il collaudo si propone come obiettivo quello di valutare il software secondo un insieme di parametri.

2.2.1 Limiti del testing

La presenza di difetti nel software `estrettamente correlata alla sua complessit`a,la tabella 2.1 mostra l’ottima rappresentazione fornita da [BP84] dell’andamento del rapporto che intercorre fra le dimensioni (misurate in linee di codice) di un program- ma e la presenza di difetti.

N. di linee sorgenti totali binari totali sorgenti con errori binari con errori 0-50 53 258 3 49 51-100 107 70 16 25 101-150 80 26 20 13 151-200 56 13 19 7 201-250 34 1 12 1 251-300 14 1 9 0 301-350 7 1 4 1 351-400 9 0 7 0 >400 10 0 6 0 - Total 370 370 96 96 Tabella 2.1: Analisi della distribuzione degli errori in un progetto software di medie dimensioni

La presenza di bug in un software deriva dunque dalla complessit`astessa e non ´e direttamente correlata alle capacit`atecniche dei programmatori che ne hanno curato progettazione e implementazione. Per lo stesso motivo, scoprire i difetti ´ealtrettan- to difficile. Collaudare un sistema coprendo tutto l’insieme di dati accettabile dallo 2.3. VERIFICA E VALIDAZIONE 17 stesso ´eimpraticabile; si pu`oaverne la dimostrazione prendendo in considerazione un semplice programma sommatore a due operandi di numeri interi a 32 bit come oggetto del collaudo: significherebbe testare il funzionamento del sistema con 264 combinazioni, con grande dispendio di tempo e risorse [Pan99].

Un’ulteriore complicazione deriva dalla frequenza di aggiornamento del software: un test case scritto ed eseguito con successo durante le prime fasi di sviluppo potrebbe fallire in una successiva occasione a causa di modifiche introdotte nel codice sorgente. E` evidente che l’improvviso fallimento di un test case richiede un’indagine approfon- dita sia del codice del programma che dello stesso test: potrebbe essere necessario aggiornare il meccanismo di collaudo per renderlo conforme al nuovo comportamen- to del software. In alternativa, nel caso in cui l’errore non fosse n´enel codice n´e nei dati di input del test, bisogner`ariparare il difetto all’interno del programma. Infine, sar`anecessario eseguire nuovamente il test. E` evidente come tutte queste op- erazioni abbiano dei costi. Senza una strategia e degli strumenti di ausilio all’analisi dei requisiti e alla scrittura dei componenti di collaudo, tali costi possono diventare insostenibili.

2.3 Verifica e validazione

Verifica e validazione sono elementi fondamentali nel ciclo di vita di qualsiasi soft- ware. Lo sviluppo di un programma, un sistema complesso o anche un solo singolo componente unitario non pu`omai perdere di vista il suo obiettivo: soddisfare cor- rettamente un insieme definito di requisiti.

I concetti di validazione e verifica vengono talvolta confusi, per comprendere le sottili ma fondamentali differenze fra questi concetti ´epossibile ricorrere a diverse fonti in letteratura. Le definizioni formali pi`ulargamente diffuse e accettate sono fornite da [PCCW93]:

• la validazione ´e “il processo di valutazione del software, messo in atto paral- lelamente o alla fine del processo di sviluppo, allo scopo di determinare se lo stesso rispetti o meno i requisiti stabiliti”;

• la verifica ´e “il processo di valutazione del software atto a determinare se i prodotti di una certa fase di sviluppo soddisfino le condizioni iniziali”. 18 CAPITOLO 2. ANALISI E PROGETTAZIONE

Secondo [Boe89], verifica e validazione devono rispondere alle seguenti domande:

• validazione: “stiamo sviluppando il prodotto corretto?”;

• verifica: “il prodotto che stiamo sviluppando `ecorretto?”.

2.3.1 Tecniche di verifica

Esiste una vasta letteratura sui numerosi approcci e le tecniche di verifica. La prima macro suddivisione si basa sulla natura stessa del tipo di collaudo, che pu`oessere statico o dinamico [Tra99]:

• lo static testing ´el’insieme di analisi e valutazioni compiute senza la necessit`a di eseguire il software oggetto di collaudo. Esempi di attivit`astatiche sono la verifica formale e l’analisi metrica del codice sorgente;

• per dynamic testing si intendono tutte le procedure eseguite a sistema gi`a avviato; tipicamente tali attivit`acoinvolgono la comparazione di risultati attesi con quelli ottenuti a partire da un certo insieme di dati di input introdotti nel sistema.

Le metodologie statiche possono essere suddivise in due categorie [Tra99]:

• verifiche di coerenza: alcuni esempi sono le verifiche di sintassi, tipizzazione e corrispondenza dei parametri fra procedure diverse;

• tecniche di misurazione: includono verifiche di leggibilit`adel codice e livelli di struttura [And86].

Gli approcci dinamici al collaudo vengono tipicamente suddivisi in tre grandi categorie [Tra99]:

• testing funzionale: vengono identificate e collaudate le funzionalit`apreviste dalle specifiche; il classico esempio di test funzionale ´enoto come collaudo a scatola nera;

• testing strutturale: viene collaudato il funzionamento interno del software; questo prevede una conoscenza totale della sua architettura e delle scelte im- plementative e di design; il tipico esempio di test strutturale ´eil collaudo a scatola bianca; 2.3. VERIFICA E VALIDAZIONE 19

• testing casuale: prevede l’esecuzione di un numero di casi di test selezionati, con l’ausilio di un algoritmo pseudocasuale, tra quelli facenti parte di una determinata collezione.

E` da notare che la strategia in grado di coprire tutte le possibili combinazioni dei dati di input, nome come collaudo esaustivo, non ´ealtro che un caso particolare di collaudo casuale. Bench´etale strategia consenta di verificare in modo completo il corretto funzionamento di un sistema, nella grande maggioranza dei casi tale scopo `eimpossibile da raggiungere [And86].

2.3.2 Test fixture e oggetti fittizi

Tipicamente, prima di avviare una sessione di collaudo, si rende necessario configu- rare un contesto all’interno del quale verranno eseguiti i test: tale contesto prende il nome di test fixture.

Una test fixture rappresenta dunque un insieme di dati e operazioni da eseguire per portare il sistema sottoposto a collaudo a un determinato stato iniziale. Alcuni esempi di test fixture seguono:

• inizializzazione del file system, con creazione, copia o spostamento di file o cartelle all’interno di percorsi predefiniti;

• inizializzazione di database con predefiniti valori iniziali;

• cancellazione di file, cartelle o interi filesystem;

• inizializzazione di componenti software esterni, necessari al corretto svolgi- mento dei test; il comportamento di alcuni di questi possono essere emulati attraverso l’utilizzo di oggetti fittizi.

Gli oggetti fittizi, altres`ınoti come mock, sono utilizzati per simulare il funzion- amento di singoli componenti o intere architetture software che non fanno parte degli obiettivi del collaudo; tali oggetti sono frequentemente utilizzati nel test unitario, dove le operazioni di collaudo si concentrano su singole unit`apseudo-atomiche, allo scopo di ridurre al minimo le interferenze esterne. 20 CAPITOLO 2. ANALISI E PROGETTAZIONE

2.3.3 Tecniche di validazione

Tipicamente la validazione avviene una volta completata una fase di sviluppo al fine proprio di determinare se il prodotto rispetta le specifiche iniziali. Esiste una vasta letteratura anche sulle metodologie e le tecniche di validazione [Tra99], alcune di queste vengono discusse di seguito:

• analisi formale: utilizzo di espressioni logico-matematiche per formalizzare, analizzare e indagare le specifiche, il progetto, la documentazione e il compor- tamento del sistema;

• induzione di guasti: introduzione intenzionale di errori al fine di analizzare il comportamento del sistema; possono essere guasti di tipo fisico o software;

• analisi di affidabilit`a: contempla metodi per l’identificazione e la ricerca di criticit`ae rischi all’interno del sistema [Kop11].

2.3.4 Verifica e validazione in FileRock

Nell’ambito del progetto FileRock il candidato si `eavvalso di una serie di tecniche di V&V allo scopo di verificare il corretto funzionamento del sistema.

Le attivit`aprincipali sono state finalizzate al testing dinamico: scrittura di test cases, generazione dati di input, collezione e raggruppamento dei risultati per casi d’uso. Il software in oggetto `estato sottoposto a collaudo con entrambi gli approcci di testing white box e black box. Si `evoluto inoltre adottare l’approccio di fault in- jection che, insieme a delle procedure di random testing per la generazione di dati di input pseudo casuali, ha permesso di valutare e correggere la gestione delle eccezioni da parte del sistema.

Come strumento di analisi formale ´estato utilizzato pylint [pyl]. Tale software esegue controlli di coerenza sintattica e conformit`adel codice allo standard PEP- 8 [pep] del linguaggio Python e supporta la generazione di diagrammi nel linguaggio UML. 2.4. GARANZIA DI QUALITA` 21

2.4 Garanzia di qualit`a

Innumerevoli soggetti pubblici e privati affidano le proprie funzioni a complesse ar- chitetture software. Numerosi di questi soggetti si occupano delle persone e dei loro interessi, della loro salute o risorse, molti altri si occupano di telecomunicazioni o trasporti, altri ancora di questioni di difesa nazionale. Le attivit`alavorative e i risultati di numerosi enti, societ`ae persone dipendono dalle caratteristiche di cor- rettezza e predicibilit`a del software che essi utilizzano [GW08]. Un software difettoso pu`operci`oavere conseguenze estremamente gravi per i propri utenti. Le tecniche di verifica e validazione analizzate in 3.3 vengono solitamente affiancate a procedure mirate ad assicurare che il prodotto software finale risponda a criteri di qualit`a.

2.4.1 Definizioni

Dopo circa settanta anni la prima storica formalizzazione del concetto di qualit`a fornita da [She31], l’Organizzazione Internazionale per la Normazione ha applicato quest’ultimo all’ingegneria del software, ridefinendolo come un misura della “confor- mit`adel prodotto software ai requisiti” [iso99, iso10]. Tale definizione non rappre- senta per tutti la descrizione pi`uappropriata, poich´ea seconda della prospettiva e dei parametri presi in considerazione la sola conformit`astretta alle specifiche iniziali pu`onon essere sufficiente a garantire un funzionamento del software soddisfacente.

In [KP96, Gar88] vengono proposte cinque diversi approcci alla definizione for- male di software quality, ognuno di questi prende in considerazione una prospettiva diversa:

• l’utente finale `einteressato che il prodotto funzioni correttamente in un dato numero di contesti. Si tratta di una prospettiva pi`upragmatica, il prodotto `estato progettato e prodotto per soddisfare una particolare necessit`adei suoi utilizzatori;

• il produttore si occupa di verificare che il prodotto finale rispetti dei requisiti di qualit`a; standard internazionali come [iso99] mettono in risalto tali requisiti;

• la qualit`adel prodotto pu`oessere considerata e valutata attraverso la mis- urazione delle caratteristiche intrinseche del prodotto stesso; 22 CAPITOLO 2. ANALISI E PROGETTAZIONE

• il valore trascendentale della qualit`ariguarda gli aspetti utopici del con- cetto stesso, come un obiettivo ideale a cui si deve sempre tendere, sempre consapevoli della reale impossibilit`adi raggiungerlo [KP96];

• con una prospettiva mirata al profitto si realizza come i diversi approcci alla assicurazione di qualit`apossano assumere un’importanza diversa a seconda dei contesti.

Un’interessante definizione viene fornita da [JG88]: “La parola qualit`aha diver- si significati. Due di questi predominano sugli altri: 1. la qualit`aconsiste in quelle caratteristiche dei prodotti che soddisfano le necessit`adei clienti, producendo dunque soddisfazione verso il prodotto stesso 2. la qualit`aconsiste nell’assenza di deficien- ze. Tuttavia, in un libro tascabile come questo, `ecomodo ricorrere a una definizione abbreviata della parola qualit`a:idoneit`aall’uso”.

In [DeM99] la qualit`adi un prodotto viene definita in funzione di “quanto il prodotto contribuisce a rendere il mondo un posto migliore”.

2.4.2 Indicatori di qualit`ae obiettivi

L’obiettivo principale della software quality assurance `edunque garantire che il prodotto finale soddisfi i requisiti e rispetti le specifiche.

Struttura, classificazione e terminologia degli indicatori di qualit`ae delle tec- niche applicate alla valutazione degli stessi derivano da [iso03, iso05]. Di seguito verranno brevemente illustrate le cinque caratteristiche fondamentali, indici di qual- it`adel software, prese in considerazione dal candidato durante le fasi di analisi e progettazione degli strumenti di collaudo automatici:

• efficienza: meno risorse vengono utilizzate e maggiore `el’efficienza; le risorse vengono tipicamente espresse in termini di tempo di utilizzo della CPU e spazio di memoria necessari al software per operare;

• affidabilit`a: minore `ela frequenza di guasti, maggiore `el’affidabilit`adi un software; talvolta si basa sulla misura del mean time between failures, ovvero il valore atteso ti tempo che intercorre fra due guasti correlati successivi [Jon87] altro fattore importante `erappresentato dalla capacit`adi reazione ai guasti di un sistema; 2.4. GARANZIA DI QUALITA` 23

• sicurezza: si riferisce alle politiche di controllo degli accessi messe in atto dal sistema al fine di evitare intrusioni indesiderate;

• manutenibilit`a: un codice ben strutturato e un’architettura modulare forma- ta da entit`alogiche coerentemente raggruppate si dimostra tipicamente facile da mantenere, estendere e correggere.

In 2.1 [qua] viene mostrato l’albero delle dipendenze che intercorrono fra i prin- cipali indicatori di qualit`ae le rispettive caratteristiche misurabili.

Figura 2.1: Sulla sinistra gli attributi oggetti delle misurazioni, a destra le caratteristiche di qualit`a

2.4.3 Garanzia di qualit`ain FileRock

L’attivit`aprincipale atta a garantire la conformit`adel software alle specifiche `estata l’analisi di copertura del codice. 24 CAPITOLO 2. ANALISI E PROGETTAZIONE

L’analisi di copertura `euna misurazione effettuata sul codice sorgente a collaudo terminato al fine di quantificare la porzione di codice effettivamente controllata dai test. I criteri generali pi`ucomuni per verificare la copertura dei test sono elencati di seguito:

• statement coverage: per ogni linea, indica il numero di volte che `estata effettivamente eseguita;

• function coverage: indica la frequenza di esecuzione di ogni routine o fun- zione;

• branch coverage: per ogni istruzione di controllo if...else indica se tutte le possibilit`asono state esplorate o meno;

• condition coverage: per ogni istruzione if...else indica se l’istruzione booleana di entrata del controllo `estata valutata per entrambi i casi vero e falso

• multiple condition coverage: per ogni istruzione if...else indica se la tavola di verit`adella condizione di entrata del blocco `estata completamente valutata.

Per valutare la copertura dei test in FileRock il candidato ha adottato Nose [nos] e il modulo coverage [cov]. L’adozione di Nose ha inoltre facilitato l’adozione di strategie di esecuzione automatica dei test; il supporto all’automazione verr`adiscus- so nei successivi capitoli.

2.5 Analisi: scenario iniziale

La prima operazione svolta all’inizio dei lavori `estata effettuare un’approfondita analisi del codice sorgente del componente software responsabile della gestione delle strutture dati autenticate utilizzate all’interno del progetto per la memorizzazione dei dati dell’utente.

2.5.1 Struttura

Il progetto `esuddiviso in diversi moduli principali, vengono elencati di seguito solo quelli oggetto del presente lavoro: 2.5. ANALISI: SCENARIO INIZIALE 25

• server: componente lato server del servizio; incapsula la parte dell’implemen- tazione dell’algoritmo di integrit`ache gestisce la persistenza delle strutture dati autenticate;

• client: codice relativo all’applicazione client; contiene il componente lato client del meccanismo di verifica dell’integrit`anecessario all’utente per sincronizzare i dati in locale con la controparte remota, gestita dal server;

• librerie condivise: codice condiviso da entrambi i sopra elencati componenti, gestito in modo indipendente al fine di evitare fenomeni di duplicazione del codice.

Dopo un primo studio del funzionamento del sistema, il candidato ha testato il meccanismo di integrit`amanualmente al fine di aumentare il livello di confidenza con il codice. Durante questa prima fase, le caratteristiche di introspezione e la semplicit`adi sintassi del linguaggio Python si sono rivelate estremamente utili ai fini della comprensione.

2.5.2 Analisi delle criticit`ae piano di lavoro

Fin dalle primissime fasi del lavoro, si `erivelata evidente la necessit`adi avere a dis- posizione un collezione di metodi e oggetti per la generazione dei dati di ingresso a partire da un insieme di file e directory, appositamente selezionati dall’utente prima dell’esecuzione dei test. A tal fine `estato progettato l’oggetto Dataset il quale, a partire da una porzione di filesystem, genera un insieme di richieste e operazioni da effettuare sulle strutture dati autenticate. I dettagli implementativi e le scelte progettuali verranno dettagliatamente descritte nel capitolo successivo.

Insieme al componente di generazione dei dati di input, `estato progettato e implementato un meccanismo di caricamento dinamico di fixture da file di configu- razione; ci`oha consentito di personalizzare l’esecuzione automatica dei test grazie all’ausilio di profili che potevano essere generati manualmente o via script. Inizial- mente si era pensato di utilizzare il linguaggio JavaScript Object Notation [Cro06] come formato per i file di configurazione; il candidato ha optato per il formato INI- style per ragioni di convenienza e semplicit`a[kis]. 26 CAPITOLO 2. ANALISI E PROGETTAZIONE

Per monitorare l’avanzamento dei lavori e consentire agli sviluppatori del proget- to di eseguire regolarmente le sessioni di collaudo `estato progettato un test runner per il lancio sequenziale delle suite di test e le successive fasi di raccolta e presen- tazione dei risultati. L’analisi dei requisiti ha evidenziato la necessit`adi caratter- istiche di interoperabilit`acon il software Nose, scelto come pilota nei processi di esecuzione automatica grazie alla presenza di un meccanismo di autodiscovering dei casi e delle suite di test.

Parallelamente allo sviluppo degli strumenti di automazione del collaudo, si `e proceduto alla scrittura dei primi test unitari, aventi come obiettivo principale quel- lo di garantire la correttezza delle operazioni svolte dai singoli oggetti e metodi presenti nelle librerie condivise del progetto. Una prima struttura gerarchica del filesystem prevedeva la suddivisione in cartelle dei casi di test secondo le tipologie di approccio dinamico. In una successiva fase di analisi, per ragioni di convenienza e coerenza, si `epreferito classificare i test case secondo i componenti sottoposti a collaudo, fatta eccezione per quelle particolari tipologie di collaudo che prevedevano l’interazione fra molteplici componenti (test di interazione e smoke test).

2.6 Debian packaging e integrazione in Ubuntu

Il candidato si `eoccupato di risolvere un’incompatibilit`afra wxWdigets [wxw], le librerie grafiche utilizzate per lo sviluppo dell’applicazione client di FileRock, e Uni- ty [uni], l’interfaccia grafica del sistema operativo Ubuntu [ubua], la quale causava alcuni problemi nell’integrazione del client nell’esperienza utente globale fornita dal sistema sponsorizzato dalla nota derivata di Debian [debb].

Infine, grazie all’esperienza maturata negli anni come Debian Developer [deba] e Ubuntu Core Developer [ubub], il candidato ha potuto curato con successo la pac- chettizzazione dell’applicazione client di FileRock per Debian e derivate. Capitolo 3

Realizzazione del software

In questo capitolo sono illustrate le fasi di progettazione e realizzazione del software di ausilio ai test del meccanismo di verifica dell’integrit`adei dati.

Vengono accuratamente descritti lo sviluppo e il funzionamento degli oggetti e delle funzioni che compongono l’architettura di quality assurance prodotta dal can- didato durante l’esperienza come ingegnere software per FileRock.

Inoltre, alla fine del presente capitolo, sono state inseriti riferimenti ed alcune nozioni relative al lavoro di pacchettizzazione dell’applicazione client per distribuzioni Debian e derivate.

3.1 Casistiche e tipologie di test

A differenti problematiche corrispondono differenti approcci e tipologie di test, alcuni dei pi`ucomuni livelli e tipi di collaudo vengono elencati di seguito:

• unit test o test unitario: metodo di collaudo che si focalizza su singoli compo- nenti o sottosistemi di ridotte dimensioni dell’architettura software;

• functional testing o test funzionale: si concentra sulla verifica e validazione di una specifica funzionalit`adel codice;

• integration testing o test di integrazione: metodologie di collaudo atte a verifi- care che le interfacce utilizzate dai vari componenti di un sistema e l’interazione fra le stesse soddisfino i requisiti delle specifiche;

27 28 CAPITOLO 3. REALIZZAZIONE DEL SOFTWARE

• performance testing o collaudo prestazionale: comprende misurazioni e tec- niche atte a valutare le prestazioni del software;

• regression testing o collaudo di regressione: lo scopo principale `equello di verifi- care il corretto funzionamento di molteplici aree di un sistema successivamente all’introduzione di cambiamenti rilevanti.

Le tecniche e gli strumenti per l’automazione delle sessioni di collaudo verranno affrontate nei paragrafi successivi. I dettagli delle tipologie di test affrontate dal candidato vengono descritte di seguito.

3.1.1 Test unitario

Il test unitario `estata un’attivit`ache ha richiesto notevole cura, da parte del can- didato, nelle diverse fasi di sviluppo; la risoluzione di problemi quali la duplicazione del codice, il disaccoppiamento della logica dai dati e la progettazione dei dati di input ha richiesto numerose ore di analisi e scrittura di codice.

Il testing modulare comprende funzioni, casi d’uso, procedure e dati di input con l’unico fine di verificare il corretto funzionamento di una o pi`uparti atomiche del software [KH07]. Mentre nella programmazione modulare tali unit`asono associate a funzioni o moduli, nella programmazione orientata agli oggetti si fa solitamente riferimento a classi, oggetti e interfacce.

In FileRock, il candidato ha sottoposto a collaudo ogni singola funzionalit`aoffer- ta dalle classi che compongono il sotto sistema di verifica dell’integrit`a,organizzando e suddividendo i moduli di test seguendo la stessa convenzione dei nomi utilizzati dagli stessi moduli in sottoposti a collaudo. Un esempio di codice estratto dalla test suite `emostrato di seguito: 3.1. CASISTICHE E TIPOLOGIE DI TEST 29 def test_CorruptedLeaf(self): hashset = [(u’nonexistant_file0000’, ’8eec5e665c8b14757cec6d1a7460c00e’)] self.empty_skiplist.updateSkipList(hashlist=hashset, recomputeBasis=False) leaf = self.empty_skiplist.leaves[u’nonexistant_file0000’] assert_is_not_none(leaf) leaf.filehash = None with assert_raises(UnexpectedBasisException): self.empty_skiplist.getBasis() Il codice del listato mostra un tipico esempio di fault injection. In una struttura dati inizializzata vuota, si inserisce un nuovo dato tra gli elementi foglia del grafo al fine di verificare il lancio di un’eccezione: il test ha successo se l’errore viene corret- tamente rilevato.

Il test unitario comporta diversi vantaggi:

• i test unitari consentono di scoprire difetti in anticipo;

• semplifica le modifiche e, insieme alle tecniche di collaudo di regressione, con- sente agli sviluppatori di eseguire il refactoring del codice con la certezza che i singoli moduli continueranno a funzionare;

• verificando che i singoli componenti funzionano correttamente, rende semplice l’integrazione fra gli stessi.

Tutti i componenti unitari del meccanismo di verifica di integrit`adei dati sono stati sottoposti a testing unitario.

3.1.2 Test funzionale

Il classico esempio di test funzionale `eil collaudo a scatola nera che, basandosi sulle specifiche del software, ha lo scopo di verificare le funzionalit`apreviste dalle stesse specifiche, tralasciando i meccanismi interni di funzionamento.Le funzionalit`a vengono collaudate con l’inserimento di un determinato insieme di dati di input, i risultati ottenuti vengono infine confrontati con i valori attesi.

La procedura seguita dal candidato durante la progettazione e lo sviluppo dei test case funzionali si pu`osuddividere principalmente in cinque fasi [Bor06]: 30 CAPITOLO 3. REALIZZAZIONE DEL SOFTWARE

• ricerca e identificazione delle funzionalit`aall’interno delle specifiche;

• progettazione dei dati di input a partire dalle specifiche;

• determinazione dei risultati attesi;

• esecuzione di codice di test;

• comparazione dei risultati con i valori attesi.

L’inserimento di un nuovo elemento in una struttura dati autenticata rientra nei casi d’uso pi`ufrequenti considerati durante il collaudo. La seguente funzione di test, estratta dal codice prodotto dal candidato, mostra un esempio di test funzionale; si noti che si occupa di collaudare entrambi i componenti lato server e client, senza necessariamente stabilire una connessione di rete fra gli stessi al fine di trascurare eventuali problemi di rete che potrebbero inficiare i risultati dei test: def test_RandomInsertPathnames(self): basis_zero = self.server.adsmanager.getCurrentBasis() assert_not_equals(basis_zero, EMPTY_BASIS) assert_true(self.client.intmanager.isCurrent(basis_zero)) for i in xrange(int(self.dataset_random_insert_nitems)): pathname, filehash = self.dataset_random.random_insert_pathname() pathname = pathname.decode(’utf-8’) # The client asks the server for the proof proof = self.server.adsmanager.getUpdateProof(pathname, ’INSERT’) # The client adds the operation self.client.intmanager.addOperation(’UPLOAD’, pathname=pathname, proof=proof, filehash=filehash) # Update server’s skiplist new_basis = self.server.adsmanager.update([(pathname, filehash)]) assert_equals(new_basis, self.server.skiplist.getBasis()) # Commit on client self.client.intmanager.checkCommitResult(new_basis) # Check everything’s gone fine assert_true(self.client.intmanager.isCurrent(new_basis)) new_basis = self.server.adsmanager.getCurrentBasis() 3.1. CASISTICHE E TIPOLOGIE DI TEST 31

assert_not_equals(new_basis, EMPTY_BASIS) assert_true(self.client.intmanager.isCurrent(new_basis))

Inizializzata una struttura dati con un determinato insieme di input, il test in- serisce un numero pseudo-casuale di nuovi elementi e verifica il nuovo valore del basis alla fine di ogni operazione. Prima di terminare verifica l’uguaglianza tra i valori finali dei basis memorizzati dal client e dal server.

3.1.3 Test di integrazione

L’accentuata modularit`adell’intero meccanismo di verifica dell’integrit`aha reso nec- essaria l’adozione di tecniche e metodologie atte a verificare la correttezza delle interazioni fra i singoli componenti; la natura distribuita dell’architettura ha reso prioritaria la garanzia del corretto comportamento delle entit`acostituenti il sistema di gestione delle strutture dati autenticate.

I test di integrazione sono una logica continuazione dei test unitari e si possono individuare diversi approcci alla loro progettazione [Bin99], i pi`ucomuni sono top down, bottom up, sandwich e big bang:

• l’approccio top down prevede che i componenti ad alto livello vengano sotto- posti a collaudo prima di quelli ai livelli pi`ubassi. Tale approccio permette di ignorare gli aspetti implementativi di basso livello ma richiede un diffuso utilizzo di oggetti fittizi;

• con le tecniche bottom up sono i moduli a basso livello a venire collaudati per primi. Ne consegue la necessit`adi priorizzare l’esecuzione dei test unitari, che vanno eseguiti prima dei test di integrazione;

• la tecnica sandwich `euna combinazione dei due precedenti approcci;

• se la copertura del codice dei test unitari `epressoch´etotale, si pu`oricorrere anche all’approccio big bang, il quale prevede il collaudo di tutte le interazio- ni del sistema. Tale soluzione richiede un massiccio collaudo unitario e pu`o aumentare la complessit`adi gestione dei piani di test.

Considerato l’alto rapporto fra il tasso di copertura del codice da parte dei test unitari e il numero di interazioni fra i moduli del componente di verifica dell’integrit`a 32 CAPITOLO 3. REALIZZAZIONE DEL SOFTWARE dei dati, il candidato ha optato per l’approccio bottom up. Quello che segue `eun esempio di test di integrazione estratto dal codice del progetto:

def test_RenamePathname(self): old_basis = self.server.adsmanager.getCurrentBasis() assert_not_equals(EMPTY_BASIS, old_basis) # Rename a pathname in the Dataset object oldp, newp, filehash = self.dataset_random.random_rename_pathname() oldp = oldp.decode(’utf-8’) newp = newp.decode(’utf-8’) # The new hashset needs to be filled with the couple # containing the information about the path removed hashset = self.dataset_random.tohashset() hashset.append((oldp, None)) # Check if oldpathname exists proof_rm = self.server.adsmanager.getIntegrityProof(oldp, ’DELETE’) # Check the newpathname does not exists proof_new = self.server.adsmanager.getIntegrityProof(newp, ’INSERT’) assert_not_equals(proof_rm, proof_new) # Append delete-and-insert operations self.client.intmanager.addOperation(’DELETE’, pathname=oldp, proof=proof_rm, filehash=None) self.client.intmanager.addOperation(’INSERT’, pathname=newp, proof=proof_new, filehash=filehash) # Update the ADS hold by the server new_basis = self.server.adsmanager.update(hashset) assert_not_equals(old_basis, new_basis) # Commit on client (and do checks, of course) self.client.intmanager.checkCommitResult(new_basis) 3.2. MODELLO E GENERAZIONE DATI DI INPUT 33

# Check whether the basis match assert_true(self.client.intmanager.isCurrent(new_basis))

Il codice di test esegue un’operazione di rinomina su un elemento presente nella struttura dati: il client richiede una serie di operazioni che, in ordine, prevedono la cancellazione dell’elemento e il nuovo inserimento. Alla fine delle operazioni viene verificata la coerenza della struttura dati.

3.2 Modello e generazione dati di input

Alcuni dei casi di test definiti in fase di progettazione richiedevano che la struttura dati in fase di collaudo si trovasse in un particolare stato prima dell’avvio delle pro- cedure di collaudo. Vi era perci`ol’esigenza di progettare una nuova entit`acapace di incapsulare un insieme di elementi da caricare nelle strutture ADS prima del- l’esecuzione del codice di test; tale nuova entit`asarebbe dovuta essere di facilmente riutilizzabile dagli altri sviluppatori nella scrittura dei test.

3.2.1 Oggetti Dataset per l’incapsulamento del filesystem

Il candidato ha affrontato e risolto tale problematica con lo sviluppo della classe Dataset, dotata di caratteristiche di incapsulamento delle pi`ucomuni operazioni primitive su file e directory e gestione della loro rappresentazione nel formato richiesto dalle specifiche delle strutture dati autenticate. Scendendo a un maggior livello di dettaglio, Dataset consente di agire sul file system con le seguenti operazioni:

• creazione, rinomina e cancellazione di file e directory;

• interrogazioni in lettura (i.e. lettura dei contenuti delle directory);

• aggiornamenti in scrittura (i.e. modifiche dei contenuti dei file).

Gli oggetti di tale tipo sono in grado di fornire una rappresentazione dei propri contenuti nel formato (supportato in modo nativo dal componen- ti di verifica dell’integrit`a); tale caratteristica `estata progettata al fine di facilitare l’inserimento dei dati nelle strutture vuote operata dal codice di inizializzazione dei casi di test. 34 CAPITOLO 3. REALIZZAZIONE DEL SOFTWARE

3.2.2 Generazione dati casuali

La generazione di dati pseudo casuali si `erivelata utile in alcuni scenari di collaudo: la classe DatasetRandom estende la classe Dataset e fornisce delle utili funzional- it`aaggiuntive di interrogazione e generazione di dati successivamente utilizzati nelle procedure di inizializzazione dei test.

Entrambi le classi Dataset e DatasetRandom sono state ampiamente utilizzate durante lo sviluppo della maggior parte dei casi di test e il relativo codice `estato anch’esso sottoposto a collaudo: gli stessi approcci di verifica, validazione e collau- do utilizzati per il codice di FileRock sono stati applicati anche a queste entit`adi appoggio.

3.3 Supporto all’automazione

Uno degli obiettivi previsti era la semplificazione delle procedure di lancio dei moduli di test. Un’altra esigenza riguardava l’utilizzo di dati di input custom e la possibilit`a di eseguire pi`uvolte e in momenti diversi gli stessi test partendo da configurazioni fornite manualmente dallo sviluppatore o da uno script automatico.

3.3.1 Caricamento dei dati di input da file di configurazione

Il candidato ha prodotto una procedura automatica per il caricamento di valori predefiniti (preset) a tempo di esecuzione dei casi di test sfruttando la libreria e le caratteristiche di introspezione fornite dal linguaggio Python. Durante l’avvio e l’inizializzazione di un modulo di test, grazie a tale procedura, `estato possibile personalizzare il codice con il caricamento di configurazioni personalizzate da file di configurazione conformi al formato INI.

Un file di configurazione INI `esolitamente composto da coppie chiave-valore rag- gruppate in sezioni. Un contenuto di esempio `emostrato di seguito:

[globals] random_iter_n = 30 3.3. SUPPORTO ALL’AUTOMAZIONE 35

[test_OpsOnEmptyADS] dataset_root = . dataset_random_root = . dataset_random_seed = 1239782

[test_OpsOnNonEmptyADS] dataset_root = . dataset_random_root = . dataset_random_seed = 1239782 dataset_random_insert_nitems = 10

Prima della dichiarazione di classi e oggetti globali i moduli di test contengono una chiamata alla funzione init config(), la quale accetta come unico parametro una stringa rappresentativa del nome del modulo e inizializza automaticamente i valori delle variabili globali elencate nella sezione speciale globals del rispettivo file di configurazione.

Ogni classe di test contiene nel proprio inizializzatore una chiamata al metodo load testcase config() e passa come unico parametro il riferimento all’istanza cor- rente. Fatta eccezione per globals, ogni sezione nel file di configurazione rappresenta i valori iniziali delle variabili utilizzate dalle fixture dei rispettivi metodi di test; ´e possibile non specificare nessun valore per i metodi, in tal caso non viene impostato alcun valore predefinito.

Tale meccanismo ha consentito agli sviluppatori di rieseguire gli stessi metodi di collaudo con valori di input diversi, senza dover necessariamente introdurre modi- fiche al codice.

3.3.2 Script di esecuzione automatica

Tra le responsabilit`adel candidato vi era anche lo sviluppo di un test runner, ovvero di un componente software per il controllo dell’esecuzione automatica del codice di test. Per soddisfare i requisiti, il candidato ha progettato e implementato un controllore Python di esecuzione dei test fornito delle seguenti caratteristiche:

• selezione e raggruppamento dei casi di test in suite attraverso il pilotaggio di Nose; 36 CAPITOLO 3. REALIZZAZIONE DEL SOFTWARE

• gestione del contesto attraverso l’inizializzazione dei dati di input e il cari- camento delle procedure di avvio dei casi di test;

• raccolta e presentazione dei risultati delle operazioni di collaudo e statis- tiche sulla copertura del codice.

L’ultima caratteristica `estata sviluppata grazie all’utilizzo di coverage, un plugin facilmente integrabile con Nose. Il prodotto finale `einoltre fornito di un’interfaccia a riga di comando conforme all’estensione GNU [FSF] dello standard POSIX.1- 2008 [pos08].

3.4 Integrazione in Debian e Ubuntu

Una volta raggiunto l’obiettivo previsto dal piano originale di lavoro, il candidato ha curato l’integrazione dell’applicazione client di FileRock con Unity, l’interfaccia grafica predefinita del sistema operativo Ubuntu. Infine, il candidato ha curato il la- voro di pacchettizzazione della medesima applicazione per sistemi Debian e derivate.

3.4.1 Integrazione in Unity

L’interfaccia dell’applicazione client di FileRock `esviluppata con le librerie grafiche multi piattaforma wxWidgets e consiste principalmente in un’icona visibile nella barra delle applicazioni, la quale consente all’utente di accedere alle diverse opzioni di configurazione del proprio account e dell’applicazione stessa. Durante le fasi di collaudo del client grafico su diversi sistemi operativi, gli sviluppatori del progetto si accorsero di un comportamento inatteso da parte del programma quando eseguito su sistemi Ubuntu.

Ubuntu `eun sistema operativo free e open basato su Debian e sul kernel GNU/Linux, sviluppato dalla Comunit`adi Ubuntu con il sostegno strategico e eco- nomico di Canonical, una societ`abritannica con sede nell’Isola di Man e la sua in- terfaccia predefinita, Unity, `ebasata sulla versione pi`urecente delle librerie grafiche GTK+.

Fin dalle prime fasi di analisi del problema, il candidato ha identificato la causa del difetto nell’incompatibilit`adell’applicazione con il protocollo Application indi- 3.4. INTEGRAZIONE IN DEBIAN E UBUNTU 37 cator [app]. Grazie all’esperienza maturata negli anni precedenti nell’ambito dello stesso progetto Ubuntu, in qualit`adi Ubuntu Core Developer [ubub], il candidato ha risolto il difetto introducendo alcune modifiche nel codice atte ad aggirare le lim- itazioni imposte dall’interfaccia Unity.

3.4.2 Debian packaging

Per agevolare la distribuzione del software e aumentare la sua visibilit`agli sviluppa- tori del software si sono avvalsi della consulenza del candidato, gi`asviluppatore [ale] e membro ufficiale del progetto Debian [debb].

L’introduzione di un nuovo pacchetto all’interno del parco software di Debian avviene attraverso una rigorosa procedura di revisione approfonditamente descritta nella policy del progetto [JS]. Il software deve risponde a delle specifiche di sicurezza e di licenza che possono essere riassunte nei seguenti punti chiave:

• deve essere funzionante;

• non deve contenere codice malevole ed essere rispettoso dei dati degli utenti e della loro riservatezza;

• deve essere liberamente redistribuibile in qualsiasi forma e conforme a le Linee Guida Debian per il Software Libero [Debc];

Il candidato ha proceduto seguendo la procedura prevista dalla policy:

• segnalazione del bug di tipo Intent To Package [filb];

• scrittura del codice e dei meta dati per la compilazione e l’installazione del software.

Terminata la fase iniziale del lavoro, il pacchetto sorgente `estato caricato e man- tenuto aggiornato con il codice del progetto upstream su un archivio remoto [Tre] attraverso l’ausilio del sistema di controllo di versione distribuito Git.

Il candidato ha migliorato l’integrazione dell’applicazione client di FileRock con il resto dei programmi e delle librerie fornite da Debian con la produzione di un’in- sieme di patch presenti anch’esse sull’archivio remoto contenente il pacchetto. Tali patch vengono applicate automaticamente a tempo di compilazione del software dal 38 CAPITOLO 3. REALIZZAZIONE DEL SOFTWARE gestore Quilt, che ne semplifica la gestione e consente il tracciamento delle modifiche apportate a ogni nuova revisione [qui]. Capitolo 4

Conclusioni

Questo capitolo aggiunge le considerazioni finali del candidato sul lavoro svolto e dei possibili scenari futuri di sviluppo.

4.1 Sviluppi futuri

Oltre alle caratteristiche implementate dal candidato nel corso della realizzazione del progetto, alcuni possibili sviluppi sono desiderabili:

• estendere il piano di collaudo al maggior numero di casi d’uso possibili al fine di migliorare la qualit`agenerale del prodotto; ci`orenderebbe necessaria l’esecuzione di molteplici iterazioni del processo di sviluppo, in modo tale da consentire un’ancora pi`utempestiva rilevazione degli errori di programma;

• implementazione di strategie di continuous integration allo scopo di permettere al singolo sviluppatore di integrare frequentemente il proprio lavoro con quello del resto del team, eseguendo sessioni di collaudo automatizzate a ogni nuova iterazione.

4.2 Conclusioni

Tutti gli obiettivi del piano di lavoro iniziale sono stati raggiunti nei tempi previsti.

Durante l’esperienza lavorativa presso la Heyware s.r.l. il candidato ha avuto l’oc- casione di apprendere numerosi aspetti teorici ai quali fanno riferimento le diverse tecniche e metodologie di collaudo del software e di mettere al servizio degli altri sviluppatori, impegnati nello sviluppo del progetto FileRock, le proprie conoscenze

39 40 CAPITOLO 4. CONCLUSIONI pregresse del linguaggio Python e dei protocolli di garanzia di qualit`a,ottenendo risultati molto pi`uche soddisfacenti in termini di crescita professionale. Appendice A

Licenza

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

• Redistributions of works must retain the original copyright notice, this list of conditions and the following disclaimer.

• Redistributions in binary form must reproduce the original copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

• Neither the name of the W3C nor the names of its contributors may be used to endorse or promote products derived from this work without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, IN- CLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DIS- CLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIB- UTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOW- EVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CON- TRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,

i ii APPENDICE A. LICENZA

EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Glossario

test case Un test case ´eun insieme di dati, condizioni e operazioni attraverso le quali `epossibile determinare la correttezza del comportamento di un componente software in fase di collaudo. test fixture Una fixture ´eun insieme di attributi, operazioni e dati di input necessari all’inizializzazione di casi di test. test suite Una test suite ´euna collezione di test case correlati, solitamente eseguiti in modo sequenziale all’interno della stessa sessione di collaudo.

iii iv Glossario Bibliografia

[ale] Nm report for week ending 06 jun 2010. Online: http://lists.debian.org/debian- newmaint/2010/06/msg00006.html.

[And86] Stephen J. Andriole. Software Validation, Verification, Testing, and Documentation. Petrocelli Books, 1986. Princeton, NJ.

[app] Ubuntu application indicators. Online: https://unity.ubuntu.com/projects/ appindicators/.

[Bin99] Robert V. Binder. Testing Object-Oriented Systems: Models, Patterns, and Tools. Addison Wesley, 1999.

[Boe89] Barry W. Boehm. Software Risk Management. IEEE Computer Society Press, 1989.

[Bor06] Borland Software Corporation. How to successfully automate the functional testing process. 2006. Online: http://www.computerworld.com/pdfs/functional_testing_ process2_pdf.pdf.

[BP84] Victor R. Basili and Barry T. Perricone. Software error and complexity: An empirical investigation. Communications of the ACM, 27:42–52, January 1984. Online: http: //www.lsmod.de/~bernhard/cvs/text/dipl/papers/p42-basili.pdf.

[cov] coverage: Code coverage measurement for python. Online: https://pypi.python.org/ pypi/coverage.

[Cro06] Douglas Crockford. The application/json Media Type for JavaScript Object Notation (JSON). July 2006. Online: http://tools.ietf.org/html/rfc4627.

[deba] Becoming a debian developer. Online: https://wiki.debian.org/DebianDeveloper.

[debb] Debian - the universal operating system. Online: http://www.debian.org/intro/ about.

[Debc] Il Progetto Debian. Il Contratto Sociale e le Linee Guida Debian per il Software Libero. Online: http://www.debian.org/social_contract.it.html.

[DeM99] Tom DeMarco. Management can make quality (im)possible. In Cutter IT Summit, Boston, April 1999.

[fila] Online: http://www.filerock.com/.

[filb] ITP: filerock-client – client for FileRock Secure Cloud Storage. Online: http://bugs. debian.org/cgi-bin/bugreport.cgi?bug=696541.

[FSF] Inc. Free Software Foundation. Standards for command line interfaces. Online: http: //www.gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html.

v vi BIBLIOGRAFIA

[Gar88] David A. Garvin. Managing Quality: The Strategic and Competitive Edge. Free Press, February 1988.

[GT01] Michael T. Goodrich, , and Roberto Tamassia. Efficient authenticated dictionaries with skip lists and commutative hashing. January 2001. Online: http://www.cs.jhu.edu/ ~goodrich/cgc/pubs/hashskip.pdf.

[GTS01] Michael T. Goodrich, Roberto Tamassia, and Andrew Schwerin. Implementation of an authenticated dictionary with skip lists and commutative hashing. In DARPA INFORMATION SURVIVABILITY CONFERENCE AND EXPOSITION, pages 68– 82. IEEE Computer Society Press, 2001. Online: http://cs.brown.edu/cgc/stms/ papers/discex2001.pdf.

[GW08] Karen Mercedes Goertzel and Theodore Winograd. Enhancing the development life cycle to produce secure software. Technical Report DAN 358844, DACS Data and Analysis Center for Software, October 2008. Online: http://www.seas.upenn.edu/ ~lee/09cis480/papers/DACS-358844.pdf.

[Har00] M. J. Harrold. Testing: a roadmap. In Proceedings of the Conference on the Future of Software Engineering, ICSE ’00. ACM, June 2000.

[HH88] W.C. Hetzel and B. Hetzel. The Complete Guide to Software Testing. Wiley, 1988.

[iso99] Iso/iec 9001: Quality management systems - requirements. Technical report, International Standards Organization, 1999.

[iso03] Iso/iec 9126-3: Software engineering – product quality – part 3: Internal metrics. Tech- nical report, International Standards Organization, 2003. Online: http://www.iso. org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=22891.

[iso05] Software engineering – software product quality requirements and evaluation (square) – guide to square. Technical report, International Standards Organization, 2005.

[iso10] Iso/iec 24765: Systems and software engineering - vocabulary. Technical report, International Standards Organization, 2010.

[JG88] Joseph M. Juran and Frank M. Gryna. Juran’s quality control handbook. McGraw-Hill, 1988.

[Jon87] James V. Jones. Integrated Logistics Support Handbook. McGraw Hill Professional, June 1987.

[JS] Ian Jackson and Christian Schwarz. Debian policy manual. Online: http://www. debian.org/doc/debian-policy/.

[KH07] Adam Kolawa and Dorota Huizinga. Automated Defect Prevention: Best Practices in Software Management. Wiley-IEEE Computer Society Press, 2007.

[kis] Keep It Simple, Stupid principle. Online: http://people.apache.org/~fhanik/kiss. html.

[Koc98] Paul C. Kocher. On certificate revocation and validation. 1998.

[Kop11] H. Kopetz. Real-Time Systems: Design Principles for Distributed Embedded Applications. Real-Time Systems Series. Springer, 2011. BIBLIOGRAFIA vii

[KP96] B. Kitchenham and S.L. Pfleeger. Software quality: the elusive target. In Software, IEEE, volume 13, pages 12–21. IEEE Computer Society Press, January 1996.

[Mer80] Ralph C. Merkle. Protocols for public key cryptosystems. 1980.

[Nar12] Massimo Nardelli. Strutture dati autenticate applicate in un servizio di sincronizzazione e backup, 2012.

[NN98] Moni Naor and Kobbi Nissim. Certificate revocation and certificate update. In USENIX SECURITY SYMPOSIUM. USENIX Association, 1998.

[nos] Online: http://nose.readthedocs.org/.

[Pan99] Jiantao Pan. Software testing. Topics in Dependable Embedded Systems, 1999. Carnegie Mellon University.

[PCCW93] Mark C. Paulk, Bill Curtis, Mary Beth Chrissis, and Charles V. Weber. Capability maturity model for software, version 1.1. Technical Report CMU/SEI-93-TR-024, ESC- TR-93-177, Carnegie Mellon University, Feb 1993. Online: http://www.sei.cmu.edu/ reports/93tr024.pdf.

[pep] Pep-8: Style guide for python code. Online: http://www.python.org/dev/peps/pep- 0008/.

[Per11] Chad Perrin. The CIA Triad. 2011. Online: http://www.techrepublic.com/blog/ security/the-cia-triad/.

[pos08] Posix.1-2008 - the open group base specifications issue 7, 2008. Online: http://pubs. opengroup.org/onlinepubs/9699919799/.

[Pug90] William Pugh. Skip lists: A probabilistic alternative to balanced trees. Communications of the ACM, 33:668–676, January 1990. Online: http://www.cs.jhu.edu/~goodrich/ cgc/pubs/hashskip.pdf.

[pyl] Online: http://www.pylint.org/.

[Pyt91] Python Software Foundation. HISTORY file. 1991. Online: http://svn.python.org/ view/*checkout*/python/trunk/Misc/HISTORY.

[pyt09] Is python slower than Java. 2009. Online: http://stackoverflow.com/a/1177553.

[qua] Online: http://en.wikipedia.org/wiki/File:SoftwareQualityCharacteristicAttributeRelationship. png.

[qui] Quilt. Online: http://savannah.nongnu.org/projects/quilt.

[Riv92] Ronald L. Rivest. The MD5 Message-Digest Algorithm. April 1992. Online: http: //tools.ietf.org/html/rfc1321.

[She31] Walter A. Shewhart. Economic control of quality of manufactured product. 1931.

[Tra99] Eushiuan Tran. Verification/validation/certification. Topics in Dependable Embedded Systems, 1999. Carnegie Mellon University.

[Tre] Alessio Treglia. FileRock client packaging. Online: http://anonscm.debian.org/ gitweb/?p=collab-maint/filerock-client.git.

[ubua] Ubuntu. Online: http://www.ubuntu.com. viii BIBLIOGRAFIA

[ubub] Ubuntu Core Developers. Online: https://wiki.ubuntu.com/UbuntuDevelopers# Ubuntu_Core_Developers.

[uni] Unity. Online: https://unity.ubuntu.com/.

[wxw] wxWidgets. Online: http://www.wxwidgets.org/. Ringraziamenti

Questa opera `ededicata a Valentina, senza la quale mi sarei perso nell’oscurit`adella mia follia, e a Gianna e Gianni, i miei genitori, senza i quali non sarei mai arrivato a questo punto.

Seguo un elenco pressoch`eesaustivo di persone, organizzazioni, progetti, animali e cose che hanno contribuito, direttamente o indirettamente, al suo compimento e il supporto di ognuno di loro `estato assolutamente indispensabile durante una o pi`ufasi della sua realizzazione:

Maurizio Pizzonia, Ludovica Adacher, il Programma Erasmus e l’Unione Europea, the City of Aberdeen, the University of Aberdeen, Francesco Giovanni Malcangi, Susanna Cocco, Alex Turner-Moore, Alberto Lazzarin, Karoly Albert Szabo, Reinhard Schillberg, Niccol`oC. M. Bianchi, Christoph Oberlack, Amandine Fouquault, Stefanie Gerdes, Andy Braescu, David Bowitz, Martha Riva, Daniele La Cecilia, Margherita Di Leo, Martina Loleo, Matteo Cesaro, Pietro Zanta, Sotirios Longinos, l’inverno scozzese, Andrea Grandi, Andrea Cimitan, Fabio Marzocca, Flavia Weisghizzi, Luca Ferretti, Dennis Ritchie, Guido Van Rossum, The Debian Project, The Ubuntu Communi- ty, KDE, The LaTeX project, Sublime Text, Stefano Zacchiroli, Luca Falavigna, Enrico Zini, Leo Iannacone, Matteo F. Vescovi, The Debian Multimedia Maintainers Team, Agostino Russo, Mauro Sbarigia, Marco Trevisan, Elia Silvia, Simone Martinelli, Marella Santilli, Alessio il barbiere, l’intero albero genealogico della Famiglia Severin, l’intero albero genealogico della Famiglia Treglia, Nello Martinelli, Stefania Silvagni, Martina Martinelli, Assuntina, Pizzeria On The Green, Zia Assun- ta, Zio Dario, Eugenio Sbardella, Anna Eugenia Morini, Gianluca Palmieri, Francesco Benedetto, Thangavel Thevar, Heyware s.r.l., Glow Digital Ltd, Google Inc., Facebook Inc., Canonical Ltd, Sourcefabric o.p.s., Toshiba Corporation, Acer Inc., Dropbox Inc., AS Roma, Francesco Totti, Fed- erico Balzaretti, Dario Fo, Boris la Serie (e il Film), Corrado Guzzanti, Caterina Guzzanti, Francesco Pannofino, Pietro Sermonti, Alessandro Tiberi, Paolo Calabresi, Ninni Bruschetta, Antonio Cata- nia, Karin Proia, Carolina Crescentini, Valerio Mastandrea, Giorgio Tirabassi, Gli Sceneggiatori, Antonio Albanese, Daniele Luttazzi, Fabrizio De Andr`e,Giorgio Gaber, Georges Brassens, Ennio Morricone, Luis Bacalov, Vangelis, Miles Davis, Paolo Conte, Frank Zappa, Giorgio Moroder, Don- na Summer, Aretha Franklin, Bee Gees, Franco Micalizzi, Raphael Gualazzi, Mario Biondi, Daft Punk, Justice, Air, R¨oyksopp, Stuart Price, Guns N Roses, John Legend, , , Phoenix, Mirwais, Cassius, Benjamin Diamond, Franz Ferdinand, , Chicken Lips, Stardust, Chicks on Speed, Peaches, Parov Stellar, , Iggy Pop, Kraftwerk, Solomon Burke, Elvis Costello, Arctic Monkeys, The Presets, Digitalism, Soulwax, LCD Soundystem, The Rolling Stones, Elton John, The Queen, The Doors, Bob Marley, Tom Jones, The Who, Three Dog Night, Joe Cocker, John Cleary and the Absolute Monster Gentlemen, Annibale e I Cantori x BIBLIOGRAFIA

Moderni, Prophilax, Ceppaflex, Marino Sumo, Sergio Leone, Carlo Verdone, Paolo Sorrentino, Rid- ley Scott, Quentin Tarantino, Eli Roth, Samuel L. Jackson, Leonardo Di Caprio, Christoph Waltz, Jamie Foxx, Tim Roth, Sacha Baron Cohen, Rupert Everett, Hugh Laurie, Clint Eastwood, Gian Maria Volont`e, Lee Van Cliff, Eli Wallach, Franco Nero, Tom´as Mili´an, Franco Lechner, Alberto Sordi, Nino Manfredi, Ugo Tognazzi, Bud Spencer, Terence Hill, Paolo Villaggio, Friedrich Wilhelm Nietzsche, Johann Gottlieb Fichte, Gorgia, Lucius Annaeus Seneca, Marcus Annaeus Lucanus, Lu- cretius Carus, Quintus Horatius Flaccus, Gaius Lucilius, Gaius Petronius Arbiter, Marcus Valerius Martialis, Decimus Iunius Iuvenalis, il Fatto Quotidiano, Laphroaig, Oban, Glenfiddich, Old Putney, Union Bar, The Archibald Simpson, Sir Duncan Rice Library, il Comune e la Biblioteca comunale di Aprilia, Bar Rossi, Liceo Statale A. Meucci, Scuola Media A. Gramsci, il Comune e la Biblioteca comunale di Anzio, the City of Edinburgh, Tiki Cafe, Student Residents’ Assistants at Hillhead Halls, Grosvenor Casino, Espionage, the City of London, the Lambeth Council, Clapham Park, Abode Clapham, Her Majesty The Queen In Right Of England Elizabeth II, United Kingdom, Fed- erico Gasparro, Peter Ilinov, Valeria Galli, Cosmo Di Nitto, Daniele Palladino, Manuel Ottaviani, Issam, Alessio Guzzon, Vincenzo Luongo, Davide Albarello, Paolo Segreto, Roberto Grigatti, Marco Ferrazza, Alessandro Faiella, Simone Sartori, Mauro Rasera, il gruppo del poker, Clay (Armanda) e Baccaro.